def test_root_runtime_bad_names(self): working_set = mocks.WorkingSet({ 'calmjs.runtime': [ 'bad name = calmjs.npm:npm.runtime', 'bad.name = calmjs.npm:npm.runtime', 'badname:likethis = calmjs.npm:npm.runtime', ] }) stderr = mocks.StringIO() with pretty_logging(logger='calmjs.runtime', level=DEBUG, stream=stderr): rt = runtime.Runtime(working_set=working_set) err = stderr.getvalue() self.assertIn("bad 'calmjs.runtime' entry point", err) stub_stdouts(self) with self.assertRaises(SystemExit): rt(['-h']) out = sys.stdout.getvalue() # this results in unnatural argparsing situation self.assertNotIn('bad name', out) # reserved for disambiguation self.assertNotIn('bad.name', out) self.assertNotIn('badname:likethis', out) # command listing naturally not available. self.assertNotIn('npm', out)
def test_dummy_implemented_multiple_modules(self): from calmjs.testing import module1 from calmjs.testing import module2 working_set = mocks.WorkingSet({__name__: [ 'calmjs.testing.module1 = calmjs.testing.module1', 'calmjs.testing.module2 = calmjs.testing.module2', ]}, dist=Distribution(project_name='calmjs.testing')) registry = DummyModuleRegistry(__name__, _working_set=working_set) # it should be merged like so: result = registry.get_records_for_package('calmjs.testing') self.assertEqual(result, { 'calmjs.testing.module1': module1, 'calmjs.testing.module2': module2, }) # root will not work result = registry.get_records_for_package('calmjs') self.assertEqual(result, {}) # likewise not for the module. result = registry.get_records_for_package('calmjs.testing.module1') self.assertEqual(result, {}) # singular result at the module level should still work result = registry.get('calmjs.testing.module2') self.assertEqual(result, {'calmjs.testing.module2': module2})
def test_resolve_child_module_registries_lineage_malformed_loop(self): working_set = mocks.WorkingSet({}) root = BaseModuleRegistry('root', _working_set=working_set) parent = ChildModuleRegistry('root.child', _parent=root, _working_set=working_set) child = ChildModuleRegistry('root.child.child', _parent=parent, _working_set=working_set) grandchild = ChildModuleRegistry('root.child.child.child', _parent=child, _working_set=working_set) # force a bad loop parent.parent = grandchild with pretty_logging(stream=mocks.StringIO()) as log: with self.assertRaises(TypeError) as e: resolve_child_module_registries_lineage(parent) self.assertEqual( "registry 'root.child' was already recorded in the lineage, " "indicating that it may be some (grand)child of itself, which is " "an illegal reference in the registry system; previously resolved " "lineage is: ['root.child.child', 'root.child.child.child', " "'root.child']", str(e.exception)) self.assertIn( "the parent registry 'root.child.child.child' somehow has a " "longer name than its child registry 'root.child'; the underlying " "registry class may be constructed in an invalid manner", log.getvalue())
def test_simple_record(self): working_set = mocks.WorkingSet( { __name__: [ 'dummy/whatever/module.js = module', 'dummy/whatever/module-slim.js = module', ] }, dist=Distribution(project_name='calmjs.testing')) registry = base.BaseExternalModuleRegistry(__name__, _working_set=working_set) self.assertEqual(len(registry.raw_entry_points), 2) self.assertEqual(registry.get_record('module'), { 'dummy/whatever/module.js', 'dummy/whatever/module-slim.js', }) self.assertEqual(list(registry.iter_records()), [('module', { 'dummy/whatever/module.js', 'dummy/whatever/module-slim.js', })]) self.assertEqual(registry.get_records_for_package('calmjs.testing'), [ 'dummy/whatever/module.js', 'dummy/whatever/module-slim.js', ])
def setup_runtime(self): make_dummy_dist(self, (('bower.json', json.dumps({ 'name': 'site', 'dependencies': { 'jquery': '~3.1.0', }, })), ), 'example.package1', '1.0') make_dummy_dist(self, (('bower.json', json.dumps({ 'name': 'site', 'dependencies': { 'underscore': '~1.8.3', }, })), ), 'example.package2', '2.0') working_set = pkg_resources.WorkingSet([self._calmjs_testing_tmpdir]) # Stub out the underlying data needed for the cli for the tests # to test against our custom data for reproducibility. stub_item_attr_value(self, dist, 'default_working_set', working_set) stub_mod_check_interactive(self, [cli], True) # Of course, apply a mock working set for the runtime instance # so it can use the bower runtime. working_set = mocks.WorkingSet({ 'calmjs.runtime': [ 'bower = calmjs.bower:bower.runtime', ], }) return runtime.Runtime(working_set=working_set)
def test_registry_load_entry_point_missing_attrs(self): working_set = mocks.WorkingSet( { 'nunja.mold': [ 'nunja.testing.mold1 = nunja.testing', 'nunja.testing.mold2 = nunja:testing.mold', ] }, dist=Distribution(project_name='nunjatesting', version='0.0')) with pretty_logging(logger='nunja', stream=mocks.StringIO()) as stream: registry = MoldRegistry('nunja.mold', _working_set=working_set) msg = stream.getvalue() self.assertIn( "entry_point 'nunja.testing.mold1 = nunja.testing' " "from package 'nunjatesting 0.0' incompatible ", msg, ) self.assertIn( "entry_point 'nunja.testing.mold2 = nunja:testing.mold' " "from package 'nunjatesting 0.0' incompatible ", msg, ) records = registry.get_records_for_package('nunjatesting') self.assertEqual(records, {})
def test_registry_load_working_set(self): # do note these mocking sets are for the registry; actual # filenames is not overridden (uses pkg_resources directly) working_set = mocks.WorkingSet( {'nunja.tmpl': [ 'nunja.testing.templates = nunja.testing:mold', ]}, dist=Distribution(project_name='nunjatesting', version='0.0')) with pretty_logging(logger='nunja', stream=mocks.StringIO()) as stream: registry = JinjaTemplateRegistry('nunja.tmpl', _working_set=working_set) self.assertIn('7 templates', stream.getvalue()) self.assertNotIn('scripts', stream.getvalue()) # to prevent the export of names into the calmjs toolchain, the # standard record retrieval provides nothing. self.assertEqual({}, registry.get_records_for_package('nunjatesting')) self.assertEqual(registry.get_record('nunja.testing.templates/basic'), {}) # records are available via an alternative method. self.assertEqual([ 'nunja.testing.templates/basic/template.nja', 'nunja.testing.templates/include_by_name/empty.nja', 'nunja.testing.templates/include_by_name/template.nja', 'nunja.testing.templates/include_by_value/template.nja', 'nunja.testing.templates/itemlist/template.nja', 'nunja.testing.templates/noinit/template.nja', 'nunja.testing.templates/problem/template.nja', ], sorted(registry.templates.keys()))
def test_no_op_default(self): working_set = mocks.WorkingSet( {__name__: [ 'calmjs.testing.module1 = calmjs.testing.module1', ]}) with pretty_logging(stream=mocks.StringIO()) as s: base.BaseModuleRegistry(__name__, _working_set=working_set) self.assertIn('NotImplemented', s.getvalue())
def test_standard_construction(self): # this mock WorkingSet.find will always return a distribution working_set = mocks.WorkingSet({}) with pretty_logging(stream=mocks.StringIO()) as stream: registry = calmjs.registry.Registry('calmjs.registry', _working_set=working_set) self.assertEqual('calmjs.registry', registry.registry_name) self.assertEqual('', stream.getvalue())
def mk_test_registry(self, entry_points=None): if entry_points is None: entry_points = ['nunja.testing.templates = nunja.testing:mold'] working_set = mocks.WorkingSet({'nunja.tmpl': entry_points}, dist=Distribution( project_name='nunjatesting', version='0.0')) return JinjaTemplateRegistry.create(_working_set=working_set)
def test_got_record_cloned(self): # returned records should clones. working_set = mocks.WorkingSet({__name__: [ 'calmjs.testing.module1 = calmjs.testing.module1', ]}) registry = DummyModuleRegistry(__name__, _working_set=working_set) record1 = registry.get_record('calmjs.testing.module1') record2 = registry.get_record('calmjs.testing.module1') self.assertIsNot(record1, record2)
def test_entry_points(self): working_set = mocks.WorkingSet({__name__: [ 'module1 = calmjs.testing.module1', 'module2 = calmjs.testing.module2', 'module3 = calmjs.testing.module3', ]}) registry = base.BaseRegistry(__name__, _working_set=working_set) self.assertEqual(len(registry.raw_entry_points), 3)
def test_registry_load_working_set(self): # do note these mocking sets are for the registry; actual # filenames is not overridden (uses pkg_resources directly) working_set = mocks.WorkingSet( {'nunja.mold': [ 'nunja.testing.molds = nunja.testing:mold', ]}, dist=Distribution(project_name='nunjatesting', version='0.0')) with pretty_logging(logger='nunja', stream=mocks.StringIO()) as stream: registry = MoldRegistry('nunja.mold', _working_set=working_set) records = registry.get_records_for_package('nunjatesting') keys = [ 'nunja.testing.molds/include_by_name/index', 'nunja.testing.molds/include_by_value/index', 'nunja.testing.molds/itemlist/index', 'nunja.testing.molds/noinit/index', 'nunja.testing.molds/problem/index', 'text!nunja.testing.molds/basic/template.nja', 'text!nunja.testing.molds/include_by_name/empty.nja', 'text!nunja.testing.molds/include_by_name/template.nja', 'text!nunja.testing.molds/include_by_value/template.nja', 'text!nunja.testing.molds/itemlist/template.nja', 'text!nunja.testing.molds/noinit/template.nja', 'text!nunja.testing.molds/problem/template.nja', ] self.assertEqual(sorted(records.keys()), keys) self.assertIn('7 templates', stream.getvalue()) self.assertIn('5 scripts', stream.getvalue()) self.assertIn('generated 6 molds', stream.getvalue()) # select directly by mold_id through get_record self.assertEqual( sorted(registry.get_record('nunja.testing.molds/basic').keys()), ['text!nunja.testing.molds/basic/template.nja'], ) self.assertEqual( sorted(registry.get_record('nunja.testing.molds/itemlist').keys()), [ 'nunja.testing.molds/itemlist/index', 'text!nunja.testing.molds/itemlist/template.nja', ], ) self.assertEqual( sorted( registry.get_record( 'nunja.testing.molds/include_by_name').keys()), [ 'nunja.testing.molds/include_by_name/index', 'text!nunja.testing.molds/include_by_name/empty.nja', 'text!nunja.testing.molds/include_by_name/template.nja', ], )
def setup_runtime(self): # create a working set with our custom runtime entry point # TODO should really improve the test case to provide custom # runtime instances separate from actual data. working_set = mocks.WorkingSet({ 'calmjs.runtime': [ 'cmd = calmjs.npm:npm.runtime', ], }) return runtime.Runtime(working_set=working_set, prog='calmjs')
def test_resolve_child_module_registries_lineage_base(self): working_set = mocks.WorkingSet({}) root = BaseModuleRegistry('root.module', _working_set=working_set) child = ChildModuleRegistry('root.module.child', _parent=root, _working_set=working_set) self.assertEqual([ root, child, ], list(resolve_child_module_registries_lineage(child)))
def test_reservation_free(self): working_set = mocks.WorkingSet({}, dist=None) with pretty_logging(stream=mocks.StringIO()) as stream: registry = calmjs.registry.Registry( 'calmjs.testing.registry', reserved=None, _working_set=working_set, ) self.assertEqual('calmjs.testing.registry', registry.registry_name) self.assertEqual('', stream.getvalue())
def test_module_registry_through_registry(self): """ Show that the module registry instantiated through the global registry's get function will result in the resulting module registry being populated properly with the module entries when using a constrained set of entry points. """ working_set = mocks.WorkingSet( { 'calmjs.module': [ 'module1 = calmjs.testing.module1', 'module2 = calmjs.testing.module2', 'module3 = calmjs.testing.module3', ], 'calmjs.reserved': [ 'calmjs.module = calmjs.testing', ], __name__: [ 'calmjs.module = calmjs.module:ModuleRegistry', ] }, dist=Distribution(project_name='calmjs.testing', version='0.0')) utils.stub_mod_working_set(self, [calmjs.base], working_set) # Not going to use the global registry, and using our custom # reservation entry local_root_registry = Registry(__name__, 'calmjs.testing', _working_set=working_set) with pretty_logging(stream=mocks.StringIO()): # silences "distribution 'calmjs.testing 0.0' not found" # warnings from stdout produced by the indexer, as the # provided working_set is invalid with entry points that do # not have a valid distribution. global_registry = get('calmjs.module') registry = local_root_registry.get_record('calmjs.module') self.assertIsNot(registry, global_registry) self.assertEqual(sorted(k for k, v in registry.iter_records()), [ 'calmjs.testing.module1', 'calmjs.testing.module2', 'calmjs.testing.module3', ]) results = registry.get_records_for_package('calmjs.testing') self.assertEqual(sorted(results.keys()), [ 'calmjs/testing/module1/hello', 'calmjs/testing/module2/helper', 'calmjs/testing/module2/index', 'calmjs/testing/module3/math', ]) module1 = registry.get_record('calmjs.testing.module1') self.assertIn('calmjs/testing/module1/hello', module1)
def test_dummy_implemented(self): from calmjs.testing import module1 working_set = mocks.WorkingSet({__name__: [ 'calmjs.testing.module1 = calmjs.testing.module1', ]}) registry = DummyModuleRegistry(__name__, _working_set=working_set) result = registry.get_record('calmjs.testing.module1') self.assertEqual(result, {'calmjs.testing.module1': module1}) self.assertEqual(list(registry.iter_records()), [ ('calmjs.testing.module1', {'calmjs.testing.module1': module1}), ])
def test_simply_externals(self): # same case as above, but in externals self.assertTrue( toolchain.check_name_declared( alias={}, loaders={}, externals={'text!some/file.txt'}, loader_registry=LoaderPluginRegistry( 'missing', _working_set=mocks.WorkingSet({})), name='text!some/file.txt', ))
def test_dupe_register(self): # returned records should clones. working_set = mocks.WorkingSet({ __name__: [ 'calmjs.testing.module1 = calmjs.testing', 'calmjs.testing.module2 = calmjs.testing', ] }) with pretty_logging(stream=mocks.StringIO()) as s: DummyModuleRegistry(__name__, _working_set=working_set) self.assertIn("overwriting keys: ['calmjs.testing']", s.getvalue())
def test_registry_graceful_fail(self): working_set = mocks.WorkingSet({ 'calmjs.registry': [ 'failure = calmjs.testing.no_such_module:NoClass', ] }) registry = calmjs.registry.Registry('calmjs.registry', _working_set=working_set) # This should not be registered or available self.assertIsNone(registry.get_record('calmjs.module')) self.assertIsNone(registry.get_record('failure'))
def test_bad_record(self): working_set = mocks.WorkingSet({__name__: [ 'calmjs.testing.not_a_module = calmjs.testing.not_a_module', ]}) with pretty_logging(stream=mocks.StringIO()) as s: registry = base.BaseModuleRegistry( __name__, _working_set=working_set) self.assertIn( 'ImportError: calmjs.testing.not_a_module not found; ' 'skipping registration', s.getvalue(), ) self.assertEqual(len(registry.raw_entry_points), 1) self.assertEqual(registry.get_record('module'), {}) self.assertEqual(list(registry.iter_records()), [])
def test_missing_plugin(self): with pretty_logging(stream=mocks.StringIO()) as s: self.assertFalse( toolchain.check_name_declared( alias={'some/file.txt': 'some/file.txt'}, loaders={'text': 'text-loader/index.js'}, externals={}, loader_registry=LoaderPluginRegistry( 'missing', _working_set=mocks.WorkingSet({})), name='text!some/file.txt', )) self.assertIn( "check_name_declared cannot resolve handler for " "'text!some/file.txt'", s.getvalue())
def test_registry_graceful_fail_bad_constructor(self): working_set = mocks.WorkingSet({ 'calmjs.registry': [ 'failure = calmjs.testing.module3.module:NotRegistry', ] }) registry = calmjs.registry.Registry('calmjs.registry', _working_set=working_set) # This should not be registered or available self.assertIsNone(registry.get_record('calmjs.module')) with pretty_logging(stream=mocks.StringIO()) as stream: self.assertIsNone(registry.get_record('failure')) # exact error message differs between Python versions. self.assertIn('TypeError: __init__() ', stream.getvalue())
def test_root_runtime_errors_ignored(self): stub_stdouts(self) working_set = mocks.WorkingSet({ 'calmjs.runtime': [ 'foo = calmjs.nosuchmodule:no.where', 'bar = calmjs.npm:npm', 'npm = calmjs.npm:npm.runtime', ] }) rt = runtime.Runtime(working_set=working_set) with self.assertRaises(SystemExit): rt(['-h']) out = sys.stdout.getvalue() self.assertNotIn('foo', out) self.assertIn('npm', out)
def test_registry_fresh_from_entrypoint(self): working_set = mocks.WorkingSet({ 'calmjs.registry': [ 'custom = calmjs.testing.module3.module:CustomModuleRegistry', ] }) registry = calmjs.registry.Registry('calmjs.registry', _working_set=working_set) self.assertEqual(len(registry.records), 0) registry.get_record('custom') self.assertEqual(len(registry.records), 1) from calmjs.testing.module3.module import CustomModuleRegistry self.assertTrue( isinstance(registry.get_record('custom'), CustomModuleRegistry))
def test_registry_graceful_fail(self): working_set = mocks.WorkingSet({ 'calmjs.registry': [ 'failure = calmjs.testing.no_such_module:NoClass', ] }) registry = calmjs.registry.Registry('calmjs.registry', _working_set=working_set) with pretty_logging(stream=mocks.StringIO()) as stream: self.assertIsNone(registry.get_record('calmjs.module')) self.assertIn("'calmjs.module' does not resolve", stream.getvalue()) with pretty_logging(stream=mocks.StringIO()) as stream: self.assertIsNone(registry.get_record('failure')) self.assertIn("ImportError 'failure", stream.getvalue())
def test_auto_self_reference(self): # ensure that the identity is returned working_set = mocks.WorkingSet({ 'calmjs.registry': [ # correct self-referential definition 'calmjs.registry = calmjs.registry:Registry', 'calmjsregistry = calmjs.registry:Registry', ], 'calmjsregistry': [ # unrelated self-referential definition 'calmjs.registry = calmjs.registry:Registry', # incorrect self-referential type 'calmjsregistry = calmjs.module:ModuleRegistry', ], }) # stub out real working sets because usage of standard APIs stub_item_attr_value(self, calmjs.registry, 'working_set', working_set) stub_item_attr_value(self, calmjs.base, 'working_set', working_set) with pretty_logging(stream=mocks.StringIO()) as stream: registry = calmjs.registry.Registry('calmjs.registry') self.assertFalse(registry.records) mismatched = registry.get('calmjsregistry') # not the same name self.assertTrue(isinstance(mismatched, calmjs.registry.Registry)) self.assertIsNot(mismatched, registry) # correct identity self.assertIs(registry, registry.get('calmjs.registry')) self.assertIn('calmjs.registry', registry.records) # unrelated registry also unrelated = mismatched.get('calmjs.registry') self.assertTrue(isinstance(unrelated, calmjs.registry.Registry)) self.assertIsNot(unrelated, registry) mistyped = mismatched.get('calmjsregistry') # not a None self.assertTrue(mistyped) # also not identity, as they are not the same type. self.assertIsNot(mistyped, mismatched) self.assertIn( "registry 'calmjs.registry' has entry point 'calmjs.registry = " "calmjs.registry:Registry' which is the identity registration", stream.getvalue(), )
def test_missing_package_warning(self): # without a distribution provided by the working set, the # provided package name will not be resolved. working_set = mocks.WorkingSet({}, dist=None) with pretty_logging(stream=mocks.StringIO()) as stream: registry = calmjs.registry.Registry( 'some.registry', package_name='some.package', _working_set=working_set, ) self.assertEqual('some.registry', registry.registry_name) self.assertIn( "ERROR calmjs.registry failed to set up registry_name " "reservations for registry 'some.registry', as the specified " "package 'some.package' could not found in the current " "working_set; maybe it is not correctly installed?", stream.getvalue())
def setup_runtime(self): make_dummy_dist(self, (('package.json', json.dumps({ 'name': 'site', 'dependencies': { 'jquery': '~3.1.0', }, })), ), 'example.package1', '1.0') make_dummy_dist(self, (('package.json', json.dumps({ 'name': 'site', 'dependencies': { 'underscore': '~1.8.3', }, })), ), 'example.package2', '2.0') make_dummy_dist(self, ( ('requires.txt', '\n'.join([ 'example.package1', 'example.package2', ])), ('package.json', json.dumps({ 'dependencies': { 'backbone': '~1.3.2', }, })), ), 'example.package3', '2.0') working_set = pkg_resources.WorkingSet([self._calmjs_testing_tmpdir]) # Stub out the underlying data needed for the cli for the tests # to test against our custom data for reproducibility. stub_item_attr_value(self, dist, 'default_working_set', working_set) stub_mod_check_interactive(self, [cli], True) # Of course, apply a mock working set for the runtime instance # so it can use the npm runtime, however we will use a different # keyword. Note that the runtime is invoked using foo. working_set = mocks.WorkingSet({ 'calmjs.runtime': [ 'foo = calmjs.npm:npm.runtime', ], }) return runtime.Runtime(working_set=working_set)