pax_global_header00006660000000000000000000000064126743077060014526gustar00rootroot0000000000000052 comment=9d623d38ffd0db165cd86176de3eaaeb041a596a preggy-1.3.0/000077500000000000000000000000001267430770600130245ustar00rootroot00000000000000preggy-1.3.0/.coveragerc000066400000000000000000000003551267430770600151500ustar00rootroot00000000000000[run] omit = *tests.py branch = True source = preggy preggy.assertions preggy.assertions.types [report] exclude_lines = pragma: no cover def __repr__ raise NotImplementedError if __name__ == .__main__.: preggy-1.3.0/.coveralls.yml000066400000000000000000000000561267430770600156200ustar00rootroot00000000000000repo_token: owzdV25WHOWEL6b8ly0JHEqsXXHLCiHH6 preggy-1.3.0/.editorconfig000066400000000000000000000004111267430770600154750ustar00rootroot00000000000000# EditorConfig is awesome: http://EditorConfig.org # top-most EditorConfig file root = true # Unix-style newlines with a newline ending every file [*] end_of_line = lf insert_final_newline = true # 4 space indentation [*.py] indent_style = space indent_size = 4 preggy-1.3.0/.env000066400000000000000000000000161267430770600136120ustar00rootroot00000000000000workon preggy preggy-1.3.0/.gitignore000066400000000000000000000004571267430770600150220ustar00rootroot00000000000000*.py[cod] # C extensions *.so # Packages *.egg *.egg-info dist build eggs parts bin var sdist develop-eggs .installed.cfg lib lib64 # Installer logs pip-log.txt # Unit test / coverage reports .coverage .tox nosetests.xml # Translations *.mo # Mr Developer .mr.developer.cfg .project .pydevproject preggy-1.3.0/.travis.yml000066400000000000000000000004401267430770600151330ustar00rootroot00000000000000language: python python: - "2.6" - "2.7" - "3.2" - "3.3" - "3.4" - "pypy" install: # install python requirements - pip install coveralls --use-mirrors - pip install -e .[tests] --use-mirrors script: # finally run tests - make ci-test after_success: - coveralls preggy-1.3.0/CONTRIBUTING.md000066400000000000000000000026761267430770600152700ustar00rootroot00000000000000CONTRIBUTING ============ So, you want to contribute? Awesome! Hacking `preggy` is simple: - Code whatever you feel like - Test your changes - Check the tests on preggy’s supported version of Python: 2.6, 2.7, 3.2, 3.3, and pypy. For that last item, we recommend `pythonbrew` to install all those Python versions. Installing `pythonbrew` ----------------------- **Step 1:** Grab the file and install it: ```bash $ curl -kL http://xrl.us/pythonbrewinstall | bash ``` **Step 2:** Add this line to your `.bashrc` or `.bash_profile` (or your favorite shell’s equivalent): ```bash [[ -s $HOME/.pythonbrew/etc/bashrc ]] && source $HOME/.pythonbrew/etc/bashrc ``` **Step 3:** Install supported Python versions (*except pypy*; see below!): ```bash # find out the available versions $ pythonbrew list -k Python-1.5.2 Python-1.6.1 Python-2.0.1 Python-2.1.3 Python-2.2.3 Python-2.3.7 Python-2.4.6 Python-2.5.6 Python-2.6.8 Python-2.7.3 Python-3.0.1 Python-3.1.4 Python-3.2.3 Python-3.3.0 # install the supported versions of Python $ pythonbrew install Python-2.6.8 $ pythonbrew install Python-2.7.3 $ pythonbrew install Python-3.2.3 $ pythonbrew install Python-3.3.0 ``` ### Pypy Pypy should be installed separately: - [pypy download page](http://pypy.org/download.html) - Or, if you use OS X and Homebrew: `brew install pypy` Now you're ready to build. -------------------------- To build preggy for all supported Python versions: make tox preggy-1.3.0/MANIFEST.in000066400000000000000000000001261267430770600145610ustar00rootroot00000000000000prune dist prune build recursive-include preggy *.py recursive-include tests *.py preggy-1.3.0/Makefile000066400000000000000000000011171267430770600144640ustar00rootroot00000000000000NOSE_TEST_COVER_OPTS = --with-coverage --cover-package=preggy --cover-package=preggy.assertions --cover-package=preggy.assertions.types NOSE_TEST = @nosetests -vv --detailed-errors --with-yanc -s $(NOSE_TEST_COVER_OPTS) tests/ test: $(NOSE_TEST) $(NOSE_TEST_COVER_OPTS) ci-test: @rm -f .coverage $(NOSE_TEST) --with-coverage tox: @tox setup: @pip install -e .[tests] release: @git commit -am "Release `python -c "import preggy; print preggy.__version__"`" @git push @git tag `python -c "import preggy; print preggy.__version__"` @git push --tags @python setup.py sdist upload preggy-1.3.0/README.md000066400000000000000000000162001267430770600143020ustar00rootroot00000000000000preggy ====== [![Build Status](https://travis-ci.org/heynemann/preggy.png?branch=master)](https://travis-ci.org/heynemann/preggy) [![PyPi version](https://pypip.in/v/preggy/badge.png)](https://crate.io/packages/preggy/) [![PyPi downloads](https://pypip.in/d/preggy/badge.png)](https://crate.io/packages/preggy/) [![Coverage Status](https://coveralls.io/repos/heynemann/preggy/badge.png?branch=master)](https://coveralls.io/r/heynemann/preggy?branch=master) **preggy is an assertion library for Python.** What were you `expect`ing? Extracted from the [PyVows](http://pyvows.org) project. Installing ========== We recommend using `pip`: pip install preggy Usage ===== Simply tell your test what to `expect()`: ```python from preggy import expect def test_roses_are_red(): rose = Rose() expect(rose.color).to_equal('red') def test_violets_are_not_red(): violet = Violet() expect(violet.color).not_to_equal('red') ``` Built-in Expectations ===================== Equality -------- ```python expect(4).to_equal(4) expect(5).Not.to_equal(4) expect(5).not_to_equal(4) # same as previous ``` Comparison -------- ```python expect(4).to_be_lesser_than(5) expect(5).to_be_greater_than(4) expect(5).Not.to_be_lesser_than(4) expect(4).not_to_be_greater(5) # same as previous expect(4).to_be_lesser_or_equal_to(5) expect(4).to_be_lesser_or_equal_to(4) expect(5).not_to_be_lesser_or_equal_to(4) expect(5).to_be_greater_or_equal_to(4) expect(5).to_be_greater_or_equal_to(5) expect(4).not_to_be_greater_or_equal_to(5) expect("b").to_be_greater_than("a") expect("a").to_be_lesser_than("b") expect([1, 2, 3]).to_be_greater_than([1, 2]) # comparing using length expect((1, 2, 3)).to_be_greater_than((1, 2)) # comparing using length expect({ "a": "b", "c": "d" }).to_be_greater_than({ "a": "b" }) # comparing using length of keys ``` Similarity ---------- ```python expect('sOmE RandOm     CAse StRiNG').to_be_like('some random case string') expect(1).to_be_like(1) expect(1).to_be_like(1.0) expect(1).to_be_like(long(1)) expect([1, 2, 3]).to_be_like([3, 2, 1]) expect([1, 2, 3]).to_be_like((3, 2, 1)) expect([[1, 2], [3,4]]).to_be_like([4, 3], [2, 1]]) expect({ 'some': 1, 'key': 2 }).to_be_like({ 'key': 2, 'some': 1 }) expect('sOmE RandOm     CAse StRiNG').Not.to_be_like('other string') expect('sOmE RandOm     CAse StRiNG').not_to_be_like('other string') # same as previous expect(1).not_to_be_like(2) expect([[1, 2], [3,4]]).not_to_be_like([4, 4], [2, 1]]) expect({ 'some': 1, 'key': 2 }).not_to_be_like({ 'key': 3, 'some': 4 }) ``` Type ---- ```python expect(os.path).to_be_a_function() expect(1).to_be_numeric() expect({ 'some': 1, 'key': 2 }).to_be_instance_of(dict) expect(open(__file__)).to_be_a_file() expect('some').Not.to_be_a_function() expect('some').Not.to_be_numeric() expect('some').Not.to_be_instance_of(dict) expect('some').Not.to_be_a_file() ``` True / False ------------ ```python expect(True).to_be_true() expect('some').to_be_true() expect([1, 2, 3]).to_be_true() expect({ 'a': 'b' }).to_be_true() expect(1).to_be_true() expect(False).to_be_false() # not_to_be_true() would work, too. but, it's so...eww expect(None).to_be_false() expect('').to_be_false() expect(0).to_be_false() expect([]).to_be_false() expect({}).to_be_false() ``` None ---- ```python expect(None).to_be_null() expect('some').Not.to_be_null() expect('some').not_to_be_null() # same as previous ``` Inclusion --------- ```python expect([1, 2, 3]).to_include(2) expect((1, 2, 3)).to_include(2) expect('123').to_include('2') expect({ 'a': 1, 'b': 2, 'c': 3}).to_include('b') expect([1, 3]).Not.to_include(2) # or, exclusion... ``` Regular Expressions ------------------- ```python expect('some').to_match(r'^[a-z]+') expect('Some').Not.to_match(r'^[a-z]+') ``` Length ------ ```python expect([1, 2, 3]).to_length(3) expect((1, 2, 3)).to_length(3) expect('abc').to_length(3) expect({ 'a': 1, 'b': 2, 'c': 3}).to_length(3) expect(lifo_queue).to_length(2) expect(queue).to_length(3) expect([1]).Not.to_length(3) expect([1]).not_to_length(3) # same as previous ``` Emptiness --------- ```python expect([]).to_be_empty() expect(tuple()).to_be_empty() expect({}).to_be_empty() expect('').to_be_empty() expect([1]).not_to_be_empty() expect((1,2)).not_to_be_empty() expect({'a': 1}).not_to_be_empty() expect('roses are red').not_to_be_empty() ``` Exceptions ---------- ```python expect(RuntimeError()).to_be_an_error()  expect(RuntimeError()).to_be_an_error_like(RuntimeError) expect(ValueError('error')).to_have_an_error_message_of('error') expect("I'm not an error").Not.to_be_an_error() expect(ValueError()).Not.to_be_an_error_like(RuntimeError) expect(ValueError('some')).Not.to_have_an_error_message_of('error') # when expecting a method to error err = expect.error_to_happen(RuntimeError) # attribute to a variable so you can use the exception later with err: raise RuntimeError("something is wrong") expect(err).to_have_an_error_message_of('something is wrong') # or the shorter version with expect.error_to_happen(RuntimeError, message="something is wrong"): raise RuntimeError("something is wrong") # or if you don't care about the message: with expect.error_to_happen(RuntimeError): raise RuntimeError("something is wrong") # or if you need to make sure error does not happen with expect.error_not_to_happen(RuntimeError, message="something is wrong"): raise RuntimeError("something is wrong") # Fails with AssertionError # or if you don't care about the message, only that the error does not happen: with expect.error_not_to_happen(RuntimeError): raise RuntimeError("something is wrong") # Fails with AssertionError ``` Failure ------- ```python expect.not_to_be_here() # raises AssertionError # raises AssertionError with error message expect.not_to_be_here("some error message") ``` Chained Assertions ------------------ ```python # assertions may be chained, for brevity: expect(6).not_to_be_null().to_equal(6) # a more *sensible* example: expect(foo).not_to_be_null().to_equal(expected.get('foo')) ``` Contributing ============ See [DEVELOPING.md]. License ======= The MIT License (MIT) Copyright (c) 2013 Bernardo Heynemann Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. preggy-1.3.0/preggy/000077500000000000000000000000001267430770600143215ustar00rootroot00000000000000preggy-1.3.0/preggy/__init__.py000066400000000000000000000015221267430770600164320ustar00rootroot00000000000000# -*- coding: utf-8 -*- '''preggy is an assertion library for Python. (What were you ``expect()``ing?) EXAMPLE ======= from preggy import expect def test_roses_are_red(): rose = Rose() expect(rose.color).to_equal('red') def test_violets_are_not_red(): violet = Violet() expect(violet.color).not_to_equal('red') For more info: http://heynemann.github.io/preggy ''' # preggy assertions # https://github.com/heynemann/preggy # Licensed under the MIT license: # http://www.opensource.org/licenses/mit-license # Copyright (c) 2013 Bernardo Heynemann heynemann@gmail.com # flake8: noqa from __future__ import absolute_import from preggy.core import (assertion, create_assertions, Expect as expect) from preggy.assertions import * from preggy.__meta__ import __version__ __version__ = __version__ preggy-1.3.0/preggy/__main__.py000077500000000000000000000106461267430770600164250ustar00rootroot00000000000000#!/usr/bin/env python # -*- coding: utf-8 -*- from __future__ import print_function #import os #from os import path #from os.path import (abspath, basename, dirname, join as joinpath) from textwrap import dedent import sys try: from colorama import Fore, Style except ImportError: class _NoColor(object): def __getattribute__(self): return '' Fore = Style = _NoColor() from preggy import __meta__ from preggy.core import _registered_assertions #-------------------------------------------------------------------------------- # Misc Functions #-------------------------------------------------------------------------------- _longest_of_list= lambda lst: max([len(i) for i in lst]) def _format_module_name(m_name): m_formatted = m_name[18:] # remove "assertions." if m_formatted.startswith('types'): m_formatted = m_formatted[6:] # remove "types." return m_formatted.capitalize()# + ':' def _sort_assertion(func): name = func.__name__ if name.startswith('not_to_'): return name[7:] + '_z' # ensure that `not_...` comes second return name[3:] def _map_assertions_to_modules(modules=None, assertions=None, sort_func=_sort_assertion): '''Returns a dict containing (module:[sorted list of assertions]).''' mod_to_assertions = dict.fromkeys(modules) for mod in mod_to_assertions.keys(): _assertions = [f for f in assertions if mod == f.__module__] _assertions = sorted(_assertions, key=sort_func) mod_to_assertions[mod] = _assertions return mod_to_assertions def _print_assertions(): #PREGGY_DIR = dirname(__file__) #ASSERTIONS_DIR = joinpath(PREGGY_DIR, 'assertions') DIVIDER = '-' * 55 DIVIDER = ''.join((Style.DIM, DIVIDER, Style.RESET_ALL)) FMT_FIRST_LINE = ' {colors[module]}{module:<{module_space}}{colors[reset]}{colors[assertion]}{assertions[0]}{colors[reset]}' FMT_OTHER_LINES = ' {indent}{colors[assertion]}{name}{colors[reset]}' #assertion_names = _registered_assertions.keys() assertion_fns = _registered_assertions.values() module_names = set(i.__module__ for i in assertion_fns) # remove duplicates module_names = sorted(module_names) formatted_module_names = [_format_module_name(m) for m in module_names] #longest_assertion_name = _longest_of_list(assertion_names) longest_module_name = _longest_of_list(formatted_module_names) assertions_by_module = _map_assertions_to_modules( modules=module_names, assertions=assertion_fns) for modname in module_names: module = _format_module_name(modname).upper() _assertions = [ '{indent}{name}'.format( name = f.__name__, indent = '' if (f.__name__.startswith('not')) else 4*' ' ) for f in assertions_by_module[modname] ] colors = { 'module': Style.DIM, 'assertion':Style.NORMAL, 'reset': Fore.RESET + Style.RESET_ALL, } print(DIVIDER) print(FMT_FIRST_LINE.format( module =module, module_space=longest_module_name+4, assertions = _assertions, colors = colors )) _assertions = [FMT_OTHER_LINES.format( indent = ' ' * (4+longest_module_name), name = name, colors = colors) for name in _assertions ] print('\n'.join(_assertions[1:])) print(DIVIDER) #-------------------------------------------------------------------------------- # The main's mane #-------------------------------------------------------------------------------- def main(): print('\n') print( Style.BRIGHT, '{0:^55}'.format('Assertions Reference', ).upper(), Style.RESET_ALL, sep='') _print_assertions() INFO_STR = dedent( ''' {0.__name__} {0.__version__} {Style.DIM}({0.__date__:%Y/%m/%d}){Style.RESET_ALL} {Fore.RESET}{Style.NORMAL}{0.__url__}{Style.RESET_ALL}{Fore.RESET} '''.format(__meta__, Fore=Fore, Style=Style) ) print(INFO_STR) print('{0.__copyright__}'.format(__meta__), end=2*'\n') print('{0.__license_full__}'.format(__meta__), end= 2*'\n') if __name__ == '__main__': sys.exit(main()) preggy-1.3.0/preggy/__meta__.py000066400000000000000000000037031267430770600164200ustar00rootroot00000000000000# -*- coding: utf-8 -*- '''All metadata not related to the installation process.''' # preggy assertions # https://github.com/heynemann/preggy # Licensed under the MIT license: # http://www.opensource.org/licenses/mit-license # Copyright (c) 2013 Bernardo Heynemann heynemann@gmail.com # flake8: noqa from datetime import date #-------------------------------------------------------------------------------- # GENERAL #-------------------------------------------------------------------------------- __name__ = 'preggy' # normally preggy.__meta__ __version__ = '1.3.0' __date__ = date(2016, 3, 22) # TODO: auto-populate each release using a git hook __keywords__ = 'test testing assert assertion library development' __status__ = 'Production' #-------------------------------------------------------------------------------- # URLS #-------------------------------------------------------------------------------- __url__ = 'http://heynemann.github.io/preggy' __download_url__= 'https://github.com/heynemann/preggy/releases/tag/{version}'.format(version=__version__) __bugtrack_url__= 'http://github.com/heynemann/preggy/issues' #-------------------------------------------------------------------------------- # PEOPLE #-------------------------------------------------------------------------------- __author__ = 'Bernardo Heynemann' __author_email__= 'heynemann@gmail.com' __maintainer__ = 'Zearin' __maintainer_email__= 'zearin@gonk.net' __credits__ = (__author__, __maintainer__,) #-------------------------------------------------------------------------------- # LEGAL #-------------------------------------------------------------------------------- __copyright__ = 'Copyright (c) 2013 {author} <{email}>'.format( author=__author__, email=__author_email__) __license__ = 'MIT' __license_full__= ''' Licensed under the MIT license: http://www.opensource.org/licenses/mit-license '''.strip() preggy-1.3.0/preggy/assertions/000077500000000000000000000000001267430770600165135ustar00rootroot00000000000000preggy-1.3.0/preggy/assertions/__init__.py000066400000000000000000000006341267430770600206270ustar00rootroot00000000000000# -*- coding: utf-8 -*- from __future__ import absolute_import # NOQA from preggy.assertions.emptiness import * # NOQA from preggy.assertions.equality import * # NOQA from preggy.assertions.inclusion import * # NOQA from preggy.assertions.length import * # NOQA from preggy.assertions.like import * # NOQA from preggy.assertions.comparison import * # NOQA from preggy.assertions.types import * # NOQA preggy-1.3.0/preggy/assertions/comparison.py000066400000000000000000000032071267430770600212410ustar00rootroot00000000000000# -*- coding: utf-8 -*- '''preggy comparison assertion. For use with `expect()` (see `preggy.core`). ''' # preggy assertions # https://github.com/heynemann/preggy # Licensed under the MIT license: # http://www.opensource.org/licenses/mit-license # Copyright (c) 2013 Bernardo Heynemann heynemann@gmail.com from __future__ import absolute_import from preggy import create_assertions from preggy import utils @create_assertions def to_be_greater_than(topic, expected): '''Asserts that `topic > expected`.''' topic = utils.fix_string(topic) expected = utils.fix_string(expected) if isinstance(expected, (tuple, list, set, dict)): return len(topic) > len(expected) return topic > expected @create_assertions def to_be_lesser_than(topic, expected): '''Asserts that `topic < expected`.''' topic = utils.fix_string(topic) expected = utils.fix_string(expected) if isinstance(expected, (tuple, list, set, dict)): return len(topic) < len(expected) return topic < expected @create_assertions def to_be_greater_or_equal_to(topic, expected): '''Asserts that `topic >= expected`.''' topic = utils.fix_string(topic) expected = utils.fix_string(expected) if isinstance(expected, (tuple, list, set, dict)): return len(topic) >= len(expected) return topic >= expected @create_assertions def to_be_lesser_or_equal_to(topic, expected): '''Asserts that `topic <= expected`.''' topic = utils.fix_string(topic) expected = utils.fix_string(expected) if isinstance(expected, (tuple, list, set, dict)): return len(topic) <= len(expected) return topic <= expected preggy-1.3.0/preggy/assertions/emptiness.py000066400000000000000000000007751267430770600211050ustar00rootroot00000000000000# -*- coding: utf-8 -*- '''preggy emptiness assertion. For use with `expect()` (see `preggy.core`).''' # preggy assertions # https://github.com/heynemann/preggy # Licensed under the MIT license: # http://www.opensource.org/licenses/mit-license # Copyright (c) 2013 Bernardo Heynemann heynemann@gmail.com from __future__ import absolute_import from preggy import create_assertions @create_assertions def to_be_empty(topic): '''Asserts that the `len` of `topic` is `0`.''' return len(topic) == 0 preggy-1.3.0/preggy/assertions/equality.py000066400000000000000000000012251267430770600207220ustar00rootroot00000000000000# -*- coding: utf-8 -*- '''preggy equality assertion. For use with `expect()` (see `preggy.core`). ''' # preggy assertions # https://github.com/heynemann/preggy # Licensed under the MIT license: # http://www.opensource.org/licenses/mit-license # Copyright (c) 2013 Bernardo Heynemann heynemann@gmail.com from __future__ import absolute_import from preggy import create_assertions from preggy import utils @create_assertions def to_equal(topic, expected): '''Asserts that `topic == expected`.''' topic = utils.fix_string(topic) expected = utils.fix_string(expected) try: return expected == topic except: return False preggy-1.3.0/preggy/assertions/inclusion.py000066400000000000000000000016151267430770600210730ustar00rootroot00000000000000# -*- coding: utf-8 -*- '''preggy inclusion assertion. For use with `expect()` (see `preggy.core`). ''' # preggy assertions # https://github.com/heynemann/preggy # Licensed under the MIT license: # http://www.opensource.org/licenses/mit-license # Copyright (c) 2013 Bernardo Heynemann heynemann@gmail.com from __future__ import absolute_import try: import six except ImportError: # pragma: no cover import warnings warnings.warn("Ignoring six. Probably setup.py installing package.") from preggy import create_assertions @create_assertions def to_include(topic, expected): '''Asserts that `expected` is in `topic`.''' if isinstance(topic, six.string_types + tuple([six.binary_type, six.text_type])): return str(expected) in topic for t in topic: try: if expected == t: return True except: pass return False preggy-1.3.0/preggy/assertions/length.py000066400000000000000000000033111267430770600203440ustar00rootroot00000000000000# -*- coding: utf-8 -*- '''preggy length assertions. For use with `expect()` (see `preggy.core`). ''' # preggy assertions # https://github.com/heynemann/preggy # Licensed under the MIT license: # http://www.opensource.org/licenses/mit-license # Copyright (c) 2013 Bernardo Heynemann heynemann@gmail.com from __future__ import absolute_import from preggy import assertion #------------------------------------------------------------------------------------------------- # Helpers #------------------------------------------------------------------------------------------------- def _get_length(topic, expected): length = None try: length = len(topic) except (AttributeError, TypeError): if hasattr(topic, 'qsize'): length = topic.qsize() if length is None: msg = "Could not determine \"{0}\"'s length.".format(topic) raise AssertionError(msg) return length #------------------------------------------------------------------------------------------------- # Assertions #------------------------------------------------------------------------------------------------- @assertion def to_length(topic, expected): '''Asserts that `len(topic)` == `expected`.''' length = _get_length(topic, expected) if length != expected: msg = 'Expected topic({0!r}) to have {1} of length, but it has {2}'.format(topic, expected, length) raise AssertionError(msg) @assertion def not_to_length(topic, expected): '''Asserts that `len(topic)` != `expected`.''' length = _get_length(topic, expected) if length == expected: msg = 'Expected topic({0!r}) not to have {1} of length'.format(topic, expected) raise AssertionError(msg) preggy-1.3.0/preggy/assertions/like.py000077500000000000000000000177251267430770600200300ustar00rootroot00000000000000# -*- coding: utf-8 -*- '''preggy 'like' assertions. For use with `expect()` (see `preggy.core`). ''' # preggy assertions # https://github.com/heynemann/preggy # Licensed under the MIT license: # http://www.opensource.org/licenses/mit-license # Copyright (c) 2013 Bernardo Heynemann heynemann@gmail.com from __future__ import absolute_import, print_function import re from datetime import datetime import difflib from uuid import UUID try: from six import string_types, binary_type, PY2, PY3 except ImportError: # pragma: no cover import warnings warnings.warn('Ignoring six. Probably setup.py installing package.') import numbers from preggy import assertion from preggy import utils __all__ = ('to_be_like', 'not_to_be_like') #------------------------------------------------------------------------------------------------- # CONSTANTS #------------------------------------------------------------------------------------------------- DATE_THRESHOLD = 5.0 RESET = '\033[m' RED = '\033[31m' GREEN = '\033[32m' YELLOW = '\033[33m' REMOVE_COLORS_REGEX = re.compile( r'(\033|\x1b|\x03)' # prefixes r'\[' # non-regex bracket r'([0-9]*[;])?' # semi-colon r'[0-9]*m', # suffix flags=re.UNICODE ) NORMALIZE_WHITESPACE_REGEX = re.compile( r'\s+', flags=re.UNICODE | re.MULTILINE | re.IGNORECASE ) #------------------------------------------------------------------------------------------------- # HELPERS #------------------------------------------------------------------------------------------------- _filter_str = lambda s: NORMALIZE_WHITESPACE_REGEX.sub('', s.lower()).strip() def compare(first, second): matcher = difflib.SequenceMatcher(None, first, second) first = get_match_for_text(matcher, first, True) second = get_match_for_text(matcher, second, True) return matcher, first, second def get_match_for_text(matcher, text, first): result = [] COLOR_MAP = { 'delete': RED, 'insert': GREEN, 'replace': YELLOW } for tag, i1, i2, j1, j2 in matcher.get_opcodes(): start, stop = (i1, i2) if first else (j1, j2) to_append = text[start:stop] if tag in COLOR_MAP: to_append = ''.join((COLOR_MAP[tag], to_append, RESET)) result.append(to_append) return ''.join(result) def _match_alike(expected, topic, diff=False): '''Determines the types of `expected` and `topic`, and calls the appropriate comparison function.''' if topic is None: return expected is None if isinstance(topic, UUID): return _compare_uuid(expected, topic) if isinstance(topic, string_types + (binary_type, )): return _compare_strings(expected, topic) if isinstance(topic, numbers.Number): return _compare_numbers(expected, topic) if isinstance(topic, (list, tuple, set)): return _compare_lists(expected, topic) if isinstance(topic, dict): return _compare_dicts(expected, topic) if isinstance(topic, datetime): return _compare_datetime(expected, topic) if _is_comparable(topic) and _is_comparable(expected): return _compare_comparables(expected, topic) raise RuntimeError('Could not compare {expected} and {topic}'.format(expected=expected, topic=topic)) def _strip_string(text): if not text: return text text = utils.fix_string(text) text = REMOVE_COLORS_REGEX.sub('', text) text = _filter_str(text) return text def _is_comparable(obj): if PY2: return hasattr(obj, '__eq__') or hasattr(obj, '__cmp__') if PY3: return obj.__class__.__eq__ != object.__eq__ def _compare_strings(expected, topic): '''Asserts the "like"-ness of `topic` and `expected` as strings. Allows some leeway. (Strings don't have to exactly match.) ''' topic = _strip_string(topic) expected = _strip_string(expected) return expected == _filter_str(topic) def _compare_uuid(expected, topic): '''Asserts the "like"-ness of `topic` and `expected` as UUID.''' topic = str(topic) expected = str(expected) return expected == topic def __timedelta_to_seconds(timedelta): ms = 10 ** 6 # microseconds/second days = 24 * 60 * 60 # seconds/day ms_as_seconds = float(timedelta.microseconds) / ms seconds = float(timedelta.seconds) days_as_seconds = float(timedelta.days) * days total_seconds = sum((ms_as_seconds, seconds, days_as_seconds)) return abs(total_seconds) # abs() comes last def _compare_datetime(expected, topic): return __timedelta_to_seconds(topic - expected) <= DATE_THRESHOLD def _compare_numbers(expected, topic): '''Asserts the "like"-ness of `topic` and `expected` as Numbers.''' FALSE_CONDITIONS = (not isinstance(topic, numbers.Number), not isinstance(expected, numbers.Number), ) if any(FALSE_CONDITIONS): return False return float(expected) == float(topic) def _compare_dicts(expected, topic): '''Asserts the "like"-ness of `topic` and `expected` as dicts.''' return _match_dicts(expected, topic) and _match_dicts(topic, expected) def _match_dicts(expected, topic): '''Asserts the "like"-ness of all keys and values in `topic` and `expected`.''' for k, v in expected.items(): if not k in topic or not _match_alike(topic[k], v): return False return True def _compare_lists(expected, topic): '''Asserts the "like"-ness of `topic` and `expected` as lists.''' return _match_lists(expected, topic) and _match_lists(topic, expected) def _compare_comparables(expected, topic): '''Asserts the "like"-ness of `topic` and `expected` as comparable objects.''' try: return expected == topic except: return False def _match_lists(expected, topic): '''Asserts the "like"-ness each item in of `topic` and `expected` (as lists or tuples).''' # TODO: Rewrite this using itertools # http://docs.python.org/2/library/itertools.html for item in expected: if isinstance(item, (list, tuple)): found = False for inner_item in topic: if isinstance(inner_item, (list, tuple)) and _compare_lists(item, inner_item): found = True break if not found: return False else: found = False for t in topic: try: if item == t: found = True break except: continue if not found: return False return True #------------------------------------------------------------------------------------------------- # Assertions #------------------------------------------------------------------------------------------------- @assertion def to_be_like(topic, expected, diff=True): '''Asserts that `topic` is like (similar to) `expected`. Allows some leeway.''' result = _match_alike(expected, topic, diff=diff) is_str = lambda x: isinstance(x, string_types + (binary_type,)) if not result: if diff is True and ( is_str(topic) and is_str(expected) ): first, second = _strip_string(topic), _strip_string(expected) matcher, first, second = compare(first, second) print() print('Expected strings to be equal, but they were different:') print(first) print(second) print() raise AssertionError("Expected topic('{topic}') to be like '{expected}'".format(topic=topic, expected=expected)) @assertion def not_to_be_like(topic, expected, diff=False): '''Asserts that `topic` is NOT like (NOT similar to) `expected`. Allows some leeway.''' result = _match_alike(expected, topic, diff=diff) if result: raise AssertionError("Expected topic('{topic}') not to be like '{expected}'".format(topic=topic, expected=expected)) preggy-1.3.0/preggy/assertions/types/000077500000000000000000000000001267430770600176575ustar00rootroot00000000000000preggy-1.3.0/preggy/assertions/types/__init__.py000066400000000000000000000006551267430770600217760ustar00rootroot00000000000000# -*- coding: utf-8 -*- from __future__ import absolute_import from preggy.assertions.types.boolean import * from preggy.assertions.types.classes import * from preggy.assertions.types.errors import * from preggy.assertions.types.file import * from preggy.assertions.types.function import * from preggy.assertions.types.nullable import * from preggy.assertions.types.numeric import * from preggy.assertions.types.regexp import * preggy-1.3.0/preggy/assertions/types/boolean.py000066400000000000000000000020701267430770600216470ustar00rootroot00000000000000# -*- coding: utf-8 -*- '''preggy boolean assertions. For use with `expect()` (see `preggy.core`). ''' # preggy assertions # https://github.com/heynemann/preggy # Licensed under the MIT license: # http://www.opensource.org/licenses/mit-license # Copyright (c) 2013 Bernardo Heynemann heynemann@gmail.com from __future__ import absolute_import from preggy import assertion @assertion def to_be_true(topic): '''Asserts that the boolean value of `topic` == `True`.''' if not bool(topic): msg = 'Expected topic({0}) to be truthy'.format(topic) raise AssertionError(msg) @assertion def to_be_false(topic): '''Asserts that the boolean value of `topic` == `False`.''' if bool(topic): msg = 'Expected topic({0}) to be falsy'.format(topic) raise AssertionError(msg) @assertion def not_to_be_true(topic): '''Asserts that the boolean value of `topic` != `True`.''' return to_be_false(topic) @assertion def not_to_be_false(topic): '''Asserts that the boolean value of `topic` != `False`.''' return to_be_true(topic) preggy-1.3.0/preggy/assertions/types/classes.py000066400000000000000000000024361267430770600216730ustar00rootroot00000000000000# -*- coding: utf-8 -*- '''preggy instance assertions. For use with `expect()` (see `preggy.core`). ''' # preggy assertions # https://github.com/heynemann/preggy # Licensed under the MIT license: # http://www.opensource.org/licenses/mit-license # Copyright (c) 2013 Bernardo Heynemann heynemann@gmail.com from __future__ import absolute_import import inspect from preggy import assertion @assertion def to_be_instance_of(topic, expected): '''Asserts that `topic` is an instance of `expected`.''' TRUE_CONDITIONS = [ isinstance(topic, expected), (inspect.isclass(topic) and inspect.isclass(expected)) and issubclass(topic, expected), ] try: TRUE_CONDITIONS.append(topic == expected) except: pass if any(TRUE_CONDITIONS): return True msg = 'Expected topic({0}) to be an instance of {1}, but it was a {2}'.format( topic, expected, topic.__class__) raise AssertionError(msg) @assertion def not_to_be_instance_of(topic, expected): '''Asserts that `topic` is NOT an instance of `expected`.''' try: to_be_instance_of(topic, expected) except AssertionError: return True msg = 'Expected topic({0}) not to be an instance of {1}'.format(topic, expected) raise AssertionError(msg) preggy-1.3.0/preggy/assertions/types/errors.py000066400000000000000000000032311267430770600215440ustar00rootroot00000000000000# -*- coding: utf-8 -*- '''preggy error assertions. For use with `expect()` (see `preggy.core`). ''' # preggy assertions # https://github.com/heynemann/preggy # Licensed under the MIT license: # http://www.opensource.org/licenses/mit-license # Copyright (c) 2013 Bernardo Heynemann heynemann@gmail.com from __future__ import absolute_import import inspect from preggy import assertion, create_assertions, utils @assertion def to_be_an_error_like(topic, expected): '''Asserts that `topic` is an instance (or subclass) of type `expected`.''' if not isinstance(topic, expected): msg = 'Expected topic({0}) to be an error of type {1}, but it was a {2}' values = topic, expected, topic.__class__ err = AssertionError(msg.format(*values), *values) raise err @assertion def to_have_an_error_message_of(topic, expected): '''Asserts that `topic` has an error message of `expected`.''' if utils.text_type(topic) != expected: msg = 'Expected topic({0!r}) to be an error with message {1!r}' values = utils.text_type(topic), expected err = AssertionError(msg.format(*values)) raise err @create_assertions def to_be_an_error(topic): '''Asserts that `topic` is an error.''' return isinstance(topic, BaseException) @assertion def not_to_be_an_error_like(topic, expected): '''Asserts that `topic` not is an instance (or subclass) of type `expected`.''' if isinstance(topic, expected): msg = 'Expected topic({0}) not to be an error of type {1}, but it was a {2}' values = topic, expected, topic.__class__ err = AssertionError(msg.format(*values), *values) raise err preggy-1.3.0/preggy/assertions/types/file.py000066400000000000000000000051621267430770600211540ustar00rootroot00000000000000# -*- coding: utf-8 -*- '''preggy file assertions. For use with `expect()` (see `preggy.core`). For these assertions, "file" can be either a string or a file object. Since a string is required to create a file object in the first place, these assertions provide a convenient, flexible way to test whether a topic is a "file" in your tests. ''' # preggy assertions # https://github.com/heynemann/preggy # Licensed under the MIT license: # http://www.opensource.org/licenses/mit-license # Copyright (c) 2013 Bernardo Heynemann heynemann@gmail.com from __future__ import absolute_import try: import six except ImportError: # pragma: no cover import warnings warnings.warn("Ignoring six. Probably setup.py installing package.") try: import io except ImportError: # pragma: no cover pass ## FIXME: explain using "pass" here from os.path import isfile import types from preggy import assertion #------------------------------------------------------------------------------------------------- # Helpers #------------------------------------------------------------------------------------------------- _is_file = lambda topic: isfile(topic) _is_string = lambda topic: isinstance(topic, (six.string_types, six.text_type)) def _is_file_obj(topic): try: return isinstance(topic, types.FileType) except AttributeError: # pragma: no cover # FIXME: add comment... # what is this for? return isinstance(topic, io.IOBase) #------------------------------------------------------------------------------------------------- # Assertions #------------------------------------------------------------------------------------------------- @assertion def to_be_a_file(topic): '''Asserts that `topic` is a file. If `topic` is a string, this asserts that `os.path.isfile()` returns `True`. Otherwise, this asserts whether `topic` is an instance of the built-in `file` type. ''' if _is_string(topic) and _is_file(topic): return True elif _is_file_obj(topic): return True msg = 'Expected topic({0}) to be a file, but it was {1!r}'.format(topic, type(topic)) raise AssertionError(msg) @assertion def not_to_be_a_file(topic): '''Asserts that `topic` is NOT a file. If `topic` is a string, this asserts that `os.path.isfile()` returns `False`. Otherwise, this asserts whether `topic` is NOT an instance of the built-in `file` type. ''' try: to_be_a_file(topic) except AssertionError: return True msg = 'Expected topic({0}) not to be a file, but it was'.format(topic) raise AssertionError(msg) preggy-1.3.0/preggy/assertions/types/function.py000066400000000000000000000026271267430770600220650ustar00rootroot00000000000000# -*- coding: utf-8 -*- '''preggy function assertions. For use with `expect()` (see `preggy.core`). ''' # preggy assertions # https://github.com/heynemann/preggy # Licensed under the MIT license: # http://www.opensource.org/licenses/mit-license # Copyright (c) 2013 Bernardo Heynemann heynemann@gmail.com from __future__ import absolute_import import inspect from preggy import assertion #------------------------------------------------------------------------------------------------- # Helpers #------------------------------------------------------------------------------------------------- _is_func = lambda topic: inspect.ismethod(topic) or inspect.isfunction(topic) #------------------------------------------------------------------------------------------------- # Assertions #------------------------------------------------------------------------------------------------- @assertion def to_be_a_function(topic): '''Asserts that `topic` is a function.''' if not _is_func(topic): msg = 'Expected topic({0}) to be a function or a method, but it was a {1}'.format( topic, topic.__class__ ) raise AssertionError(msg) @assertion def not_to_be_a_function(topic): '''Asserts that `topic` is NOT a function.''' if _is_func(topic): msg = 'Expected topic({0}) not to be a function or a method'.format(topic) raise AssertionError(msg) preggy-1.3.0/preggy/assertions/types/nullable.py000066400000000000000000000014241267430770600220300ustar00rootroot00000000000000# -*- coding: utf-8 -*- '''preggy "null" (None) assertions. For use with `expect()` (see `preggy.core`). ''' # preggy assertions # https://github.com/heynemann/preggy # Licensed under the MIT license: # http://www.opensource.org/licenses/mit-license # Copyright (c) 2013 Bernardo Heynemann heynemann@gmail.com from __future__ import absolute_import from preggy import assertion @assertion def to_be_null(topic): '''Asserts that `topic` is `None`.''' if topic is not None: msg = 'Expected topic({0}) to be None'.format(topic) raise AssertionError(msg) @assertion def not_to_be_null(topic): '''Asserts that `topic` is NOT `None`.''' if topic is None: msg = 'Expected topic({0}) not to be None'.format(topic) raise AssertionError(msg) preggy-1.3.0/preggy/assertions/types/numeric.py000066400000000000000000000010271267430770600216730ustar00rootroot00000000000000# -*- coding: utf-8 -*- '''preggy numeric assertion. For use with `expect()` (see `preggy.core`). ''' # preggy assertions # https://github.com/heynemann/preggy # Licensed under the MIT license: # http://www.opensource.org/licenses/mit-license # Copyright (c) 2013 Bernardo Heynemann heynemann@gmail.com from __future__ import absolute_import import numbers from preggy import create_assertions @create_assertions def to_be_numeric(topic): '''Asserts that `topic` is a Number.''' return isinstance(topic, numbers.Number) preggy-1.3.0/preggy/assertions/types/regexp.py000066400000000000000000000017351267430770600215310ustar00rootroot00000000000000# -*- coding: utf-8 -*- '''preggy regular expression assertions. For use with `expect()` (see `preggy.core`). ''' # preggy assertions # https://github.com/heynemann/preggy # Licensed under the MIT license: # http://www.opensource.org/licenses/mit-license # Copyright (c) 2013 Bernardo Heynemann heynemann@gmail.com from __future__ import absolute_import import re from preggy import assertion @assertion def to_match(topic, expected): '''Asserts that `topic` matches the regular expression `expected`.''' if not re.match(expected, topic): msg = 'Expected topic({0!r}) to match the regular expression {1!r}'.format(topic, expected) raise AssertionError(msg) @assertion def not_to_match(topic, expected): '''Asserts that `topic` DOES NOT match the regular expression `expected`.''' if re.match(expected, topic): msg = 'Expected topic({0!r}) not to match the regular expression {1!r}'.format(topic, expected) raise AssertionError(msg) preggy-1.3.0/preggy/core.py000066400000000000000000000236121267430770600156270ustar00rootroot00000000000000# -*- coding: utf-8 -*- '''preggy core: the `Expect` class, and the `@assertion` and `@create_assertions` decorators. ''' # preggy assertions # https://github.com/heynemann/preggy # Licensed under the MIT license: # http://www.opensource.org/licenses/mit-license # Copyright (c) 2013 Bernardo Heynemann heynemann@gmail.com from __future__ import absolute_import import functools from preggy import utils _registered_assertions = utils.AssertionsMap() def assertion(func): '''Function decorator. Provides lower-level control for custom assertions than `@preggy.create_assertions`. This decorator is preferable over `@preggy.create_assertions` if you need to fine-tune your error message, or if your assertion doesn’t have a corresponding `not_`. Unlike `@preggy.create_assertions`, functions decorated with this shouldn’t return a boolean. Instead, they should check for undesirable conditions and raise an `AssertionError` when appropriate. Whenever possible, you should declare both the normal assertion as well as a `not_` counterpart, so they can be used like this: ... # doctest: +ELLIPSIS, +NORMALIZE_WHITESPACE >>> >>> import preggy >>> from preggy.core import Expect as expect >>> >>> @preggy.assertion ... def to_be_a_positive_integer(topic): ... if not topic > 0: ... raise AssertionError("Expected topic('{topic}') to be a positive integer".format(topic=topic)) ... >>> @preggy.assertion ... def not_to_be_a_positive_integer(topic): ... if not topic < 0: ... raise AssertionError("Expected topic('{topic}') not to be a positive integer".format(topic=topic)) ... >>> expect(5).to_be_a_positive_integer() >>> expect(-3).Not.to_be_a_positive_integer() ''' if not hasattr(func, 'humanized'): setattr(func, 'humanized', utils.humanized_name(func.__name__)) @functools.wraps(func) def wrapper(*args, **kw): func(*args, **kw) return Expect(args[0]) _registered_assertions[wrapper.__name__] = wrapper return wrapper def create_assertions(func): '''Function decorator. Use to create custom assertions for your tests. ''' ''' Creating new assertions for use with `expect` is as simple as using this decorator on a function. The function expects `topic` as the first parameter, and `expectation` second: @preggy.create_assertions def to_be_greater_than(topic, expected): return topic > expected This creates both the assertion AND its `not_*` counterpart. ... # doctest: +ELLIPSIS, +NORMALIZE_WHITESPACE >>> from preggy.core import (assertion, create_assertions, Expect as expect) >>> from preggy.assertions import * >>> expect(2).to_be_greater_than(3) Traceback (most recent call last): ... AssertionError: Expected topic(2) to be greater than 3 >>> expect(4).not_to_be_greater_than(3) Traceback (most recent call last): ... AssertionError: Expected topic(4) not to be greater than 3 ''' # set custom func attribute "humanized" setattr(func, 'humanized', utils.humanized_name(func.__name__)) # modified functools.update_wrapper def _update_wrapper(wrapper, wrapped, not_assertion=True): '''A modified version of functools.update_wrapper. Auto-modifies the wrapper's __name__ and __doc__ to create a not_assertion. ''' # begin as usual wrapper = functools.update_wrapper(wrapper, wrapped) # compute overrides for not_* assertions values if not_assertion: new_name = 'not_{0.__name__}'.format(wrapped) new_doc = '' # .format(wrapped) # set our overrides setattr(wrapper, '__name__', new_name) setattr(wrapper, '__doc__', new_doc) # update to reflect new __name__ setattr(wrapper, 'humanized', utils.humanized_name(wrapper.__name__)) # Return the wrapper so this can be used as a decorator via partial() return wrapper # First assertion @assertion @functools.wraps(func) def test_assertion(*args): if not func(*args): raw_msg = utils.format_assertion_msg(func.humanized, *args) err_msg = raw_msg.format(*args) raise AssertionError(err_msg) return Expect(args[0]) # Second assertion: prepare def test_not_assertion(*args): if func(*args): raw_msg = utils.format_assertion_msg('not {0!s}'.format(func.humanized), *args) err_msg = raw_msg.format(*args) raise AssertionError(err_msg) return Expect(args[0]) # Second assertion: update and register test_not_assertion = _update_wrapper(test_not_assertion, func) test_not_assertion = assertion(test_not_assertion) class ErrorToHappenContext(object): def __init__(self, error_class, message=None): self.error_class = error_class self.message = message self._error = None @property def error(self): return self._error def __enter__(self): return self def __exit__(self, exc_type, exc_val, exc_tb): has_exception = exc_type is not None is_subclass = has_exception and (exc_type is self.error_class or issubclass(exc_type, self.error_class)) or False if not has_exception: raise AssertionError('Expected "%s.%s" to happen but no errors happened during execution of with block.' % ( self.error_class.__module__, self.error_class.__name__, )) if has_exception and not is_subclass: raise AssertionError('Expected "%s.%s" to happen but "%s.%s" happened during execution of with block.' % ( self.error_class.__module__, self.error_class.__name__, exc_type.__module__, exc_type.__name__ )) if self.message is not None: error_msg = getattr(exc_val, 'message', utils.text_type(exc_val)) if error_msg != self.message: raise AssertionError('Expected "%s.%s" to have a message of "%s", but the actual error was "%s".' % ( self.error_class.__module__, self.error_class.__name__, self.message, error_msg )) if has_exception and is_subclass: self._error = exc_val return True return False class NotErrorToHappenContext(object): def __init__(self, error_class, message=None): self.error_class = error_class self.message = message self._error = None @property def error(self): return self._error def __enter__(self): return self def __exit__(self, exc_type, exc_val, exc_tb): has_exception = exc_type is not None is_subclass = has_exception and (exc_type is self.error_class or issubclass(exc_type, self.error_class)) or False if has_exception and self.message is not None: error_msg = getattr(exc_val, 'message', utils.text_type(exc_val)) if error_msg != self.message: raise AssertionError('Expected "%s.%s" to have a message of "%s", but the actual error was "%s".' % ( self.error_class.__module__, self.error_class.__name__, self.message, error_msg )) if has_exception and not is_subclass: raise AssertionError('Expected "%s.%s" not to happen but "%s.%s" happened during execution of with block.' % ( self.error_class.__module__, self.error_class.__name__, exc_type.__module__, exc_type.__name__ )) if has_exception: raise AssertionError('Expected "%s.%s" not to happen but it happened during execution of with block.' % ( self.error_class.__module__, self.error_class.__name__, )) class Expect(object): '''This atypical class provides a key part of the preggy testing syntax. For example: >>> from preggy.core import (assertion, create_assertions, Expect as expect) >>> from preggy.assertions import * >>> >>> expect(True).to_be_true() >>> expect(False).to_be_false() ''' def __init__(self, topic): self.topic = topic if isinstance(self.topic, ErrorToHappenContext): self.topic = self.topic.error self.not_assert = False @classmethod def not_to_be_here(cls, message=None): error = '' if message is not None: error = ' (%s)' % message raise AssertionError("Should not have gotten this far%s." % error) @classmethod def error_to_happen(cls, error_class=Exception, message=None): return ErrorToHappenContext(error_class, message=message) @classmethod def not_error_to_happen(cls, error_class=Exception, message=None): return NotErrorToHappenContext(error_class, message=message) @classmethod def error_not_to_happen(cls, error_class=Exception, message=None): return cls.not_error_to_happen(error_class, message) def __getattr__(self, name): # common cases if name in ['topic', 'not_to_be_here']: return super(Expect, self).__getattr__(name) if name == 'Not': self.not_assert = not self.not_assert return self # determine whether assertion is of "not" form method_name = 'not_{name}'.format(name=name) if self.not_assert else name # if program gets this far, then it’s time to perform the assertion. (...FINALLY! ;D) def _assert_topic(*args, **kw): # Allows chained calls to assertions, such as `expect(topic).to_be_true()`. return _registered_assertions[method_name](self.topic, *args, **kw) return _assert_topic preggy-1.3.0/preggy/utils.py000066400000000000000000000045231267430770600160370ustar00rootroot00000000000000# -*- coding: utf-8 -*- '''Assorted helpers used elsewhere in preggy. Currently contains only string formatting code, but this may (or may not) change. ''' # preggy assertions # https://github.com/heynemann/preggy # Licensed under the MIT license: # http://www.opensource.org/licenses/mit-license # Copyright (c) 2013 Bernardo Heynemann heynemann@gmail.com from __future__ import absolute_import import logging import re try: import six text_type = six.text_type except ImportError: # pragma: no cover import warnings warnings.warn('Ignoring six. Probably setup.py installing package.') try: from unidecode import unidecode except ImportError: # pragma: no cover import warnings warnings.warn('Ignoring unidecode. Probably setup.py installing package.') logging.basicConfig(level=logging.INFO) log = logging.getLogger(__name__) UNDERSCORES = re.compile(r'_+') def humanized_name(thing): try: return UNDERSCORES.sub(' ', thing.__name__) except AttributeError: return UNDERSCORES.sub(' ', thing) def format_assertion_msg(assertion_clause, *args): raw_msg = 'Expected topic({{0!r}}) {assertion_clause}' raw_msg = raw_msg.format(assertion_clause=assertion_clause) if len(args) is 2: raw_msg += ' {1!r}' return raw_msg def fix_string(obj): if isinstance(obj, (six.binary_type, )): try: return obj.decode('utf-8') except Exception: return obj return obj class AssertionsMap(dict): '''A simple dict with a dash of logging.''' def __getitem__(self, k): log.debug('fetching assertion: {name!r}'.format(name=k)) return super(AssertionsMap, self).__getitem__(k) def __setitem__(self, k, v): _keys = self.keys() if k not in _keys: log.debug('registering assertion: {name!r}, with function: {func!r}'.format(name=k, func=v)) elif self[k] is not v: # existing key with new assertion function log.debug('re-registering assertion: {name!r}, with new function: {func!r}'.format(name=k, func=v)) elif self[k] is v: # same key, same function return return super(AssertionsMap, self).__setitem__(k, v) def __delitem__(self, k): log.debug('deleting assertion: {name!r}'.format(name=k)) return super(AssertionsMap, self).__delitem__(k) preggy-1.3.0/requirements.txt000066400000000000000000000003701267430770600163100ustar00rootroot00000000000000coverage==3.6 ipdb==0.7 ipython==0.13.2 nose==1.3.0 -e git+git@github.com:heynemann/preggy.git@b2510e1e941aaded75bad0674a427f5358de5b2c#egg=preggy-dev py==1.4.13 six==1.3.0 Unidecode==0.04.13 tox==1.4.3 virtualenv==1.9.1 wsgiref==0.1.2 yanc==0.2.4 preggy-1.3.0/setup.py000077500000000000000000000042371267430770600145470ustar00rootroot00000000000000#!/usr/bin/env python # -*- coding: utf-8 -*- # preggy assertions # https://github.com/heynemann/preggy # Licensed under the MIT license: # http://www.opensource.org/licenses/mit-license # Copyright (c) 2011 Bernardo Heynemann heynemann@gmail.com from setuptools import setup, find_packages from preggy import __doc__, __meta__, __version__ REQUIREMENTS = { 'install': ['six', 'unidecode'], 'extras': { 'tests':['nose', 'yanc', 'coverage', 'tox',] } } setup( name ='preggy', version =__version__, description =__doc__.splitlines()[0], long_description=__doc__, keywords =__meta__.__keywords__, author =__meta__.__author__, author_email=__meta__.__author_email__, maintainer =__meta__.__maintainer__, maintainer_email=__meta__.__maintainer_email__, url =__meta__.__url__, download_url=__meta__.__download_url__, ### For future, when Python packaging gets its crap together. See: ### http://stackoverflow.com/questions/14459828/how-to-set-bug-tracker-url-in-setup-py-script #bugtrack_url='http://github.com/heynemann/preggy/issues', license =__meta__.__license__, classifiers=[ 'Development Status :: 4 - Beta', 'Intended Audience :: Developers', 'License :: OSI Approved :: MIT License', 'Natural Language :: English', 'Operating System :: MacOS', 'Operating System :: MacOS :: MacOS X', 'Operating System :: POSIX', 'Operating System :: Unix', 'Operating System :: OS Independent', 'Programming Language :: Python :: 2.6', 'Programming Language :: Python :: 2.7', 'Programming Language :: Python :: 3.2', 'Programming Language :: Python :: 3.3', 'Programming Language :: Python :: 3.4', 'Programming Language :: Python :: Implementation :: PyPy', 'Topic :: Software Development :: Libraries', 'Topic :: Software Development :: Testing' ], packages=find_packages(exclude=['tests', 'tests.*']), install_requires= REQUIREMENTS['install'], extras_require = REQUIREMENTS['extras'], entry_points={}, ) preggy-1.3.0/tests/000077500000000000000000000000001267430770600141665ustar00rootroot00000000000000preggy-1.3.0/tests/__init__.py000066400000000000000000000023511267430770600163000ustar00rootroot00000000000000# -*- coding: utf-8 -*- class Comparable(object): def __init__(self, foo='bar'): self.foo = foo def __hash__(self): return hash(self.foo) def __lt__(self, other): return self.foo < other.foo def __le__(self, other): return self.foo <= other.foo def __eq__(self, other): return self.foo == other.foo def __ne__(self, other): return self.foo != other.foo def __gt__(self, other): return self.foo > other.foo def __ge__(self, other): return self.foo >= other.foo def __cmp__(self, other): return cmp(self.foo, other.foo) class AnotherComparable(object): def __init__(self, baz='qux'): self.baz = baz def __hash__(self): return hash(self.baz) def __lt__(self, other): return self.baz < other.baz def __le__(self, other): return self.baz <= other.baz def __eq__(self, other): return self.baz == other.baz def __ne__(self, other): return self.baz != other.baz def __gt__(self, other): return self.baz > other.baz def __ge__(self, other): return self.baz >= other.baz def __cmp__(self, other): return cmp(self.baz, other.baz) preggy-1.3.0/tests/test_be_here.py000066400000000000000000000020371267430770600171720ustar00rootroot00000000000000# -*- coding: utf-8 -*- # preggy assertions # https://github.com/heynemann/preggy # Licensed under the MIT license: # http://www.opensource.org/licenses/mit-license # Copyright (c) 2013 Bernardo Heynemann heynemann@gmail.com import sys from preggy import expect def test_expect_not_to_be_here(): try: expect.not_to_be_here() except AssertionError: err = sys.exc_info()[1] expect(err).to_be_an_error() expect(err).to_be_an_error_like(AssertionError) expect(err).to_have_an_error_message_of("Should not have gotten this far.") else: assert False, "Should not have gotten this far." def test_expect_not_to_be_here_with_message(): try: expect.not_to_be_here("qweqwe") except AssertionError: err = sys.exc_info()[1] expect(err).to_be_an_error() expect(err).to_be_an_error_like(AssertionError) expect(err).to_have_an_error_message_of("Should not have gotten this far (qweqwe).") else: assert False, "Should not have gotten this far." preggy-1.3.0/tests/test_chaining.py000066400000000000000000000027241267430770600173640ustar00rootroot00000000000000# -*- coding: utf-8 -*- # preggy assertions # https://github.com/heynemann/preggy # Licensed under the MIT license: # http://www.opensource.org/licenses/mit-license # Copyright (c) 2014 Pablo Santiago Blum de Aguiar from preggy import expect def test_chaining(): expect('qwe') \ .not_to_be_null() \ .to_be_instance_of(str) \ .to_be_like('QWE') \ .to_equal('qwe') expect(1729) \ .not_to_be_null() \ .to_be_instance_of(int) \ .to_be_numeric() \ .to_be_greater_or_equal_to(496) \ .to_equal(1729) expect(3.14159265358979) \ .not_to_be_null() \ .to_be_instance_of(float) \ .to_be_numeric() \ .to_be_lesser_or_equal_to(3.1416) \ .to_be_like(3.14159265358979) expect([1, 2, 3]) \ .not_to_be_null() \ .not_to_be_empty() \ .to_be_instance_of(list) \ .to_be_like([3, 2, 1]) expect({'a': 'b', 'x': 'z'}) \ .not_to_be_null() \ .not_to_be_empty() \ .to_be_instance_of(dict) \ .to_be_like({'x': 'z', 'a': 'b'}) meaning = {'x': 42} of_life = {'x': 42} expect(meaning.get('y')).to_equal(of_life.get('y')) expect(meaning.get('x')).not_to_be_null().to_equal(of_life.get('x')) try: expect(meaning.get('y')).not_to_be_null().to_equal(of_life.get('x')) except AssertionError: return else: assert False, 'Should not have gotten this far' preggy-1.3.0/tests/test_comparison.py000066400000000000000000000114611267430770600177540ustar00rootroot00000000000000# -*- coding: utf-8 -*- # preggy assertions # https://github.com/heynemann/preggy # Licensed under the MIT license: # http://www.opensource.org/licenses/mit-license # Copyright (c) 2013 Bernardo Heynemann heynemann@gmail.com from preggy import expect #----------------------------------------------------------------------------- TEST_DATA = ( 'qwe', b'qwe', 5, {'a': 'b', 'c': 'd'}, tuple([2, 3]), list([2, 3]), set([2, 3]), ) GREATER_THAN_DATA = ( 'asd', b'asd', 2, {'c': 'd'}, tuple([3]), list([3]), set([3]), ) LESSER_THAN_DATA = ( 'zcs', b'zcs', 7, {'a': 'b', 'c': 'd', 'e': 'f'}, tuple([3, 4, 5]), list([3, 4, 5]), set([3, 4, 5]), ) LESSER_OR_EQUAL_TO_DATA = ( 'qwe', b'qwe', 5, {'a': 'b', 'c': 'd'}, tuple([2, 3]), list([2, 3]), set([2, 3]), ) NOT_LESSER_OR_EQUAL_TO_DATA = ( 'zcs', b'zcs', 7, {'a': 'b', 'c': 'd', 'e': 'f'}, tuple([3, 4, 5]), list([3, 4, 5]), set([3, 4, 5]), ) LESSER_OR_EQUAL_TO_DATA_2 = ( 'zcs', b'zcs', 7, {'a': 'b', 'c': 'd', 'e': 'f'}, tuple([3, 4, 5]), list([3, 4, 5]), set([3, 4, 5]), ) GREATER_OR_EQUAL_TO_DATA = ( 'qwe', b'qwe', 5, {'a': 'b', 'c': 'd'}, tuple([2, 3]), list([2, 3]), set([2, 3]), ) NOT_GREATER_OR_EQUAL_TO_DATA = ( 'abc', b'abc', 1, {'a': 'b'}, tuple([3]), list([3]), set([3]), ) GREATER_OR_EQUAL_TO_DATA_2 = ( 'abc', b'abc', 1, {'a': 'b'}, tuple([3]), list([3]), set([3]), ) #----------------------------------------------------------------------------- def is_greater_than(topic): item, expected = topic expect(item).to_be_greater_than(expected) def is_not_greater_than(topic): item, expected = topic expect(item).Not.to_be_greater_than(expected) expect(item).not_to_be_greater_than(expected) def is_lesser_than(topic): item, expected = topic expect(item).to_be_lesser_than(expected) def is_not_lesser_than(topic): item, expected = topic expect(item).Not.to_be_lesser_than(expected) expect(item).not_to_be_lesser_than(expected) def is_greater_or_equal_to(topic): item, expected = topic expect(item).to_be_greater_or_equal_to(expected) def is_not_greater_or_equal_to(topic): item, expected = topic expect(item).Not.to_be_greater_or_equal_to(expected) expect(item).not_to_be_greater_or_equal_to(expected) def is_lesser_or_equal_to(topic): item, expected = topic expect(item).to_be_lesser_or_equal_to(expected) def is_not_lesser_or_equal_to(topic): item, expected = topic expect(item).Not.to_be_lesser_or_equal_to(expected) expect(item).not_to_be_lesser_or_equal_to(expected) #----------------------------------------------------------------------------- def test_greater_than(): for index, item in enumerate(TEST_DATA): expected = GREATER_THAN_DATA[index] yield is_greater_than, (item, expected) def test_not_greater_than(): for index, item in enumerate(TEST_DATA): expected = GREATER_THAN_DATA[index] yield is_not_greater_than, (expected, item) def test_lesser_than(): for index, item in enumerate(TEST_DATA): expected = LESSER_THAN_DATA[index] yield is_lesser_than, (item, expected) def test_not_lesser_than(): for index, item in enumerate(TEST_DATA): expected = LESSER_THAN_DATA[index] yield is_not_lesser_than, (expected, item) def test_greater_or_equal_to(): for index, item in enumerate(TEST_DATA): expected = GREATER_OR_EQUAL_TO_DATA[index] yield is_greater_or_equal_to, (item, expected) for index, item in enumerate(TEST_DATA): expected = GREATER_OR_EQUAL_TO_DATA_2[index] yield is_greater_or_equal_to, (item, expected) def test_not_greater_or_equal_to(): for index, item in enumerate(TEST_DATA): expected = NOT_GREATER_OR_EQUAL_TO_DATA[index] yield is_not_greater_or_equal_to, (expected, item) for index, item in enumerate(TEST_DATA): expected = GREATER_OR_EQUAL_TO_DATA_2[index] yield is_not_greater_or_equal_to, (expected, item) def test_lesser_or_equal_to(): for index, item in enumerate(TEST_DATA): expected = LESSER_OR_EQUAL_TO_DATA[index] yield is_lesser_or_equal_to, (item, expected) for index, item in enumerate(TEST_DATA): expected = LESSER_OR_EQUAL_TO_DATA_2[index] yield is_lesser_or_equal_to, (item, expected) def test_not_lesser_or_equal_to(): for index, item in enumerate(TEST_DATA): expected = NOT_LESSER_OR_EQUAL_TO_DATA[index] yield is_not_lesser_or_equal_to, (expected, item) for index, item in enumerate(TEST_DATA): expected = LESSER_OR_EQUAL_TO_DATA_2[index] yield is_not_lesser_or_equal_to, (expected, item) preggy-1.3.0/tests/test_emptiness.py000066400000000000000000000017601267430770600176120ustar00rootroot00000000000000# -*- coding: utf-8 -*- # preggy assertions # https://github.com/heynemann/preggy # Licensed under the MIT license: # http://www.opensource.org/licenses/mit-license # Copyright (c) 2013 Bernardo Heynemann heynemann@gmail.com from preggy import expect #----------------------------------------------------------------------------- EMPTY_DATA = ( '', [], {}, tuple([]) ) NOT_EMPTY_DATA = ( 'qwe', [1], {'a': 'b'}, tuple([2]) ) #----------------------------------------------------------------------------- def is_empty(item): expect(item).to_be_empty() def is_not_empty(item): expect(item).Not.to_be_empty() expect(item).not_to_be_empty() #----------------------------------------------------------------------------- def test_emptiness_assertion_works(): for empty_item in EMPTY_DATA: yield is_empty, empty_item def test_not_emptiness_assertion_works(): for not_empty_item in NOT_EMPTY_DATA: yield is_not_empty, not_empty_item preggy-1.3.0/tests/test_equality.py000066400000000000000000000025511267430770600174370ustar00rootroot00000000000000# -*- coding: utf-8 -*- # preggy assertions # https://github.com/heynemann/preggy # Licensed under the MIT license: # http://www.opensource.org/licenses/mit-license # Copyright (c) 2013 Bernardo Heynemann heynemann@gmail.com from preggy import expect from tests import Comparable, AnotherComparable #----------------------------------------------------------------------------- TEST_DATA = ( 'qwe', b'qwe', b'\xff\xd8\xff\xe0\x00\x10JFIF', [1], {'a': 'b'}, tuple([2]), Comparable() ) UNICODE_TEST_DATA = ( b'asdqwe123', 'asdqwe123', ) UNEQUAL_DATA = ( 'asd', [2], {'c': 'd'}, tuple([3]), Comparable('baz'), AnotherComparable() ) #----------------------------------------------------------------------------- def is_equal(topic): item, expected = topic expect(item).to_equal(expected) def is_not_equal(topic): item, expected = topic expect(item).Not.to_equal(expected) expect(item).not_to_equal(expected) #----------------------------------------------------------------------------- def test_unicode_equal(): is_equal((UNICODE_TEST_DATA[0], UNICODE_TEST_DATA[1])) def test_equal(): for item in TEST_DATA: yield is_equal, (item, item) def test_not_equal(): for item in TEST_DATA: for unequal in UNEQUAL_DATA: yield is_not_equal, (item, unequal) preggy-1.3.0/tests/test_inclusion.py000066400000000000000000000025021267430770600176010ustar00rootroot00000000000000# -*- coding: utf-8 -*- # preggy assertions # https://github.com/heynemann/preggy # Licensed under the MIT license: # http://www.opensource.org/licenses/mit-license # Copyright (c) 2013 Bernardo Heynemann heynemann@gmail.com from preggy import expect from tests import Comparable #----------------------------------------------------------------------------- TEST_DATA = ( 'my_string', [1, 2, 3, ], {'a': 1, 'b': 2}, tuple([1, 2, 3]), '123', '3.14', (None, Comparable(), 'deliberately the last one') ) INCLUDED_DATA = ( 'str', 1, 'a', 2, 1, 3.1, 'deliberately the last one' ) NOT_INCLUDED_DATA = ( 'potatoh', 4, 'c', 5, 4, 4.2, 2.718281828 ) #----------------------------------------------------------------------------- def is_included(item, expected): expect(item).to_include(expected) def is_not_included(item, expected): expect(item).Not.to_include(expected) expect(item).not_to_include(expected) #----------------------------------------------------------------------------- def test_includes(): for index, item in enumerate(TEST_DATA): yield is_included, item, INCLUDED_DATA[index] def test_not_includes(): for index, item in enumerate(TEST_DATA): yield is_not_included, item, NOT_INCLUDED_DATA[index] preggy-1.3.0/tests/test_length.py000066400000000000000000000042711267430770600170640ustar00rootroot00000000000000# -*- coding: utf-8 -*- # preggy assertions # https://github.com/heynemann/preggy # Licensed under the MIT license: # http://www.opensource.org/licenses/mit-license # Copyright (c) 2013 Bernardo Heynemann heynemann@gmail.com import sys try: from Queue import LifoQueue except ImportError: from queue import LifoQueue from preggy import expect #----------------------------------------------------------------------------- queue = LifoQueue() queue.put(1) queue.put(2) queue.put(3) TEST_DATA = ( '12345', [1, 2, 3], {'a': 1, 'b': 2}, tuple([1, 2, 3, 4, 5, 6]), queue ) EXPECTED_DATA = ( 5, 3, 2, 6, 3 ) NOT_EXPECTED_DATA = ( 7, 2, 3, 5, 5 ) #----------------------------------------------------------------------------- def is_expected(item, expected): expect(item).to_length(expected) try: expect(item).not_to_length(expected) except AssertionError: return assert False, 'Should not have gotten this far' def is_not_expected(item, expected): expect(item).Not.to_length(expected) expect(item).not_to_length(expected) try: expect(item).to_length(expected) except AssertionError: return assert False, 'Should not have gotten this far' #----------------------------------------------------------------------------- def test_length(): for index, item in enumerate(TEST_DATA): yield is_expected, item, EXPECTED_DATA[index] def test_not_includes(): for index, item in enumerate(TEST_DATA): yield is_not_expected, item, NOT_EXPECTED_DATA[index] def test_unable_to_identify_length(): try: expect(object()).to_length(1) except AssertionError: exc = sys.exc_info()[1] expect(str(exc)).to_match('Could not determine "