def __init__(self, name=None, negative=False, obj=None): self._name = name self.negative = negative self.obj = obj self._callable_args = [] self._callable_kw = {} self._that = AssertionHelper(self.obj)
def __call__(self, obj): self.obj = obj if isinstance(obj, self.__class__): self.obj = obj.obj self._that = AssertionHelper(self.obj) return self
def within(self, first, *rest): if isinstance(first, Iterable): collection_should = AssertionHelper(first) else: args = [first] + list(rest) collection_should = AssertionHelper(range(*args)) if self.negative: return collection_should.does_not_contain(self.obj) else: return collection_should.contains(self.obj)
def throw(self, *args, **kw): _that = AssertionHelper(self.obj, with_args=self._callable_args, and_kwargs=self._callable_kw) if self.negative: msg = "{0} called with args {1} and kwargs {2} should " "not raise {3} but raised {4}" exc = args and args[0] or Exception try: self.obj(*self._callable_args, **self._callable_kw) return True except Exception as e: err = msg.format(self.obj, self._that._callable_args, self._that._callable_kw, exc, e) raise AssertionError(err) return _that.raises(*args, **kw)
def cool(self): _that = AssertionHelper(self.obj, with_args=self._callable_args, and_kwargs=self._callable_kw) if self.negative: try: return _that.raises(Exception) except AssertionError: raise AssertionError('The callable `{0}` was supposed to not be cool and throw an exception, but it is too cool for that'.format(self.obj.__name__)) try: self.obj(*self._callable_args, **self._callable_kw) except Exception as e: raise AssertionError('The callable `{2}` should be cool but threw {0}: {1}'.format( e.__class__.__name__, str(e), self.obj.__name__ )) return True
def cool(self): _that = AssertionHelper(self.obj, with_args=self._callable_args, and_kwargs=self._callable_kw) if self.negative: try: return _that.raises(Exception) except AssertionError: raise AssertionError( 'The callable `{0}` was supposed to not be cool and throw an exception, but it is too cool for that' .format(self.obj.__name__)) try: self.obj(*self._callable_args, **self._callable_kw) except Exception as e: raise AssertionError( 'The callable `{2}` should be cool but threw {0}: {1}'.format( e.__class__.__name__, str(e), self.obj.__name__)) return True
def within(self, first, *rest): if isinstance(first, Iterable): collection_should = AssertionHelper(first) if self.negative: return collection_should.does_not_contain(self.obj) else: return collection_should.contains(self.obj) elif len(rest) == 1: return self.within_range(first, rest[0]) else: if self.negative: ppath = '{0}.should_not.be.within'.format(self.obj) else: ppath = '{0}.should.be.within'.format(self.obj) raise AssertionError( ('{0}({1}, {2}) must be called with either a iterable:\n' '{0}([1, 2, 3, 4])\n' 'or with a range of numbers:' '{0}(1, 3000)').format(ppath, first, ", ".join([repr(x) for x in rest])))
def within(self, first, *rest): if isinstance(first, Iterable): collection_should = AssertionHelper(first) if self.negative: return collection_should.does_not_contain(self.obj) else: return collection_should.contains(self.obj) elif len(rest) == 1: return self.within_range(first, rest[0]) else: if self.negative: ppath = '{0}.should_not.be.within'.format(self.obj) else: ppath = '{0}.should.be.within'.format(self.obj) raise AssertionError(( '{0}({1}, {2}) must be called with either a iterable:\n' '{0}([1, 2, 3, 4])\n' 'or with a range of numbers:' '{0}(1, 3000)' ).format(ppath, first, ", ".join([repr(x) for x in rest])))
def throw(self, *args, **kw): _that = AssertionHelper(self.obj, with_args=self._callable_args, and_kwargs=self._callable_kw) if self.negative: msg = ("{0} called with args {1} and kwargs {2} should " "not raise {3} but raised {4}") exc = args and args[0] or Exception try: self.obj(*self._callable_args, **self._callable_kw) return True except Exception as e: err = msg.format( self.obj, self._that._callable_args, self._that._callable_kw, exc, e, ) raise AssertionError(err) return _that.raises(*args, **kw)
def within(self, first, *rest): if isinstance(first, Iterable): collection_should = AssertionHelper(first) else: args = [first] + list(rest) collection_should = AssertionHelper(list(range(*args))) if self.negative: return collection_should.does_not_contain(self.obj) else: return collection_should.contains(self.obj)
class AssertionBuilder(object): def __init__(self, name=None, negative=False, obj=None): self._name = name self.negative = negative self.obj = obj self._callable_args = [] self._callable_kw = {} self._that = AssertionHelper(self.obj) def __call__(self, obj): self.obj = obj if isinstance(obj, self.__class__): self.obj = obj.obj self._that = AssertionHelper(self.obj) return self def __getattr__(self, attr): special_case = False special_case = attr in (POSITIVES + NEGATIVES) negative = attr in NEGATIVES if special_case: return AssertionBuilder(attr, negative=negative, obj=self.obj) return super(AssertionBuilder, self).__getattribute__(attr) @assertionproperty def callable(self): if self.negative: assert not callable(self.obj), "expected `{0}` to not be callable but it is".format(safe_repr(self.obj)) else: assert callable(self.obj), "expected {0} to be callable".format(safe_repr(self.obj)) return True @assertionproperty def be(self): import os if os.getenv("DEBUG"): import ipdb ipdb.set_trace() return IdentityAssertion(self) being = be @assertionproperty def not_be(self): return IdentityAssertion(self.should_not) not_being = not_be @assertionproperty def not_have(self): return self.should_not @assertionproperty def to_not(self): return self.should_not @assertionproperty def to(self): return self @assertionproperty def when(self): return self @assertionproperty def have(self): return self @assertionproperty def with_value(self): return self def property(self, name): has_it = hasattr(self.obj, name) if self.negative: assert not has_it, "%r should not have the property `%s`, " "but it is %r" % ( self.obj, name, getattr(self.obj, name), ) return True assert has_it, "%r should have the property `%s` but does not" % (self.obj, name) return expect(getattr(self.obj, name)) def key(self, name): has_it = name in self.obj if self.negative: assert not has_it, "%r should not have the key `%s`, " "but it is %r" % (self.obj, name, self.obj[name]) return True assert has_it, "%r should have the key `%s` but does not" % (self.obj, name) return expect(self.obj[name]) @assertionproperty def empty(self): representation = safe_repr(self.obj) length = len(self.obj) if self.negative: assert length > 0, "expected `{0}` to not be empty".format(representation) else: assert length == 0, "expected `{0}` to be empty but it has {1} items".format(representation, length) return True @assertionproperty def ok(self): if self.negative: msg = "expected `{0}` to be falsy".format(self.obj) assert not bool(self.obj), msg else: msg = "expected `{0}` to be truthy".format(self.obj) assert bool(self.obj), msg return True truthy = ok true = ok @assertionproperty def falsy(self): if self.negative: msg = "expected `{0}` to be truthy".format(self.obj) assert bool(self.obj), msg else: msg = "expected `{0}` to be falsy".format(self.obj) assert not bool(self.obj), msg return True false = falsy @assertionproperty def none(self): if self.negative: assert self.obj is not None, r"expected `{0}` to not be None".format(self.obj) else: assert self.obj is None, r"expected `{0}` to be None".format(self.obj) return True @assertionmethod def within(self, first, *rest): if isinstance(first, Iterable): collection_should = AssertionHelper(first) else: args = [first] + list(rest) collection_should = AssertionHelper(list(range(*args))) if self.negative: return collection_should.does_not_contain(self.obj) else: return collection_should.contains(self.obj) @assertionmethod def equal(self, what): try: comparison = DeepComparison(self.obj, what).compare() error = False except AssertionError as e: error = e comparison = None if isinstance(comparison, DeepExplanation): error = comparison.get_assertion(self.obj, what) if self.negative: if error: return True msg = "%s should differ to %s, but is the same thing" raise AssertionError(msg % (safe_repr(self.obj), safe_repr(what))) else: if not error: return True raise error eql = equal equals = equal equal_to = equal @assertionmethod def an(self, klass): if isinstance(klass, type): class_name = klass.__name__ elif isinstance(klass, string_types): class_name = klass.strip() else: class_name = text_type(klass) is_vowel = class_name[0] in "aeiou" if isinstance(klass, string_types): if "." in klass: items = klass.split(".") first = items.pop(0) if not items: items = [first] first = "_abcoll" else: if sys.version_info <= (3, 0, 0): first = "__builtin__" else: first = "builtins" items = [klass] klass = reduce(getattr, items, __import__(first)) suffix = is_vowel and "n" or "" if self.negative: assert not isinstance(self.obj, klass), "expected `{0}` to not be a{1} {2}".format( self.obj, suffix, class_name ) else: assert isinstance(self.obj, klass), "expected `{0}` to be a{1} {2}".format(self.obj, suffix, class_name) return True a = an @assertionmethod def greater_than(self, dest): if self.negative: msg = "expected `{0}` to not be greater than `{1}`".format(self.obj, dest) assert not self.obj > dest, msg else: msg = "expected `{0}` to be greater than `{1}`".format(self.obj, dest) assert self.obj > dest, msg return True @assertionmethod def greater_than_or_equal_to(self, dest): if self.negative: msg = "expected `{0}` to not be greater than or equal to `{1}`".format(self.obj, dest) assert not self.obj >= dest, msg else: msg = "expected `{0}` to be greater than or equal to `{1}`".format(self.obj, dest) assert self.obj >= dest, msg return True @assertionmethod def lower_than(self, dest): if self.negative: msg = "expected `{0}` to not be lower than `{1}`".format(self.obj, dest) assert not self.obj < dest, msg else: msg = "expected `{0}` to be lower than `{1}`".format(self.obj, dest) assert self.obj < dest, msg return True @assertionmethod def lower_than_or_equal_to(self, dest): if self.negative: msg = "expected `{0}` to not be lower than or equal to `{1}`".format(self.obj, dest) assert not self.obj <= dest, msg else: msg = "expected `{0}` to be lower than or equal to `{1}`".format(self.obj, dest) assert self.obj <= dest, msg return True @assertionmethod def below(self, num): if self.negative: msg = "{0} should not be below {1}".format(self.obj, num) assert not self.obj < num, msg else: msg = "{0} should be below {1}".format(self.obj, num) assert self.obj < num, msg return True @assertionmethod def above(self, num): if self.negative: msg = "{0} should not be above {1}".format(self.obj, num) assert not self.obj > num, msg else: msg = "{0} should be above {1}".format(self.obj, num) assert self.obj > num, msg return True @assertionmethod def length_of(self, num): if self.negative: return self._that.len_is_not(num) return self._that.len_is(num) @assertionmethod def called_with(self, *args, **kw): self._callable_args = args self._callable_kw = kw return self called = builtins.property(called_with) @assertionmethod def throw(self, *args, **kw): _that = AssertionHelper(self.obj, with_args=self._callable_args, and_kwargs=self._callable_kw) if self.negative: msg = "{0} called with args {1} and kwargs {2} should " "not raise {3} but raised {4}" exc = args and args[0] or Exception try: self.obj(*self._callable_args, **self._callable_kw) return True except Exception as e: err = msg.format(self.obj, self._that._callable_args, self._that._callable_kw, exc, e) raise AssertionError(err) return _that.raises(*args, **kw) @assertionmethod def return_value(self, value): return_value = self.obj(*self._callable_args, **self._callable_kw) return this(return_value).should.equal(value) @assertionmethod def look_like(self, value): if self.negative: try: self._that.looks_like(value) except AssertionError: return True else: msg = "%r should not look like %r but does" raise AssertionError(msg % (self.obj, value)) return self._that.looks_like(value) @assertionmethod def contain(self, what): if self.negative: return expect(what).to.not_be.within(self.obj) else: return expect(what).to.be.within(self.obj) @assertionmethod def match(self, regex, *args): obj_repr = repr(self.obj) assert isinstance(self.obj, basestring), "{0} should be a string in order to compare using .match()".format( obj_repr ) matched = re.search(regex, self.obj, *args) modifiers_map = {re.I: "i", re.L: "l", re.M: "m", re.S: "s", re.U: "u"} modifiers = "".join([modifiers_map.get(x, "") for x in args]) regex_representation = "/{0}/{1}".format(regex, modifiers) if self.negative: assert matched is None, "{0} should not match the regular expression {1}".format( obj_repr, regex_representation ) else: assert matched is not None, "{0} doesn't match the regular expression {1}".format( obj_repr, regex_representation ) return True
class AssertionBuilder(object): def __init__(self, name=None, negative=False, obj=None, callable_args=None, callable_kw=None): self._name = name self.negative = negative self.obj = obj self._callable_args = callable_args or [] self._callable_kw = callable_kw or {} self._that = AssertionHelper(self.obj) def __call__(self, obj): self.obj = obj if isinstance(obj, self.__class__): self.obj = obj.obj self._callable_args = obj._callable_args self._callable_kw = obj._callable_kw self._that = AssertionHelper(self.obj) return self def __getattr__(self, attr): special_case = False special_case = attr in (POSITIVES + NEGATIVES) negative = attr in NEGATIVES if special_case: return AssertionBuilder(attr, negative=negative, obj=self.obj, callable_args=self._callable_args, callable_kw=self._callable_kw) return super(AssertionBuilder, self).__getattribute__(attr) @assertionproperty def callable(self): if self.negative: assert not callable(self.obj), ( 'expected `{0}` to not be callable but it is'.format( safe_repr(self.obj))) else: assert callable(self.obj), ('expected {0} to be callable'.format( safe_repr(self.obj))) return True @assertionproperty def be(self): return IdentityAssertion(self) being = be @assertionproperty def not_be(self): return IdentityAssertion(self.should_not) not_being = not_be @assertionproperty def not_have(self): return self.should_not @assertionproperty def to_not(self): return self.should_not @assertionproperty def to(self): return self which = to @assertionproperty def when(self): return self @assertionproperty def have(self): return self @assertionproperty def with_value(self): return self def property(self, name): has_it = hasattr(self.obj, name) if self.negative: assert not has_it, ('%r should not have the property `%s`, ' 'but it is %r' % (self.obj, name, getattr(self.obj, name))) return True assert has_it, ("%r should have the property `%s` but does not" % (self.obj, name)) return expect(getattr(self.obj, name)) def key(self, name): has_it = name in self.obj if self.negative: assert not has_it, ('%r should not have the key `%s`, ' 'but it is %r' % (self.obj, name, self.obj[name])) return True assert has_it, ("%r should have the key `%s` but does not" % (self.obj, name)) return expect(self.obj[name]) @assertionproperty def empty(self): representation = safe_repr(self.obj) length = len(self.obj) if self.negative: assert length > 0, ( "expected `{0}` to not be empty".format(representation)) else: assert length == 0, ( "expected `{0}` to be empty but it has {1} items".format( representation, length)) return True @assertionproperty def ok(self): if self.negative: msg = 'expected `{0}` to be falsy'.format(self.obj) assert not bool(self.obj), msg else: msg = 'expected `{0}` to be truthy'.format(self.obj) assert bool(self.obj), msg return True truthy = ok true = ok @assertionproperty def falsy(self): if self.negative: msg = 'expected `{0}` to be truthy'.format(self.obj) assert bool(self.obj), msg else: msg = 'expected `{0}` to be falsy'.format(self.obj) assert not bool(self.obj), msg return True false = falsy @assertionproperty def none(self): if self.negative: assert self.obj is not None, ( r"expected `{0}` to not be None".format(self.obj)) else: assert self.obj is None, (r"expected `{0}` to be None".format( self.obj)) return True @assertionmethod def within_range(self, start, end): start = ensure_type('within_range', int, start) end = ensure_type('within_range', int, end) subject = ensure_type('within_range', int, self.obj) is_within_range = subject >= start and subject <= end if self.negative: if is_within_range: raise AssertionError( 'expected {0} to NOT be within {1} and {2}'.format( subject, start, end)) return not is_within_range else: if not is_within_range: raise AssertionError( 'expected {0} to be within {1} and {2}'.format( subject, start, end)) return is_within_range @assertionmethod def within(self, first, *rest): if isinstance(first, Iterable): collection_should = AssertionHelper(first) if self.negative: return collection_should.does_not_contain(self.obj) else: return collection_should.contains(self.obj) elif len(rest) == 1: return self.within_range(first, rest[0]) else: if self.negative: ppath = '{0}.should_not.be.within'.format(self.obj) else: ppath = '{0}.should.be.within'.format(self.obj) raise AssertionError( ('{0}({1}, {2}) must be called with either a iterable:\n' '{0}([1, 2, 3, 4])\n' 'or with a range of numbers:' '{0}(1, 3000)').format(ppath, first, ", ".join([repr(x) for x in rest]))) @assertionmethod def equal(self, what, epsilon=None): try: comparison = DeepComparison(self.obj, what, epsilon).compare() error = False except AssertionError as e: error = e comparison = None if isinstance(comparison, DeepExplanation): error = comparison.get_assertion(self.obj, what) if self.negative: if error: return True msg = '%s should differ from %s, but is the same thing' raise AssertionError(msg % (safe_repr(self.obj), safe_repr(what))) else: if not error: return True raise error eql = equal equals = equal equal_to = equal @assertionmethod def different_of(self, what): differ = difflib.Differ() source = self.obj.strip().splitlines(True) destination = what.strip().splitlines(True) result = differ.compare(source, destination) difference = "".join(result) if self.negative: if self.obj != what: assert not difference, "Difference:\n\n{0}".format(difference) else: if self.obj == what: raise AssertionError("{0} should be different of {1}".format( self.obj, what)) return True @assertionmethod def an(self, klass): if isinstance(klass, type): class_name = klass.__name__ elif isinstance(klass, string_types): class_name = klass.strip() else: class_name = text_type(klass) is_vowel = class_name[0] in 'aeiou' if isinstance(klass, string_types): if '.' in klass: items = klass.split('.') first = items.pop(0) if not items: items = [first] first = '_abcoll' else: if sys.version_info <= (3, 0, 0): first = '__builtin__' else: first = 'builtins' items = [klass] klass = reduce(getattr, items, __import__(first)) suffix = is_vowel and "n" or "" if self.negative: assert not isinstance( self.obj, klass), ('expected `{0}` to not be a{1} {2}'.format( self.obj, suffix, class_name)) else: assert isinstance(self.obj, klass), ('expected `{0}` to be a{1} {2}'.format( self.obj, suffix, class_name)) return True a = an @assertionmethod def greater_than(self, dest): if self.negative: msg = "expected `{0}` to not be greater than `{1}`".format( self.obj, dest) assert not self.obj > dest, msg else: msg = "expected `{0}` to be greater than `{1}`".format( self.obj, dest) assert self.obj > dest, msg return True @assertionmethod def greater_than_or_equal_to(self, dest): if self.negative: msg = "expected `{0}` to not be greater than or equal to `{1}`".format( self.obj, dest) assert not self.obj >= dest, msg else: msg = "expected `{0}` to be greater than or equal to `{1}`".format( self.obj, dest) assert self.obj >= dest, msg return True @assertionmethod def lower_than(self, dest): if self.negative: msg = "expected `{0}` to not be lower than `{1}`".format( self.obj, dest) assert not self.obj < dest, msg else: msg = "expected `{0}` to be lower than `{1}`".format( self.obj, dest) assert self.obj < dest, msg return True @assertionmethod def lower_than_or_equal_to(self, dest): if self.negative: msg = "expected `{0}` to not be lower than or equal to `{1}`".format( self.obj, dest) assert not self.obj <= dest, msg else: msg = "expected `{0}` to be lower than or equal to `{1}`".format( self.obj, dest) assert self.obj <= dest, msg return True @assertionmethod def below(self, num): if self.negative: msg = "{0} should not be below {1}".format(self.obj, num) assert not self.obj < num, msg else: msg = "{0} should be below {1}".format(self.obj, num) assert self.obj < num, msg return True @assertionmethod def above(self, num): if self.negative: msg = "{0} should not be above {1}".format(self.obj, num) assert not self.obj > num, msg else: msg = "{0} should be above {1}".format(self.obj, num) assert self.obj > num, msg return True @assertionmethod def length_of(self, num): if self.negative: return self._that.len_is_not(num) return self._that.len_is(num) def called_with(self, *args, **kw): self._callable_args = args self._callable_kw = kw return self called = builtins.property(called_with) @assertionmethod def throw(self, *args, **kw): _that = AssertionHelper(self.obj, with_args=self._callable_args, and_kwargs=self._callable_kw) if self.negative: msg = ("{0} called with args {1} and kwargs {2} should " "not raise {3} but raised {4}") exc = args and args[0] or Exception try: self.obj(*self._callable_args, **self._callable_kw) return True except Exception as e: err = msg.format( self.obj, self._that._callable_args, self._that._callable_kw, exc, e, ) raise AssertionError(err) return _that.raises(*args, **kw) thrown = throw raised = thrown @assertionmethod def return_value(self, value): return_value = self.obj(*self._callable_args, **self._callable_kw) return this(return_value).should.equal(value) returned_the_value = return_value @assertionmethod def look_like(self, value): if self.negative: try: self._that.looks_like(value) except AssertionError: return True else: msg = '%r should not look like %r but does' raise AssertionError(msg % (self.obj, value)) return self._that.looks_like(value) @assertionmethod def contain(self, what): obj = self.obj if self.negative: return expect(what).to.not_be.within(obj) else: return expect(what).to.be.within(obj) @assertionmethod def match(self, regex, *args): obj_repr = repr(self.obj) assert isinstance(self.obj, basestring), ( "{0} should be a string in order to compare using .match()".format( obj_repr)) matched = re.search(regex, self.obj, *args) modifiers_map = { re.I: "i", re.L: "l", re.M: "m", re.S: "s", re.U: "u", } modifiers = "".join([modifiers_map.get(x, "") for x in args]) regex_representation = '/{0}/{1}'.format(regex, modifiers) if self.negative: assert matched is None, ( "{0} should not match the regular expression {1}".format( obj_repr, regex_representation)) else: assert matched is not None, ( "{0} doesn't match the regular expression {1}".format( obj_repr, regex_representation)) return True
class AssertionBuilder(object): def __init__(self, name=None, negative=False, obj=None): self._name = name self.negative = negative self.obj = obj self._callable_args = [] self._callable_kw = {} self._that = AssertionHelper(self.obj) def __call__(self, obj): self.obj = obj if isinstance(obj, self.__class__): self.obj = obj.obj self._that = AssertionHelper(self.obj) return self def __getattr__(self, attr): special_case = False special_case = attr in (POSITIVES + NEGATIVES) negative = attr in NEGATIVES if special_case: return AssertionBuilder(attr, negative=negative, obj=self.obj) return super(AssertionBuilder, self).__getattribute__(attr) @assertionproperty def callable(self): if self.negative: assert not callable(self.obj), ( 'expected `{0}` to not be callable but it is'.format( safe_repr(self.obj))) else: assert callable(self.obj), ('expected {0} to be callable'.format( safe_repr(self.obj))) return True @assertionproperty def be(self): import os if os.getenv("DEBUG"): import ipdb ipdb.set_trace() return IdentityAssertion(self) being = be @assertionproperty def not_be(self): return IdentityAssertion(self.should_not) not_being = not_be @assertionproperty def not_have(self): return self.should_not @assertionproperty def to_not(self): return self.should_not @assertionproperty def to(self): return self @assertionproperty def when(self): return self @assertionproperty def have(self): return self @assertionproperty def with_value(self): return self def property(self, name): has_it = hasattr(self.obj, name) if self.negative: assert not has_it, ('%r should not have the property `%s`, ' 'but it is %r' % (self.obj, name, getattr(self.obj, name))) return True assert has_it, ("%r should have the property `%s` but does not" % (self.obj, name)) return expect(getattr(self.obj, name)) def key(self, name): has_it = name in self.obj if self.negative: assert not has_it, ('%r should not have the key `%s`, ' 'but it is %r' % (self.obj, name, self.obj[name])) return True assert has_it, ("%r should have the key `%s` but does not" % (self.obj, name)) return expect(self.obj[name]) @assertionproperty def empty(self): representation = safe_repr(self.obj) length = len(self.obj) if self.negative: assert length > 0, ( u"expected `{0}` to not be empty".format(representation)) else: assert length == 0, ( u"expected `{0}` to be empty but it has {1} items".format( representation, length)) return True @assertionproperty def ok(self): if self.negative: msg = u'expected `{0}` to be falsy'.format(self.obj) assert not bool(self.obj), msg else: msg = u'expected `{0}` to be truthy'.format(self.obj) assert bool(self.obj), msg return True truthy = ok true = ok @assertionproperty def falsy(self): if self.negative: msg = u'expected `{0}` to be truthy'.format(self.obj) assert bool(self.obj), msg else: msg = u'expected `{0}` to be falsy'.format(self.obj) assert not bool(self.obj), msg return True false = falsy @assertionproperty def none(self): if self.negative: assert self.obj is not None, ( r"expected `{0}` to not be None".format(self.obj)) else: assert self.obj is None, (r"expected `{0}` to be None".format( self.obj)) return True @assertionmethod def within(self, first, *rest): if isinstance(first, Iterable): collection_should = AssertionHelper(first) else: args = [first] + list(rest) collection_should = AssertionHelper(list(range(*args))) if self.negative: return collection_should.does_not_contain(self.obj) else: return collection_should.contains(self.obj) @assertionmethod def equal(self, what): try: comparison = DeepComparison(self.obj, what).compare() error = False except AssertionError as e: error = e comparison = None if isinstance(comparison, DeepExplanation): error = comparison.get_assertion(self.obj, what) if self.negative: if error: return True msg = '%s should differ to %s, but is the same thing' raise AssertionError(msg % (safe_repr(self.obj), safe_repr(what))) else: if not error: return True raise error eql = equal equals = equal equal_to = equal @assertionmethod def an(self, klass): if isinstance(klass, type): class_name = klass.__name__ elif isinstance(klass, string_types): class_name = klass.strip() else: class_name = text_type(klass) is_vowel = class_name[0] in 'aeiou' if isinstance(klass, string_types): if '.' in klass: items = klass.split('.') first = items.pop(0) if not items: items = [first] first = '_abcoll' else: if sys.version_info <= (3, 0, 0): first = u'__builtin__' else: first = u'builtins' items = [klass] klass = reduce(getattr, items, __import__(first)) suffix = is_vowel and "n" or "" if self.negative: assert not isinstance( self.obj, klass), ('expected `{0}` to not be a{1} {2}'.format( self.obj, suffix, class_name)) else: assert isinstance(self.obj, klass), ('expected `{0}` to be a{1} {2}'.format( self.obj, suffix, class_name)) return True a = an @assertionmethod def greater_than(self, dest): if self.negative: msg = u"expected `{0}` to not be greater than `{1}`".format( self.obj, dest) assert not self.obj > dest, msg else: msg = u"expected `{0}` to be greater than `{1}`".format( self.obj, dest) assert self.obj > dest, msg return True @assertionmethod def greater_than_or_equal_to(self, dest): if self.negative: msg = u"expected `{0}` to not be greater than or equal to `{1}`".format( self.obj, dest) assert not self.obj >= dest, msg else: msg = u"expected `{0}` to be greater than or equal to `{1}`".format( self.obj, dest) assert self.obj >= dest, msg return True @assertionmethod def lower_than(self, dest): if self.negative: msg = u"expected `{0}` to not be lower than `{1}`".format( self.obj, dest) assert not self.obj < dest, msg else: msg = u"expected `{0}` to be lower than `{1}`".format( self.obj, dest) assert self.obj < dest, msg return True @assertionmethod def lower_than_or_equal_to(self, dest): if self.negative: msg = u"expected `{0}` to not be lower than or equal to `{1}`".format( self.obj, dest) assert not self.obj <= dest, msg else: msg = u"expected `{0}` to be lower than or equal to `{1}`".format( self.obj, dest) assert self.obj <= dest, msg return True @assertionmethod def below(self, num): if self.negative: msg = u"{0} should not be below {1}".format(self.obj, num) assert not self.obj < num, msg else: msg = u"{0} should be below {1}".format(self.obj, num) assert self.obj < num, msg return True @assertionmethod def above(self, num): if self.negative: msg = u"{0} should not be above {1}".format(self.obj, num) assert not self.obj > num, msg else: msg = u"{0} should be above {1}".format(self.obj, num) assert self.obj > num, msg return True @assertionmethod def length_of(self, num): if self.negative: return self._that.len_is_not(num) return self._that.len_is(num) @assertionmethod def called_with(self, *args, **kw): self._callable_args = args self._callable_kw = kw return self called = builtins.property(called_with) @assertionmethod def throw(self, *args, **kw): _that = AssertionHelper(self.obj, with_args=self._callable_args, and_kwargs=self._callable_kw) if self.negative: msg = (u"{0} called with args {1} and kwargs {2} should " "not raise {3} but raised {4}") exc = args and args[0] or Exception try: self.obj(*self._callable_args, **self._callable_kw) return True except Exception as e: err = msg.format( self.obj, self._that._callable_args, self._that._callable_kw, exc, e, ) raise AssertionError(err) return _that.raises(*args, **kw) @assertionmethod def return_value(self, value): return_value = self.obj(*self._callable_args, **self._callable_kw) return this(return_value).should.equal(value) @assertionmethod def look_like(self, value): if self.negative: try: self._that.looks_like(value) except AssertionError: return True else: msg = '%r should not look like %r but does' raise AssertionError(msg % (self.obj, value)) return self._that.looks_like(value) @assertionmethod def contain(self, what): if self.negative: return expect(what).to.not_be.within(self.obj) else: return expect(what).to.be.within(self.obj) @assertionmethod def match(self, regex, *args): obj_repr = repr(self.obj) assert isinstance(self.obj, basestring), ( "{0} should be a string in order to compare using .match()".format( obj_repr)) matched = re.search(regex, self.obj, *args) modifiers_map = { re.I: "i", re.L: "l", re.M: "m", re.S: "s", re.U: "u", } modifiers = "".join([modifiers_map.get(x, "") for x in args]) regex_representation = '/{0}/{1}'.format(regex, modifiers) if self.negative: assert matched is None, ( "{0} should not match the regular expression {1}".format( obj_repr, regex_representation)) else: assert matched is not None, ( "{0} doesn't match the regular expression {1}".format( obj_repr, regex_representation)) return True
class AssertionBuilder(object): def __init__(self, name=None, negative=False, obj=None, callable_args=None, callable_kw=None): self._name = name self.negative = negative self.obj = obj self._callable_args = callable_args or [] self._callable_kw = callable_kw or {} self._that = AssertionHelper(self.obj) def __call__(self, obj): self.obj = obj if isinstance(obj, self.__class__): self.obj = obj.obj self._callable_args = obj._callable_args self._callable_kw = obj._callable_kw self._that = AssertionHelper(self.obj) return self def __getattr__(self, attr): special_case = False special_case = attr in (POSITIVES + NEGATIVES) negative = attr in NEGATIVES if special_case: return AssertionBuilder(attr, negative=negative, obj=self.obj, callable_args=self._callable_args, callable_kw=self._callable_kw) return super(AssertionBuilder, self).__getattribute__(attr) @assertionproperty def callable(self): if self.negative: assert not callable(self.obj), ( 'expected `{0}` to not be callable but it is'.format(safe_repr(self.obj))) else: assert callable(self.obj), ( 'expected {0} to be callable'.format(safe_repr(self.obj))) return True @assertionproperty def be(self): return IdentityAssertion(self) being = be @assertionproperty def not_be(self): return IdentityAssertion(self.should_not) not_being = not_be @assertionproperty def not_have(self): return self.should_not @assertionproperty def to_not(self): return self.should_not @assertionproperty def to(self): return self which = to @assertionproperty def when(self): return self @assertionproperty def have(self): return self @assertionproperty def with_value(self): return self def property(self, name): has_it = hasattr(self.obj, name) if self.negative: assert not has_it, ( '%r should not have the property `%s`, ' 'but it is %r' % (self.obj, name, getattr(self.obj, name))) return True assert has_it, ( "%r should have the property `%s` but does not" % ( self.obj, name)) return expect(getattr(self.obj, name)) def key(self, name): has_it = name in self.obj if self.negative: assert not has_it, ( '%r should not have the key `%s`, ' 'but it is %r' % (self.obj, name, self.obj[name])) return True assert has_it, ( "%r should have the key `%s` but does not" % ( self.obj, name)) return expect(self.obj[name]) @assertionproperty def empty(self): representation = safe_repr(self.obj) length = len(self.obj) if self.negative: assert length > 0, ( "expected `{0}` to not be empty".format(representation)) else: assert length == 0, ( "expected `{0}` to be empty but it has {1} items".format(representation, length)) return True @assertionproperty def ok(self): if self.negative: msg = 'expected `{0}` to be falsy'.format(self.obj) assert not bool(self.obj), msg else: msg = 'expected `{0}` to be truthy'.format(self.obj) assert bool(self.obj), msg return True truthy = ok true = ok @assertionproperty def falsy(self): if self.negative: msg = 'expected `{0}` to be truthy'.format(self.obj) assert bool(self.obj), msg else: msg = 'expected `{0}` to be falsy'.format(self.obj) assert not bool(self.obj), msg return True false = falsy @assertionproperty def none(self): if self.negative: assert self.obj is not None, ( r"expected `{0}` to not be None".format(self.obj)) else: assert self.obj is None, ( r"expected `{0}` to be None".format(self.obj)) return True @assertionmethod def within_range(self, start, end): start = ensure_type('within_range', int, start) end = ensure_type('within_range', int, end) subject = ensure_type('within_range', int, self.obj) is_within_range = subject >= start and subject <= end if self.negative: if is_within_range: raise AssertionError('expected {0} to NOT be within {1} and {2}'.format(subject, start, end)) return not is_within_range else: if not is_within_range: raise AssertionError('expected {0} to be within {1} and {2}'.format(subject, start, end)) return is_within_range @assertionmethod def within(self, first, *rest): if isinstance(first, Iterable): collection_should = AssertionHelper(first) if self.negative: return collection_should.does_not_contain(self.obj) else: return collection_should.contains(self.obj) elif len(rest) == 1: return self.within_range(first, rest[0]) else: if self.negative: ppath = '{0}.should_not.be.within'.format(self.obj) else: ppath = '{0}.should.be.within'.format(self.obj) raise AssertionError(( '{0}({1}, {2}) must be called with either a iterable:\n' '{0}([1, 2, 3, 4])\n' 'or with a range of numbers:' '{0}(1, 3000)' ).format(ppath, first, ", ".join([repr(x) for x in rest]))) @assertionmethod def equal(self, what, epsilon=None): try: comparison = DeepComparison(self.obj, what, epsilon).compare() error = False except AssertionError as e: error = e comparison = None if isinstance(comparison, DeepExplanation): error = comparison.get_assertion(self.obj, what) if self.negative: if error: return True msg = '%s should differ from %s, but is the same thing' raise AssertionError(msg % (safe_repr(self.obj), safe_repr(what))) else: if not error: return True raise error eql = equal equals = equal equal_to = equal @assertionmethod def different_of(self, what): differ = difflib.Differ() source = self.obj.strip().splitlines(True) destination = what.strip().splitlines(True) result = differ.compare(source, destination) difference = "".join(result) if self.negative: if self.obj != what: assert not difference, "Difference:\n\n{0}".format(difference) else: if self.obj == what: raise AssertionError("{0} should be different of {1}".format(self.obj, what)) return True @assertionmethod def an(self, klass): if isinstance(klass, type): class_name = klass.__name__ elif isinstance(klass, string_types): class_name = klass.strip() else: class_name = text_type(klass) is_vowel = class_name[0] in 'aeiou' if isinstance(klass, string_types): if '.' in klass: items = klass.split('.') first = items.pop(0) if not items: items = [first] first = '_abcoll' else: if sys.version_info <= (3, 0, 0): first = '__builtin__' else: first = 'builtins' items = [klass] klass = reduce(getattr, items, __import__(first)) suffix = is_vowel and "n" or "" if self.negative: assert not isinstance(self.obj, klass), ( 'expected `{0}` to not be a{1} {2}'.format( self.obj, suffix, class_name)) else: assert isinstance(self.obj, klass), ( 'expected `{0}` to be a{1} {2}'.format( self.obj, suffix, class_name)) return True a = an @assertionmethod def greater_than(self, dest): if self.negative: msg = "expected `{0}` to not be greater than `{1}`".format( self.obj, dest) assert not self.obj > dest, msg else: msg = "expected `{0}` to be greater than `{1}`".format( self.obj, dest) assert self.obj > dest, msg return True @assertionmethod def greater_than_or_equal_to(self, dest): if self.negative: msg = "expected `{0}` to not be greater than or equal to `{1}`".format( self.obj, dest) assert not self.obj >= dest, msg else: msg = "expected `{0}` to be greater than or equal to `{1}`".format( self.obj, dest) assert self.obj >= dest, msg return True @assertionmethod def lower_than(self, dest): if self.negative: msg = "expected `{0}` to not be lower than `{1}`".format( self.obj, dest) assert not self.obj < dest, msg else: msg = "expected `{0}` to be lower than `{1}`".format( self.obj, dest) assert self.obj < dest, msg return True @assertionmethod def lower_than_or_equal_to(self, dest): if self.negative: msg = "expected `{0}` to not be lower than or equal to `{1}`".format( self.obj, dest) assert not self.obj <= dest, msg else: msg = "expected `{0}` to be lower than or equal to `{1}`".format( self.obj, dest) assert self.obj <= dest, msg return True @assertionmethod def below(self, num): if self.negative: msg = "{0} should not be below {1}".format(self.obj, num) assert not self.obj < num, msg else: msg = "{0} should be below {1}".format(self.obj, num) assert self.obj < num, msg return True @assertionmethod def above(self, num): if self.negative: msg = "{0} should not be above {1}".format(self.obj, num) assert not self.obj > num, msg else: msg = "{0} should be above {1}".format(self.obj, num) assert self.obj > num, msg return True @assertionmethod def length_of(self, num): if self.negative: return self._that.len_is_not(num) return self._that.len_is(num) def called_with(self, *args, **kw): self._callable_args = args self._callable_kw = kw return self called = builtins.property(called_with) @assertionmethod def throw(self, *args, **kw): _that = AssertionHelper(self.obj, with_args=self._callable_args, and_kwargs=self._callable_kw) if self.negative: msg = ("{0} called with args {1} and kwargs {2} should " "not raise {3} but raised {4}") exc = args and args[0] or Exception try: self.obj(*self._callable_args, **self._callable_kw) return True except Exception as e: err = msg.format( self.obj, self._that._callable_args, self._that._callable_kw, exc, e, ) raise AssertionError(err) return _that.raises(*args, **kw) thrown = throw raised = thrown @assertionmethod def return_value(self, value): return_value = self.obj(*self._callable_args, **self._callable_kw) return this(return_value).should.equal(value) returned_the_value = return_value @assertionmethod def look_like(self, value): if self.negative: try: self._that.looks_like(value) except AssertionError: return True else: msg = '%r should not look like %r but does' raise AssertionError(msg % (self.obj, value)) return self._that.looks_like(value) @assertionmethod def contain(self, what): obj = self.obj if self.negative: return expect(what).to.not_be.within(obj) else: return expect(what).to.be.within(obj) @assertionmethod def match(self, regex, *args): obj_repr = repr(self.obj) assert isinstance(self.obj, basestring), ( "{0} should be a string in order to compare using .match()".format(obj_repr) ) matched = re.search(regex, self.obj, *args) modifiers_map = { re.I: "i", re.L: "l", re.M: "m", re.S: "s", re.U: "u", } modifiers = "".join([modifiers_map.get(x, "") for x in args]) regex_representation = '/{0}/{1}'.format(regex, modifiers) if self.negative: assert matched is None, ( "{0} should not match the regular expression {1}".format( obj_repr, regex_representation)) else: assert matched is not None, ( "{0} doesn't match the regular expression {1}".format( obj_repr, regex_representation)) return True
class AssertionBuilder(object): def __init__(self, name=None, negative=False): self._name = name self.negative = negative self._callable_args = [] self._callable_kw = {} def __call__(self, obj): self.obj = obj if isinstance(obj, self.__class__): self.obj = obj.obj self._that = AssertionHelper(self.obj) return self def __getattr__(self, attr): special_case = False special_case = attr in (POSITIVES + NEGATIVES) self.negative = attr in NEGATIVES if attr in POSITIVES: self.negative = False special_case = True if attr in NEGATIVES: self.negative = True special_case = True if special_case: return self return super(AssertionBuilder, self).__getattribute__(attr) @assertionproperty def callable(self): if self.negative: assert not callable(self.obj), ( 'expected `{0}` to not be callable but it is'.format(safe_repr(self.obj))) else: assert callable(self.obj), ( 'expected {0} to be callable'.format(safe_repr(self.obj))) return True @assertionproperty def be(self): return self @assertionproperty def being(self): return self @assertionproperty def not_being(self): return self.should_not @assertionproperty def not_be(self): return self.obj.should_not @assertionproperty def not_have(self): return self.obj.should_not @assertionproperty def to_not(self): return self.obj.should_not @assertionproperty def to(self): return self @assertionproperty def when(self): return self @assertionproperty def have(self): return self @assertionproperty def with_value(self): return self def property(self, name): has_it = hasattr(self.obj, name) if self.negative: assert not has_it, ( '%r should not have the property `%s`, ' 'but it is %r' % (self.obj, name, getattr(self.obj, name))) return True assert has_it, ( "%r should have the property `%s` but doesn't" % ( self.obj, name)) return expect(getattr(self.obj, name)) def key(self, name): has_it = name in self.obj if self.negative: assert not has_it, ( '%r should not have the key `%s`, ' 'but it is %r' % (self.obj, name, self.obj[name])) return True assert has_it, ( "%r should have the key `%s` but doesn't" % ( self.obj, name)) return expect(self.obj[name]) @assertionproperty def empty(self): representation = safe_repr(self.obj) length = len(self.obj) if self.negative: assert length > 0, ( u"expected `{0}` to not be empty".format(representation)) else: assert length is 0, ( u"expected `{0}` to be empty but it has {1} items".format(representation, length)) return True @assertionproperty def ok(self): if self.negative: msg = u'expected `{0}` to be falsy'.format(self.obj) assert not bool(self.obj), msg else: msg = u'expected `{0}` to be truthy'.format(self.obj) assert bool(self.obj), msg return True truthy = ok true = ok @assertionproperty def falsy(self): if self.negative: msg = u'expected `{0}` to be truthy'.format(self.obj) assert bool(self.obj), msg else: msg = u'expected `{0}` to be falsy'.format(self.obj) assert not bool(self.obj), msg return True false = falsy @assertionproperty def none(self): if self.negative: assert self.obj is not None, ( ur"expected `{0}` to not be None".format(self.obj)) else: assert self.obj is None, ( ur"expected `{0}` to be None".format(self.obj)) return True @assertionmethod def within(self, first, *rest): if isinstance(first, Iterable): collection_should = AssertionHelper(first) else: args = [first] + list(rest) collection_should = AssertionHelper(range(*args)) if self.negative: return collection_should.does_not_contain(self.obj) else: return collection_should.contains(self.obj) @assertionmethod def equal(self, what): try: comparison = DeepComparison(self.obj, what).compare() error = False except AssertionError as e: error = e comparison = None if isinstance(comparison, DeepExplanation): error = comparison.get_assertion(self.obj, what) if self.negative: if error: return True msg = '%r should differ to %r, but is the same thing' raise AssertionError(msg % (self.obj, what)) else: if not error: return True raise error eql = equal equals = equal @assertionmethod def an(self, klass): if isinstance(klass, type): class_name = klass.__name__ elif isinstance(klass, basestring): class_name = klass.strip() else: class_name = unicode(klass) is_vowel = class_name[0] in 'aeiou' if isinstance(klass, basestring): if '.' in klass: items = klass.split('.') first = items.pop(0) if not items: items = [first] first = '_abcoll' else: if sys.version_info <= (3, 0, 0): first = u'__builtin__' else: first = u'builtins' items = [klass] klass = reduce(getattr, items, __import__(first)) suffix = is_vowel and "n" or "" if self.negative: assert not isinstance(self.obj, klass), ( 'expected `{0}` to not be a{1} {2}'.format( self.obj, suffix, class_name)) else: assert isinstance(self.obj, klass), ( 'expected `{0}` to be a{1} {2}'.format( self.obj, suffix, class_name)) return True a = an @assertionmethod def greater_than(self, dest): if self.negative: msg = u"expected `{0}` to not be greater than `{1}`".format( self.obj, dest) assert not self.obj > dest, msg else: msg = u"expected `{0}` to be greater than `{1}`".format( self.obj, dest) assert self.obj > dest, msg return True @assertionmethod def greater_than_or_equal_to(self, dest): if self.negative: msg = u"expected `{0}` to not be greater than or equal to `{1}`".format( self.obj, dest) assert not self.obj >= dest, msg else: msg = u"expected `{0}` to be greater than or equal to `{1}`".format( self.obj, dest) assert self.obj >= dest, msg return True @assertionmethod def lower_than(self, dest): if self.negative: msg = u"expected `{0}` to not be lower than `{1}`".format( self.obj, dest) assert not self.obj < dest, msg else: msg = u"expected `{0}` to be lower than `{1}`".format( self.obj, dest) assert self.obj < dest, msg return True @assertionmethod def lower_than_or_equal_to(self, dest): if self.negative: msg = u"expected `{0}` to not be lower than or equal to `{1}`".format( self.obj, dest) assert not self.obj <= dest, msg else: msg = u"expected `{0}` to be lower than or equal to `{1}`".format( self.obj, dest) assert self.obj <= dest, msg return True @assertionmethod def below(self, num): if self.negative: msg = u"{0} should not be below {1}".format(self.obj, num) assert not self.obj < num, msg else: msg = u"{0} should be below {1}".format(self.obj, num) assert self.obj < num, msg return True @assertionmethod def above(self, num): if self.negative: msg = u"{0} should not be above {1}".format(self.obj, num) assert not self.obj > num, msg else: msg = u"{0} should be above {1}".format(self.obj, num) assert self.obj > num, msg return True @assertionmethod def length_of(self, num): if self.negative: return self._that.len_is_not(num) return self._that.len_is(num) @assertionmethod def called_with(self, *args, **kw): self._callable_args = args self._callable_kw = kw return self called = builtins.property(called_with) @assertionmethod def throw(self, *args, **kw): _that = AssertionHelper(self.obj, with_args=self._callable_args, and_kwargs=self._callable_kw) if self.negative: msg = (u"{0} called with args {1} and kwargs {2} should " "not raise {3} but raised {4}") exc = args and args[0] or Exception try: self.obj(*self._callable_args, **self._callable_kw) return True except Exception, e: err = msg.format( self.obj, self._that._callable_args, self._that._callable_kw, exc, e, ) raise AssertionError(err) return _that.raises(*args, **kw)