| Conditions | 49 |
| Total Lines | 181 |
| Lines | 0 |
| Ratio | 0 % |
| Changes | 2 | ||
| Bugs | 0 | Features | 0 |
Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.
For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.
Commonly applied refactorings include:
If many parameters/temporary variables are present:
Complex classes like describe_template() often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.
Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.
| 1 | # pylint: disable=unused-variable,expression-not-assigned,misplaced-comparison-constant,singleton-comparison |
||
| 17 | def describe_template(): |
||
| 18 | |||
| 19 | def it_supports_comparison(): |
||
| 20 | t1 = Template('abc', "A Thing") |
||
| 21 | t2 = Template('def') |
||
| 22 | t3 = Template('def', "Do This") |
||
| 23 | |||
| 24 | assert t1 != t2 |
||
| 25 | assert t2 == t3 |
||
| 26 | assert t1 < t3 |
||
| 27 | |||
| 28 | def describe_get_path(): |
||
| 29 | |||
| 30 | @patch('pathlib.Path.is_file', Mock(return_value=True)) |
||
| 31 | def it_returns_default_when_no_style(template): |
||
| 32 | expect(template.get_path()) == Path("abc/default.png") |
||
| 33 | |||
| 34 | @patch('pathlib.Path.is_file', Mock(return_value=True)) |
||
| 35 | def it_returns_alternate_when_style_provided(template): |
||
| 36 | expect(template.get_path('Custom')) == Path("abc/custom.png") |
||
| 37 | |||
| 38 | @patch('pathlib.Path.is_file', Mock(return_value=True)) |
||
| 39 | def it_returns_default_when_style_is_none(template): |
||
| 40 | expect(template.get_path(None)) == Path("abc/default.png") |
||
| 41 | |||
| 42 | @patch('pathlib.Path.is_file', Mock(return_value=False)) |
||
| 43 | def it_considers_urls_valid_styles(template): |
||
| 44 | url = "http://example.com" |
||
| 45 | path = temp("a9b9f04336ce0181a08e774e01113b31") |
||
| 46 | expect(template.get_path(url)) == path |
||
| 47 | |||
| 48 | @patch('pathlib.Path.is_file', Mock(return_value=True)) |
||
| 49 | def it_caches_file_downloads(template): |
||
| 50 | url = "http://this/will/be/ignored" |
||
| 51 | path = temp("d888710f0697650eb68fc9dcbb976d4c") |
||
| 52 | expect(template.get_path(url)) == path |
||
| 53 | |||
| 54 | def it_handles_bad_urls(template): |
||
| 55 | expect(template.get_path("http://invalid")) == None |
||
| 56 | |||
| 57 | def it_handles_invalid_paths(template): |
||
| 58 | expect(template.get_path("@#$%^")) == None |
||
| 59 | |||
| 60 | def describe_path(): |
||
| 61 | |||
| 62 | def is_returned_when_file_exists(template): |
||
| 63 | template.root = "my_root" |
||
| 64 | |||
| 65 | with patch('pathlib.Path.is_file', Mock(return_value=True)): |
||
| 66 | path = template.path |
||
| 67 | |||
| 68 | expect(path) == Path("my_root/abc/default.png") |
||
| 69 | |||
| 70 | def is_none_when_no_file(template): |
||
| 71 | template.root = "my_root" |
||
| 72 | |||
| 73 | with patch('pathlib.Path.is_file', Mock(return_value=False)): |
||
| 74 | path = template.path |
||
| 75 | |||
| 76 | expect(path) == None |
||
| 77 | |||
| 78 | def describe_default_path(): |
||
| 79 | |||
| 80 | def is_based_on_lines(template): |
||
| 81 | expect(template.default_path) == "foo/bar" |
||
| 82 | |||
| 83 | def is_underscore_when_no_lines(template): |
||
| 84 | template.lines = [] |
||
| 85 | |||
| 86 | expect(template.default_path) == "_" |
||
| 87 | |||
| 88 | def describe_styles(): |
||
| 89 | |||
| 90 | @patch('os.listdir', Mock(return_value=[])) |
||
| 91 | def is_empty_when_no_alternate_images(template): |
||
| 92 | expect(template.styles) == [] |
||
| 93 | |||
| 94 | @patch('os.listdir', Mock(return_value=['foo.jpg', 'bar.png'])) |
||
| 95 | def is_filesnames_of_alternate_images(template): |
||
| 96 | expect(template.styles) == ['bar', 'foo'] |
||
| 97 | |||
| 98 | def describe_sample_path(): |
||
| 99 | |||
| 100 | def is_based_on_lines(template): |
||
| 101 | expect(template.sample_path) == "foo/bar" |
||
| 102 | |||
| 103 | def is_placeholder_when_no_lines(template): |
||
| 104 | template.lines = [] |
||
| 105 | |||
| 106 | expect(template.sample_path) == "your_text/goes_here" |
||
| 107 | |||
| 108 | def describe_keywords(): |
||
| 109 | |||
| 110 | def is_the_set_of_all_relevant_terms(template): |
||
| 111 | template.lines[0] = "A day in the life" |
||
| 112 | |||
| 113 | expect(template.keywords) == \ |
||
| 114 | {'bar', 'the', 'day', 'in', 'abc', 'a', 'life'} |
||
| 115 | |||
| 116 | def describe_search(): |
||
| 117 | |||
| 118 | def it_counts_contained_terms(template): |
||
| 119 | template.key = 'Foo' |
||
| 120 | template.name = "The Foobar Meme" |
||
| 121 | template.aliases.append('Foo') |
||
| 122 | template.aliases.append('Foobar') |
||
| 123 | template.lines[0] = "This on time foobar happened" |
||
| 124 | |||
| 125 | expect(template.search("Foo")) == 5 |
||
| 126 | |||
| 127 | def it_treats_none_specially(template): |
||
| 128 | expect(template.search(None)) == -1 |
||
| 129 | |||
| 130 | def describe_validate_meta(): |
||
| 131 | |||
| 132 | def with_no_name(template): |
||
| 133 | template.name = None |
||
| 134 | |||
| 135 | expect(template.validate_meta()) == False |
||
| 136 | |||
| 137 | def with_no_default_image(template): |
||
| 138 | expect(template.validate_meta()) == False |
||
| 139 | |||
| 140 | def with_nonalphanumberic_name(template): |
||
| 141 | template.name = "'ABC' Meme" |
||
| 142 | |||
| 143 | expect(template.validate_meta()) == False |
||
| 144 | |||
| 145 | def describe_validate_link(): |
||
| 146 | |||
| 147 | @pytest.fixture(autouse=True) |
||
| 148 | def enable_validation(monkeypatch): |
||
| 149 | monkeypatch.setenv('VALIDATE_LINKS', "true") |
||
| 150 | |||
| 151 | def with_bad_link(template): |
||
| 152 | mock_response = Mock() |
||
| 153 | mock_response.status_code = 404 |
||
| 154 | |||
| 155 | with patch('requests.head', Mock(return_value=mock_response)): |
||
| 156 | template.link = "example.com/fake" |
||
| 157 | |||
| 158 | expect(template.validate_link(delay=0)) == False |
||
| 159 | |||
| 160 | @patch('pathlib.Path.is_file', Mock(return_value=True)) |
||
| 161 | def with_cached_valid_link(template): |
||
| 162 | template.link = "already_cached_site.com" |
||
| 163 | |||
| 164 | expect(template.validate_link(delay=0)) == True |
||
| 165 | |||
| 166 | def describe_validate_size(): |
||
| 167 | |||
| 168 | @pytest.mark.parametrize('dimensions,valid', [ |
||
| 169 | ((Template.MIN_WIDTH, Template.MIN_HEIGHT), True), |
||
| 170 | ((Template.MIN_WIDTH - 1, Template.MIN_HEIGHT), False), |
||
| 171 | ((Template.MIN_WIDTH, Template.MIN_HEIGHT - 1), False), |
||
| 172 | ((Template.MIN_WIDTH - 1, Template.MIN_HEIGHT - 1), False), |
||
| 173 | ]) |
||
| 174 | @patch('PIL.Image.open') |
||
| 175 | def with_various_dimenions(mock_open, template, dimensions, valid): |
||
| 176 | mock_img = Mock() |
||
| 177 | mock_img.size = dimensions |
||
| 178 | mock_open.return_value = mock_img |
||
| 179 | |||
| 180 | expect(template.validate_size()) == valid |
||
| 181 | |||
| 182 | def describe_validate(): |
||
| 183 | |||
| 184 | def with_no_validators(template): |
||
| 185 | expect(template.validate([])) == True |
||
| 186 | |||
| 187 | def with_all_passing_validators(template): |
||
| 188 | """Verify a template is valid if all validators pass.""" |
||
| 189 | mock_validators = [lambda: True] |
||
| 190 | |||
| 191 | expect(template.validate(validators=mock_validators)) == True |
||
| 192 | |||
| 193 | def with_one_failing_validator(template): |
||
| 194 | """Verify a template is invalid if any validators fail.""" |
||
| 195 | mock_validators = [lambda: False] |
||
| 196 | |||
| 197 | expect(template.validate(validators=mock_validators)) == False |
||
| 198 |