class CompilerTest(unittest.TestCase): def setUp(self): self.compiler = SASSCompiler() self.env = Environment(root=OUTPUT_DIR, public_assets=(r'.*\.css', ), fingerprinting=False) self.env.finders.register(FileSystemFinder([SCSS_DIR])) self.env.compilers.register('.scss', self.compiler.as_handler()) self.env.register_defaults() self.env.save() def test_syntax(self): scss, css, output = fixture_load('syntax') self.assertEqual(css, output) def test_variables(self): scss, css, output = fixture_load('variables') self.assertEqual(css, output) def test_mixin(self): scss, css, output = fixture_load('mixin') self.assertEqual(css, output) def test_import(self): scss, css, output = fixture_load('import') self.assertEqual(css, output) def test_image(self): scss, css, output = fixture_load('image') self.assertEqual(css, output)
class Assets(object): """ Uses the gears package to compile all .scss and .coffee files into CSS and JS """ def __init__(self): project_dir = os.path.abspath(os.path.dirname(os.path.dirname(__file__))) app_dir = os.path.join(project_dir, 'app') public_dir = os.path.join(project_dir, 'public') self.gears = Environment(public_dir, fingerprinting=False, manifest_path=False) self.gears.finders.register(ExtFinder( [app_dir], ['.coffee', '.scss', '.handlebars', '.js', '.css'], ['app.handlebars', 'partials/header.handlebars', 'partials/footer.handlebars'] )) self.gears.compilers.register('.scss', LibsassCompiler.as_handler()) self.gears.compilers.register('.coffee', CoffeeScriptCompiler.as_handler()) self.gears.compilers.register('.handlebars', CustomHandlebarsCompiler.as_handler()) if env.is_prod(): self.gears.compressors.register('text/css', CleanCSSCompressor.as_handler()) self.gears.register_defaults() def compile(self): """ Perform the cross-compile of the assets """ self.gears.save()
class EnvironmentListTests(TestCase): def setUp(self): self.environment = Environment(STATIC_DIR) self.environment.register_defaults() self.environment.finders.register(FileSystemFinder([ASSETS_DIR])) def test_list(self): items = list(self.environment.list("js/templates", "application/javascript")) self.assertEqual(len(items), 3) for i, item in enumerate(sorted(items, key=lambda x: x[1])): path = "js/templates/%s.js.handlebars" % "abc"[i] asset_attributes, absolute_path = item self.assertIsInstance(asset_attributes, AssetAttributes) self.assertEqual(asset_attributes.path, path) self.assertEqual(absolute_path, os.path.join(ASSETS_DIR, path)) def test_list_recursively(self): items = list(self.environment.list("js/templates", "application/javascript", recursive=True)) self.assertEqual(len(items), 4) for i, item in enumerate(sorted(items, key=lambda x: x[1])): path = "js/templates/%s.js.handlebars" % ("a", "b", "c", "d/e")[i] asset_attributes, absolute_path = item self.assertIsInstance(asset_attributes, AssetAttributes) self.assertEqual(asset_attributes.path, path) self.assertEqual(absolute_path, os.path.join(ASSETS_DIR, path))
class CompilerTest(unittest.TestCase): def setUp(self): self.compiler = SASSCompiler() self.env = Environment(root=OUTPUT_DIR, public_assets=(r".*\.css",), fingerprinting=False) self.env.finders.register(FileSystemFinder([SCSS_DIR])) self.env.compilers.register(".scss", self.compiler.as_handler()) self.env.register_defaults() self.env.save() def test_syntax(self): scss, css, output = fixture_load("syntax") self.assertEqual(css, output) def test_variables(self): scss, css, output = fixture_load("variables") self.assertEqual(css, output) def test_mixin(self): scss, css, output = fixture_load("mixin") self.assertEqual(css, output) def test_import(self): scss, css, output = fixture_load("import") self.assertEqual(css, output) def test_image(self): scss, css, output = fixture_load("image") self.assertEqual(css, output)
class AbstractSassCompilerTestCase(unittest.TestCase): def setUp(self): self.output_files = [] self.addCleanup(self.remove_output_files) def remove_output_files(self): output_glob = path.join(fixtures_dir, "output", "*") for output_file in glob.glob(output_glob): if path.isdir(output_file): shutil.rmtree(output_file) else: os.remove(output_file) def setup_environment(self, directory): os.chdir(directory) self.environment = Environment( root=path.join(fixtures_dir, "output"), public_assets=(r".*\.css",), fingerprinting=False, ) self.compiler = SASSCompiler() self.environment.compilers.register(".scss", self.compiler) self.environment.finders.register(FileSystemFinder(directories=(directory,))) self.environment.register_defaults()
class EnvironmentListTests(TestCase): def setUp(self): self.environment = Environment(STATIC_DIR) self.environment.register_defaults() self.environment.finders.register(FileSystemFinder([ASSETS_DIR])) def test_list(self): items = list( self.environment.list('js/templates', 'application/javascript')) self.assertEqual(len(items), 3) for i, item in enumerate(sorted(items, key=lambda x: x[1])): path = 'js/templates/%s.js.handlebars' % 'abc'[i] asset_attributes, absolute_path = item self.assertIsInstance(asset_attributes, AssetAttributes) self.assertEqual(asset_attributes.path, path) self.assertEqual(absolute_path, os.path.join(ASSETS_DIR, path)) def test_list_recursively(self): items = list( self.environment.list( 'js/templates', 'application/javascript', recursive=True, )) self.assertEqual(len(items), 4) for i, item in enumerate(sorted(items, key=lambda x: x[1])): path = 'js/templates/%s.js.handlebars' % ('a', 'b', 'c', 'd/e')[i] asset_attributes, absolute_path = item self.assertIsInstance(asset_attributes, AssetAttributes) self.assertEqual(asset_attributes.path, path) self.assertEqual(absolute_path, os.path.join(ASSETS_DIR, path))
class Assets(object): """ Uses the gears package to compile all .scss and .coffee files into CSS and JS """ def __init__(self): project_dir = os.path.abspath( os.path.dirname(os.path.dirname(__file__))) app_dir = os.path.join(project_dir, 'app') public_dir = os.path.join(project_dir, 'public') self.gears = Environment(public_dir, public_assets=[self._public_assets], fingerprinting=False, manifest_path=False) self.gears.finders.register( ExtFinder([app_dir], ['.coffee', '.scss', '.handlebars'], [ 'app.handlebars', 'partials/header.handlebars', 'partials/footer.handlebars' ])) self.gears.compilers.register('.scss', SCSSCompiler.as_handler()) self.gears.compilers.register('.coffee', CoffeeScriptCompiler.as_handler()) self.gears.compilers.register('.handlebars', CustomHandlebarsCompiler.as_handler()) if env.is_prod(): self.gears.compressors.register('text/css', CleanCSSCompressor.as_handler()) self.gears.register_defaults() def _public_assets(self, path): """ Method is used by gears to determine what should be copied/published Allows only the app.js and app.css files to be compiled, filtering out all others since they should be included via require, require_tree, etc directives. Also, anything not js or css will be allowed through. :param path: The filesystem path to check :return: If the path should be copied to the public folder """ if path in ['js/app.js', 'css/app.css']: return True return not any(path.endswith(ext) for ext in ('.css', '.js')) def compile(self): """ Perform the cross-compile of the assets """ self.gears.save()
class EnvironmentFindTests(TestCase): def setUp(self): self.environment = Environment(STATIC_DIR) self.environment.register_defaults() self.environment.finders.register(FakeFinder()) self.environment.compilers.register( '.coffee', FakeCompiler('application/javascript')) def check_asset_attributes(self, attrs, path): self.assertIsInstance(attrs, AssetAttributes) self.assertIs(attrs.environment, self.environment) self.assertEqual(attrs.path, path) def test_find_by_path(self): attrs, path = self.environment.find('js/models.js.coffee') self.check_asset_attributes(attrs, 'js/models.js.coffee') self.assertEqual(path, '/assets/js/models.js.coffee') def test_find_nothing_by_path(self): with self.assertRaises(FileNotFound): self.environment.find('js/models.js') def test_find_by_path_list(self): attrs, path = self.environment.find(['js/app.js', 'js/app/index.js']) self.check_asset_attributes(attrs, 'js/app/index.js') self.assertEqual(path, '/assets/js/app/index.js') def test_find_nothing_by_path_list(self): with self.assertRaises(FileNotFound): self.environment.find(['style.css', 'style/index.css']) def test_find_by_asset_attributes(self): attrs = AssetAttributes(self.environment, 'js/app.js') attrs, path = self.environment.find(attrs) self.check_asset_attributes(attrs, 'js/app/index.js') self.assertEqual(path, '/assets/js/app/index.js') def test_find_nothing_by_asset_attributes(self): attrs = AssetAttributes(self.environment, 'js/models.js') with self.assertRaises(FileNotFound): self.environment.find(attrs) def test_find_by_logical_path(self): attrs, path = self.environment.find('js/models.js', logical=True) self.check_asset_attributes(attrs, 'js/models.js.coffee') self.assertEqual(path, '/assets/js/models.js.coffee') def test_find_nothing_by_logical_path(self): with self.assertRaises(FileNotFound): self.environment.find('js/views.js', logical=True) def test_save_file(self): with remove_static_dir(): self.environment.save_file('js/script.js', 'hello world') with open(os.path.join(STATIC_DIR, 'js', 'script.js')) as f: self.assertEqual(f.read(), 'hello world')
class EnvironmentFindTests(TestCase): def setUp(self): self.environment = Environment(STATIC_DIR) self.environment.register_defaults() self.environment.finders.register(FakeFinder()) self.environment.engines.register('.coffee', FakeEngine('application/javascript')) def check_asset_attributes(self, attrs, path): self.assertIsInstance(attrs, AssetAttributes) self.assertIs(attrs.environment, self.environment) self.assertEqual(attrs.path, path) def test_find_by_path(self): attrs, path = self.environment.find('js/models.js.coffee') self.check_asset_attributes(attrs, 'js/models.js.coffee') self.assertEqual(path, '/assets/js/models.js.coffee') def test_find_nothing_by_path(self): with self.assertRaises(FileNotFound): self.environment.find('js/models.js') def test_find_by_path_list(self): attrs, path = self.environment.find(['js/app.js', 'js/app/index.js']) self.check_asset_attributes(attrs, 'js/app/index.js') self.assertEqual(path, '/assets/js/app/index.js') def test_find_nothing_by_path_list(self): with self.assertRaises(FileNotFound): self.environment.find(['style.css', 'style/index.css']) def test_find_by_asset_attributes(self): attrs = AssetAttributes(self.environment, 'js/app.js') attrs, path = self.environment.find(attrs) self.check_asset_attributes(attrs, 'js/app/index.js') self.assertEqual(path, '/assets/js/app/index.js') def test_find_nothing_by_asset_attributes(self): attrs = AssetAttributes(self.environment, 'js/models.js') with self.assertRaises(FileNotFound): self.environment.find(attrs) def test_find_by_logical_path(self): attrs, path = self.environment.find('js/models.js', logical=True) self.check_asset_attributes(attrs, 'js/models.js.coffee') self.assertEqual(path, '/assets/js/models.js.coffee') def test_find_nothing_by_logical_path(self): with self.assertRaises(FileNotFound): self.environment.find('js/views.js', logical=True) def test_save_file(self): with remove_static_dir(): self.environment.save_file('js/script.js', 'hello world') with open(os.path.join(STATIC_DIR, 'js', 'script.js')) as f: self.assertEqual(f.read(), 'hello world')
class Assets(object): """ Uses the gears package to compile all .scss and .coffee files into CSS and JS """ def __init__(self): project_dir = os.path.abspath(os.path.dirname(os.path.dirname(__file__))) app_dir = os.path.join(project_dir, "app") public_dir = os.path.join(project_dir, "public") self.gears = Environment( public_dir, public_assets=[self._public_assets], fingerprinting=False, manifest_path=False ) self.gears.finders.register( ExtFinder( [app_dir], [".coffee", ".scss", ".handlebars"], ["app.handlebars", "partials/header.handlebars", "partials/footer.handlebars"], ) ) self.gears.compilers.register(".scss", SCSSCompiler.as_handler()) self.gears.compilers.register(".coffee", CoffeeScriptCompiler.as_handler()) self.gears.compilers.register(".handlebars", CustomHandlebarsCompiler.as_handler()) if env.is_prod(): self.gears.compressors.register("text/css", CleanCSSCompressor.as_handler()) self.gears.register_defaults() def _public_assets(self, path): """ Method is used by gears to determine what should be copied/published Allows only the app.js and app.css files to be compiled, filtering out all others since they should be included via require, require_tree, etc directives. Also, anything not js or css will be allowed through. :param path: The filesystem path to check :return: If the path should be copied to the public folder """ if path in ["js/app.js", "css/app.css"]: return True return not any(path.endswith(ext) for ext in (".css", ".js")) def compile(self): """ Perform the cross-compile of the assets """ self.gears.save()
class EnvironmentFindTests(TestCase): def setUp(self): self.environment = Environment(STATIC_DIR) self.environment.register_defaults() self.environment.finders.register(FakeFinder()) self.environment.compilers.register( '.coffee', FakeCompiler('application/javascript')) def check_asset_attributes(self, attrs, path): self.assertIsInstance(attrs, AssetAttributes) self.assertIs(attrs.environment, self.environment) self.assertEqual(attrs.path, path) def test_find_by_path(self): attrs, path = self.environment.find('js/models.js.coffee') self.check_asset_attributes(attrs, 'js/models.js.coffee') self.assertEqual(path, '/assets/js/models.js.coffee') def test_find_nothing_by_path(self): with self.assertRaises(FileNotFound): self.environment.find('js/models.js') def test_find_by_asset_attributes(self): attrs = AssetAttributes(self.environment, 'js/app.js') attrs, path = self.environment.find(attrs) self.check_asset_attributes(attrs, 'js/app/index.js') self.assertEqual(path, '/assets/js/app/index.js') def test_find_nothing_by_asset_attributes(self): attrs = AssetAttributes(self.environment, 'js/models.js') with self.assertRaises(FileNotFound): self.environment.find(attrs) def test_find_by_logical_path(self): attrs, path = self.environment.find('js/models.js', logical=True) self.check_asset_attributes(attrs, 'js/models.js.coffee') self.assertEqual(path, '/assets/js/models.js.coffee') def test_find_by_logical_path_with_unrecognized_extension(self): attrs, path = self.environment.find('images/logo.png', logical=True) self.check_asset_attributes(attrs, 'images/logo.png') self.assertEqual(path, '/assets/images/logo.png') def test_find_nothing_by_logical_path(self): with self.assertRaises(FileNotFound): self.environment.find('js/views.js', logical=True) def test_save_file(self): source = str('hello world').encode('utf-8') with remove_static_dir(): self.environment.save_file('js/script.js', source) with open(os.path.join(STATIC_DIR, 'js', 'script.js'), 'rb') as f: self.assertEqual(f.read(), source)
class Assets(object): """ Uses the gears package to compile all .scss and .coffee files into CSS and JS """ def __init__(self): project_dir = os.path.abspath(os.path.dirname(os.path.dirname(__file__))) app_dir = os.path.join(project_dir, 'app') public_dir = os.path.join(project_dir, 'public') self.gears = Environment(public_dir, public_assets=[self._public_assets]) self.gears.finders.register(ExtFinder([app_dir], ['.coffee', '.scss', '.handlebars'])) self.gears.compilers.register('.scss', SCSSCompiler.as_handler()) self.gears.compilers.register('.coffee', CoffeeScriptCompiler.as_handler()) self.gears.compilers.register('.handlebars', CustomHandlebarsCompiler.as_handler()) if env.is_prod(): self.gears.compressors.register('application/javascript', UglifyJSCompressor.as_handler()) self.gears.compressors.register('text/css', CleanCSSCompressor.as_handler()) self.gears.register_defaults() def _public_assets(self, path): """ Method is used by gears to determine what should be copied/published Allows only the app.js and app.css files to be compiled, filtering out all others since they should be included via require, require_tree, etc directives. Also, anything not js or css will be allowed through. :param path: The filesystem path to check :return: If the path should be copied to the public folder """ if path in ['js/app.js', 'js/package.js', 'css/app.css']: return True return not any(path.endswith(ext) for ext in ('.css', '.js')) def compile(self): """ Perform the cross-compile of the assets """ self.gears.save()
class CompilerTest(unittest.TestCase): def setUp(self): self.compiler = JSXCompiler() self.env = Environment(root=OUTPUT_DIR, public_assets=(r'.*\.js',), fingerprinting=False) self.env.finders.register(FileSystemFinder([JSX_DIR])) self.env.compilers.register('.jsx', self.compiler.as_handler()) self.env.register_defaults() self.env.save() def test_transform(self): jsx, js, output = fixture_load('transform') self.assertEqual(js, output)
def init_environment(self, app): environment = Environment( root=self.get_static_folder(app), public_assets=self.get_public_assets(app), cache=self.get_cache(app), ) if self.defaults: environment.register_defaults() environment.finders.register(self.get_default_finder(app)) if self.compilers is not None: for extension, compiler in self.compilers.items(): environment.compilers.register(extension, compiler) if self.compressors is not None: for mimetype, compressor in self.compressors.items(): environment.compressors.register(mimetype, compressor) app.extensions['gears']['environment'] = environment
class EnvironmentListTests(TestCase): def setUp(self): self.environment = Environment(STATIC_DIR) self.environment.register_defaults() self.environment.finders.register(FileSystemFinder([ASSETS_DIR])) def test_list(self): items = list(self.environment.list('js/templates', ['.js', '.handlebars'])) self.assertEqual(len(items), 3) for i, item in enumerate(sorted(items, key=lambda x: x[1])): path = 'js/templates/%s.js.handlebars' % 'abc'[i] asset_attributes, absolute_path = item self.assertIsInstance(asset_attributes, AssetAttributes) self.assertEqual(asset_attributes.path, path) self.assertEqual(absolute_path, os.path.join(ASSETS_DIR, path))
class EnvironmentTests(TestCase): def setUp(self): self.environment = Environment(STATIC_DIR) def test_suffixes(self): self.environment.mimetypes.register(".css", "text/css") self.environment.mimetypes.register(".txt", "text/plain") self.environment.compilers.register(".styl", FakeCompiler("text/css")) self.assertItemsEqual(self.environment.suffixes.find(), [".css", ".styl", ".css.styl", ".txt"]) def test_register_defaults(self): self.environment.mimetypes = Mock() self.environment.preprocessors = Mock() self.environment.register_defaults() self.environment.mimetypes.register_defaults.assert_called_once_with() self.environment.preprocessors.register_defaults.assert_called_once_with()
def init_environment(self, app): environment = Environment( root=self.get_static_folder(app), public_assets=self.get_public_assets(app), cache=self.get_cache(app), gzip=self.gzip, ) if self.defaults: environment.register_defaults() environment.finders.register(self.get_default_finder(app)) if self.compilers is not None: for extension, compiler in self.compilers.items(): environment.compilers.register(extension, compiler) if self.compressors is not None: for mimetype, compressor in self.compressors.items(): environment.compressors.register(mimetype, compressor) app.extensions['gears']['environment'] = environment
class EnvironmentTests(TestCase): def setUp(self): self.environment = Environment(STATIC_DIR) def test_suffixes(self): self.environment.mimetypes.register('.css', 'text/css') self.environment.mimetypes.register('.txt', 'text/plain') self.environment.compilers.register('.styl', FakeCompiler('text/css')) self.assertItemsEqual(self.environment.suffixes.find(), [ '.css', '.styl', '.css.styl', '.txt', ]) def test_register_defaults(self): self.environment.mimetypes = Mock() self.environment.preprocessors = Mock() self.environment.register_defaults() self.environment.mimetypes.register_defaults.assert_called_once_with() self.environment.preprocessors.register_defaults.assert_called_once_with()
class EnvironmentTests(TestCase): def setUp(self): self.environment = Environment(STATIC_DIR) def test_suffixes(self): self.environment.mimetypes.register('.css', 'text/css') self.environment.mimetypes.register('.txt', 'text/plain') self.environment.compilers.register('.styl', FakeCompiler('text/css')) self.assertItemsEqual(self.environment.suffixes.find(), ['.css', '.css.styl', '.txt']) def test_register_defaults(self): self.environment.compilers = Mock() self.environment.mimetypes = Mock() self.environment.public_assets = Mock() self.environment.preprocessors = Mock() self.environment.register_defaults() self.environment.compilers.register_defaults.assert_called_once_with() self.environment.mimetypes.register_defaults.assert_called_once_with() self.environment.public_assets.register_defaults.assert_called_once_with() self.environment.preprocessors.register_defaults.assert_called_once_with()
class Assets(object): """ Uses the gears package to compile all .scss and .coffee files into CSS and JS """ def __init__(self): project_dir = os.path.abspath( os.path.dirname(os.path.dirname(__file__))) app_dir = os.path.join(project_dir, 'app') public_dir = os.path.join(project_dir, 'public') self.gears = Environment(public_dir, fingerprinting=False, manifest_path=False) self.gears.finders.register( ExtFinder([app_dir], ['.coffee', '.scss', '.handlebars', '.js', '.css'], [ 'app.handlebars', 'partials/header.handlebars', 'partials/footer.handlebars' ])) self.gears.compilers.register('.scss', LibsassCompiler.as_handler()) self.gears.compilers.register('.coffee', CoffeeScriptCompiler.as_handler()) self.gears.compilers.register('.handlebars', CustomHandlebarsCompiler.as_handler()) if env.is_prod(): self.gears.compressors.register('text/css', CleanCSSCompressor.as_handler()) self.gears.register_defaults() def compile(self): """ Perform the cross-compile of the assets """ self.gears.save()
def get_environment(self, fixture): finder = self.get_finder(fixture) environment = Environment(os.path.join(TESTS_DIR, 'static')) environment.finders.register(finder) environment.register_defaults() return environment
import os from gears.environment import Environment from gears.finders import FileSystemFinder from gears_handlebars import HandlebarsCompiler ROOT_DIR = os.path.abspath(os.path.dirname(__file__)) ASSETS_DIR = os.path.join(ROOT_DIR, 'assets') STATIC_DIR = os.path.join(ROOT_DIR, 'static') env = Environment(STATIC_DIR) env.finders.register(FileSystemFinder([ASSETS_DIR])) env.compilers.register('.hbs', HandlebarsCompiler.as_handler()) env.register_defaults() if __name__ == '__main__': env.save()
path = path.lstrip('/') fingerprint_path = env.manifest.files[path] asset[path_type] = fingerprint_path with open(filename, 'wb') as f: f.write(unicode(soup.prettify())) def delete_dest(): if os.path.exists(DEST_DIR): shutil.rmtree(DEST_DIR) if __name__ == '__main__': #clean slate delete_dest() #defines where files will be emitted env = Environment(DEST_DIR, public_assets=( lambda path: any(path.endswith(ext) for ext in ('.css', '.js', '.html')), lambda path: any(path.startswith(ext) for ext in ('fonts', 'images'))) ) env.finders.register(FileSystemFinder([SOURCE_DIR])) env.register_defaults() env.save() reference_fingerprinted_files(env) delete_unused_files(env.manifest)
class EnvironmentFindTests(TestCase): def setUp(self): self.environment = Environment(STATIC_DIR) self.environment.register_defaults() self.environment.finders.register(FakeFinder()) self.environment.compilers.register(".coffee", FakeCompiler("application/javascript")) def check_asset_attributes(self, attrs, path): self.assertIsInstance(attrs, AssetAttributes) self.assertIs(attrs.environment, self.environment) self.assertEqual(attrs.path, path) def test_find_by_path(self): attrs, path = self.environment.find("js/models.js.coffee") self.check_asset_attributes(attrs, "js/models.js.coffee") self.assertEqual(path, "/assets/js/models.js.coffee") def test_find_nothing_by_path(self): with self.assertRaises(FileNotFound): self.environment.find("js/models.js") def test_find_by_path_list(self): attrs, path = self.environment.find(["js/app.js", "js/app/index.js"]) self.check_asset_attributes(attrs, "js/app/index.js") self.assertEqual(path, "/assets/js/app/index.js") def test_find_nothing_by_path_list(self): with self.assertRaises(FileNotFound): self.environment.find(["style.css", "style/index.css"]) def test_find_by_asset_attributes(self): attrs = AssetAttributes(self.environment, "js/app.js") attrs, path = self.environment.find(attrs) self.check_asset_attributes(attrs, "js/app/index.js") self.assertEqual(path, "/assets/js/app/index.js") def test_find_nothing_by_asset_attributes(self): attrs = AssetAttributes(self.environment, "js/models.js") with self.assertRaises(FileNotFound): self.environment.find(attrs) def test_find_by_logical_path(self): attrs, path = self.environment.find("js/models.js", logical=True) self.check_asset_attributes(attrs, "js/models.js.coffee") self.assertEqual(path, "/assets/js/models.js.coffee") def test_find_by_logical_path_with_unrecognized_extension(self): attrs, path = self.environment.find("images/logo.png", logical=True) self.check_asset_attributes(attrs, "images/logo.png") self.assertEqual(path, "/assets/images/logo.png") def test_find_nothing_by_logical_path(self): with self.assertRaises(FileNotFound): self.environment.find("js/views.js", logical=True) def test_save_file(self): source = "hello world" if sys.version_info >= (3, 0): source = bytes(source, "utf-8") with remove_static_dir(): self.environment.save_file("js/script.js", source) with open(os.path.join(STATIC_DIR, "js", "script.js"), "rb") as f: self.assertEqual(f.read(), source)