def get_unisolated_module_type(self): ''' get_type() should return a requested module type, given the fully qualified name including module. The same type should be returned on successive invocations. The same type should also be returned from different contexts. State in a module should not be isolated within each context''' _types = {'StateAlteringClass': 'module_with_state'} execution_context = ExecutionContext(isolate_imports=False) execution_context.add_import_path(self._nonsrc_path(execution_context)) for _type, mod in _types.items(): fully_qualified_name = '%s.%s' % (mod, _type) same_type = execution_context.get_type(fully_qualified_name) lancelot.Spec(same_type.__name__).it().should_be(_type) spec = lancelot.Spec(execution_context) spec.get_type(fully_qualified_name).should_be(SameAs(same_type)) other_context = ExecutionContext(isolate_imports=False) other_context.add_import_path(self._nonsrc_path(other_context)) different_type = other_context.get_type(fully_qualified_name) spec.get_type(fully_qualified_name).should_be( SameAs(different_type)) instances = same_type(), different_type() spec = lancelot.Spec(instances[0]) spec.when(spec.alter_state()) spec.then(spec.get_state()).should_contain(1) spec.then(instances[1].get_state).should_contain(1) execution_context.cleanup_imports() other_context.cleanup_imports()
def get_unisolated_imported_module(self): ''' get_module() should return a requested module, which should remain in sys.modules as it has been loaded unisolated. The same module should be returned on successive invocations. The same module should be returned from different contexts ''' same_context = ExecutionContext() same_context.add_import_path(self._nonsrc_path(same_context)) different_context = ExecutionContext(isolate_imports=False) different_context.add_import_path(self._nonsrc_path(different_context)) for mod in ('import_me', 'module_with_state'): spec = lancelot.Spec(same_context) spec.get_module(mod).should_be(Type(types.ModuleType)) same_module = same_context.get_module(mod) spec.get_module(mod).should_be(SameAs(same_module)) sys_spec = lancelot.Spec(sys.modules) sys_spec.it().should_contain(mod) different_module = different_context.get_module(mod) spec.get_module(mod).should_be(SameAs(different_module)) same_context.cleanup_imports() different_context.cleanup_imports()
def handles_stoptest_exceptions(self): ''' if stop test exception is thrown stop executing instructions ''' mock_fn = lancelot.MockSpec(name='mock_fn') mock_call = lancelot.MockSpec(name='mock_call') results = lancelot.MockSpec(name='results') a_list = [ ['id_', 'call', 'instance', 'fn', 'arg'], ['id_', 'call', 'instance2', 'fn2', 'arg2'] ] instructions = Instructions(a_list, lambda item: mock_fn.instruction_for(item)) spec = lancelot.Spec(instructions) ctx = ExecutionContext() msg = "I couldn't eat another thing. I'm absolutely stuffed." # Suppress warning log message that we know will be generated logger = logging.getLogger('Instructions') log_level = logger.getEffectiveLevel() logger.setLevel(logging.ERROR) try: spec.execute(ctx, results).should_collaborate_with( mock_fn.instruction_for(a_list[0]).will_return(mock_call), mock_call.execute(ctx, results).will_raise(StopTestException(msg)), results.failed(mock_call, msg, True) ) finally: # Put logger back to how it was logger.setLevel(log_level) ctx.cleanup_imports()
def handles_stoptest_exceptions(self): ''' if stop test exception is thrown stop executing instructions ''' mock_fn = lancelot.MockSpec(name='mock_fn') mock_call = lancelot.MockSpec(name='mock_call') results = lancelot.MockSpec(name='results') a_list = [['id_', 'call', 'instance', 'fn', 'arg'], ['id_', 'call', 'instance2', 'fn2', 'arg2']] instructions = Instructions(a_list, lambda item: mock_fn.instruction_for(item)) spec = lancelot.Spec(instructions) ctx = ExecutionContext() msg = "I couldn't eat another thing. I'm absolutely stuffed." # Suppress warning log message that we know will be generated logger = logging.getLogger('Instructions') log_level = logger.getEffectiveLevel() logger.setLevel(logging.ERROR) try: spec.execute(ctx, results).should_collaborate_with( mock_fn.instruction_for(a_list[0]).will_return(mock_call), mock_call.execute(ctx, results).will_raise(StopTestException(msg)), results.failed(mock_call, msg, True)) finally: # Put logger back to how it was logger.setLevel(log_level) ctx.cleanup_imports()
def get_unisolated_module_type(self): ''' get_type() should return a requested module type, given the fully qualified name including module. The same type should be returned on successive invocations. The same type should also be returned from different contexts. State in a module should not be isolated within each context''' _types = {'StateAlteringClass':'module_with_state'} execution_context = ExecutionContext(isolate_imports=False) execution_context.add_import_path(self._nonsrc_path(execution_context)) for _type, mod in _types.items(): fully_qualified_name = '%s.%s' % (mod, _type) same_type = execution_context.get_type(fully_qualified_name) lancelot.Spec(same_type.__name__).it().should_be(_type) spec = lancelot.Spec(execution_context) spec.get_type(fully_qualified_name).should_be(SameAs(same_type)) other_context = ExecutionContext(isolate_imports=False) other_context.add_import_path(self._nonsrc_path(other_context)) different_type = other_context.get_type(fully_qualified_name) spec.get_type(fully_qualified_name).should_be( SameAs(different_type)) instances = same_type(), different_type() spec = lancelot.Spec(instances[0]) spec.when(spec.alter_state()) spec.then(spec.get_state()).should_contain(1) spec.then(instances[1].get_state).should_contain(1) execution_context.cleanup_imports() other_context.cleanup_imports()
def get_type_all_lowercaps(self): ''' get_type(namewithoutspaces) => get_type (Namewithoutspaces) ''' context = ExecutionContext() context.add_type_prefix('waferslim.examples.helper_fixtures') multiplication = context.get_type('Multiplication') spec = lancelot.Spec(context) spec.get_type('multiplication').should_be(multiplication) context.cleanup_imports()
def handles_builtins(self): ''' get_type() should handle builtin types and get_module() should not affect sys.modules when module was already loaded, e.g. builtins''' context = ExecutionContext() spec = lancelot.Spec(context) spec.get_type('builtins.dict').should_be(dict) spec.get_type('builtins.str').should_be(str) spec.get_module('builtins').should_be(SameAs(sys.modules['builtins'])) context.cleanup_imports()
def handles_builtins(self): ''' get_type() should handle builtin types and get_module() should not affect sys.modules when module was already loaded, e.g. __builtin__''' context = ExecutionContext() spec = lancelot.Spec(context) spec.get_type('__builtin__.dict').should_be(dict) spec.get_type('__builtin__.str').should_be(str) spec.get_module('__builtin__').should_be(SameAs(sys.modules['__builtin__'])) context.cleanup_imports()
def raises_exceptions(self): ''' Requesting a non-existent module should raise ImportError. Requesting a non-existent type should raise TypeError.''' context = ExecutionContext() spec = lancelot.Spec(context) spec.get_module('no.such.module').should_raise(ImportError) spec.get_type('no.such.module.Type').should_raise(ImportError) spec.get_type('NoSuchType').should_raise(TypeError) spec.get_type('waferslim.Mint').should_raise(TypeError) context.cleanup_imports()
def uses_added_type_context(self): ''' add_type_context() should allow classes to be found without fully-dot-qualified prefixes''' ctx = ExecutionContext() test_case_type = ctx.get_type('unittest.TestCase') spec = lancelot.Spec(ctx) spec.get_type('TestCase').should_raise(TypeError) spec.when(spec.add_type_prefix('unittest')) spec.then(spec.get_type('TestCase')).should_not_raise(TypeError) spec.then(spec.get_type('TestCase')).should_be(test_case_type) ctx.cleanup_imports()
def uses_added_import_paths(self): ''' add_import_path() should allow packages or modules to be found without altering sys.path''' execution_context = ExecutionContext() spec = lancelot.Spec(execution_context) spec.get_module('import_me').should_raise(ImportError) path = self._nonsrc_path(execution_context) spec.when(spec.add_import_path(path)) spec.then(spec.get_module('import_me')).should_not_raise(ImportError) lancelot.Spec(sys.path).it().should_not_contain(path) execution_context.cleanup_imports()
def stores_instance(self): ''' store_instance(name, value) should put the name,value pair in the instances dict where it can be retrieved by get_instance(name). instances should be isolated across execution contexts''' context = ExecutionContext() spec = lancelot.Spec(context) spec.get_instance('wafer thin').should_be(None) spec.when(spec.store_instance('wafer thin', 'mint')) spec.then(spec.get_instance('wafer thin')).should_be('mint') spec = lancelot.Spec(ExecutionContext()) spec.get_instance('wafer thin').should_be(None) context.cleanup_imports()
def uses_added_type_context(self): ''' add_type_context() should allow classes to be found without fully-dot-qualified prefixes. A unicode param may be passed.''' ctx = ExecutionContext() test_case_type = ctx.get_type('unittest.TestCase') spec = lancelot.Spec(ctx) spec.get_type('TestCase').should_raise(TypeError) spec.when(spec.add_type_prefix('unittest')) spec.then(spec.get_type('TestCase')).should_not_raise(TypeError) spec.then(spec.get_type('TestCase')).should_be(test_case_type) second_ctx = ExecutionContext() spec = lancelot.Spec(second_ctx) spec.when(spec.add_type_prefix(u'waferslim.examples.decision_table')) spec.then(spec.get_type(u'ShouldIBuyMilk')).should_not_raise(TypeError) ctx.cleanup_imports()
def imports_twisted(self): ''' Bug #497245: cannot import twisted ''' from os.path import join, exists for location in sys.path: pkg = join(location, join('twisted', '__init__.py')) if exists(pkg) \ or exists(pkg + 'c') \ or exists(pkg + 'o'): twisted_found = True break lancelot.Spec(twisted_found).it().should_be(True) context = ExecutionContext(isolate_imports=False) #TODO: isolated?! context.add_import_path(self._nonsrc_path(context)) spec = lancelot.Spec(context) spec.get_module('import_twisted').should_be(Type(types.ModuleType)) spec.get_module('twisted').should_be(Type(types.ModuleType)) context.cleanup_imports()
def stores_symbol(self): ''' store_symbol(name, value) should put the name,value pair in the symbols dict where it can be retrieved by get_symbol(name). symbols should be isolated across execution contexts. If a symbol is undefined then the value returned is the name of the symbol prefixed with $ -- Bug #537020''' ctx1 = ExecutionContext() spec = lancelot.Spec(ctx1) spec.get_symbol('another_bucket').should_be('$another_bucket') spec.when(spec.store_symbol('another_bucket', 'for monsieur')) spec.then(spec.get_symbol('another_bucket')).should_be('for monsieur') ctx2 = ExecutionContext() spec = lancelot.Spec(ctx2) spec.get_symbol('another_bucket').should_be('$another_bucket') ctx1.cleanup_imports() ctx2.cleanup_imports()
def loops_through_list(self): ''' Instructions should collaborate with instruction_for to instantiate a list of instructions, which execute() loops through ''' mock_fn = lancelot.MockSpec(name='mock_fn') mock_make = lancelot.MockSpec(name='mock_make') mock_call = lancelot.MockSpec(name='mock_call') a_list = [['id_0', 'make', 'instance', 'fixture', 'argument'], ['id_1', 'call', 'instance', 'f', '3']] instructions = Instructions(a_list, lambda item: mock_fn.instruction_for(item)) spec = lancelot.Spec(instructions) ctx = ExecutionContext() results = Results() spec.execute(ctx, results).should_collaborate_with( mock_fn.instruction_for(a_list[0]).will_return(mock_make), mock_make.execute(ctx, results), mock_fn.instruction_for(a_list[1]).will_return(mock_call), mock_call.execute(ctx, results)) ctx.cleanup_imports()
def stores_libraries(self): ''' store_instance(library, value) should put the value with the libraries where it can be retrieved by get_library_method(name). libraries should be isolated across execution contexts''' mr_death = ExecutionContextBehaviour.DeathKnocksAtTheDoor() context = ExecutionContext() spec = lancelot.Spec(context) spec.get_library_method('do_come_in_mr_death').should_be(None) spec.get_library_method('doComeInMrDeath').should_be(None) context.store_instance('libraryXYZ', mr_death) spec = lancelot.Spec(context) spec.get_library_method('do_come_in_mr_death').should_be(mr_death.do_come_in_mr_death) spec.get_library_method('doComeInMrDeath').should_be(mr_death.do_come_in_mr_death) spec = lancelot.Spec(ExecutionContext()) spec.get_library_method('do_come_in_mr_death').should_be(None) spec.get_library_method('doComeInMrDeath').should_be(None) context.cleanup_imports()
def gets_library_methods_from_fifo_stack(self): ''' Library methods should be retrieved from a fifo stack ''' class GrimReaperKnocks(ExecutionContextBehaviour.DeathKnocksAtTheDoor): def do_come_in_mr_death(self): return "I'm afraid we don't have any beer" context = ExecutionContext() mr_death = ExecutionContextBehaviour.DeathKnocksAtTheDoor() reaper = GrimReaperKnocks() context.store_instance('library1', mr_death) context.store_instance('library2', reaper) spec = lancelot.Spec(context) spec.get_library_method('do_come_in_mr_death').should_be(reaper.do_come_in_mr_death) context.store_instance('library2', mr_death) spec = lancelot.Spec(context) spec.get_library_method('do_come_in_mr_death').should_be(mr_death.do_come_in_mr_death) spec.get_library_method('doComeInMrDeath').should_be(mr_death.do_come_in_mr_death) context.cleanup_imports()
def stores_libraries(self): ''' store_instance(library, value) should put the value with the libraries where it can be retrieved by get_library_method(name). libraries should be isolated across execution contexts''' mr_death = ExecutionContextBehaviour.DeathKnocksAtTheDoor() context = ExecutionContext() spec = lancelot.Spec(context) spec.get_library_method('do_come_in_mr_death').should_be(None) spec.get_library_method('doComeInMrDeath').should_be(None) context.store_instance('libraryXYZ', mr_death) spec = lancelot.Spec(context) spec.get_library_method('do_come_in_mr_death').should_be( mr_death.do_come_in_mr_death) spec.get_library_method('doComeInMrDeath').should_be( mr_death.do_come_in_mr_death) spec = lancelot.Spec(ExecutionContext()) spec.get_library_method('do_come_in_mr_death').should_be(None) spec.get_library_method('doComeInMrDeath').should_be(None) context.cleanup_imports()
def loops_through_list(self): ''' Instructions should collaborate with instruction_for to instantiate a list of instructions, which execute() loops through ''' mock_fn = lancelot.MockSpec(name='mock_fn') mock_make = lancelot.MockSpec(name='mock_make') mock_call = lancelot.MockSpec(name='mock_call') a_list = [ ['id_0', 'make', 'instance', 'fixture', 'argument'], ['id_1', 'call', 'instance', 'f', '3'] ] instructions = Instructions(a_list, lambda item: mock_fn.instruction_for(item)) spec = lancelot.Spec(instructions) ctx = ExecutionContext() results = Results() spec.execute(ctx, results).should_collaborate_with( mock_fn.instruction_for(a_list[0]).will_return(mock_make), mock_make.execute(ctx, results), mock_fn.instruction_for(a_list[1]).will_return(mock_call), mock_call.execute(ctx, results) ) ctx.cleanup_imports()
def gets_library_methods_from_fifo_stack(self): ''' Library methods should be retrieved from a fifo stack ''' class GrimReaperKnocks(ExecutionContextBehaviour.DeathKnocksAtTheDoor): def do_come_in_mr_death(self): return "I'm afraid we don't have any beer" context = ExecutionContext() mr_death = ExecutionContextBehaviour.DeathKnocksAtTheDoor() reaper = GrimReaperKnocks() context.store_instance('library1', mr_death) context.store_instance('library2', reaper) spec = lancelot.Spec(context) spec.get_library_method('do_come_in_mr_death').should_be( reaper.do_come_in_mr_death) context.store_instance('library2', mr_death) spec = lancelot.Spec(context) spec.get_library_method('do_come_in_mr_death').should_be( mr_death.do_come_in_mr_death) spec.get_library_method('doComeInMrDeath').should_be( mr_death.do_come_in_mr_death) context.cleanup_imports()