def given_typechecking_behaviour(): ''' Spec for check that given=... is correct type ''' def spec_for_dict_given_empty_list(): ''' callable method to defer instance creation until within Spec ''' return Spec(type({}), given=lambda: []) spec = Spec(spec_for_dict_given_empty_list) type_error = TypeError("[] is not instance of <class 'dict'>") spec.__call__().should_raise(type_error)
def desc_should_use_comparator(self): ''' describe_constraint should delegate to comparator.description ''' comparator = MockSpec() spec = Spec(Constraint(comparator)) comparator_description = comparator.description() comparator_description.will_return('subtitled') spec.describe_constraint() spec.should_collaborate_with(comparator_description, and_result='should be subtitled')
def should_use_nothing_comparator(self): ''' Constraint should use Nothing comparator by default''' spec = Spec(Constraint()) spec.describe_constraint().should_be('should be nothing') spec.verify_value(1).should_be(False) spec.verify_value(2).should_be(False) spec.verify_value(None).should_be(False) spec.verify_value(['majestic', 'moose']).should_be(False) spec.verify_value({'gumby': 'brain surgeon'}).should_be(False)
def should_verify_each_item(self): ''' verify() should execute each included item ''' a_list = [] lambda_list_append1 = lambda: a_list.append(0) lambda_list_append2 = lambda: a_list.extend((1, 2)) spec = Spec(AllVerifiable, given=silent_listener) spec.when(spec.include(lambda_list_append1), spec.include(lambda_list_append2), spec.verify()) spec.then(a_list.__len__).should_be(3)
def should_trap_incorrect_return(self): ''' Specified and_result="bar" but was "baz": UnmetSpecification. Note: and_result refers to the value returned from the callable invoked in verify(), not the return value from the mock. See the Hungarian gentleman in the examples for a clearer picture... ''' mock_spec = MockSpec() spec = Spec( CollaborateWith(mock_spec.foo().will_return('baz'), and_result='bar')) spec.verify(lambda: mock_spec.foo()).should_raise(UnmetSpecification)
def should_trap_incorrect_args(self): ''' Specified foo(2) & bar(), and foo(1) called: UnmetSpecification''' mock_spec = MockSpec() collaborations = (mock_spec.foo(2), mock_spec.bar()) descriptions = [ collaboration.description() for collaboration in collaborations ] spec = Spec(CollaborateWith(*collaborations)) spec.describe_constraint().should_be(','.join(descriptions)) spec.verify(lambda: mock_spec.foo(1)).should_raise(UnmetSpecification)
def supply_different_values_each_time(self): ''' supplies(a,b,...) should return a,b,... on successive calls ''' spec = Spec(MockResult(MockCall(MockSpec(), ''))) spec.when(spec.times(3)) spec.then(spec.supplies('x', 'y', 'z')).should_not_raise(ValueError) spec.then(spec.specified_times()).should_be(3) spec.then(spec.next()).should_be('x') spec.then(spec.next()).should_be('y') spec.then(spec.next()).should_be('z') spec.then(spec.next()).should_raise(UnmetSpecification)
def return_twice(self): ''' times(2) should return default (None) value just twice ''' spec = Spec(MockResult(MockCall(MockSpec(), ''))) spec.when(spec.times(2)) spec.then(spec.specified_times()).should_be(2) spec.then(spec.times_remaining()).should_be(2) spec.then(spec.times_remaining()).should_be(2) spec.then(spec.next()).should_be(None) spec.then(spec.times_remaining()).should_be(1) spec.then(spec.next()).should_be(None) spec.then(spec.times_remaining()).should_be(0) spec.then(spec.next()).should_raise(UnmetSpecification)
def should_mimic_specification(self): ''' result_of should be callable and return specified value or raise specified exception ''' mock_call = MockSpec().foo() mock_call_result = mock_call.result_of('foo') spec = Spec(mock_call_result) spec.__call__().should_be(None) mock_call = MockSpec().foo().will_return(1) mock_call_result = mock_call.result_of('foo') spec = Spec(mock_call_result) spec.__call__().should_be(1) mock_call = MockSpec().foo().will_return((2, 3)) mock_call_result = mock_call.result_of('foo') spec = Spec(mock_call_result) spec.__call__().should_be((2, 3)) mock_call = MockSpec().foo().will_raise(StopIteration) mock_call_result = mock_call.result_of('foo') spec = Spec(mock_call_result) spec.__call__().should_raise(StopIteration) value_error = ValueError("that's no ordinary rabbit") mock_spec = MockSpec() mock_call = mock_spec.foo().will_raise(value_error) mock_call_result = mock_call.result_of('foo') spec = Spec(mock_call_result) spec.__call__().should_raise(value_error) # check that after exception raised the collaboration is 'over' Spec(mock_spec).verify().should_not_raise(UnmetSpecification)
def external_then_behaviour(): ''' Spec for then()... actions that call outside the spec itself. Note that the action on the spec is invoked in client code with parens(): spec.then( * spec.__len__() * ).should_be(1) but the action outside the spec is NOT: spec.then( * 'they called him brian'.__len__ * ).should_be(21) ''' spec = Spec([]) spec.when(spec.append('brian')) spec.then(spec.__len__()).should_be(1) spec.then('they called him brian'.__len__).should_be(21)
def raise_exception(self): ''' raises(exception) should raise exceptions in the same fashion as will_suppply_values should return values ''' spec = Spec(MockResult(MockCall(MockSpec(), ''))) exception = ValueError('the number of the counting shall be three') spec.when(spec.raises(exception)) spec.then(spec.next()).should_raise(exception) spec.then(spec.times_remaining()).should_be(0) spec.then(spec.next()).should_raise(UnmetSpecification) spec = Spec(MockResult(MockCall(MockSpec(), ''))) exception = ValueError('the number of the counting shall be three') spec.when(spec.times(2), spec.raises(exception)) spec.then(spec.next()).should_raise(exception) spec.then(spec.next()).should_raise(exception) spec.then(spec.next()).should_raise(UnmetSpecification) spec = Spec(MockResult(MockCall(MockSpec(), ''))) exceptions = (ValueError('the number of the counting shall be three'), ValueError('Four shalt thou not count')) spec.when(spec.times(2), spec.raises(*exceptions)) spec.then(spec.next()).should_raise(exceptions[0]) spec.then(spec.next()).should_raise(exceptions[1]) spec.then(spec.next()).should_raise(UnmetSpecification)
def grouped_methods_should_verify(self): ''' grouping() methods should allow them to be executed & verified ''' all_verifiable = silent_listener() def add_related_verifiables(): grouping(RelatedVerifiables, all_verifiable) verifiable(RelatedVerifiables.verifiable1, all_verifiable) verifiable(RelatedVerifiables.verifiable2, all_verifiable) all_verifiable.add_related_verifiables = add_related_verifiables spec = Spec(all_verifiable) spec.when(spec.add_related_verifiables()) spec.then(spec.total()).should_be(2) spec.then(spec.verify()) spec.should_be({'total': 2, 'verified': 2, 'unverified': 0})
def default_mock_spec_comparators(self): ''' ExceptionValue should be default for comparing exceptions, and FloatValue for comparing floats. All other types compare with EqualsEquals ''' spec = Spec(MockSpec()) spec.comparable(IndexError('the number of the counting')) spec.should_be(Type(ExceptionValue)) spec.comparable(1.99) spec.should_be(Type(FloatValue)) spec.comparable(3).should_be(Type(EqualsEquals)) spec.comparable('holy hand grenade').should_be(Type(EqualsEquals)) spec.comparable([]).should_be(Type(EqualsEquals)) spec.comparable({}).should_be(Type(EqualsEquals))
def result_of_successive_times(): ''' result_of should "iterate" over will_return value(s) and provide a meaningful error message if the specification is unmet''' mock_call = MockSpec(name='x').foo().times(2).will_return(3, 4) spec = Spec(mock_call.result_of('foo')) spec.__call__().should_be(3) spec = Spec(mock_call.result_of('foo')) spec.__call__().should_be(4) spec = Spec(mock_call.result_of('foo')) msg = 'should be collaborating with x.foo() only 2 successive times' spec.__call__().should_raise(UnmetSpecification(msg)) mock_call = MockSpec(name='y').bar().times(3).will_return(5) spec = Spec(mock_call.result_of('bar')) spec.__call__().should_be(5) spec = Spec(mock_call.result_of('bar')) spec.__call__().should_be(5) spec = Spec(mock_call.result_of('bar')) spec.__call__().should_be(5) spec = Spec(mock_call.result_of('bar')) msg = 'should be collaborating with y.bar() only 3 successive times' spec.__call__().should_raise(UnmetSpecification(msg))
def should_reject_non_classes(self): ''' grouping(not a type or class) should raise exception ''' msg = '1 is not a type: perhaps you meant to use @verifiable instead?' Spec(grouping).grouping(1).should_raise(TypeError(msg))
def should_return_decorated_class(self): ''' grouping(cls) should return the cls ''' spec = Spec(grouping) spec.grouping(RelatedVerifiables, silent_listener()) spec.should_be(RelatedVerifiables)