def test_build_artifacts_logs_and_failures(self): with pretty_logging(stream=mocks.StringIO()) as stream: self.registry.process_package('app') log = stream.getvalue() self.assertIn( "unable to import the target builder for the entry point " "'not_exist.js = calmjs_testing_dummy:not_exist' from package " "'app 1.0'", log ) self.assertIn( "the builder referenced by the entry point " "'bad.js = calmjs_testing_dummy:bad_builder' from package " "'app 1.0' has an incompatible signature", log ) # try again using the artifact builder from calmjs.registry import _inst _inst.records.pop('calmjs.artifacts', None) self.addCleanup(_inst.records.pop, 'calmjs.artifacts') _inst.records['calmjs.artifacts'] = self.registry builder = ArtifactBuilder('calmjs.artifacts') with pretty_logging(stream=mocks.StringIO()) as stream: self.assertFalse(builder(['app'])) log = stream.getvalue() self.assertIn( "unable to import the target builder for the entry point " "'not_exist.js = calmjs_testing_dummy:not_exist' from package " "'app 1.0'", log )
def test_pkg_manager_init_exists_and_overwrite(self): self.setup_requirements_json() cwd = mkdtemp(self) driver = cli.PackageManagerDriver( pkg_manager_bin='mgr', pkgdef_filename='requirements.json', dep_keys=('require',), working_dir=cwd, ) target = join(cwd, 'requirements.json') with open(target, 'w') as fd: result = json.dump({"require": {}}, fd) with pretty_logging(stream=mocks.StringIO()) as err: driver.pkg_manager_init('calmpy.pip', overwrite=False) self.assertIn('not overwriting existing ', err.getvalue()) self.assertIn('requirements.json', err.getvalue()) with open(target) as fd: result = json.load(fd) self.assertNotEqual(result, {"require": {"setuptools": "25.1.6"}}) stub_mod_call(self, cli) with pretty_logging(stream=mocks.StringIO()) as err: # ensure the return value is False self.assertFalse( driver.pkg_manager_install('calmpy.pip', overwrite=False)) driver.pkg_manager_init('calmpy.pip', overwrite=True) with open(target) as fd: result = json.load(fd) self.assertEqual(result, { "require": {"setuptools": "25.1.6"}, "name": "calmpy.pip", })
def test_relocated_distribution(self): root = mkdtemp(self) dummyns_path = join(root, 'dummyns') make_dummy_dist(self, (( 'namespace_packages.txt', 'dummyns\n', ), ( 'entry_points.txt', '[dummyns]\n' 'dummyns = dummyns:attr\n', ),), 'dummyns', '1.0', working_dir=root) working_set = pkg_resources.WorkingSet([ root, self.ds_egg_root, ]) # activate this as the working set stub_item_attr_value(self, pkg_resources, 'working_set', working_set) dummyns_ep = next(working_set.iter_entry_points('dummyns')) with pretty_logging(stream=StringIO()) as fd: p = indexer.resource_filename_mod_entry_point( 'dummyns', dummyns_ep) # since the actual location is not created) self.assertIsNone(p) self.assertIn("does not exist", fd.getvalue()) # retry with the module directory created at the expected location os.mkdir(dummyns_path) with pretty_logging(stream=StringIO()) as fd: p = indexer.resource_filename_mod_entry_point( 'dummyns', dummyns_ep) self.assertEqual(normcase(p), normcase(dummyns_path)) self.assertEqual('', fd.getvalue())
def test_plugin_package_chained_loaders_initial_simple(self): working_dir = mkdtemp(self) reg, base, extra, base_dir, extra_dir = self.create_base_extra_plugins( working_dir) simple = reg.records['simple'] = LoaderPluginHandler(reg, 'simple') toolchain = NullToolchain() spec = Spec(working_dir=working_dir) with pretty_logging(stream=StringIO()) as stream: self.assertEqual( {}, simple.generate_handler_sourcepath(toolchain, spec, { 'simple!fun.file': 'fun.file', }), ) with pretty_logging(stream=StringIO()) as stream: self.assertEqual({ 'extra': join(extra_dir, 'extra.js'), }, simple.generate_handler_sourcepath(toolchain, spec, { 'simple!extra!fun.file': 'fun.file', }), ) self.assertIn("for loader plugin 'extra'", stream.getvalue())
def test_set_node_path(self): stub_mod_call(self, cli) stub_base_which(self) node_path = mkdtemp(self) driver = cli.PackageManagerDriver( node_path=node_path, pkg_manager_bin='mgr') # ensure env is passed into the call. with pretty_logging(stream=mocks.StringIO()): driver.pkg_manager_install(['calmjs']) self.assertEqual(self.call_args, ((['mgr', 'install'],), { 'env': finalize_env({'NODE_PATH': node_path}), })) # will be overridden by instance settings. with pretty_logging(stream=mocks.StringIO()): driver.pkg_manager_install(['calmjs'], env={ 'PATH': '.', 'MGR_ENV': 'dev', 'NODE_PATH': '/tmp/somewhere/else/node_mods', }) self.assertEqual(self.call_args, ((['mgr', 'install'],), { 'env': finalize_env( {'NODE_PATH': node_path, 'MGR_ENV': 'dev', 'PATH': '.'}), }))
def test_requirejs_text_issue123_handling(self): f = loaderplugin.TextPlugin(None).requirejs_text_issue123 with pretty_logging( 'calmjs.rjs.loaderplugin', stream=StringIO()) as stream: self.assertEqual(f('file'), ['file', '']) self.assertEqual(f('dir/text'), ['dir/text', '']) self.assertEqual(f('dir/text.txt'), ['dir/text', 'txt']) self.assertEqual(f('dotted.dir/text'), ['dotted', 'dir/text']) self.assertEqual( f('dotted.dir/text.txt'), ['dotted.dir/text', 'txt']) self.assertEqual(stream.getvalue(), '') with pretty_logging( 'calmjs.rjs.loaderplugin', stream=StringIO()) as stream: # the following also implement the stripping of trailing # dots which requirejs-text doesn't support correctly, # and with requirejs>=2.0.13 will fail consistently. self.assertEqual(f('file.'), ['file', '']) self.assertEqual(f('dir/text.'), ['dir/text', '']) self.assertEqual(f('dotted.dir/text.'), ['dotted.dir/text', '']) # ensure the complaining loudly is done. self.assertIn('WARNING', stream.getvalue()) self.assertIn('trailing', stream.getvalue())
def test_which_with_node_modules(self): driver = base.BaseDriver() # ensure that NODE_PATH is initially None driver.node_path = None driver.working_dir = mkdtemp(self) # initially should be empty, since no node_modules in either # directories that it should check with pretty_logging(stream=mocks.StringIO()) as s: self.assertIsNone(driver.which_with_node_modules()) # should not generate extra log messages. self.assertNotIn('will attempt', s.getvalue()) # having the NODE_PATH defined will result in such p1 = mkdtemp(self) p2 = mkdtemp(self) driver.node_path = pathsep.join([p1, p2]) with pretty_logging(stream=mocks.StringIO()) as s: self.assertIsNone(driver.which_with_node_modules()) # should not generate extra log messages, binary still not # assigned. self.assertNotIn('will attempt', s.getvalue()) driver.binary = 'dummy' with pretty_logging(stream=mocks.StringIO()) as s: self.assertIsNone(driver.which_with_node_modules()) # now the log should show what attempted. log = s.getvalue() self.assertIn( "'BaseDriver' instance will attempt to locate 'dummy' binary from " "its NODE_PATH of", log) self.assertIn(p1, log) self.assertIn(p2, log) self.assertIn("'BaseDriver' instance located 2 possible paths", log) # try again with working directory driver.node_path = None dwd_wd_nm = join(driver.working_dir, 'node_modules') os.mkdir(dwd_wd_nm) with pretty_logging(stream=mocks.StringIO()) as s: self.assertIsNone(driver.which_with_node_modules()) log = s.getvalue() # now the log should show what attempted. self.assertIn( "'BaseDriver' instance will attempt to locate 'dummy' binary from", log, ) self.assertIn(dwd_wd_nm, log) self.assertIn("located through the working directory", log) self.assertIn("'BaseDriver' instance located 1 possible paths", log)
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_compile_plugin_error(self): working_dir = utils.mkdtemp(self) mock_requirejs_text(working_dir) src_dir = utils.mkdtemp(self) src = join(src_dir, 'mod.js') with open(src, 'w') as fd: fd.write('hello world') # prepare targets target = 'target.txt' rjs = toolchain.RJSToolchain() spec = Spec(**{ 'build_dir': self.build_dir, rjs.rjs_bin_key: join(self.build_dir, 'r.js'), 'export_target': join(working_dir, 'export.js'), 'bundle_sourcepath': {}, LOADERPLUGIN_SOURCEPATH_MAPS: { 'unregistered/mod': {} }, 'working_dir': working_dir, }) with pretty_logging(logger='calmjs', stream=mocks.StringIO()) as s: rjs.prepare(spec) rjs.compile_loaderplugin_entry(spec, ( 'unregistered/mod!target.txt', src, target, 'target.txt')) self.assertIn( "loaderplugin handler found for plugin entry " "'unregistered/mod!target.txt'", s.getvalue())
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_karma_test_files_located(self): karma_config = karma.build_base_config() karma_config['files'] = ['example/package/lib.js'] spec = Spec( karma_config=karma_config, build_dir=mkdtemp(self), rjs_loader_plugin_registry=get(RJS_LOADER_PLUGIN_REGISTRY_NAME), export_module_names=['preexported'], test_module_paths_map={ 'example/package/tests/test_some_module': '/src/example/package/tests/test_some_module.js', 'example/package/tests/some_test_data': '/src/example/package/tests/some_test_data.js', }, ) with pretty_logging(stream=StringIO()): karma_requirejs(spec) with open(spec['karma_requirejs_test_script'], encoding='utf-8') as fd: script = es5(fd.read()) # this is the node for the json in the build file deps = json.loads(str(script.children()[0].children()[0].initializer)) tests = json.loads(str(script.children()[1].children()[0].initializer)) self.assertEqual(['example/package/tests/test_some_module'], tests) self.assertEqual( ['preexported', 'example/package/tests/some_test_data'], deps)
def test_generate_bundle_sourcepaths_bad_dir(self): bad_dir = utils.mkdtemp(self) with pretty_logging(stream=StringIO()) as log: mapping = dist.generate_bundle_sourcepaths( ['service'], bad_dir) self.assertEqual(sorted(mapping.keys()), []) self.assertIn('fake_modules', log.getvalue())
def test_standard_manual_tests_fail_run_continued(self): stub_stdouts(self) main = resource_filename('calmjs.dev', 'main.js') test_fail = resource_filename('calmjs.dev.tests', 'test_fail.js') spec = Spec( # null toolchain does not prepare this transpile_sourcepath={ 'calmjs/dev/main': main, }, test_module_paths_map={ 'calmjs/test_fail': test_fail, }, # register warning karma_abort_on_test_failure=False, ) toolchain = NullToolchain() with pretty_logging( logger='calmjs.dev', stream=mocks.StringIO()) as log: self.driver.run(toolchain, spec) self.assertNotEqual(spec['karma_return_code'], 0) # linked continued self.assertIn('link', spec) self.assertIn( "karma exited with return code 1; continuing as specified", log.getvalue() )
def test_yarn_no_path(self): tmpdir = mkdtemp(self) os.chdir(tmpdir) os.environ['PATH'] = '' with pretty_logging(stream=StringIO()) as stderr: self.assertIsNone(yarn.get_yarn_version()) self.assertIn("failed to execute 'yarn'", stderr.getvalue())
def test_assemble_standard_emptied(self): with pretty_logging(logger='calmjs.rjs', stream=mocks.StringIO()) as s: build_js, config_js = self.assemble_spec_config( stub_missing_with_empty=1 ) self.assertNotIn('ERROR', s.getvalue()) self.assertIn( "source file(s) referenced modules that are missing in the " "build directory: %r, %r, %r" % ( 'jquery', 'some.pylike.module', 'underscore'), s.getvalue() ) self.assertEqual(build_js['paths'], { 'jquery': 'empty:', 'some.pylike.module': 'empty:', 'underscore': 'empty:', }) self.assertEqual(config_js['paths'], { 'module1': 'module1.js?', 'module2': 'module2.js?', 'module3': 'module3.js?', 'jquery': 'empty:', 'some.pylike.module': 'empty:', 'underscore': 'empty:', })
def test_get_modpath_all_empty(self): module = ModuleType('nothing') with pretty_logging(stream=StringIO()) as fd: self.assertEqual(indexer.modpath_all(module, None), []) self.assertIn( "module 'nothing' does not appear to be a namespace module", fd.getvalue())
def test_iter_builders_verify_export_target(self): mod = ModuleType('calmjs_testing_dummy') mod.complete = generic_builder self.addCleanup(sys.modules.pop, 'calmjs_testing_dummy') sys.modules['calmjs_testing_dummy'] = mod working_dir = utils.mkdtemp(self) utils.make_dummy_dist(self, ( ('entry_points.txt', '\n'.join([ '[calmjs.artifacts]', 'artifact.js = calmjs_testing_dummy:complete', 'invalid.js = calmjs_testing_dummy:complete', ])), ), 'app', '1.0', working_dir=working_dir) mock_ws = WorkingSet([working_dir]) class FakeArtifactRegistry(ArtifactRegistry): def verify_export_target(self, export_target): return 'invalid.js' not in export_target registry = FakeArtifactRegistry( 'calmjs.artifacts', _working_set=mock_ws) # the invalid.js should be filtered out with pretty_logging(stream=mocks.StringIO()) as stream: self.assertEqual(1, len(list(registry.iter_builders_for('app')))) self.assertIn("invalid.js' has been rejected", stream.getvalue())
def test_prepare_spec_artifacts(self): stub_stdouts(self) remember_cwd(self) tmpdir = mkdtemp(self) fake = join(tmpdir, 'fake.js') real = join(tmpdir, 'real.js') os.chdir(tmpdir) with open(real, 'w') as fd: fd.write('') with pretty_logging( logger='calmjs.dev', stream=mocks.StringIO()) as log: # note the relative paths spec = Spec(artifact_paths=['real.js', 'fake.js']) prepare_spec_artifacts(spec) # note that the full path is now specified. self.assertEqual(spec['artifact_paths'], [real]) self.assertIn('does not exists', log.getvalue()) self.assertIn(fake, log.getvalue()) # should still work with full paths. spec = Spec(artifact_paths=[real, fake]) prepare_spec_artifacts(spec) self.assertEqual(spec['artifact_paths'], [real])
def test_initialize_warning_dupe_plugin(self): # ensure that we have a proper working registry working_set = WorkingSet({'calmjs.loader_plugin': [ 'example = calmjs.tests.test_loaderplugin:DupePlugin', 'example = calmjs.loaderplugin:NPMLoaderPluginHandler', ]}) # should not trigger import failure with pretty_logging(stream=StringIO()) as stream: registry = LoaderPluginRegistry( 'calmjs.loader_plugin', _working_set=working_set) self.assertIn( "loader plugin handler for 'example' was already registered to an " "instance of 'calmjs.tests.test_loaderplugin:DupePlugin'", stream.getvalue() ) # the second one will be registered self.assertTrue( isinstance(registry.get('example'), LoaderPluginHandler)) # ensure that the handler can be acquired from a full name self.assertEqual('example', registry.get('example!hi').name) self.assertEqual('example', registry.get('example?arg!hi').name) self.assertEqual('example', registry.get('example?arg').name) self.assertIsNone(registry.get('examplearg')) self.assertIsNone(registry.get('ex')) self.assertIsNone(registry.get('ex!ample'))
def test_extract_defines_amd_artifact3_missing(self): with pretty_logging(stream=StringIO()) as stream: result = requirejs.extract_defines_with_deps(artifact_multiple3) self.assertEqual(['lib4', 'lib2', 'lib1'], result) s = stream.getvalue() self.assertIn("module 'missing' required but seems to be missing", s) self.assertIn("WARNING", s)
def test_spec_missing_export_path_handling(self): with pretty_logging(stream=mocks.StringIO()) as stream: self.registry.process_package('blank') log = stream.getvalue() self.assertIn( "failed to produce a spec with the expected export_target", log)
def test_iter_builders_side_effect_build_issue(self): mod = ModuleType('calmjs_testing_dummy') mod.complete = generic_builder self.addCleanup(sys.modules.pop, 'calmjs_testing_dummy') sys.modules['calmjs_testing_dummy'] = mod working_dir = utils.mkdtemp(self) utils.make_dummy_dist(self, ( ('entry_points.txt', '\n'.join([ '[calmjs.artifacts]', 'artifact.js = calmjs_testing_dummy:complete', ])), ), 'app', '1.0', working_dir=working_dir) mock_ws = WorkingSet([working_dir]) registry = ArtifactRegistry('calmjs.artifacts', _working_set=mock_ws) registry.update_artifact_metadata('app', {}) root = join(working_dir, 'app-1.0.egg-info', 'calmjs_artifacts') # clog the build directory so build cannot happen with open(join(root), 'w'): pass ep, toolchain, spec = next(registry.iter_builders_for('app')) check = [] spec.advise('after_prepare', check.append, True) with pretty_logging(stream=mocks.StringIO()) as stream: with self.assertRaises(ToolchainAbort): toolchain(spec) self.assertIn( "an advice in group 'before_prepare' triggered an abort", stream.getvalue()) # should have stopped at before_prepare self.assertFalse(check)
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_normcase_registration(self): # create an empty working set for a clean-slate test. cwd = utils.mkdtemp(self) mock_ws = WorkingSet([]) dist_ = Distribution(cwd, project_name='pkg', version='1.0') dist_.egg_info = cwd # just lazy registry = ArtifactRegistry('calmjs.artifacts', _working_set=mock_ws) # case sensitive test; have to patch the normcase at artifact # module with the nt version from ntpath import normcase as nt_normcase utils.stub_item_attr_value(self, artifact, 'normcase', nt_normcase) # using named case for case sensitivity test. c1 = EntryPoint.parse('case.js = dummy_builder:builder1') c1.dist = dist_ c2 = EntryPoint.parse('Case.js = dummy_builder:builder2') c2.dist = dist_ # use the error one ct = join(cwd, 'calmjs_artifacts', 'Case.js') with pretty_logging(stream=mocks.StringIO()) as stream: registry.register_entry_point(c1) registry.register_entry_point(c2) log = stream.getvalue() self.assertIn( "entry point 'Case.js = dummy_builder:builder2' from package " "'pkg 1.0' resolves to the path '%s' which was already " "registered to entry point 'case.js = dummy_builder:builder1'; " "conflicting entry point registration will be ignored." % ct, log ) self.assertIn( "the file mapping error is caused by this platform's case-" "insensitive filename", log )
def test_pkg_manager_init_merge(self): self.setup_requirements_json() cwd = mkdtemp(self) driver = cli.PackageManagerDriver( pkg_manager_bin='mgr', pkgdef_filename='requirements.json', dep_keys=('require',), working_dir=cwd, ) target = join(cwd, 'requirements.json') with open(target, 'w') as fd: result = json.dump({"require": {"calmpy": "1.0.0"}}, fd) driver.pkg_manager_init('calmpy.pip', merge=True, overwrite=True) self.assertNotEqual(result, { "require": { "calmpy": "1.0.0", "setuptools": "25.1.6", }, "name": "calmpy.pip", }) stub_mod_call(self, cli) stub_base_which(self) with pretty_logging(stream=mocks.StringIO()): # ensure the return value is True, assuming successful self.assertTrue( driver.pkg_manager_install('calmpy.pip', overwrite=True))
def test_conflict_registration(self): # create an empty working set for a clean-slate test. cwd = utils.mkdtemp(self) mock_ws = WorkingSet([]) registry = ArtifactRegistry('calmjs.artifacts', _working_set=mock_ws) # using named case for case sensitivity test. st = join(cwd, 'calmjs_artifacts', 'Simple.js') dist_ = Distribution(cwd, project_name='pkg', version='1.0') dist_.egg_info = cwd # just lazy s1 = EntryPoint.parse('Simple.js = dummy_builder:builder1') s1.dist = dist_ s2 = EntryPoint.parse('Simple.js = dummy_builder:builder2') s2.dist = dist_ with pretty_logging(stream=mocks.StringIO()) as stream: registry.register_entry_point(s1) # normal registry usage shouldn't be able to do this. registry.register_entry_point(s2) log = stream.getvalue() self.assertIn( "entry point 'Simple.js = dummy_builder:builder2' from package " "'pkg 1.0' resolves to the path '%s' which was already " "registered to entry point 'Simple.js = dummy_builder:builder1'; " "conflicting entry point registration will be ignored." % st, log )
def test_process_path_error(self): build_dir = mkdtemp(self) source1 = join(build_dir, 'source1.js') source2 = join(build_dir, 'source2.js') source3 = join(build_dir, 'source3.js') with open(source1, 'w') as fd: fd.write( "define('source1/mod1', ['require','exports','module']," "function (require, exports, module) {});\n" "define('source1/mod2', ['require','exports','module']," "function (require, exports, module) {});\n" ) with open(source2, 'w') as fd: fd.write( "define('source2/mod1', ['require','exports','module']" "function (require, exports, module) {});\n" ) with open(source3, 'w') as fd: fd.write( "define('source3/mod1', ['require','exports','module']," "function (require, exports, module) {});\n" ) with pretty_logging(stream=StringIO()) as s: result = process_artifacts([source1, source2, source3]) self.assertEqual(sorted(result), [ 'source1/mod1', 'source1/mod2', 'source3/mod1']) self.assertIn('syntax error in', s.getvalue()) self.assertIn(source2, s.getvalue())
def test_get_bin_version_no_bin(self): stub_mod_check_output(self, cli, fake_error(OSError)) stub_base_which(self) with pretty_logging(stream=mocks.StringIO()) as err: results = cli.get_bin_version('some_app') self.assertIn("failed to execute 'some_app'", err.getvalue()) self.assertIsNone(results)
def test_requirejs_is_pretty_much_completely_broken(self): """ Showing how requirejs and/or requirejs-text is basically broken I mean, I covered how it basically can't deal with filename extensions correctly, so no amount of workaround can really fix the underlying brokenness. """ with pretty_logging(stream=StringIO()) as stream: result = self.registry.modname_targetpath_mapping_to_config_paths({ 'text!foo/bar.txt': 'text!/src/foo/bar.txt', 'text!foo/bar.html': 'text!/alt/src/foo/bar.html', }) err = stream.getvalue() # html comes before txt, since the mapping is pre-sorted in # alphabetical order, so txt will end up overwriting html's base # directory. self.assertEqual({ 'foo/bar': '/src/foo/bar', 'foo/bar.txt': '/src/foo/bar.txt', 'foo/bar.html': '/alt/src/foo/bar.html', }, result['paths']) self.assertIn('WARNING', err) self.assertIn("value of paths['foo/bar'] is being rewritten", err) self.assertIn("configuration may be in an invalid state", err) self.assertIn( "the value of paths['foo/bar'] is being rewritten from " "'/alt/src/foo/bar' to '/src/foo/bar'; " "configuration may be in an invalid state.", err)
def test_update_artifact_metadata(self): # inject dummy module and add cleanup mod = ModuleType('calmjs_testing_dummy') mod.complete = generic_builder self.addCleanup(sys.modules.pop, 'calmjs_testing_dummy') sys.modules['calmjs_testing_dummy'] = mod working_dir = utils.mkdtemp(self) utils.make_dummy_dist(self, ( ('requires.txt', '\n'.join([ 'calmjs', ])), ('entry_points.txt', '\n'.join([ '[calmjs.artifacts]', 'artifact.js = calmjs_testing_dummy:complete', ])), ), 'app', '1.0', working_dir=working_dir) # mock a version of calmjs within that environment too utils.make_dummy_dist(self, ( ('entry_points.txt', ''), ), 'calmjs', '1.0', working_dir=working_dir) mock_ws = WorkingSet([working_dir]) registry = ArtifactRegistry('calmjs.artifacts', _working_set=mock_ws) registry.update_artifact_metadata('app', {}) self.assertTrue(exists(registry.metadata.get('app'))) with pretty_logging(stream=mocks.StringIO()) as s: registry.update_artifact_metadata('calmjs', {}) self.assertIn( "package 'calmjs' has not declare any artifacts", s.getvalue())
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_create_spec_with_calmjs_webpack_no_registry(self): with pretty_logging(stream=StringIO()) as stream: spec = create_spec(['calmjs.webpack'], source_registry_method='none') self.assertTrue(isinstance(spec, Spec)) self.assertEqual(spec['export_target'], join(self.cwd, 'calmjs.webpack.js')) self.assertEqual(spec['calmjs_module_registry_names'], []) self.assertEqual(spec['source_package_names'], ['calmjs.webpack']) log = stream.getvalue() self.assertIn( "no module registry declarations found using packages " "['calmjs.webpack'] using acquisition method 'none'", log)
def test_npm_init_existing_broken_no_overwrite_non_interactive(self): npm.npm.cli_driver.interactive = False tmpdir = mkdtemp(self) # Broken json with open(join(tmpdir, 'package.json'), 'w') as fd: fd.write('{') os.chdir(tmpdir) with pretty_logging(stream=StringIO()) as stderr: self.assertFalse(npm.npm_init('foo')) self.assertIn("ignoring existing malformed", stderr.getvalue()) with open(join(tmpdir, 'package.json')) as fd: self.assertEqual('{', fd.read())
def test_requirejs_text_issue123_handling(self): f = plugin.TextPlugin(None).requirejs_text_issue123 with pretty_logging('calmjs.rjs.plugin', stream=StringIO()) as stream: self.assertEqual(f('file'), ['file', '']) self.assertEqual(f('dir/text'), ['dir/text', '']) self.assertEqual(f('dir/text.txt'), ['dir/text', 'txt']) self.assertEqual(f('dotted.dir/text'), ['dotted', 'dir/text']) self.assertEqual(f('dotted.dir/text.txt'), ['dotted.dir/text', 'txt']) self.assertEqual(stream.getvalue(), '') with pretty_logging('calmjs.rjs.plugin', stream=StringIO()) as stream: # the following also implement the stripping of trailing # dots which requirejs-text doesn't support correctly, # and with requirejs>=2.0.13 will fail consistently. self.assertEqual(f('file.'), ['file', '']) self.assertEqual(f('dir/text.'), ['dir/text', '']) self.assertEqual(f('dotted.dir/text.'), ['dotted.dir/text', '']) # ensure the complaining loudly is done. self.assertIn('WARNING', stream.getvalue()) self.assertIn('trailing', stream.getvalue())
def test_module_registry_standard(self): with pretty_logging(stream=mocks.StringIO()): self.registry.register_entry_points([ EntryPoint.parse( 'calmjs.testing.module1 = calmjs.testing.module1') ]) self.assertEqual( sorted(key for key, value in self.registry.iter_records()), [ 'calmjs.testing.module1', ]) module1 = self.registry.get_record('calmjs.testing.module1') key = 'calmjs/testing/module1/hello' self.assertEqual(sorted(module1.keys()), [key])
def test_pkg_manager_init_exists_and_overwrite(self): self.setup_requirements_json() cwd = mkdtemp(self) driver = cli.PackageManagerDriver( pkg_manager_bin='mgr', pkgdef_filename='requirements.json', dep_keys=('require', ), working_dir=cwd, ) target = join(cwd, 'requirements.json') with open(target, 'w') as fd: result = json.dump({"require": {}}, fd) with pretty_logging(stream=mocks.StringIO()) as err: driver.pkg_manager_init('calmpy.pip', overwrite=False) self.assertIn('not overwriting existing ', err.getvalue()) self.assertIn('requirements.json', err.getvalue()) with open(target) as fd: result = json.load(fd) self.assertNotEqual(result, {"require": {"setuptools": "25.1.6"}}) stub_mod_call(self, cli) with pretty_logging(stream=mocks.StringIO()) as err: # ensure the return value is False self.assertFalse( driver.pkg_manager_install('calmpy.pip', overwrite=False)) driver.pkg_manager_init('calmpy.pip', overwrite=True) with open(target) as fd: result = json.load(fd) self.assertEqual(result, { "require": { "setuptools": "25.1.6" }, "name": "calmpy.pip", })
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_create_spec_empty_calmjs_compat_disable(self): with pretty_logging(stream=StringIO()) as stream: spec = create_spec([], calmjs_compat=False) self.assertNotIn('packages []', stream.getvalue()) self.assertIn('no packages specified', stream.getvalue()) self.assertIn( "calmjs_compat is disabled; webpack.output.library automatically " "set to 'calmjs.webpack.export', derived from input package names " "and export filename as the entry point is defined to be the " "simplified calmjs bootstrap.", stream.getvalue()) self.assertTrue(isinstance(spec, Spec)) self.assertNotIn('webpack_externals', spec) self.assertEqual(spec['webpack_output_library'], 'calmjs.webpack.export')
def test_initialize_failure_bad_plugin(self): working_set = WorkingSet({'calmjs.loader_plugin': [ 'bad_plugin = calmjs.tests.test_loaderplugin:BadPlugin', ]}, dist=Distribution(project_name='plugin', version='1.0')) # should not trigger import failure with pretty_logging(stream=StringIO()) as stream: registry = LoaderPluginRegistry( 'calmjs.loader_plugin', _working_set=working_set) self.assertIsNone(registry.get('bad_plugin')) self.assertIn( "registration of entry point " "'bad_plugin = calmjs.tests.test_loaderplugin:BadPlugin' from " "'plugin 1.0' to registry 'calmjs.loader_plugin' failed", stream.getvalue() )
def test_npm_install_package_json(self): stub_mod_call(self, cli) stub_base_which(self, which_npm) tmpdir = mkdtemp(self) os.chdir(tmpdir) # This is faked. with pretty_logging(stream=StringIO()) as stderr: npm.npm_install() self.assertIn( "no package name supplied, " "but continuing with 'npm install'", stderr.getvalue()) # However we make sure that it's been fake called self.assertEqual(self.call_args, (([which_npm, 'install'],), {})) self.assertFalse(exists(join(tmpdir, 'package.json')))
def test_create_spec_with_calmjs_rjs(self): with pretty_logging(stream=StringIO()) as stream: spec = create_spec(['calmjs.rjs']) self.assertTrue(isinstance(spec, Spec)) self.assertEqual(spec['export_target'], 'calmjs.rjs.js') self.assertEqual(spec['calmjs_module_registry_names'], ['calmjs.module']) self.assertEqual(spec['source_package_names'], ['calmjs.rjs']) log = stream.getvalue() self.assertIn( "automatically picked registries ['calmjs.module'] for " "building source map", log, )
def test_helper_attr(self): stub_mod_call(self, cli) stub_base_which(self) driver = cli.PackageManagerDriver(pkg_manager_bin='mgr') with self.assertRaises(AttributeError) as e: driver.no_such_attr_here self.assertIn('no_such_attr_here', str(e.exception)) self.assertIsNot(driver.mgr_init, None) self.assertIsNot(driver.get_mgr_version, None) with pretty_logging(stream=mocks.StringIO()) as stderr: driver.mgr_install() self.assertIn( "no package name supplied, " "but continuing with 'mgr install'", stderr.getvalue()) self.assertEqual(self.call_args, ((['mgr', 'install'], ), {}))
def test_dummy_implemented_manual_entrypoint_double_regisetr(self): from calmjs.testing import module1 registry = DummyModuleRegistry(__name__) with pretty_logging(stream=mocks.StringIO()) as s: registry.register_entry_point( EntryPoint.parse( 'calmjs.testing.module1 = calmjs.testing.module1')) registry.register_entry_point( EntryPoint.parse( 'calmjs.testing.module1 = calmjs.testing.module1')) # no dist. self.assertIn('manually registering entry_point', s.getvalue()) result = registry.get_record('calmjs.testing.module1') # just merged together. self.assertEqual(result, {'calmjs.testing.module1': module1})
def test_module_registry_pythonic(self): registry = PythonicModuleRegistry(__name__) with pretty_logging(stream=mocks.StringIO()): registry.register_entry_points([ EntryPoint.parse( 'calmjs.testing.module1 = calmjs.testing.module1') ]) self.assertEqual(sorted(key for key, value in registry.iter_records()), [ 'calmjs.testing.module1', ]) module1 = registry.get_record('calmjs.testing.module1') key = 'calmjs.testing.module1.hello' self.assertEqual(sorted(module1.keys()), [key])
def test_yarn_install_package_json(self): stub_mod_call(self, cli) stub_base_which(self, which_yarn) tmpdir = mkdtemp(self) os.chdir(tmpdir) # This is faked. with pretty_logging(stream=StringIO()) as stderr: yarn.yarn_install() self.assertIn( "no package name supplied, " "not continuing with 'yarn install'", stderr.getvalue()) # However we make sure that it's been fake called self.assertIsNone(self.call_args) self.assertFalse(exists(join(tmpdir, 'package.json')))
def test_build_bundle_with_data(self): bundle_dir = utils.mkdtemp(self) build_dir = utils.mkdtemp(self) transpile_source_map = {} transpile_source_map.update(self._example_package_map) # include custom loader and data transpile_source_map.update(self._example_package_loader) bundle_source_map = {} export_target = join(bundle_dir, 'example.package') requirejs_plugins = { 'example/package/loader': self._example_package_data } custom_registry = LoaderPluginRegistry( 'custom', _working_set=WorkingSet({ 'custom': [ 'example/package/loader = calmjs.rjs.plugin:TextPlugin']}) ) rjs = toolchain.RJSToolchain() rjs.loader_plugin_registry = custom_registry spec = Spec( transpile_source_map=transpile_source_map, bundle_source_map=bundle_source_map, requirejs_plugins=requirejs_plugins, export_target=export_target, build_dir=build_dir, ) with pretty_logging(stream=StringIO()): # to avoid logging the issue of mismatch map to extension # to stderr. rjs(spec) self.assertTrue(exists(export_target)) # verify that the bundle works with node stdout, stderr = run_node( 'var requirejs = require("requirejs");\n' 'var define = requirejs.define;\n' '%s\n' 'var result = requirejs(\n' ' "example/package/loader!example/package/data");\n' 'process.stdout.write("" + result.results.item_count);\n', export_target, ) self.assertEqual(stderr, '') self.assertEqual(stdout, '0')
def test_npm_install_package_json_no_overwrite_interactive(self): """ Most of these package_json testing will be done in the next test class specific for ``npm init``. """ # Testing the implied init call stub_mod_call(self, cli) stub_stdouts(self) stub_stdin(self, 'n\n') stub_mod_check_interactive(self, [cli], True) tmpdir = mkdtemp(self) os.chdir(tmpdir) # All the pre-made setup. app = make_dummy_dist(self, ( ('requires.txt', '\n'.join([])), ('package.json', json.dumps({ 'dependencies': {'jquery': '~1.11.0'}, })), ), 'foo', '1.9.0') working_set = WorkingSet() working_set.add(app, self._calmjs_testing_tmpdir) stub_item_attr_value(self, dist, 'default_working_set', working_set) # We are going to have a fake package.json with open(join(tmpdir, 'package.json'), 'w') as fd: json.dump({}, fd) # capture the logging explicitly as the conditions which # determines how the errors are outputted differs from different # test harnesses. Verify that later. with pretty_logging(stream=StringIO()) as stderr: # This is faked. npm.npm_install('foo') self.assertIn( "Overwrite '%s'? (Yes/No) [No] " % join(tmpdir, 'package.json'), sys.stdout.getvalue()) # Ensure the error message. Normally this is printed through # stderr via distutils custom logger and our handler bridge for # that which is tested elsewhere. self.assertIn("not continuing with 'npm install'", stderr.getvalue()) with open(join(tmpdir, 'package.json')) as fd: result = fd.read() # This should remain unchanged as no to overwrite is default. self.assertEqual(result, '{}')
def test_create_spec_with_calmjs_webpack_output_library_disable(self): with pretty_logging(stream=StringIO()) as stream: spec = create_spec( ['calmjs.webpack'], calmjs_compat=False, webpack_entry_point='custom_entry', webpack_output_library=False, ) log = stream.getvalue() self.assertNotIn( "webpack_entry_point is ignored; set calmjs_compat to false " "to enable manual webpack.entry specification", log) self.assertIn("webpack.output.library is disabled; it will be unset.", log) self.assertEqual(spec['webpack_entry_point'], 'custom_entry') self.assertNotIn('webpack_output_library', spec)
def test_plugin_package_success_main(self): base = NPMLoaderPluginHandler(None, 'base') base.node_module_pkg_name = 'dummy_pkg' toolchain = NullToolchain() spec = Spec(working_dir=mkdtemp(self)) pkg_dir = join(spec['working_dir'], 'node_modules', 'dummy_pkg') makedirs(pkg_dir) with open(join(pkg_dir, 'package.json'), 'w') as fd: fd.write('{"main": "base.js"}') with pretty_logging(stream=StringIO()) as stream: self.assertEqual( join(pkg_dir, 'base.js'), base.generate_handler_sourcepath(toolchain, spec, {})['base'], ) self.assertIn("for loader plugin 'base'", stream.getvalue())
def test_create_spec_empty(self): with pretty_logging(stream=StringIO()) as stream: spec = create_spec([]) self.assertNotIn('packages []', stream.getvalue()) self.assertIn('no packages specified', stream.getvalue()) self.assertIn( "using calmjs bootstrap; webpack.output.library set to " "'__calmjs__'", stream.getvalue()) self.assertTrue(isinstance(spec, Spec)) self.assertEqual(spec['working_dir'], self.cwd) self.assertEqual(spec['export_target'], join(self.cwd, 'calmjs.webpack.export.js')) self.assertEqual(spec['calmjs_module_registry_names'], []) self.assertIn('webpack_externals', spec) self.assertEqual(spec['webpack_output_library'], '__calmjs__')
def test_initialize_failure_missing(self): working_set = WorkingSet({ 'calmjs.rjs.loader_plugin': [ 'not_plugin = calmjs.rjs.not_plugin:nothing', ] }) # should not trigger import failure with pretty_logging(stream=StringIO()) as stream: registry = LoaderPluginRegistry('calmjs.rjs.loader_plugin', _working_set=working_set) self.assertIsNone(registry.get('not_plugin')) self.assertIn( "registry 'calmjs.rjs.loader_plugin' failed to load loader plugin " "handler for entry point 'not_plugin =", stream.getvalue(), )
def test_initialize_failure_bad_plugin(self): working_set = WorkingSet({ 'calmjs.rjs.loader_plugin': [ 'bad_plugin = calmjs.rjs.tests.test_registry:BadPlugin', ] }) # should not trigger import failure with pretty_logging(stream=StringIO()) as stream: registry = LoaderPluginRegistry('calmjs.rjs.loader_plugin', _working_set=working_set) self.assertIsNone(registry.get('bad_plugin')) self.assertIn( "the loader plugin class registered at 'bad_plugin = " "calmjs.rjs.tests.test_registry:BadPlugin' failed " "to be instantiated with the following exception", stream.getvalue())
def test_indexer_modpath_pkg_resources_entry_point_mismatch_module(self): entry_point = EntryPoint.parse('example.mold = example.package1:mold') module1 = ModuleType('example.package1') module2 = ModuleType('example.package2') nunja_template, nunja_script, nunja_modpath = generate_modname_nunja( entry_point, module1, fext='.tmpl') with pretty_logging(logger='nunja', stream=StringIO()) as stream: nunja_modpath(module2, entry_point) msg = stream.getvalue() self.assertIn( "modpath function created for <module 'example.package1'", msg) self.assertIn("got unexpected module <module 'example.package2'", msg) self.assertIn("could not be located as a module", msg)
def test_karma_setup_basic_file(self): karma_config = karma.build_base_config() # this should be purged. karma_config['files'] = ['example/package/lib.js'] spec = Spec( karma_config=karma_config, build_dir=mkdtemp(self), toolchain_bin_path=self.setup_fake_webpack(), ) with pretty_logging(stream=StringIO()) as s: karma_webpack(spec) self.assertEqual(spec['karma_config']['files'], [join(spec['build_dir'], '__calmjs_tests__.js')]) self.assertNotIn('unsupported', s.getvalue())
def test_plugin_package_success_implied_index_js(self): working_dir = mkdtemp(self) pkg_name = 'demo' pkg_dir = join(working_dir, 'node_modules', pkg_name) makedirs(pkg_dir) with open(join(pkg_dir, 'package.json'), 'w') as fd: fd.write('{}') with open(join(pkg_dir, 'index.js'), 'w') as fd: fd.write('(function () { return {} })();') with pretty_logging(stream=StringIO(), level=DEBUG) as stream: self.assertEqual( join(pkg_dir, 'index.js'), npm.locate_package_entry_file(working_dir, pkg_name), ) self.assertEqual("", stream.getvalue())
def test_update_spec_webpack_loaders_modules_missing_alias(self): spec = Spec(calmjs_webpack_modname_loader_map={ 'some/style.css': ['style', 'css'], }, ) alias = {} with pretty_logging(stream=StringIO()) as s: update_spec_webpack_loaders_modules(spec, alias) self.assertIn( "WARNING modname 'some/style.css' requires loader chain " "['style', 'css'] but it does not have a corresponding webpack " "resolve.alias; webpack build failure may result as loaders are " "not configured for this modname", s.getvalue(), ) self.assertEqual([], spec['webpack_module_rules'])
def test_existing_removed(self): # force an existing file target = self.registry.records[('app', 'nothing.js')] os.mkdir(dirname(target)) with open(target, 'w'): pass with pretty_logging(stream=mocks.StringIO()) as stream: self.registry.process_package('app') log = stream.getvalue() self.assertIn( "package 'app' has declared 3 entry points for the " "'calmjs.artifacts' registry for artifact construction", log) log = stream.getvalue() self.assertIn("removing existing export target at ", log) self.assertFalse(exists(target))
def test_assemble_standard(self): with pretty_logging(logger='calmjs.rjs', stream=mocks.StringIO()) as s: build_js, config_js = self.assemble_spec_config() self.assertIn('ERROR', s.getvalue()) self.assertIn( "source file(s) referenced modules that are missing in the " "build directory: 'jquery', 'some.pylike.module', 'underscore'", s.getvalue()) self.assertEqual(build_js['paths'], {}) self.assertEqual( config_js['paths'], { 'module1': 'module1.js?', 'module2': 'module2.js?', 'module3': 'module3.js?', })
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 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(), )