Codebase list pyhamcrest / 91cf597
New upstream version 2.0.3 Ileana Dumitrescu 1 year, 7 months ago
76 changed file(s) with 1155 addition(s) and 652 deletion(s). Raw diff Collapse all Expand all
+0
-2
.coveragerc less more
0 [run]
1 source = hamcrest
0 ---
1 name: CI
2
3 on:
4 push:
5 branches: ["main", "master", "ci-testing-*"]
6
7 pull_request:
8 branches: ["main", "master"]
9
10 workflow_dispatch:
11
12 jobs:
13 tests:
14 name: "Python ${{ matrix.python-version }} / ${{ matrix.os }}"
15 runs-on: "${{ matrix.os }}"
16 env:
17 USING_COVERAGE: "3.7,3.8,3.9,3.10"
18
19 strategy:
20 matrix:
21 os: [ubuntu-latest, macos-latest, windows-latest]
22 python-version:
23 - "3.6"
24 - "3.7"
25 - "3.8"
26 - "3.9"
27 - "3.10.0"
28 - "pypy2"
29 - "pypy3"
30 exclude:
31 - os: macos-latest
32 python-version: pypy3
33
34 steps:
35 - uses: "actions/checkout@v2"
36 - uses: "actions/setup-python@v2"
37 with:
38 python-version: "${{ matrix.python-version }}"
39 - name: "Install dependencies"
40 run: |
41 python -VV
42 python -msite
43 python -m pip install --upgrade pip setuptools wheel
44 python -m pip install --upgrade coverage[toml] virtualenv tox tox-gh-actions
45
46 - name: "Run tox targets for ${{ matrix.python-version }}"
47 run: "python -m tox"
48
49 - name: Upload coverage data
50 uses: actions/upload-artifact@v2
51 with:
52 name: coverage-data
53 path: ".coverage.*"
54 if-no-files-found: ignore
55
56 coverage:
57 needs:
58 - tests
59 runs-on: ubuntu-latest
60 steps:
61 - uses: actions/checkout@v2
62 - uses: actions/setup-python@v2
63 with:
64 python-version: "3.10"
65
66 - name: Install coverage
67 run: python -m pip install --upgrade coverage[toml]
68
69 - name: Download coverage data
70 uses: actions/download-artifact@v2
71 with:
72 name: coverage-data
73
74 - name: Combine coverage
75 run: python -m coverage combine
76
77 # ignore-errors is so that we don't gag on missing code in .tox environments
78 - name: Generate the HTML report
79 run: python -m coverage html --skip-covered --skip-empty --ignore-errors
80
81 - name: Upload the HTML report
82 uses: actions/upload-artifact@v2
83 with:
84 name: html-report
85 path: htmlcov
86
87 # ignore-errors is so that we don't gag on missing code in .tox environments
88 - name: Enforce the coverage
89 run: python -m coverage report --ignore-errors --fail-under 95
90
91 package:
92 name: "Build & verify package"
93 runs-on: "ubuntu-latest"
94
95 steps:
96 - uses: "actions/checkout@v2"
97 - uses: "actions/setup-python@v1"
98 with:
99 python-version: "3.10"
100
101 - name: Check if we have the publish key
102 env:
103 TEST_PYPI_API_TOKEN: ${{ secrets.TEST_PYPI_API_TOKEN }}
104 if: "${{ env.TEST_PYPI_API_TOKEN != '' }}"
105 run: |
106 echo "DO_PUBLISH=yes" >> $GITHUB_ENV
107
108 - name: "Install pep517 and twine"
109 run: "python -m pip install pep517 twine"
110 - name: "Build package"
111 run: "python -m pep517.build --source --binary ."
112 - name: "List result"
113 run: "ls -l dist"
114 - name: "Check long_description"
115 run: "python -m twine check dist/*"
116 - name: "Publish package to TestPyPI"
117 uses: "pypa/gh-action-pypi-publish@release/v1"
118 if: "${{ env.DO_PUBLISH == 'yes' }}"
119 with:
120 user: "__token__"
121 password: "${{ secrets.TEST_PYPI_API_TOKEN }}"
122 repository_url: "https://test.pypi.org/legacy/"
123 skip_existing: true
124
125 install-dev:
126 strategy:
127 matrix:
128 os: ["ubuntu-latest", "windows-latest", "macos-latest"]
129
130 name: "Verify dev env / ${{ matrix.os }}"
131 runs-on: "${{ matrix.os }}"
132
133 steps:
134 - uses: "actions/checkout@v2"
135 - uses: "actions/setup-python@v2"
136 with:
137 python-version: "3.9"
138 - name: "Install in dev mode"
139 run: "python -m pip install -e .[dev]"
140 - name: "Import package"
141 run: "python -c 'import hamcrest; print(hamcrest.__version__)'"
33 build/
44 dist/
55 .tox
6 .coverage
6 .coverage*
77 .idea/
88 *~
99 .python-version
1010 .mypy_cache/
11 requirements.txt
12 requirements.in
0 repos:
1 - repo: meta
2 hooks:
3 - id: check-hooks-apply
4 - id: check-useless-excludes
5
6 - repo: https://github.com/pre-commit/pre-commit-hooks
7 rev: v4.0.1
8 hooks:
9 - id: debug-statements
10
11 - repo: https://github.com/asottile/blacken-docs
12 rev: v1.12.0
13 hooks:
14 - id: blacken-docs
15 # args: ["-l100"]
16
17 - repo: https://github.com/PyCQA/flake8
18 rev: 4.0.1
19 hooks:
20 - id: flake8
21 exclude: >-
22 (?x)^(
23 examples/.*\.py$
24 | doc/.*\.py$
25 )
26
27 - repo: https://github.com/psf/black
28 rev: 21.12b0
29 hooks:
30 - id: black
31 # args: ["-l100"]
0 ---
1 version: 2
2 python:
3 # Keep version in sync with tox.ini (docs and gh-actions).
4 version: 3.7
5
6 install:
7 - method: pip
8 path: .
9 extra_requirements:
10 - docs
+0
-62
.travis.yml less more
0 language: python
1 dist: xenial
2
3 matrix:
4 include:
5 - python: 3.5
6 env:
7 - TOX_ENV=py35
8 - python: 3.6
9 env:
10 - TOX_ENV=py36
11 - python: 3.6
12 env:
13 - TOX_ENV=pypy3.6
14 - python: 3.6
15 env:
16 - TOX_ENV=py36-numpy
17 - python: 3.7
18 sudo: yes
19 env:
20 - TOX_ENV=py37
21 - python: 3.8
22 sudo: yes
23 env:
24 - TOX_ENV=py38
25 - os: osx
26 language: generic
27 python: 3.7
28 env:
29 - TOX_ENV=py37
30 - os: windows
31 language: sh
32 python: 3.7
33 before_install:
34 - choco install python --version=3.7.5
35 - export PATH="/c/Python37:/c/Python37/Scripts:$PATH"
36 - python -m pip install --upgrade pip wheel
37 env:
38 - TOX_ENV=py37
39 - python: 3.6
40 env:
41 - TOX_ENV=docs-py3
42 - python: 3.7
43 env:
44 - TOX_ENV=check-format
45 - python: 3.8
46 env:
47 - TOX_ENV=mypy
48
49 before_install:
50 - export EASY_SETUP_URL='http://peak.telecommunity.com/dist/ez_setup.py'
51
52 install:
53 - pip install --upgrade pip tox coveralls
54 - python --version
55 - pip --version
56
57 script:
58 - tox -e $TOX_ENV
59
60 after_success:
61 - coveralls
0 2.0.3 (2021-12-12)
1 ------------------
2
3 Features ^^^^^^^^
4
5 - * Adds the tests to the sdist. Fixed by #150
6
7 `#141 <https://github.com/hamcrest/PyHamcrest/issues/141>`_
8 - * Update the CI to test Python 3.10
9
10 `#160 <https://github.com/hamcrest/PyHamcrest/issues/160>`_
11 - * Add pretty string representation for matchers objects
12
13 `#170 <https://github.com/hamcrest/PyHamcrest/issues/170>`_
14
15
16 Bugfixes ^^^^^^^^
17
18 - * Test coverage is now submitted to codecov.io.
19
20 Fixed by #150
21
22 `#135 <https://github.com/hamcrest/PyHamcrest/issues/135>`_
23 - Change to the ``has_entry()`` matcher - if exactly one key matches, but the value does not, report only the mismatching
24 value.
25
26 Fixed by #157
27
28 `#156 <https://github.com/hamcrest/PyHamcrest/issues/156>`_
29 - * Fix is_() type annotations
30
31 `#180 <https://github.com/hamcrest/PyHamcrest/issues/180>`_
32
33
34 Misc ^^^^
35
36 - `#150 <https://github.com/hamcrest/PyHamcrest/issues/150>`_, `#159 <https://github.com/hamcrest/PyHamcrest/issues/159>`_, `#162 <https://github.com/hamcrest/PyHamcrest/issues/162>`_, `#163 <https://github.com/hamcrest/PyHamcrest/issues/163>`_, `#166 <https://github.com/hamcrest/PyHamcrest/issues/166>`_, `#175 <https://github.com/hamcrest/PyHamcrest/issues/175>`_
37
38
39 ----
40
41
42 Changelog
43 =========
44
45 Version 2.0.2
46 -------------
47
48 Various type hint bug fixes.
49
50 Version 2.0.1
51 -------------
52
53 * Make hamcrest package PEP 561 compatible, i.e. supply type hints for external use.
54
55 Version 2.0.0
56 -------------
57
58 Drop formal support for 2.x
59 Drop formal support for 3.x < 3.5
60
61 Fix #128 - raises() grows support for additional matchers on exception object.
62
63 * Made has_properties() report all mismatches, not just the first.
64 * Silence warnings.
65 * Type fixes.
66 * Remove obsolete dependencies.
67
68 Version 1.10.1
69 --------------
70
71 Add support up to Python 3.8
72
73 Fix #66 - deprecate contains() in favour of contains_exactly().
74 Fix #72 - make has_properties mismatch description less verbose by adding option to AllOf not to include matcher description in its mismatch messages.
75 Fix #82 - include exception details in mismatch description.
76
77 Version 1.9.0
78 -------------
79
80 Drop formal support for 2.x < 2.7
81 Drop formal support for 3.x < 3.4
82
83 Fix #62 - Return result of a deferred call
84
85 Version 1.8.5
86 -------------
87
88 Fix #56 - incorrect handling of () in is_ matcher
89 Fix #60 - correct calling API call with args
90
91 Version 1.8.4
92 -------------
93
94 * Fix #54 - Make instance_of work with tuple like isinstance and unittest's assertIsInstance
95
96 Version 1.8.3
97 -------------
98
99 * Fix #52 - bad handling when reporting mismatches for byte arrays in Python 3
100
101 Version 1.8.2
102 -------------
103
104 * [Bug] Fix unicode syntax via u() introduction (puppsman)
105
106 Version 1.8.1
107 -------------
108
109 * Added not_ alias for is_not [Matteo Bertini]
110 * Added doc directory to the sdist [Alex Brandt]
111
112 Version 1.8
113 -----------
114
115 * Supported versions
116 - Support for Python 2.5 and Jython 2.5 has been dropped. They may still work, but no promises.
117
118 * Bug Fixes
119 - [#39] is_empty was missing from the global namespace
120
121 * New Features
122 - Support for numpy numeric values in iscloseto (Alexander Beedie)
123 - A matcher targeting exceptions and call results (Per Fagrell)
124
125 Version 1.7
126 -----------
127
128 2 Sep 2013 (Version 1.7.2)
129 * Supported versions
130 - As of this version, support for Python 3.1 has been dropped due to no available CI platform.
131 - Added support for Python 3.3
132
133 * Bug fixes:
134 - string_contains_in_order is now used in the test as it would be in an application, and is properly exported. (Romilly Cocking)
135 - Fix mismatch description of containing_inanyorder (David Keijser)
136 - added import of stringmatches to text/__init__.py (Eric Scheidemantle)
137 - added matches_regexp to __all__ list to library/__init__.py (Eric Scheidemantle)
138
139 5 Jan 2010 (Version 1.7.1)
140 * Bug fixes:
141 - included a fix by jaimegildesagredo for issue #28 (has_properties was not importable)
142 - included a fix by keys for contains_inanyorder
143
144 29 Dec 2012
145 (All changes by Chris Rose unless otherwise noted.)
146
147 * New matchers:
148 - matches_regexp matches a regular expression in a string.
149 - has_properties matches an object with more than one property.
150 - is_empty matches any object with length 0.
151
152 * Improvements:
153 - Can now do matching against old-style classes.
154 - Sequence matchers handle generators, as well as actual sequences and
155 pseudo-sequences.
156 - README enhancements by ming13
157
158
159 Version 1.6
160 -----------
161
162 27 Sep 2011
163 (All changes by Chris Rose unless otherwise noted.)
164
165 * Packaging:
166 - Python 3.2 support.
167
168 * New matchers:
169 - has_property('property_name', value_matcher) matches if object has a property with a given name whose value satisfies a given matcher.
170
171 * Improvements:
172 - hasEntries supports two new calling conventions:
173 has_entries({'key' : value_matcher, 'key_2' : other_value_matcher})
174 has_entries(key=value_matcher, key_2=other_value_matcher)
175 - Describe Unicode strings by their __repr__. Thanks to: Sebastian Arming
176 - Rewrote documentation. (Jon Reid)
177
178
179 Version 1.5
180 -----------
181
182 29 Apr 2011
183 * Packaging:
184 - Python 3.1 support. Thanks to: Chris Rose
185 - Easier installation with bootstrapping. Thanks to: Chris Rose
186
187 * Mock integration:
188 - "match_equality" wraps a matcher to define equality in terms of satisfying the matcher. This allows Hamcrest matchers to be used in libraries that are not Hamcrest-aware, such as Michael Foord's mock library. Thanks to: Chris Rose
189
190 * New matcher:
191 - "string_contains_in_order" matches string containing given list of substrings, in order. Thanks to: Romilly Cocking
192
193 * Improved matchers:
194 - For consistency, changed "any_of" and "all_of" to implicitly wrap non-matcher values in EqualTo. Thanks to: Chris Rose
195 - Changed "sameInstance" mismatch description to omit address when describing
196 None.
197
198
199 Version 1.4
200 -----------
201
202 13 Feb 2011
203 * New matchers:
204 - "has_entries" matches dictionary containing key-value pairs satisfying a given list of alternating keys and value matchers.
205
206 * "assert_that" can be invoked with a single boolean argument; the reason message is now optional. This is a convenience replacement for assertTrue. Thanks to: Jeong-Min Lee
207
208 * Improved descriptions:
209 - Reverted 1.3 change: Describe None as "<None>" after all, since it is an object.
210 - "is_" no longer says "is ..." in its description, but just lets the inner description pass through.
211 - Consistently use articles to begin descriptions, such as "a sequence containing" instead of "sequence containing".
212
213
214 Version 1.3
215 -----------
216
217 04 Feb 2011
218 * PyHamcrest is now compatible with Python 3! To install PyHamcrest on Python 3:
219 - Install the "distribute" package, http://pypi.python.org/pypi/distribute
220 - Run "python3 setup.py install"
221 Unit tests are not converted by the install procedure. Run "2to3 -nw ." separately to convert them. You may discover import statements in the __init__.py files (and one in core/base_description.py) that need dot prefixes.
222 Thanks to: Jeong-Min Lee
223
224 * Improved descriptions and mismatch descriptions of several matchers, including:
225 - Fixed "contains" and "contains_inanyorder" to describe mismatch if item is not a sequence.
226 - Fixed "described_as" to use nested matcher to generate mismatch description.
227 - "same_instance" is more readable, and includes object memory addresses.
228 - If object has a length, "has_length" mismatch describes actual length.
229 - Describe None as "None" instead of "<None>".
230 - Don't wrap angle brackets around a description that already has them.
231 - Improved readability of several matchers.
232
233
234 Version 1.2.1
235 -------------
236
237 04 Jan 2011
238 * Fixed "assert_that" to describe the diagnosis of the mismatch, not just the
239 mismatched value. PyHamcrest will now give even more useful information.
240
241 * Expanded BaseDescription.append_description_of to handle all types of values, not just self-describing values.
242
243 * Deprecated:
244 - Description.append_value no longer needed; call append_description_of instead.
245 - BaseDescription.append_value_list no longer needed; call append_list instead.
246 - SelfDescribingValue no longer needed.
247
248 1.2.1 fixes to 1.2:
249 - Corrected manifest so install works. Thanks to: Jeong-Min Lee
250
251
252 Version 1.1
253 -----------
254
255 28 Dec 2010
256 * New matchers:
257 - "contains" matches sequence containing matching items in order.
258 - "contains_inanyorder" matches sequence containing matching items in any order.
259
260 * Added Sphinx documentation support.
261
262
263 Version 1.0
264 -----------
265
266 04 Dec 2010
267 * First official release
268 * Text matchers now support Unicode strings
269
270 15 Jan 2008
271 * Initial submission
+0
-208
CHANGES.txt less more
0 === Version 2.0.2 ===
1
2 Various type hint bug fixes.
3
4 === Version 2.0.1 ===
5
6 * Make hamcrest package PEP 561 compatible, i.e. supply type hints for external use.
7
8 === Version 2.0.0 ==
9
10 Drop formal support for 2.x
11 Drop formal support for 3.x < 3.5
12
13 Fix #128 - raises() grows support for additional matchers on exception object.
14
15 * Made has_properties() report all mismatches, not just the first.
16 * Silence warnings.
17 * Type fixes.
18 * Remove obsolete dependencies.
19
20 === Version 1.10.1 ==
21
22 Add support up to Python 3.8
23
24 Fix #66 - deprecate contains() in favour of contains_exactly().
25 Fix #72 - make has_properties mismatch description less verbose by adding option to AllOf not to include matcher description in its mismatch messages.
26 Fix #82 - include exception details in mismatch description.
27
28 === Version 1.9.0 ==
29
30 Drop formal support for 2.x < 2.7
31 Drop formal support for 3.x < 3.4
32
33 Fix #62 - Return result of a deferred call
34
35 === Version 1.8.5 ===
36
37 Fix #56 - incorrect handling of () in is_ matcher
38 Fix #60 - correct calling API call with args
39
40 === Version 1.8.4 ==
41
42 * Fix #54 - Make instance_of work with tuple like isinstance and unittest's assertIsInstance
43
44 === Version 1.8.3 ===
45
46 * Fix #52 - bad handling when reporting mismatches for byte arrays in Python 3
47
48 === Version 1.8.2 ===
49
50 * [Bug] Fix unicode syntax via u() introduction (puppsman)
51
52 === Version 1.8.1 ===
53
54 * Added not_ alias for is_not [Matteo Bertini]
55 * Added doc directory to the sdist [Alex Brandt]
56
57 === Version 1.8 ==
58
59 * Supported versions
60 - Support for Python 2.5 and Jython 2.5 has been dropped. They may still work, but no promises.
61
62 * Bug Fixes
63 - [#39] is_empty was missing from the global namespace
64
65 * New Features
66 - Support for numpy numeric values in iscloseto (Alexander Beedie)
67 - A matcher targeting exceptions and call results (Per Fagrell)
68
69 === Version 1.7 ==
70
71 2 Sep 2013 (Version 1.7.2)
72 * Supported versions
73 - As of this version, support for Python 3.1 has been dropped due to no available CI platform.
74 - Added support for Python 3.3
75
76 * Bug fixes:
77 - string_contains_in_order is now used in the test as it would be in an application, and is properly exported. (Romilly Cocking)
78 - Fix mismatch description of containing_inanyorder (David Keijser)
79 - added import of stringmatches to text/__init__.py (Eric Scheidemantle)
80 - added matches_regexp to __all__ list to library/__init__.py (Eric Scheidemantle)
81
82 5 Jan 2010 (Version 1.7.1)
83 * Bug fixes:
84 - included a fix by jaimegildesagredo for issue #28 (has_properties was not importable)
85 - included a fix by keys for contains_inanyorder
86
87 29 Dec 2012
88 (All changes by Chris Rose unless otherwise noted.)
89
90 * New matchers:
91 - matches_regexp matches a regular expression in a string.
92 - has_properties matches an object with more than one property.
93 - is_empty matches any object with length 0.
94
95 * Improvements:
96 - Can now do matching against old-style classes.
97 - Sequence matchers handle generators, as well as actual sequences and
98 pseudo-sequences.
99 - README enhancements by ming13
100
101
102 === Version 1.6 ==
103
104 27 Sep 2011
105 (All changes by Chris Rose unless otherwise noted.)
106
107 * Packaging:
108 - Python 3.2 support.
109
110 * New matchers:
111 - has_property('property_name', value_matcher) matches if object has a property with a given name whose value satisfies a given matcher.
112
113 * Improvements:
114 - hasEntries supports two new calling conventions:
115 has_entries({'key' : value_matcher, 'key_2' : other_value_matcher})
116 has_entries(key=value_matcher, key_2=other_value_matcher)
117 - Describe Unicode strings by their __repr__. Thanks to: Sebastian Arming
118 - Rewrote documentation. (Jon Reid)
119
120
121 == Version 1.5 ==
122
123 29 Apr 2011
124 * Packaging:
125 - Python 3.1 support. Thanks to: Chris Rose
126 - Easier installation with bootstrapping. Thanks to: Chris Rose
127
128 * Mock integration:
129 - "match_equality" wraps a matcher to define equality in terms of satisfying the matcher. This allows Hamcrest matchers to be used in libraries that are not Hamcrest-aware, such as Michael Foord's mock library. Thanks to: Chris Rose
130
131 * New matcher:
132 - "string_contains_in_order" matches string containing given list of substrings, in order. Thanks to: Romilly Cocking
133
134 * Improved matchers:
135 - For consistency, changed "any_of" and "all_of" to implicitly wrap non-matcher values in EqualTo. Thanks to: Chris Rose
136 - Changed "sameInstance" mismatch description to omit address when describing
137 None.
138
139
140 == Version 1.4 ==
141
142 13 Feb 2011
143 * New matchers:
144 - "has_entries" matches dictionary containing key-value pairs satisfying a given list of alternating keys and value matchers.
145
146 * "assert_that" can be invoked with a single boolean argument; the reason message is now optional. This is a convenience replacement for assertTrue. Thanks to: Jeong-Min Lee
147
148 * Improved descriptions:
149 - Reverted 1.3 change: Describe None as "<None>" after all, since it is an object.
150 - "is_" no longer says "is ..." in its description, but just lets the inner description pass through.
151 - Consistently use articles to begin descriptions, such as "a sequence containing" instead of "sequence containing".
152
153
154 == Version 1.3 ==
155
156 04 Feb 2011
157 * PyHamcrest is now compatible with Python 3! To install PyHamcrest on Python 3:
158 - Install the "distribute" package, http://pypi.python.org/pypi/distribute
159 - Run "python3 setup.py install"
160 Unit tests are not converted by the install procedure. Run "2to3 -nw ." separately to convert them. You may discover import statements in the __init__.py files (and one in core/base_description.py) that need dot prefixes.
161 Thanks to: Jeong-Min Lee
162
163 * Improved descriptions and mismatch descriptions of several matchers, including:
164 - Fixed "contains" and "contains_inanyorder" to describe mismatch if item is not a sequence.
165 - Fixed "described_as" to use nested matcher to generate mismatch description.
166 - "same_instance" is more readable, and includes object memory addresses.
167 - If object has a length, "has_length" mismatch describes actual length.
168 - Describe None as "None" instead of "<None>".
169 - Don't wrap angle brackets around a description that already has them.
170 - Improved readability of several matchers.
171
172
173 == Version 1.2.1 ==
174
175 04 Jan 2011
176 * Fixed "assert_that" to describe the diagnosis of the mismatch, not just the
177 mismatched value. PyHamcrest will now give even more useful information.
178
179 * Expanded BaseDescription.append_description_of to handle all types of values, not just self-describing values.
180
181 * Deprecated:
182 - Description.append_value no longer needed; call append_description_of instead.
183 - BaseDescription.append_value_list no longer needed; call append_list instead.
184 - SelfDescribingValue no longer needed.
185
186 1.2.1 fixes to 1.2:
187 - Corrected manifest so install works. Thanks to: Jeong-Min Lee
188
189
190 == Version 1.1 ==
191
192 28 Dec 2010
193 * New matchers:
194 - "contains" matches sequence containing matching items in order.
195 - "contains_inanyorder" matches sequence containing matching items in any order.
196
197 * Added Sphinx documentation support.
198
199
200 == Version 1.0 ==
201
202 04 Dec 2010
203 * First official release
204 * Text matchers now support Unicode strings
205
206 15 Jan 2008
207 * Initial submission
0 include CHANGES.txt
1 include LICENSE.txt
2 include README.md
0 include LICENSE.txt *.rst *.md *.toml *.yml *.yaml *.ini
1 include requirements*
2 graft .github
3
4 # Tests
5 include tox.ini conftest.py
6 recursive-include tests *.py
7 recursive-include tests *.yml
8
9 # Documentation
10 include doc/Makefile doc/docutils.conf
311 recursive-include examples *.py
4 recursive-include doc *
12 recursive-include doc *.png
13 recursive-include doc *.svg
14 recursive-include doc *.py
15 recursive-include doc *.rst
16 prune doc/_build
17
18 # remove some of the random source
19 prune docker
20 exclude release.sh
21
22 # Just to keep check-manifest happy; on releases those files are gone.
23 # Last rule wins!
24 exclude changelog.d/*.rst
25 include changelog.d/towncrier_template.rst
00 PyHamcrest
11 ==========
22
3 | |docs| |travis| |coveralls| |landscape| |scrutinizer|
4 | |version| |downloads| |wheel| |supported-versions| |supported-implementations|
5 | |GitHub forks| |GitHub stars| |GitHub watchers| |GitHub contributors| |Lines of Code|
6 | |GitHub issues| |GitHub issues-closed| |GitHub pull-requests| |GitHub pull-requests closed|
7
8 .. |docs| image:: https://readthedocs.org/projects/pyhamcrest/badge/
9 :target: https://pyhamcrest.readthedocs.org/
3 | |docs| |status| |version| |downloads|
4
5 .. |docs| image:: https://readthedocs.org/projects/pyhamcrest/badge/?version=latest
6 :target: https://pyhamcrest.readthedocs.io/en/latest/?badge=latest
107 :alt: Documentation Status
118
12 .. |travis| image:: http://img.shields.io/travis/hamcrest/PyHamcrest/master.svg
13 :alt: Travis-CI Build Status
14 :target: https://travis-ci.org/hamcrest/PyHamcrest
15
16 .. |appveyor| image:: https://ci.appveyor.com/api/projects/status/github/hamcrest/PyHamcrest?branch=master&svg=true
17 :alt: AppVeyor Build Status
18 :target: https://ci.appveyor.com/project/hamcrest/PyHamcrest
19
20 .. |coveralls| image:: http://img.shields.io/coveralls/hamcrest/PyHamcrest/master.svg?style=flat
21 :alt: Coverage Status
22 :target: https://coveralls.io/r/hamcrest/PyHamcrest
23
24 .. |landscape| image:: https://landscape.io/github/hamcrest/PyHamcrest/master/landscape.svg?style=flat
25 :target: https://landscape.io/github/hamcrest/PyHamcrest/master
26 :alt: Code Quality Status
9 .. |status| image:: https://github.com/hamcrest/PyHamcrest/workflows/CI/badge.svg
10 :alt: CI Build Status
11 :target: https://github.com/hamcrest/PyHamcrest/actions?query=workflow%3ACI
2712
2813 .. |version| image:: http://img.shields.io/pypi/v/PyHamcrest.svg?style=flat
2914 :alt: PyPI Package latest release
3217 .. |downloads| image:: http://img.shields.io/pypi/dm/PyHamcrest.svg?style=flat
3318 :alt: PyPI Package monthly downloads
3419 :target: https://pypi.python.org/pypi/PyHamcrest
35
36 .. |wheel| image:: https://pypip.in/wheel/PyHamcrest/badge.svg?style=flat
37 :alt: PyPI Wheel
38 :target: https://pypi.python.org/pypi/PyHamcrest
39
40 .. |supported-versions| image:: https://pypip.in/py_versions/PyHamcrest/badge.svg?style=flat
41 :alt: Supported versions
42 :target: https://pypi.python.org/pypi/PyHamcrest
43
44 .. |GitHub forks| image:: https://img.shields.io/github/forks/hamcrest/PyHamcrest.svg?label=Fork&logo=github
45 :alt: GitHub forks
46 :target: https://github.com/hamcrest/PyHamcrest/network/members
47
48 .. |GitHub stars| image:: https://img.shields.io/github/stars/hamcrest/PyHamcrest.svg?label=Star&logo=github
49 :alt: GitHub stars
50 :target: https://github.com/hamcrest/PyHamcrest/stargazers/
51
52 .. |GitHub watchers| image:: https://img.shields.io/github/watchers/hamcrest/PyHamcrest.svg?label=Watch&logo=github
53 :alt: GitHub watchers
54 :target: https://github.com/hamcrest/PyHamcrest/watchers/
55
56 .. |GitHub contributors| image:: https://img.shields.io/github/contributors/hamcrest/PyHamcrest.svg?logo=github
57 :alt: GitHub contributors
58 :target: https://github.com/hamcrest/PyHamcrest/graphs/contributors/
59
60 .. |GitHub issues| image:: https://img.shields.io/github/issues/hamcrest/PyHamcrest.svg?logo=github
61 :alt: GitHub issues
62 :target: https://github.com/hamcrest/PyHamcrest/issues/
63
64 .. |GitHub issues-closed| image:: https://img.shields.io/github/issues-closed/hamcrest/PyHamcrest.svg?logo=github
65 :alt: GitHub issues-closed
66 :target: https://github.com/hamcrest/PyHamcrest/issues?q=is%3Aissue+is%3Aclosed
67
68 .. |GitHub pull-requests| image:: https://img.shields.io/github/issues-pr/hamcrest/PyHamcrest.svg?logo=github
69 :alt: GitHub pull-requests
70 :target: https://github.com/hamcrest/PyHamcrest/pulls
71
72 .. |GitHub pull-requests closed| image:: https://img.shields.io/github/issues-pr-closed/hamcrest/PyHamcrest.svg?logo=github
73 :alt: GitHub pull-requests closed
74 :target: https://github.com/hamcrest/PyHamcrest/pulls?utf8=%E2%9C%93&q=is%3Apr+is%3Aclosed
75
76 .. |Lines of Code| image:: https://tokei.rs/b1/github/hamcrest/PyHamcrest
77 :alt: Lines of Code
78 :target: https://github.com/hamcrest/PyHamcrest
79
80 .. |supported-implementations| image:: https://pypip.in/implementation/PyHamcrest/badge.svg?style=flat
81 :alt: Supported implementations
82 :target: https://pypi.python.org/pypi/PyHamcrest
83
84 .. |scrutinizer| image:: https://img.shields.io/scrutinizer/g/hamcrest/PyHamcrest/master.svg?style=flat
85 :alt: Scrtinizer Status
86 :target: https://scrutinizer-ci.com/g/hamcrest/PyHamcrest/
8720
8821
8922 Introduction
12457 from hamcrest import *
12558 import unittest
12659
60
12761 class BiscuitTest(unittest.TestCase):
12862 def testEquals(self):
129 theBiscuit = Biscuit('Ginger')
130 myBiscuit = Biscuit('Ginger')
63 theBiscuit = Biscuit("Ginger")
64 myBiscuit = Biscuit("Ginger")
13165 assert_that(theBiscuit, equal_to(myBiscuit))
13266
133 if __name__ == '__main__':
67
68 if __name__ == "__main__":
13469 unittest.main()
13570
13671 The ``assert_that`` function is a stylized sentence for making a test
14580
14681 .. code:: python
14782
148 assert_that(theBiscuit.getChocolateChipCount(), equal_to(10), 'chocolate chips')
149 assert_that(theBiscuit.getHazelnutCount(), equal_to(3), 'hazelnuts')
83 assert_that(theBiscuit.getChocolateChipCount(), equal_to(10), "chocolate chips")
84 assert_that(theBiscuit.getHazelnutCount(), equal_to(3), "hazelnuts")
15085
15186 As a convenience, assert_that can also be used to verify a boolean condition:
15287
15388 .. code:: python
15489
155 assert_that(theBiscuit.isCooked(), 'cooked')
90 assert_that(theBiscuit.isCooked(), "cooked")
15691
15792 This is equivalent to the ``assert_`` method of unittest.TestCase, but because
15893 it's a standalone function, it offers greater flexibility in test writing.
281216 from hamcrest.core.base_matcher import BaseMatcher
282217 from hamcrest.core.helpers.hasmethod import hasmethod
283218
219
284220 class IsGivenDayOfWeek(BaseMatcher):
285
286221 def __init__(self, day):
287222 self.day = day # Monday is 0, Sunday is 6
288223
289224 def _matches(self, item):
290 if not hasmethod(item, 'weekday'):
225 if not hasmethod(item, "weekday"):
291226 return False
292227 return item.weekday() == self.day
293228
294229 def describe_to(self, description):
295 day_as_string = ['Monday', 'Tuesday', 'Wednesday', 'Thursday',
296 'Friday', 'Saturday', 'Sunday']
297 description.append_text('calendar date falling on ') \
298 .append_text(day_as_string[self.day])
230 day_as_string = [
231 "Monday",
232 "Tuesday",
233 "Wednesday",
234 "Thursday",
235 "Friday",
236 "Saturday",
237 "Sunday",
238 ]
239 description.append_text("calendar date falling on ").append_text(
240 day_as_string[self.day]
241 )
242
299243
300244 def on_a_saturday():
301245 return IsGivenDayOfWeek(5)
325269 import unittest
326270 from isgivendayofweek import on_a_saturday
327271
272
328273 class DateTest(unittest.TestCase):
329274 def testDateIsOnASaturday(self):
330275 d = datetime.date(2008, 4, 26)
331276 assert_that(d, is_(on_a_saturday()))
332277
333 if __name__ == '__main__':
278
279 if __name__ == "__main__":
334280 unittest.main()
335281
336282 Even though the ``on_a_saturday`` function creates a new matcher each time it
0 {% for section, _ in sections.items() %} {% set underline = underlines[0] %}{% if section %}{{section}} {{ underline * section|length }}{% set underline = underlines[1] %}
1
2 {% endif %}
3
4 {% if sections[section] %} {% for category, val in definitions.items() if category in sections[section]%} {{ definitions[category]['name'] }} {{ underline * definitions[category]['name']|length }}
5
6 {% if definitions[category]['showcontent'] %} {% for text, values in sections[section][category].items() %} - {{ text }}
7
8 {{ values|join(',n ') }}
9 {% endfor %}
10
11 {% else %} - {{ sections[section][category]['']|join(', ') }}
12
13 {% endif %} {% if sections[section][category]|length == 0 %} No significant changes.
14
15 {% else %} {% endif %}
16
17 {% endfor %} {% else %} No significant changes.
18
19 {% endif %} {% endfor %} ----
+0
-2
devel-requirements.txt less more
0 pytest>=2.6
1 Sphinx>=1.2.2
1111 # serve to show the default.
1212
1313 import sys, os
14 import six
15 import sphinx_rtd_theme
14 import alabaster
1615
1716 # If extensions (or modules to document with autodoc) are in another directory,
1817 # add these directories to sys.path here. If the directory is relative to the
1918 # documentation root, use os.path.abspath to make it absolute, like shown here.
20 sys.path.insert(0, os.path.abspath('..'))
19 sys.path.insert(0, os.path.abspath("../src"))
2120
2221 from hamcrest import __version__
2322
2423 # -- General configuration -----------------------------------------------------
2524
2625 # If your documentation needs a minimal Sphinx version, state it here.
27 #needs_sphinx = '1.0'
26 # needs_sphinx = '1.0'
2827
2928 # Add any Sphinx extension module names here, as strings. They can be extensions
3029 # coming with Sphinx (named 'sphinx.ext.*') or your custom ones.
31 extensions = ['sphinx.ext.autodoc', 'sphinx.ext.intersphinx']
32
33 autodoc_default_options = {'members': None, 'show-inheritance': None}
34 intersphinx_mapping = {'python': ('http://docs.python.org/2.6', None)}
30 extensions = ["sphinx.ext.autodoc", "sphinx.ext.intersphinx", "alabaster"]
31
32 autodoc_default_options = {"members": None, "show-inheritance": None}
33 autodoc_typehints = "description"
34 intersphinx_mapping = {"python": ("http://docs.python.org/3", None)}
3535
3636 # Add any paths that contain templates here, relative to this directory.
37 templates_path = ['_templates']
37 templates_path = ["_templates"]
3838
3939 # The suffix of source filenames.
40 source_suffix = '.rst'
40 source_suffix = ".rst"
4141
4242 # The encoding of source files.
43 #source_encoding = 'utf-8-sig'
43 # source_encoding = 'utf-8-sig'
4444
4545 # The master toctree document.
46 master_doc = 'index'
46 master_doc = "index"
4747
4848 # General information about the project.
49 project = six.u('PyHamcrest')
50 copyright = six.u('2020, hamcrest.org')
49 project = "PyHamcrest"
50 copyright = "2020, hamcrest.org"
5151
5252 # The version info for the project you're documenting, acts as replacement for
5353 # |version| and |release|, also used in various other places throughout the
5454 # built documents.
5555 #
56 # The full version, including alpha/beta/rc tags.
57 version = __version__
58
5659 # The short X.Y version.
57 version = __version__
58 # The full version, including alpha/beta/rc tags.
59 release = __version__
60 release = ".".join(version.split(".")[:2])
6061
6162 # The language for content autogenerated by Sphinx. Refer to documentation
6263 # for a list of supported languages.
63 #language = None
64 # language = None
6465
6566 # There are two options for replacing |today|: either, you set today to some
6667 # non-false value, then it is used:
67 #today = ''
68 # today = ''
6869 # Else, today_fmt is used as the format for a strftime call.
69 #today_fmt = '%B %d, %Y'
70 # today_fmt = '%B %d, %Y'
7071
7172 # List of patterns, relative to source directory, that match files and
7273 # directories to ignore when looking for source files.
73 exclude_patterns = ['_build']
74 exclude_patterns = ["_build"]
7475
7576 # The reST default role (used for this markup: `text`) to use for all documents.
76 default_role = 'py:obj'
77 default_role = "py:obj"
7778
7879 # If true, '()' will be appended to :func: etc. cross-reference text.
7980 add_function_parentheses = False
8081
8182 # If true, the current module name will be prepended to all description
8283 # unit titles (such as .. function::).
83 #add_module_names = True
84 # add_module_names = True
8485
8586 # If true, sectionauthor and moduleauthor directives will be shown in the
8687 # output. They are ignored by default.
87 #show_authors = False
88 # show_authors = False
8889
8990 # The name of the Pygments (syntax highlighting) style to use.
90 pygments_style = 'sphinx'
91 pygments_style = "sphinx"
9192
9293 # A list of ignored prefixes for module index sorting.
93 #modindex_common_prefix = []
94 # modindex_common_prefix = []
9495
9596
9697 # -- Options for HTML output ---------------------------------------------------
9798
9899 # The theme to use for HTML and HTML Help pages. See the documentation for
99100 # a list of builtin themes.
100 html_theme = 'sphinx_rtd_theme'
101 html_theme = "alabaster"
101102
102103 # Theme options are theme-specific and customize the look and feel of a theme
103104 # further. For a list of options available for each theme, see the
104105 # documentation.
105 #html_theme_options = {}
106 # html_theme_options = {}
106107
107108 # Add any paths that contain custom themes here, relative to this directory.
108 #html_theme_path = []
109 html_theme_path = [ sphinx_rtd_theme.get_html_theme_path() ]
109 # html_theme_path = []
110 html_theme_path = [alabaster.get_path()]
110111
111112 # The name for this set of Sphinx documents. If None, it defaults to
112113 # "<project> v<release> documentation".
113 #html_title = None
114 # html_title = None
114115
115116 # A shorter title for the navigation bar. Default is the same as html_title.
116 #html_short_title = None
117 # html_short_title = None
117118
118119 # The name of an image file (relative to this directory) to place at the top
119120 # of the sidebar.
120 #html_logo = None
121 # html_logo = None
121122
122123 # The name of an image file (within the static path) to use as favicon of the
123124 # docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32
124125 # pixels large.
125 #html_favicon = None
126 # html_favicon = None
126127
127128 # Add any paths that contain custom static files (such as style sheets) here,
128129 # relative to this directory. They are copied after the builtin static files,
131132
132133 # If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
133134 # using the given strftime format.
134 #html_last_updated_fmt = '%b %d, %Y'
135 # html_last_updated_fmt = '%b %d, %Y'
135136
136137 # If true, SmartyPants will be used to convert quotes and dashes to
137138 # typographically correct entities.
138 #html_use_smartypants = True
139 # html_use_smartypants = True
139140
140141 # Custom sidebar templates, maps document names to template names.
141 #html_sidebars = {}
142 # html_sidebars = {}
142143
143144 # Additional templates that should be rendered to pages, maps page names to
144145 # template names.
145 #html_additional_pages = {}
146 # html_additional_pages = {}
146147
147148 # If false, no module index is generated.
148 #html_domain_indices = True
149 # html_domain_indices = True
149150
150151 # If false, no index is generated.
151 #html_use_index = True
152 # html_use_index = True
152153
153154 # If true, the index is split into individual pages for each letter.
154 #html_split_index = False
155 # html_split_index = False
155156
156157 # If true, links to the reST sources are added to the pages.
157 #html_show_sourcelink = True
158 # html_show_sourcelink = True
158159
159160 # If true, "Created using Sphinx" is shown in the HTML footer. Default is True.
160 #html_show_sphinx = True
161 # html_show_sphinx = True
161162
162163 # If true, "(C) Copyright ..." is shown in the HTML footer. Default is True.
163 #html_show_copyright = True
164 # html_show_copyright = True
164165
165166 # If true, an OpenSearch description file will be output, and all pages will
166167 # contain a <link> tag referring to it. The value of this option must be the
167168 # base URL from which the finished HTML is served.
168 #html_use_opensearch = ''
169 # html_use_opensearch = ''
169170
170171 # This is the file name suffix for HTML files (e.g. ".xhtml").
171 #html_file_suffix = None
172 # html_file_suffix = None
172173
173174 # Output file base name for HTML help builder.
174 htmlhelp_basename = 'PyHamcrestdoc'
175 htmlhelp_basename = "PyHamcrestdoc"
175176
176177
177178 # -- Options for LaTeX output --------------------------------------------------
178179
179180 # The paper size ('letter' or 'a4').
180 #latex_paper_size = 'letter'
181 # latex_paper_size = 'letter'
181182
182183 # The font size ('10pt', '11pt' or '12pt').
183 #latex_font_size = '10pt'
184 # latex_font_size = '10pt'
184185
185186 # Grouping the document tree into LaTeX files. List of tuples
186187 # (source start file, target name, title, author, documentclass [howto/manual]).
187188 latex_documents = [
188 ('index', 'PyHamcrest.tex', six.u('PyHamcrest Documentation'),
189 six.u('hamcrest.org'), 'manual'),
189 ("index", "PyHamcrest.tex", "PyHamcrest Documentation", "hamcrest.org"),
190 "manual",
190191 ]
191192
192193 # The name of an image file (relative to this directory) to place at the top of
193194 # the title page.
194 #latex_logo = None
195 # latex_logo = None
195196
196197 # For "manual" documents, if this is true, then toplevel headings are parts,
197198 # not chapters.
198 #latex_use_parts = False
199 # latex_use_parts = False
199200
200201 # If true, show page references after internal links.
201 #latex_show_pagerefs = False
202 # latex_show_pagerefs = False
202203
203204 # If true, show URL addresses after external links.
204 #latex_show_urls = False
205 # latex_show_urls = False
205206
206207 # Additional stuff for the LaTeX preamble.
207 #latex_preamble = ''
208 # latex_preamble = ''
208209
209210 # Documents to append as an appendix to all manuals.
210 #latex_appendices = []
211 # latex_appendices = []
211212
212213 # If false, no module index is generated.
213 #latex_domain_indices = True
214 # latex_domain_indices = True
214215
215216 # PyHamcrest customization: Don't skip BaseMatcher's _matches method
216217 def skip_member(app, what, name, obj, skip, options):
217 if skip and str(obj).find('BaseMatcher._matches') >= 0:
218 if skip and str(obj).find("BaseMatcher._matches") >= 0:
218219 return False
219220 return skip
220221
222
221223 def setup(app):
222 app.connect('autodoc-skip-member', skip_member)
224 app.connect("autodoc-skip-member", skip_member)
225
223226
224227 # -- Options for manual page output --------------------------------------------
225228
226229 # One entry per manual page. List of tuples
227230 # (source start file, name, description, authors, manual section).
228 man_pages = [
229 ('index', 'pyhamcrest', six.u('PyHamcrest Documentation'),
230 [six.u('hamcrest.org')], 1)
231 ]
231 man_pages = [("index", "pyhamcrest", "PyHamcrest Documentation", ["hamcrest.org"], 1)]
00 import sys
1 sys.path.append('..')
1
2 sys.path.append("..")
23
34 from hamcrest.core.base_matcher import BaseMatcher
45 from hamcrest.core.helpers.hasmethod import hasmethod
1617
1718 def _matches(self, item):
1819 """Test whether item matches."""
19 if not hasmethod(item, 'weekday'):
20 if not hasmethod(item, "weekday"):
2021 return False
2122 return item.weekday() == self.day
2223
2324 def describe_to(self, description):
2425 """Describe the matcher."""
25 day_as_string = ['Monday', 'Tuesday', 'Wednesday', 'Thursday',
26 'Friday', 'Saturday', 'Sunday']
27 description.append_text('calendar date falling on ') \
28 .append_text(day_as_string[self.day])
26 day_as_string = [
27 "Monday",
28 "Tuesday",
29 "Wednesday",
30 "Thursday",
31 "Friday",
32 "Saturday",
33 "Sunday",
34 ]
35 description.append_text("calendar date falling on ").append_text(day_as_string[self.day])
2936
3037
3138 def on_a_saturday():
3643 class SampleTest(unittest.TestCase):
3744 def testDateIsOnASaturday(self):
3845 """Example of successful match."""
39 d = datetime.date(2008, 04, 26)
46 d = datetime.date(2008, 4, 26)
4047 assert_that(d, is_(on_a_saturday()))
4148
4249 def testFailsWithMismatchedDate(self):
4350 """Example of what happens with date that doesn't match."""
44 d = datetime.date(2008, 04, 06)
51 d = datetime.date(2008, 4, 6)
4552 assert_that(d, is_(on_a_saturday()))
4653
4754 def testFailsWithNonDate(self):
4855 """Example of what happens with object that isn't a date."""
49 d = 'oops'
56 d = "oops"
5057 assert_that(d, is_(on_a_saturday()))
5158
5259
53 if __name__ == '__main__':
60 if __name__ == "__main__":
5461 unittest.main()
00 import sys
1 sys.path.append('..')
1
2 sys.path.append("..")
23
34 from hamcrest import *
45 import unittest
67
78 class ExampleWithAssertThat(unittest.TestCase):
89 def testUsingAssertThat(self):
9 assert_that('xx', is_('xx'))
10 assert_that('yy', is_not('xx'))
11 assert_that('i like cheese', contains_string('cheese'))
10 assert_that("xx", is_("xx"))
11 assert_that("yy", is_not("xx"))
12 assert_that("i like cheese", contains_string("cheese"))
1213
1314 def testCanAlsoSupplyDescriptiveReason(self):
14 assert_that('xx', is_('xx'), 'description')
15 assert_that("xx", is_("xx"), "description")
1516
1617 def testCanAlsoAssertPlainBooleans(self):
17 assert_that(True, 'This had better not fail')
18 assert_that(True, "This had better not fail")
1819
1920
20 if __name__ == '__main__':
21 if __name__ == "__main__":
2122 unittest.main()
0 [build-system]
1 requires = ["setuptools>=40.6.0", "wheel"]
2 build-backend = "setuptools.build_meta"
3
4
5 [tool.coverage.run]
6 parallel = true
7 branch = true
8 source = ["hamcrest"]
9
10 [tool.coverage.paths]
11 source = ["src", ".tox/*/site-packages"]
12
13 [tool.coverage.report]
14 show_missing = true
15 skip_covered = true
16 exclude_lines = [
17 # a more strict default pragma
18 "\\# pragma: no cover\\b",
19
20 # allow defensive code
21 "^\\s*raise AssertionError\\b",
22 "^\\s*raise NotImplementedError\\b",
23 "^\\s*return NotImplemented\\b",
24 "^\\s*raise$",
25
26 # typing-related code
27 "^if (False|TYPE_CHECKING):",
28 ": \\.\\.\\.(\\s*#.*)?$",
29 "^ +\\.\\.\\.$",
30 "-> ['\"]?NoReturn['\"]?:",
31 ]
32 [tool.black]
33 line_length = 100
34
35 [tool.interrogate]
36 verbose = 2
37 fail-under = 100
38 whitelist-regex = ["test_.*"]
39
40
41 [tool.isort]
42 profile = "hamcrests"
43
44 known_first_party = "hamcrest"
45 known_third_party = ["hypothesis", "pytest", "setuptools", "six"]
46
47
48 [tool.towncrier]
49 package = "hamcrest"
50 package_dir = "src"
51 filename = "CHANGELOG.rst"
52 template = "changelog.d/towncrier_template.rst"
53 issue_format = "`#{issue} <https://github.com/hamcrest/PyHamcrest/issues/{issue}>`_"
54 directory = "changelog.d"
55 title_format = "{version} ({project_date})"
56 underlines = ["-", "^"]
+0
-1
requirements.txt less more
0
+0
-3
setup.cfg less more
0 [egg_info]
1 ;tag_build = .dev
2 ;tag_svn_revision = true
1616 # On Python 3, we can't "from hamcrest import __version__" (get ImportError),
1717 # so we extract the variable assignment and execute it ourselves.
1818 fh = open("src/hamcrest/__init__.py")
19
20 # this will be overridden
21 __version__ = None
1922 try:
2023 for line in fh:
2124 if re.match("__version__.*", line):
2225 exec(line)
26
2327 finally:
2428 if fh:
2529 fh.close()
30
31 assert __version__ is not None
32
33 REQUIREMENTS_DOCS = ["sphinx~=3.0", "alabaster~=0.7"]
34 TESTS_BASIC = [
35 "pytest>=5.0",
36 "pytest-sugar",
37 "pytest-xdist",
38 "coverage[toml]",
39 # No point on Pypy thanks to https://github.com/python/typed_ast/issues/111
40 "pytest-mypy-plugins; platform_python_implementation != 'PyPy'",
41 "types-mock",
42 ]
43 TESTS_NUMPY = ["numpy"]
44 DEV_TOOLS = [
45 "towncrier",
46 "twine",
47 "pytest-mypy",
48 "flake8",
49 "black",
50 "tox",
51 "tox-pyenv",
52 "tox-asdf",
53 ]
54
2655
2756 params = dict(
2857 name="PyHamcrest",
4170 package_data={"hamcrest": ["py.typed"]},
4271 provides=["hamcrest"],
4372 long_description=read("README.rst"),
73 long_description_content_type="text/x-rst",
4474 python_requires=">=3.5",
4575 install_requires=[],
76 extras_require={
77 "docs": REQUIREMENTS_DOCS,
78 "tests": TESTS_BASIC,
79 "tests-numpy": TESTS_BASIC + TESTS_NUMPY,
80 "dev": REQUIREMENTS_DOCS + TESTS_BASIC + DEV_TOOLS,
81 },
4682 classifiers=[
4783 "Development Status :: 5 - Production/Stable",
4884 "Environment :: Console",
5187 "Natural Language :: English",
5288 "Operating System :: OS Independent",
5389 "Programming Language :: Python :: 3",
54 "Programming Language :: Python :: 3.5",
5590 "Programming Language :: Python :: 3.6",
5691 "Programming Language :: Python :: 3.7",
5792 "Programming Language :: Python :: 3.8",
00 from hamcrest.core import *
11 from hamcrest.library import *
2 from hamcrest import core, library
23
3 __version__ = "2.0.2"
4 __version__ = "2.0.3"
45 __author__ = "Chris Rose"
56 __copyright__ = "Copyright 2020 hamcrest.org"
67 __license__ = "BSD, see License.txt"
8
9 __all__ = []
10 __all__.extend(core.__all__)
11 __all__.extend(library.__all__)
33 __author__ = "Jon Reid"
44 __copyright__ = "Copyright 2011 hamcrest.org"
55 __license__ = "BSD, see License.txt"
6
7 __all__ = [
8 "assert_that",
9 "all_of",
10 "any_of",
11 "anything",
12 "calling",
13 "described_as",
14 "equal_to",
15 "instance_of",
16 "is_",
17 "is_not",
18 "none",
19 "not_",
20 "not_none",
21 "raises",
22 "same_instance",
23 ]
0 from textwrap import shorten
01 from typing import Optional, TypeVar
12
23 from hamcrest.core.description import Description
2425 def __str__(self) -> str:
2526 return tostring(self)
2627
28 def __repr__(self) -> str:
29 """Returns matcher string representation."""
30 return "<{0}({1})>".format(
31 self.__class__.__name__, shorten(tostring(self), 60, placeholder="...")
32 )
33
2734 def _matches(self, item: T) -> bool:
2835 raise NotImplementedError("_matches")
2936
1414 __author__ = "Jon Reid"
1515 __copyright__ = "Copyright 2011 hamcrest.org"
1616 __license__ = "BSD, see License.txt"
17
18 __all__ = [
19 "all_of",
20 "any_of",
21 "anything",
22 "calling",
23 "described_as",
24 "equal_to",
25 "instance_of",
26 "is_",
27 "is_not",
28 "none",
29 "not_",
30 "not_none",
31 "raises",
32 "same_instance",
33 ]
0 from typing import Optional, Type, TypeVar, Union, overload
0 from typing import Optional, Type, TypeVar, overload, Any
11
22 from hamcrest.core.base_matcher import BaseMatcher
33 from hamcrest.core.description import Description
4545
4646
4747 @overload
48 def is_(x: Type) -> Matcher[object]:
48 def is_(x: Type) -> Matcher[Any]:
4949 ...
5050
5151
5252 @overload
53 def is_(x: Union[Matcher[T], T]) -> Matcher[T]:
53 def is_(x: Matcher[T]) -> Matcher[T]:
54 ...
55
56
57 @overload
58 def is_(x: T) -> Matcher[T]:
5459 ...
5560
5661
1010
1111 class IsAnything(BaseMatcher[Any]):
1212 def __init__(self, description: Optional[str]) -> None:
13 self.description = description or "ANYTHING" # type: str
13 self.description: str = description or "ANYTHING"
1414
1515 def _matches(self, item: Any) -> bool:
1616 return True
2121 self.pattern = pattern
2222 self.matcher = matching
2323 self.expected = expected
24 self.actual = None # type: Optional[BaseException]
25 self.function = None # type: Optional[Callable[..., Any]]
24 self.actual: Optional[BaseException] = None
25 self.function: Optional[Callable[..., Any]] = None
2626
2727 def _matches(self, function: Callable[..., Any]) -> bool:
2828 if not callable(function):
114114 class DeferredCallable(object):
115115 def __init__(self, func: Callable[..., Any]):
116116 self.func = func
117 self.args = tuple() # type: Tuple[Any, ...]
118 self.kwargs = {} # type: Mapping[str, Any]
117 self.args: Tuple[Any, ...] = tuple()
118 self.kwargs: Mapping[str, Any] = {}
119119
120120 def __call__(self):
121121 self.func(*self.args, **self.kwargs)
0 from typing import Any, Iterable, Sequence
0 from typing import Any, Iterable
11
22 __author__ = "Jon Reid"
33 __copyright__ = "Copyright 2011 hamcrest.org"
00 from typing import Any, List, Type
11
2 MOCKTYPES = [] # type: List[Type]
2 MOCKTYPES: List[Type] = []
33 try:
44 from mock import Mock
55
1212 __author__ = "Chris Rose"
1313 __copyright__ = "Copyright 2013 hamcrest.org"
1414 __license__ = "BSD, see License.txt"
15
16 __all__ = [
17 "contains",
18 "contains_exactly",
19 "contains_inanyorder",
20 "empty",
21 "has_entries",
22 "has_entry",
23 "has_item",
24 "has_items",
25 "has_key",
26 "has_value",
27 "is_in",
28 "only_contains",
29 ]
0 from typing import Hashable, Mapping, TypeVar, Union
0 from typing import Hashable, Mapping, MutableMapping, TypeVar, Union
11
22 from hamcrest.core.base_matcher import BaseMatcher
33 from hamcrest.core.description import Description
3131 self.key_matcher
3232 ).append_text(": ").append_description_of(self.value_matcher).append_text("]")
3333
34 def describe_mismatch(self, item: Mapping[K, V], mismatch_description: Description) -> None:
35 key_matches = self._matching_keys(item)
36 if len(key_matches) == 1:
37 key, value = key_matches.popitem()
38 mismatch_description.append_text("value for ").append_description_of(key).append_text(
39 " "
40 )
41 self.value_matcher.describe_mismatch(value, mismatch_description)
42 else:
43 super().describe_mismatch(item, mismatch_description)
44
45 def describe_match(self, item: Mapping[K, V], match_description: Description) -> None:
46 key_matches = self._matching_keys(item)
47 if len(key_matches) == 1:
48 key, value = key_matches.popitem()
49 match_description.append_text("value for ").append_description_of(key).append_text(" ")
50 self.value_matcher.describe_mismatch(value, match_description)
51 else:
52 super().describe_match(item, match_description)
53
54 def _matching_keys(self, item):
55 key_matches: MutableMapping[K, V] = {}
56 if hasmethod(item, "items"):
57 for key, value in item.items():
58 if self.key_matcher.matches(key):
59 key_matches[key] = value
60 return key_matches
61
3462
3563 def has_entry(
3664 key_match: Union[K, Matcher[K]], value_match: Union[V, Matcher[V]]
2929 for key, value_matcher in self.value_matchers:
3030
3131 try:
32 if not key in item:
32 if key not in item:
3333 if mismatch_description:
3434 mismatch_description.append_text("no ").append_description_of(
3535 key
3838 class IsSequenceContainingEvery(BaseMatcher[Sequence[T]]):
3939 def __init__(self, *element_matchers: Matcher[T]) -> None:
4040 delegates = [cast(Matcher[Sequence[T]], has_item(e)) for e in element_matchers]
41 self.matcher = all_of(*delegates) # type: Matcher[Sequence[T]]
41 self.matcher: Matcher[Sequence[T]] = all_of(*delegates)
4242
4343 def _matches(self, item: Sequence[T]) -> bool:
4444 try:
1313
1414
1515 def isnumeric(value: Any) -> bool:
16 """Confirm that 'value' can be treated numerically; duck-test accordingly
17 """
16 """Confirm that 'value' can be treated numerically; duck-test accordingly"""
1817 if isinstance(value, (float, complex, int)):
1918 return True
2019
2322 return True
2423 except ArithmeticError:
2524 return True
26 except:
25 except Exception:
2726 return False
2827
2928
00 # coding: utf-8
1 import platform
12 from unittest.mock import sentinel
23
34 import pytest
3940 (Described(), "described"),
4041 ("unicode-py3", "'unicode-py3'"),
4142 (b"bytes-py3", "<b'bytes-py3'>"),
42 ("\U0001F4A9", "'{0}'".format("\U0001F4A9")),
43 pytest.param(
44 "\U0001F4A9",
45 "'{0}'".format("\U0001F4A9"),
46 marks=pytest.mark.skipif(
47 platform.python_implementation() == "PyPy",
48 reason="Inexplicable failure on PyPy. Not super important, I hope!",
49 ),
50 ),
4351 ),
4452 )
4553 def test_append_description_types(desc, described, appended):
44
55 import unittest
66
7 from hamcrest.core.base_matcher import *
8 from hamcrest_unit_test.matcher_test import *
7 from hamcrest.core.base_matcher import BaseMatcher
8 from hamcrest_unit_test.matcher_test import assert_match_description, assert_mismatch_description
99
1010 __author__ = "Jon Reid"
1111 __copyright__ = "Copyright 2011 hamcrest.org"
3636 def testMatchDescriptionShouldDescribeItem(self):
3737 assert_match_description("was <99>", PassingBaseMatcher(), 99)
3838
39 def testMatcherReprShouldDescribeMatcher(self):
40 assert repr(FailingBaseMatcher()) == "<FailingBaseMatcher(SOME DESCRIPTION)>"
41
42 def testMatcherReprShouldTruncateLongDescription(self):
43 class LongDescriptionMatcher(BaseMatcher):
44 def describe_to(self, description):
45 description.append_text("1234 " * 13)
46
47 assert (
48 repr(LongDescriptionMatcher())
49 == "<LongDescriptionMatcher(1234 1234 1234 1234 1234 1234 1234 1234 1234 1234 1234...)>"
50 )
51
3952
4053 if __name__ == "__main__":
4154 unittest.main()
0 from hamcrest.library.collection.is_empty import *
0 from hamcrest.library.collection.is_empty import empty
11 from hamcrest_unit_test.matcher_test import MatcherTest
22
33 __author__ = "Chris Rose"
00 import unittest
11
2 from hamcrest import starts_with
23 from hamcrest.core.core.isequal import equal_to
3 from hamcrest.library.collection.isdict_containing import *
4 from hamcrest_unit_test.matcher_test import MatcherTest
4 from hamcrest.library.collection.isdict_containing import has_entry
5 from hamcrest_unit_test.matcher_test import (
6 MatcherTest,
7 assert_match_description,
8 assert_mismatch_description,
9 )
510
611 from .quasidict import QuasiDictionary
712
3944 def testDescribeMismatch(self):
4045 self.assert_describe_mismatch("was 'bad'", has_entry("a", 1), "bad")
4146
47 def test_describe_single_matching_key_mismatching_value(self):
48 assert_mismatch_description("value for 'a' was <2>", has_entry("a", 1), {"a": 2})
49 assert_mismatch_description(
50 "value for 'aa' was <2>", has_entry(starts_with("a"), 1), {"aa": 2}
51 )
52 assert_mismatch_description(
53 "was <{'ab': 2, 'ac': 3}>", has_entry(starts_with("a"), 1), {"ab": 2, "ac": 3}
54 )
55
56 def test_describe_match(self):
57 assert_match_description("value for 'a' was <1>", has_entry("a", 1), {"a": 1, "b": 2})
58
4259
4360 if __name__ == "__main__":
4461 unittest.main()
66 import unittest
77
88 from hamcrest.core.core.isequal import equal_to
9 from hamcrest.library.collection.isdict_containingentries import *
9 from hamcrest.library.collection.isdict_containingentries import has_entries
1010 from hamcrest_unit_test.matcher_test import MatcherTest
1111
1212 __author__ = "Jon Reid"
00 import unittest
11
22 from hamcrest.core.core.isequal import equal_to
3 from hamcrest.library.collection.isdict_containingkey import *
3 from hamcrest.library.collection.isdict_containingkey import has_key
44 from hamcrest_unit_test.matcher_test import MatcherTest
55
66 from .quasidict import QuasiDictionary
00 import unittest
11
22 from hamcrest.core.core.isequal import equal_to
3 from hamcrest.library.collection.isdict_containingvalue import *
3 from hamcrest.library.collection.isdict_containingvalue import has_value
44 from hamcrest_unit_test.matcher_test import MatcherTest
55
66 from .quasidict import QuasiDictionary
00 import unittest
11
2 from hamcrest.library.collection.isin import *
2 from hamcrest.library.collection.isin import is_in
33 from hamcrest_unit_test.matcher_test import MatcherTest
44
55 from .sequencemixin import GeneratorForm, SequenceForm
00 import unittest
11
22 from hamcrest.core.core.isequal import equal_to
3 from hamcrest.library.collection.issequence_containing import *
3 from hamcrest.library.collection.issequence_containing import has_item, has_items
44 from hamcrest_unit_test.matcher_test import MatcherTest
55
66 from .quasisequence import QuasiSequence
00 import unittest
11
22 from hamcrest.core.core.isequal import equal_to
3 from hamcrest.library.collection.issequence_containinginanyorder import *
3 from hamcrest.library.collection.issequence_containinginanyorder import contains_inanyorder
44 from hamcrest_unit_test.matcher_test import MatcherTest
55
66 from .quasisequence import QuasiSequence
00 import unittest
11
22 from hamcrest.core.core.isequal import equal_to
3 from hamcrest.library.collection.issequence_containinginorder import *
3 from hamcrest.library.collection.issequence_containinginorder import contains, contains_exactly
44 from hamcrest_unit_test.matcher_test import MatcherTest
55
66 from .quasisequence import QuasiSequence
00 import unittest
11
22 from hamcrest.core.core.isequal import equal_to
3 from hamcrest.library.collection.issequence_onlycontaining import *
3 from hamcrest.library.collection.issequence_onlycontaining import only_contains
44 from hamcrest.library.number.ordering_comparison import less_than
55 from hamcrest_unit_test.matcher_test import MatcherTest
66
55
66 import unittest
77
8 from hamcrest.core.core.allof import *
8 from hamcrest.core.core.allof import AllOf, all_of
99 from hamcrest.core.core.isequal import equal_to
1010 from hamcrest_unit_test.matcher_test import MatcherTest
1111
55
66 import unittest
77
8 from hamcrest.core.core.anyof import *
8 from hamcrest.core.core.anyof import any_of
99 from hamcrest.core.core.isequal import equal_to
1010 from hamcrest_unit_test.matcher_test import MatcherTest
1111
00 import unittest
11
2 from hamcrest.core.core.described_as import *
2 from hamcrest.core.core.described_as import described_as
33 from hamcrest.core.core.isanything import anything
44 from hamcrest_unit_test.matcher_test import MatcherTest
55
00 import unittest
11
2 from hamcrest.core.core.is_ import *
2 from hamcrest.core.core.is_ import is_
33 from hamcrest.core.core.isequal import equal_to
44 from hamcrest_unit_test.matcher_test import MatcherTest
55
55
66 import unittest
77
8 from hamcrest.core.core.isanything import *
8 from hamcrest.core.core.isanything import anything
99 from hamcrest_unit_test.matcher_test import MatcherTest
1010
1111 __author__ = "Jon Reid"
55
66 import unittest
77
8 from hamcrest.core.core.isequal import *
8 from hamcrest.core.core.isequal import equal_to
99 from hamcrest_unit_test.matcher_test import MatcherTest
1010
1111 __author__ = "Jon Reid"
00 import sys
11 import unittest
22
3 from hamcrest.core.core.isinstanceof import *
3 from hamcrest.core.core.isinstanceof import instance_of
44 from hamcrest_unit_test.matcher_test import MatcherTest
55
66 if __name__ == "__main__":
55
66 import unittest
77
8 from hamcrest.core.core.isnone import *
8 from hamcrest.core.core.isnone import none, not_none
99 from hamcrest_unit_test.matcher_test import MatcherTest
1010
1111 __author__ = "Jon Reid"
66 import unittest
77
88 from hamcrest.core.core.isequal import equal_to
9 from hamcrest.core.core.isnot import *
9 from hamcrest.core.core.isnot import is_not
1010 from hamcrest_unit_test.matcher_test import MatcherTest
1111
1212 __author__ = "Jon Reid"
66 import re
77 import unittest
88
9 from hamcrest.core.core.issame import *
9 from hamcrest.core.core.issame import same_instance
1010 from hamcrest.core.string_description import StringDescription
1111 from hamcrest_unit_test.matcher_test import MatcherTest
1212
9393
9494 self.assert_matches(
9595 "Regex",
96 raises(AssertionError, "([\d, ]+)"),
96 raises(AssertionError, r"([\d, ]+)"),
9797 calling(raise_exception).with_args(3, 1, 4),
9898 )
9999
66 import unittest
77
88 from hamcrest.core.core.isequal import equal_to
9 from hamcrest.library.integration.match_equality import *
9 from hamcrest.library.integration.match_equality import match_equality, tostring
1010
1111 __author__ = "Chris Rose"
1212 __copyright__ = "Copyright 2011 hamcrest.org"
00 import unittest
11
2 from hamcrest.library.number.iscloseto import *
2 from hamcrest.library.number.iscloseto import Decimal, close_to, isnumeric
33 from hamcrest_unit_test.matcher_test import MatcherTest
44
55 __author__ = "Jon Reid"
66 import unittest
77 from datetime import date
88
9 from hamcrest.library.number.ordering_comparison import *
9 from hamcrest.library.number.ordering_comparison import (
10 greater_than,
11 greater_than_or_equal_to,
12 less_than,
13 less_than_or_equal_to,
14 )
1015 from hamcrest_unit_test.matcher_test import MatcherTest
1116
1217 __author__ = "Jon Reid"
77
88 from hamcrest.core.core.isequal import equal_to
99 from hamcrest.library.number.ordering_comparison import greater_than
10 from hamcrest.library.object.haslength import *
10 from hamcrest.library.object.haslength import has_length
1111 from hamcrest_unit_test.matcher_test import MatcherTest
1212
1313 __author__ = "Jon Reid"
66 import unittest
77
88 from hamcrest import greater_than
9 from hamcrest.library.object.hasproperty import *
9 from hamcrest.library.object.hasproperty import has_properties, has_property
1010 from hamcrest_unit_test.matcher_test import MatcherTest
1111
1212 __author__ = "Chris Rose"
66 import unittest
77
88 from hamcrest.core.core.isequal import equal_to
9 from hamcrest.library.object.hasstring import *
9 from hamcrest.library.object.hasstring import has_string
1010 from hamcrest_unit_test.matcher_test import MatcherTest
1111
1212 __author__ = "Jon Reid"
22
33 import pytest
44 from hamcrest.core.selfdescribing import SelfDescribing
5 from hamcrest.core.string_description import *
5 from hamcrest.core.string_description import StringDescription
66
77 __author__ = "Jon Reid"
88 __copyright__ = "Copyright 2011 hamcrest.org"
00 import unittest
11
2 from hamcrest.library.text.isequal_ignoring_whitespace import *
2 from hamcrest.library.text.isequal_ignoring_whitespace import equal_to_ignoring_whitespace
33 from hamcrest_unit_test.matcher_test import MatcherTest
44
55 __author__ = "Jon Reid"
00 import pytest
11 from hamcrest.library.text.stringcontains import contains_string
2 from hamcrest_unit_test.matcher_test import *
2 from hamcrest_unit_test.matcher_test import (
3 assert_description,
4 assert_does_not_match,
5 assert_matches,
6 assert_mismatch_description,
7 assert_no_mismatch_description,
8 )
39
410 __author__ = "Jon Reid"
511 __copyright__ = "Copyright 2011 hamcrest.org"
5864
5965
6066 if __name__ == "__main__":
67 import unittest
68
6169 unittest.main()
0 if __name__ == "__main__":
1 import sys
2
3 sys.path.insert(0, "..")
4 sys.path.insert(0, "../..")
5
6 import unittest
7
8 from hamcrest.core.string_description import StringDescription
9 from hamcrest.library.text import string_contains_in_order
10 from hamcrest_unit_test.matcher_test import MatcherTest
11
12 __author__ = "Romilly Cocking"
13 __copyright__ = "Copyright 2011 hamcrest.org"
14 __license__ = "BSD, see License.txt"
15
16
17 matcher = string_contains_in_order("string one", "string two", "string three")
18
19
20 class StringContainsInOrderTest(MatcherTest):
21 def testMatchesIfOrderIsCorrect(self):
22 self.assert_matches(
23 "correct order", matcher, "string one then string two followed by string three"
24 )
25
26 def testDoesNotMatchIfOrderIsIncorrect(self):
27 self.assert_does_not_match(
28 "incorrect order", matcher, "string two then string one followed by string three"
29 )
30
31 def testDoesNotMatchIfExpectedSubstringsAreMissing(self):
32 self.assert_does_not_match("missing string one", matcher, "string two then string three")
33 self.assert_does_not_match("missing string two", matcher, "string one then string three")
34 self.assert_does_not_match("missing string three", matcher, "string one then string two")
35
36 def testMatcherCreationRequiresString(self):
37 self.assertRaises(TypeError, string_contains_in_order, 3)
38
39 def testFailsIfMatchingAgainstNonString(self):
40 self.assert_does_not_match("non-string", matcher, object())
41
42 def testHasAReadableDescription(self):
43 self.assert_description(
44 "a string containing 'string one', 'string two', 'string three' in order", matcher
45 )
46
47 def testSuccessfulMatchDoesNotGenerateMismatchDescription(self):
48 self.assert_no_mismatch_description(
49 matcher, "string one then string two followed by string three"
50 )
51
52 def testMismatchDescription(self):
53 self.assert_mismatch_description("was 'bad'", matcher, "bad")
54
55 def testDescribeMismatch(self):
56 self.assert_describe_mismatch("was 'bad'", matcher, "bad")
0 from hamcrest.library.text import string_contains_in_order
1 from hamcrest_unit_test.matcher_test import MatcherTest
2
3 __author__ = "Romilly Cocking"
4 __copyright__ = "Copyright 2011 hamcrest.org"
5 __license__ = "BSD, see License.txt"
6
7
8 matcher = string_contains_in_order("string one", "string two", "string three")
9
10
11 class StringContainsInOrderTest(MatcherTest):
12 def testMatchesIfOrderIsCorrect(self):
13 self.assert_matches(
14 "correct order", matcher, "string one then string two followed by string three"
15 )
16
17 def testDoesNotMatchIfOrderIsIncorrect(self):
18 self.assert_does_not_match(
19 "incorrect order", matcher, "string two then string one followed by string three"
20 )
21
22 def testDoesNotMatchIfExpectedSubstringsAreMissing(self):
23 self.assert_does_not_match("missing string one", matcher, "string two then string three")
24 self.assert_does_not_match("missing string two", matcher, "string one then string three")
25 self.assert_does_not_match("missing string three", matcher, "string one then string two")
26
27 def testMatcherCreationRequiresString(self):
28 self.assertRaises(TypeError, string_contains_in_order, 3)
29
30 def testFailsIfMatchingAgainstNonString(self):
31 self.assert_does_not_match("non-string", matcher, object())
32
33 def testHasAReadableDescription(self):
34 self.assert_description(
35 "a string containing 'string one', 'string two', 'string three' in order", matcher
36 )
37
38 def testSuccessfulMatchDoesNotGenerateMismatchDescription(self):
39 self.assert_no_mismatch_description(
40 matcher, "string one then string two followed by string three"
41 )
42
43 def testMismatchDescription(self):
44 self.assert_mismatch_description("was 'bad'", matcher, "bad")
45
46 def testDescribeMismatch(self):
47 self.assert_describe_mismatch("was 'bad'", matcher, "bad")
00 import unittest
11
2 from hamcrest.library.text.stringendswith import *
2 from hamcrest.library.text.stringendswith import ends_with
33 from hamcrest_unit_test.matcher_test import MatcherTest
44
55 __author__ = "Jon Reid"
33 sys.path.insert(0, "..")
44 sys.path.insert(0, "../..")
55
6 import re
67 import unittest
78
8 from hamcrest.library.text.stringmatches import *
9 from hamcrest.library.text.stringmatches import matches_regexp
910 from hamcrest_unit_test.matcher_test import MatcherTest
1011
1112 __author__ = "Chris Rose"
00 import unittest
11
2 from hamcrest.library.text.stringstartswith import *
2 from hamcrest.library.text.stringstartswith import starts_with
33 from hamcrest_unit_test.matcher_test import MatcherTest
44
55 __author__ = "Jon Reid"
22 class MyTest(object):
33 pass
44
5
65 except TypeError:
76 print("Object class defined at {0}".format(getattr(object, "__file__", "NOWHERE")))
87 raise
0 - case: is
1 # pypy + mypy doesn't work. See https://foss.heptapod.net/pypy/pypy/-/issues/3526
2 skip: platform.python_implementation() == "PyPy"
3 main: |
4 from hamcrest import assert_that, is_, empty
5 from typing import Any, Sequence
6
7 a: Sequence[Any] = []
8 b = 99
9
10 assert_that(a, is_(empty()))
11 assert_that(b, is_(empty())) # E: Cannot infer type argument 1 of "assert_that"
0 - case: assert_that
1 # pypy + mypy doesn't work. See https://foss.heptapod.net/pypy/pypy/-/issues/3526
2 skip: platform.python_implementation() == "PyPy"
3 main: |
4 from hamcrest import assert_that, instance_of, starts_with
5
6 assert_that("string", starts_with("str"))
7 assert_that("str", instance_of(str))
8 assert_that(99, starts_with("str"))
9 out: |
10 main:5: error: Cannot infer type argument 1 of "assert_that"
0 - case: empty
1 # pypy + mypy doesn't work. See https://foss.heptapod.net/pypy/pypy/-/issues/3526
2 skip: platform.python_implementation() == "PyPy"
3 main: |
4 from hamcrest import assert_that, is_, empty
5
6 assert_that([], empty())
7 assert_that(99, empty()) # E: Cannot infer type argument 1 of "assert_that"
0 - case: equal_to_ignoring_case
1 # pypy + mypy doesn't work. See https://foss.heptapod.net/pypy/pypy/-/issues/3526
2 skip: platform.python_implementation() == "PyPy"
3 main: |
4 from hamcrest import equal_to_ignoring_case
5
6 reveal_type(equal_to_ignoring_case(""))
7 equal_to_ignoring_case("")
8 equal_to_ignoring_case(99)
9 out: |
10 main:3: note: Revealed type is "hamcrest.core.matcher.Matcher[builtins.str]"
11 main:5: error: Argument 1 to "equal_to_ignoring_case" has incompatible type "int"; expected "str"
+0
-5
tests/type-hinting/test.yml less more
0 - case: equal_to_ignoring_case
1 main: |
2 from hamcrest.library.text.isequal_ignoring_case import equal_to_ignoring_case
3
4 reveal_type(equal_to_ignoring_case("")) # N: Revealed type is 'builtins.str*'
0 [pytest]
1 addopts = -ra
2 testpaths = tests
3 xfail_strict = true
4 filterwarnings =
5 once::Warning
6 ignore:::pympler[.*]
7 looponfailroots =
8 src
9 tests
10
11 # Keep docs in sync with docs env and .readthedocs.yml.
12 [gh-actions]
13 python =
14 3.6: py36, py36-numpy
15 3.7: py37, py37-numpy
16 3.8: py38, py38-numpy
17 3.9: py39, py39-numpy, lint, manifest, typing, changelog, docs
18 3.10: py310
19 pypy-2: pypy2
20 pypy-3: pypy3
21
22
023 [tox]
1 envlist = py35,py36,py37,py38,pypy2.7,pypy3.6,docs-py3
2 # Jython is not testable, but there's no reason it should not work.
24 envlist = typing,lint,py36{,-numpy},py37{,-numpy},py38{,-numpy},py39{,-numpy},py310{,-numpy},pypy{,-numpy},pypy3{,-numpy},manifest,docs,pypi-description,changelog,coverage-report
25 isolated_build = True
26
327
428 [testenv]
5 commands = {envbindir}/py.test []
6 {envpython} tests/object_import.py
7 deps = pytest~=5.0
8 pytest-cov~=2.0
29 # Prevent random setuptools/pip breakages like
30 # https://github.com/pypa/setuptools/issues/1042 from breaking our builds.
31 setenv =
32 VIRTUALENV_NO_DOWNLOAD=1
33 extras = {env:TOX_AP_TEST_EXTRAS:tests}
34 commands = python -m pytest {posargs}
935
10 [testenv:jython]
11 deps = pytest
12 commands = {envbindir}/jython tests/alltests.py []
13 {envpython} tests/object_import.py
36
37 [testenv:py27]
38 extras = {env:TOX_AP_TEST_EXTRAS:tests}
39 commands = coverage run -m pytest {posargs}
1440
1541 [testenv:py36-numpy]
16 basepython = python3.6
17 deps = {[testenv]deps}
18 numpy
19 setenv =
20 PYTHONHASHSEED = 4
42 extras = tests-numpy
43 commands = python -m pytest {posargs}
2144
22 [testenv:docs-py3]
23 basepython = python3.6
24 deps = sphinx
25 sphinx_rtd_theme
26 changedir = {toxinidir}/doc
27 commands = sphinx-build -W -b html -d {envtmpdir}/doctrees . {envtmpdir}/html
45 [testenv:py37-numpy]
46 extras = tests-numpy
47 commands = python -m pytest {posargs}
2848
29 [testenv:format]
30 basepython = python3
49 [testenv:py38-numpy]
50 extras = tests-numpy
51 commands = python -m pytest {posargs}
52
53 [testenv:py39-numpy]
54 extras = tests-numpy
55 commands = python -m pytest {posargs}
56
57 [testenv:py37]
58 # Python 3.6+ has a number of compile-time warnings on invalid string escapes.
59 # PYTHONWARNINGS=d and --no-compile below make them visible during the Tox run.
60 install_command = pip install --no-compile {opts} {packages}
61 setenv =
62 PYTHONWARNINGS=d
63 extras = {env:TOX_AP_TEST_EXTRAS:tests}
64 commands = coverage run -m pytest {posargs}
65
66
67 [testenv:py38]
68 # Python 3.6+ has a number of compile-time warnings on invalid string escapes.
69 # PYTHONWARNINGS=d and --no-compile below make them visible during the Tox run.
70 basepython = python3.8
71 install_command = pip install --no-compile {opts} {packages}
72 setenv =
73 PYTHONWARNINGS=d
74 extras = {env:TOX_AP_TEST_EXTRAS:tests}
75 commands = coverage run -m pytest {posargs}
76
77
78 [testenv:py39]
79 # Python 3.6+ has a number of compile-time warnings on invalid string escapes.
80 # PYTHONWARNINGS=d and --no-compile below make them visible during the Tox run.
81 basepython = python3.9
82 install_command = pip install --no-compile {opts} {packages}
83 setenv =
84 PYTHONWARNINGS=d
85 extras = {env:TOX_AP_TEST_EXTRAS:tests}
86 commands = coverage run -m pytest {posargs}
87
88 [testenv:py310]
89 # Python 3.6+ has a number of compile-time warnings on invalid string escapes.
90 # PYTHONWARNINGS=d and --no-compile below make them visible during the Tox run.
91 basepython = python3.10
92 install_command = pip install --no-compile {opts} {packages}
93 setenv =
94 PYTHONWARNINGS=d
95 extras = {env:TOX_AP_TEST_EXTRAS:tests}
96 commands = coverage run -m pytest {posargs}
97
98 [testenv:coverage-report]
99 basepython = python3.9
100 skip_install = true
101 deps = coverage[toml]>=5.0.2
102 commands =
103 coverage combine
104 coverage report
105
106
107 [testenv:lint]
108 basepython = python3.9
31109 skip_install = true
32110 deps =
33 black~=19.10b0
34 isort~=4.0
111 pre-commit
112 passenv = HOMEPATH # needed on Windows
35113 commands =
36 isort {toxinidir}/setup.py
37 isort -rc {toxinidir}/src/
38 isort -rc {toxinidir}/tests/
39 black -l100 -tpy35 src/ tests/ setup.py
114 pre-commit run --all-files
40115
41 [testenv:check-format]
42 basepython = python3
116
117 [testenv:docs]
118 # Keep basepython in sync with gh-actions and .readthedocs.yml.
119 basepython = python3.9
120 extras = docs
121 commands =
122 sphinx-build -n -T -b html -d {envtmpdir}/doctrees doc doc/_build/html
123
124
125 [testenv:manifest]
126 basepython = python3.9
127 deps = check-manifest
43128 skip_install = true
44 deps = {[testenv:format]deps}
45 commands =
46 isort --check-only {toxinidir}/setup.py
47 isort --check-only -rc {toxinidir}/src/
48 isort --check-only -rc {toxinidir}/tests/
49 black --check -l100 -tpy35 src/ tests/ setup.py
129 commands = check-manifest
50130
51 [tool:isort]
52 multi_line_output=3
53 include_trailing_comma=True
54 force_grid_wrap=0
55 use_parentheses=True
56 line_length=100
57131
58 [testenv:flake8]
59 basepython = python3
132 [testenv:pypi-description]
133 basepython = python3.9
60134 skip_install = true
61135 deps =
62 flake8~=3.0
63 flake8-bugbear~=18.0
64 flake8-comprehensions~=1.0
65 flake8-mutable~=1.0
66 mccabe~=0.6
67 flake8-blind-except~=0.1
68 flake8-builtins~=1.0
69 flake8-pep3101~=1.0
70 flake8-print~=3.0
71 flake8-string-format~=0.2
72 flake8-logging-format~=0.5
136 twine
137 pip >= 18.0.0
138 commands =
139 pip wheel -w {envtmpdir}/build --no-deps .
140 twine check {envtmpdir}/build/*
73141
142
143 [testenv:changelog]
144 basepython = python3.9
145 deps = towncrier
146 skip_install = true
147 commands = towncrier --draft
148
149
150 [testenv:typing]
151 basepython = python3.9
152 deps =
153 mypy
154 types-mock
74155 commands =
75 flake8 src/ tests/ setup.py
156 mypy src/
157
158
76159
77160 [flake8]
78 max-complexity = 5
161 max-complexity = 15
79162 max-line-length = 100
80163 show-source = True
81164 enable-extensions = M,B,C,T,P
82165 ignore = C812,W503,P103,E1,E2,E3,E5
83166 statistics = True
84
85 [testenv:mypy]
86 basepython = python3.8
87 skip_install = true
88 deps =
89 mypy~=0.6
90 commands =
91 mypy src/ tests/ --ignore-missing-imports {posargs}
92
93 [testenv:test-hinting]
94 basepython = python3
95 skip_install = true
96 deps =
97 pytest-mypy-plugins~=1.0
98 commands =
99 pytest --mypy-ini-file=tox.ini tests/type-hinting/ {posargs}
100
101 [testenv:pyre]
102 basepython = python3.7
103 skip_install = true
104 deps =
105 pyre-check
106 commands =
107 pyre --source-directory src/ check {posargs}
108 pyre --source-directory tests/ --search-path src/ check {posargs}
167 per-file-ignores =
168 src/*/__init__.py:F401,F403,F405
169 src/hamcrest/__init__.py:F401,F403