diff --git a/.gitignore b/.gitignore index 7b97ea1a..176ce8f6 100644 --- a/.gitignore +++ b/.gitignore @@ -1,7 +1,6 @@ # moban hashes .moban.hashes - # Extra rules from https://github.com/github/gitignore/ # Python rules # Byte-compiled / optimized / DLL files diff --git a/.moban.cd/changelog.yml b/.moban.cd/changelog.yml index 9ed1eeb4..4f0ea291 100644 --- a/.moban.cd/changelog.yml +++ b/.moban.cd/changelog.yml @@ -1,6 +1,14 @@ name: moban organisation: moremoban releases: +- changes: + - action: Updated + details: + - '`#18`: file exists test' + - "`#23`: custom jinja plugins" + - '`#26`: repr filter' + date: unreleased + version: 0.2.0 - changes: - action: Updated details: diff --git a/.moban.cd/moban.yml b/.moban.cd/moban.yml index 4694e501..7f770940 100644 --- a/.moban.cd/moban.yml +++ b/.moban.cd/moban.yml @@ -3,8 +3,8 @@ organisation: moremoban author: C. W. contact: wangc_2011@hotmail.com license: MIT -version: 0.1.4 -current_version: 0.1.4 +version: 0.2.0 +current_version: 0.2.0 release: 0.1.4 branch: master command_line_interface: "moban" @@ -15,6 +15,7 @@ keywords: dependencies: - pyyaml>=3.11 - jinja2>=2.7.1 + - lml==0.0.2 - crayons description: Yet another jinja2 cli command for static text generation scm_host: github.com \ No newline at end of file diff --git a/CHANGELOG.rst b/CHANGELOG.rst index a245d228..1c5a4a0e 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -1,6 +1,16 @@ Change log ================================================================================ +0.2.0 - unreleased +-------------------------------------------------------------------------------- + +Updated +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +#. `#18 `_: file exists test +#. `#23 `_: custom jinja plugins +#. `#26 `_: repr filter + 0.1.4 - 29-May-2018 -------------------------------------------------------------------------------- diff --git a/docs/extension.rst b/docs/extension.rst new file mode 100644 index 00000000..ce42902a --- /dev/null +++ b/docs/extension.rst @@ -0,0 +1,32 @@ +Development guide +======================= + +Jinja2 extensions for Moban +------------------------------ + +Since version 0.2, mobanfile supports an extra field `plugin_dir`, along with +`template_dir`. When you put your own jinja2 filters, tests and globals in +your moban repo, you can let moban know about them via this keyword. + +Importantly, you have to have `__init__.py` file in your `plugin_dir`. Otherwise, +your plugins will NOT be loaded. + +Jinja2 Filter +******************* + +.. literalinclude:: ../../moban/filters/repr.py + + +Jinja2 Test +******************* + +.. literalinclude:: ../../moban/tests/files.py + +Jinja2 Globals +******************* + +.. literalinclude:: ../../tests/test_engine.py + :lines: 49-61 + +It is possible to write an installable package including your own jinja2 +filters, tests and globals. Please email me for more details. diff --git a/docs/index.rst b/docs/index.rst index ba219da8..1b693796 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -21,9 +21,17 @@ examples folder. level-4-single-command/README.rst level-5-custom-configuration/README.rst level-6-complex-configuration/README.rst + level-7-use-custom-jinja2-filter-test-n-global/README.rst For more complex use case, please look at `its usage in pyexcel project `_ +Developer Guide +================================================================================ + +.. toctree:: + + extension + .. include:: ../CHANGELOG.rst Indices and tables diff --git a/docs/level-7-use-custom-jinja2-filter-test-n-global/.moban.yml b/docs/level-7-use-custom-jinja2-filter-test-n-global/.moban.yml new file mode 100644 index 00000000..a68e9b8f --- /dev/null +++ b/docs/level-7-use-custom-jinja2-filter-test-n-global/.moban.yml @@ -0,0 +1,10 @@ +configuration: + template_dir: + - my-templates + plugin_dir: + - custom-jj2-plugin + configuration: data.yml +targets: + - filter.output: filter.jj2 + - test.output: test.jj2 + - global.output: global.jj2 \ No newline at end of file diff --git a/docs/level-7-use-custom-jinja2-filter-test-n-global/README.rst b/docs/level-7-use-custom-jinja2-filter-test-n-global/README.rst new file mode 100644 index 00000000..049b7cad --- /dev/null +++ b/docs/level-7-use-custom-jinja2-filter-test-n-global/README.rst @@ -0,0 +1,45 @@ +Level 7: Custom jinja filters, tests and globals +================================================================================ + +Level 7 example demonstrates advanced plugin capabilities of moban. The following +moban file had `plugin_dir` specified:: + + + configuration: + template_dir: + - my-templates + plugin_dir: + - custom-jj2-plugin + configuration: data.yml + targets: + - filter.output: filter.jj2 + - test.output: test.jj2 + +Where `custom-jj2-plugin` is a directory holding all jinja2 filters, tests +and globals. Under it, there are 4 files:: + + __init__.py filter.py test.py global.py + +It is very important to have `__init__.py`, otherwise, it will NOT work. Other three +files are named to show case the feature. You can choose whichever name you prefer, +as long as you and your team could make sense of the names. + + +Evaluation +-------------------------------------------------------------------------------- + +Please go to `docs/level-7-use-custom-jinja2-filter-test-n-global` directory, + +Here is the command to launch it: + +.. code-block:: bash + + $ moban + Templating filter.jj2 to filter.output + Templating test.jj2 to test.output + Templating global.jj2 to global.output + Templated 3 files. + Everything is up to date! + +Please examine individual template and its associated plugin for more details. + diff --git a/docs/level-7-use-custom-jinja2-filter-test-n-global/custom-jj2-plugin/__init__.py b/docs/level-7-use-custom-jinja2-filter-test-n-global/custom-jj2-plugin/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/docs/level-7-use-custom-jinja2-filter-test-n-global/custom-jj2-plugin/filter.py b/docs/level-7-use-custom-jinja2-filter-test-n-global/custom-jj2-plugin/filter.py new file mode 100644 index 00000000..a35b1c76 --- /dev/null +++ b/docs/level-7-use-custom-jinja2-filter-test-n-global/custom-jj2-plugin/filter.py @@ -0,0 +1,13 @@ +import sys +import base64 +from moban.extensions import JinjaFilter + + +@JinjaFilter('base64encode') +def base64_encode(string): + if sys.version_info[0] > 2: + content = base64.b64encode(string.encode('utf-8')) + content = content.decode('utf-8') + else: + content = base64.b64encode(string) + return content diff --git a/docs/level-7-use-custom-jinja2-filter-test-n-global/custom-jj2-plugin/global.py b/docs/level-7-use-custom-jinja2-filter-test-n-global/custom-jj2-plugin/global.py new file mode 100644 index 00000000..a3943ee0 --- /dev/null +++ b/docs/level-7-use-custom-jinja2-filter-test-n-global/custom-jj2-plugin/global.py @@ -0,0 +1,4 @@ +from moban.extensions import jinja_global + + +jinja_global('global', dict(hello='world')) diff --git a/docs/level-7-use-custom-jinja2-filter-test-n-global/custom-jj2-plugin/test.py b/docs/level-7-use-custom-jinja2-filter-test-n-global/custom-jj2-plugin/test.py new file mode 100644 index 00000000..3632afdd --- /dev/null +++ b/docs/level-7-use-custom-jinja2-filter-test-n-global/custom-jj2-plugin/test.py @@ -0,0 +1,6 @@ +from moban.extensions import JinjaTest + + +@JinjaTest('level7') +def test_level7(value): + return value == 'level7' diff --git a/docs/level-7-use-custom-jinja2-filter-test-n-global/data.yml b/docs/level-7-use-custom-jinja2-filter-test-n-global/data.yml new file mode 100644 index 00000000..25ca76fe --- /dev/null +++ b/docs/level-7-use-custom-jinja2-filter-test-n-global/data.yml @@ -0,0 +1,2 @@ +level: level7 +level8: level8 diff --git a/docs/level-7-use-custom-jinja2-filter-test-n-global/filter.output b/docs/level-7-use-custom-jinja2-filter-test-n-global/filter.output new file mode 100644 index 00000000..83ee822d --- /dev/null +++ b/docs/level-7-use-custom-jinja2-filter-test-n-global/filter.output @@ -0,0 +1 @@ +YWJj \ No newline at end of file diff --git a/docs/level-7-use-custom-jinja2-filter-test-n-global/global.output b/docs/level-7-use-custom-jinja2-filter-test-n-global/global.output new file mode 100644 index 00000000..04fea064 --- /dev/null +++ b/docs/level-7-use-custom-jinja2-filter-test-n-global/global.output @@ -0,0 +1 @@ +world \ No newline at end of file diff --git a/docs/level-7-use-custom-jinja2-filter-test-n-global/my-templates/filter.jj2 b/docs/level-7-use-custom-jinja2-filter-test-n-global/my-templates/filter.jj2 new file mode 100644 index 00000000..d6eb5e4d --- /dev/null +++ b/docs/level-7-use-custom-jinja2-filter-test-n-global/my-templates/filter.jj2 @@ -0,0 +1 @@ +{{ 'abc' | base64encode }} \ No newline at end of file diff --git a/docs/level-7-use-custom-jinja2-filter-test-n-global/my-templates/global.jj2 b/docs/level-7-use-custom-jinja2-filter-test-n-global/my-templates/global.jj2 new file mode 100644 index 00000000..2f8b8a71 --- /dev/null +++ b/docs/level-7-use-custom-jinja2-filter-test-n-global/my-templates/global.jj2 @@ -0,0 +1 @@ +{{ global.hello }} \ No newline at end of file diff --git a/docs/level-7-use-custom-jinja2-filter-test-n-global/my-templates/test.jj2 b/docs/level-7-use-custom-jinja2-filter-test-n-global/my-templates/test.jj2 new file mode 100644 index 00000000..f45d5032 --- /dev/null +++ b/docs/level-7-use-custom-jinja2-filter-test-n-global/my-templates/test.jj2 @@ -0,0 +1,11 @@ +{% if level is level7%} +Hello, you are in level 7 example +{% else %} +Hello, you are not in {{level}} +{% endif %} + +{% if level8 is level7%} +Hello, you are in level 7 example +{% else %} +Hello, you are not in level 7 +{% endif %} \ No newline at end of file diff --git a/moban/constants.py b/moban/constants.py index a48f4d84..152c4dbc 100644 --- a/moban/constants.py +++ b/moban/constants.py @@ -20,6 +20,7 @@ # Command line options LABEL_CONFIG = "configuration" LABEL_CONFIG_DIR = "configuration_dir" +LABEL_PLUGIN_DIRS = "plugin_dir" LABEL_TEMPLATE = "template" LABEL_TMPL_DIRS = "template_dir" LABEL_OUTPUT = "output" @@ -68,3 +69,9 @@ HAS_CHANGES = 1 ERROR = 2 NO_CHANGES = 0 + + +# Extension +JINJA_FILTER_EXTENSION = "jinja_filter" +JINJA_TEST_EXTENSION = "jinja_test" +JINJA_GLOBALS_EXTENSION = "jinja_globals" diff --git a/moban/copier.py b/moban/copier.py index e973b6c0..7dd99155 100644 --- a/moban/copier.py +++ b/moban/copier.py @@ -5,6 +5,7 @@ class Copier(object): + def __init__(self, template_dirs): self.template_dirs = template_dirs self._count = 0 @@ -19,7 +20,8 @@ def copy_files(self, file_list): self._count = self._count + 1 else: reporter.report_error_message( - "{0} cannot be found".format(src)) + "{0} cannot be found".format(src) + ) def number_of_copied_files(self): return self._count diff --git a/moban/engine.py b/moban/engine.py index 59a48923..4b0b55b0 100644 --- a/moban/engine.py +++ b/moban/engine.py @@ -3,15 +3,30 @@ from collections import defaultdict from jinja2 import Environment, FileSystemLoader +from lml.loader import scan_plugins + from moban.hashstore import HashStore -from moban.filters.text import split_length -from moban.filters.github import github_expand +from moban.extensions import JinjaFilterManager, JinjaTestManager +from moban.extensions import JinjaGlobalsManager import moban.utils as utils import moban.constants as constants import moban.exceptions as exceptions import moban.reporter as reporter +BUILTIN_EXENSIONS = [ + "moban.filters.repr", + "moban.filters.github", + "moban.filters.text", + "moban.tests.files", +] + +_FILTERS = JinjaFilterManager() +_TESTS = JinjaTestManager() +_GLOBALS = JinjaGlobalsManager() +scan_plugins("moban_", "moban", None, BUILTIN_EXENSIONS) + + class EngineFactory(object): @staticmethod @@ -39,9 +54,17 @@ def __init__(self, template_dirs, context_dirs): trim_blocks=True, lstrip_blocks=True, ) - self.jj2_environment.filters["split_length"] = split_length - self.jj2_environment.filters["github_expand"] = github_expand + for filter_name, filter_function in _FILTERS.get_all(): + self.jj2_environment.filters[filter_name] = filter_function + + for test_name, test_function in _TESTS.get_all(): + self.jj2_environment.tests[test_name] = test_function + + for global_name, helper_obj in _GLOBALS.get_all(): + self.jj2_environment.globals[global_name] = helper_obj.payload + self.context = Context(context_dirs) + self.template_dirs = template_dirs self.hash_store = HashStore() self.__file_count = 0 self.__templated_count = 0 @@ -53,7 +76,7 @@ def render_to_file(self, template_file, data_file, output_file): rendered_content = template.render(**data) utils.write_file_out(output_file, rendered_content) - utils.file_permissions_copy(template_file, output_file) + self._file_permissions_copy(template_file, output_file) def render_to_files(self, array_of_param_tuple): sta = Strategy(array_of_param_tuple) @@ -114,6 +137,14 @@ def _apply_template(self, template, data, output): utils.file_permissions_copy(template.filename, output) return flag + def _file_permissions_copy(self, template_file, output_file): + true_template_file = template_file + for a_template_dir in self.template_dirs: + true_template_file = os.path.join(a_template_dir, template_file) + if os.path.exists(true_template_file): + break + utils.file_permissions_copy(true_template_file, output_file) + class Context(object): diff --git a/moban/extensions.py b/moban/extensions.py new file mode 100644 index 00000000..52d5d0fc --- /dev/null +++ b/moban/extensions.py @@ -0,0 +1,67 @@ +from lml.plugin import PluginManager, PluginInfo +import moban.constants as constants + + +class PluginMixin: + + def get_all(self): + for name in self.registry.keys(): + # only the first matching one is returned + the_filter = self.load_me_now(name) + yield (name, the_filter) + + +class JinjaFilterManager(PluginManager, PluginMixin): + + def __init__(self): + super(JinjaFilterManager, self).__init__( + constants.JINJA_FILTER_EXTENSION + ) + + +class JinjaFilter(PluginInfo): + + def __init__(self, filter_name): + super(JinjaFilter, self).__init__( + constants.JINJA_FILTER_EXTENSION, tags=[filter_name] + ) + + +class JinjaTestManager(PluginManager, PluginMixin): + + def __init__(self): + super(JinjaTestManager, self).__init__(constants.JINJA_TEST_EXTENSION) + + +class JinjaTest(PluginInfo): + + def __init__(self, test_name): + super(JinjaTest, self).__init__( + constants.JINJA_TEST_EXTENSION, tags=[test_name] + ) + + +def jinja_tests(**keywords): + for key, value in keywords.items(): + JinjaTest(key)(value) + + +class JinjaGlobalsManager(PluginManager, PluginMixin): + + def __init__(self): + super(JinjaGlobalsManager, self).__init__( + constants.JINJA_GLOBALS_EXTENSION + ) + + +class PluginHelper(object): + + def __init__(self, identifier, payload_obj): + self.payload = payload_obj + self.__name__ = identifier + + +def jinja_global(identifier, dict_obj): + plugin = PluginInfo(constants.JINJA_GLOBALS_EXTENSION, tags=[identifier]) + helper = PluginHelper(identifier, dict_obj) + plugin(helper) diff --git a/moban/filters/github.py b/moban/filters/github.py index da111eef..96cf47a3 100644 --- a/moban/filters/github.py +++ b/moban/filters/github.py @@ -1,4 +1,6 @@ import re +from moban.extensions import JinjaFilter + GITHUB_REF_PATTERN = "`([^`]*?#[0-9]+)`" ISSUE = "^.*?" + GITHUB_REF_PATTERN + ".*?$" @@ -9,6 +11,7 @@ ISSUES = "issues" +@JinjaFilter("github_expand") def github_expand(line, name, organisation): result = re.match(ISSUE, line) if result: diff --git a/moban/filters/repr.py b/moban/filters/repr.py new file mode 100644 index 00000000..f518e9ae --- /dev/null +++ b/moban/filters/repr.py @@ -0,0 +1,9 @@ +from moban.extensions import JinjaFilter + + +@JinjaFilter("repr") +def repr_function(string): + if isinstance(string, list): + return ["'{0}'".format(str(element)) for element in string] + else: + return "'{0}'".format(str(string)) diff --git a/moban/filters/text.py b/moban/filters/text.py index 8e976576..3b6c8f6d 100644 --- a/moban/filters/text.py +++ b/moban/filters/text.py @@ -1,6 +1,8 @@ import re +from moban.extensions import JinjaFilter +@JinjaFilter("split_length") def split_length(input_line, length): start = 0 limit = length diff --git a/moban/hashstore.py b/moban/hashstore.py index 08d78c3b..5d7129f9 100644 --- a/moban/hashstore.py +++ b/moban/hashstore.py @@ -63,8 +63,6 @@ def get_file_hash(afile): def get_hash(content): md5 = hashlib.md5() - if PY2: - content = content.decode("utf-8") md5.update(content) return md5.digest().decode("latin1") diff --git a/moban/main.py b/moban/main.py index 708df99a..bb3a5f70 100644 --- a/moban/main.py +++ b/moban/main.py @@ -106,8 +106,10 @@ def handle_moban_file(moban_file, options): raise exceptions.MobanfileGrammarException( constants.ERROR_INVALID_MOBAN_FILE % moban_file ) - if (constants.LABEL_TARGETS not in moban_file_configurations and - constants.LABEL_COPY not in moban_file_configurations): + if ( + constants.LABEL_TARGETS not in moban_file_configurations + and constants.LABEL_COPY not in moban_file_configurations + ): raise exceptions.MobanfileGrammarException( constants.ERROR_NO_TARGETS % moban_file ) diff --git a/moban/mobanfile.py b/moban/mobanfile.py index bf9559de..43fcd1dd 100644 --- a/moban/mobanfile.py +++ b/moban/mobanfile.py @@ -1,4 +1,9 @@ import os +import re +import sys + +from lml.utils import do_import + import moban.constants as constants import moban.reporter as reporter from moban.engine import EngineFactory @@ -23,9 +28,7 @@ def handle_copy(template_dirs, copy_config): def handle_targets(merged_options, targets): - list_of_templating_parameters = parse_targets( - merged_options, targets, - ) + list_of_templating_parameters = parse_targets(merged_options, targets) engine_class = EngineFactory.get_engine( merged_options[constants.LABEL_TEMPLATE_TYPE] ) @@ -38,6 +41,19 @@ def handle_targets(merged_options, targets): return engine.number_of_templated_files() +def handle_plugin_dirs(plugin_dirs): + for plugin_dir in plugin_dirs: + plugin_path = os.path.dirname(os.path.abspath(plugin_dir)) + if plugin_path not in sys.path: + sys.path.append(plugin_path) + pysearchre = re.compile(".py$", re.IGNORECASE) + pluginfiles = filter(pysearchre.search, os.listdir(plugin_dir)) + plugins = list(map(lambda fp: os.path.splitext(fp)[0], pluginfiles)) + for plugin in plugins: + plugin_module = os.path.basename(plugin_dir) + "." + plugin + do_import(plugin_module) + + def handle_moban_file_v1(moban_file_configurations, command_line_options): merged_options = None if constants.LABEL_CONFIG in moban_file_configurations: @@ -46,6 +62,9 @@ def handle_moban_file_v1(moban_file_configurations, command_line_options): moban_file_configurations[constants.LABEL_CONFIG], ) merged_options = merge(command_line_options, constants.DEFAULT_OPTIONS) + plugins_dirs = merged_options.get(constants.LABEL_PLUGIN_DIRS) + if plugins_dirs: + handle_plugin_dirs(plugins_dirs) targets = moban_file_configurations.get(constants.LABEL_TARGETS) if targets: @@ -56,7 +75,7 @@ def handle_moban_file_v1(moban_file_configurations, command_line_options): if constants.LABEL_COPY in moban_file_configurations: number_of_copied_files = handle_copy( merged_options[constants.LABEL_TMPL_DIRS], - moban_file_configurations[constants.LABEL_COPY] + moban_file_configurations[constants.LABEL_COPY], ) else: number_of_copied_files = 0 diff --git a/moban/tests/__init__.py b/moban/tests/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/moban/tests/files.py b/moban/tests/files.py new file mode 100644 index 00000000..27ebc0d2 --- /dev/null +++ b/moban/tests/files.py @@ -0,0 +1,23 @@ +from os.path import isdir, isfile, isabs, exists +from os.path import lexists, islink, samefile, ismount + +from moban.extensions import jinja_tests + + +jinja_tests( + is_dir=isdir, + directory=isdir, + is_file=isfile, + file=isfile, + is_link=islink, + link=islink, + exists=exists, + link_exists=lexists, + # path testing + is_abs=isabs, + abs=isabs, + is_same_file=samefile, + same_file=samefile, + is_mount=ismount, + mount=ismount, +) diff --git a/mobanfile b/mobanfile index b5256ad1..473e29d2 100644 --- a/mobanfile +++ b/mobanfile @@ -3,6 +3,8 @@ configuration: - "setupmobans/templates" - ".moban.d" configuration: moban.yml + plugin_dir: + - "setupmobans/plugins" targets: - setup.py: setup.py - .travis.yml: travis.yml diff --git a/requirements.txt b/requirements.txt index 2c04399c..217e4314 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,3 +1,4 @@ pyyaml>=3.11 jinja2>=2.7.1 +lml==0.0.2 crayons diff --git a/setup.py b/setup.py index 90d9d2fe..f6a7990a 100644 --- a/setup.py +++ b/setup.py @@ -11,7 +11,7 @@ NAME = 'moban' AUTHOR = 'C. W.' -VERSION = '0.1.4' +VERSION = '0.2.0' EMAIL = 'wangc_2011@hotmail.com' LICENSE = 'MIT' ENTRY_POINTS = { @@ -46,6 +46,7 @@ INSTALL_REQUIRES = [ 'pyyaml>=3.11', 'jinja2>=2.7.1', + 'lml==0.0.2', 'crayons', ] SETUP_COMMANDS = {} diff --git a/tests/fixtures/globals/basic.template b/tests/fixtures/globals/basic.template new file mode 100644 index 00000000..a71a3726 --- /dev/null +++ b/tests/fixtures/globals/basic.template @@ -0,0 +1,3 @@ +{{ test.hello }} + +{{ globals }} \ No newline at end of file diff --git a/tests/fixtures/globals/basic.yml b/tests/fixtures/globals/basic.yml new file mode 100644 index 00000000..4f804496 --- /dev/null +++ b/tests/fixtures/globals/basic.yml @@ -0,0 +1 @@ +globals: test \ No newline at end of file diff --git a/tests/fixtures/jinja_tests/file_tests.template b/tests/fixtures/jinja_tests/file_tests.template new file mode 100644 index 00000000..3f216230 --- /dev/null +++ b/tests/fixtures/jinja_tests/file_tests.template @@ -0,0 +1,6 @@ +{% if 'tests/fixtures/jinja_tests/file_tests.template' is exists %} +yes +{%else%} +no +{% endif %} +{{ test }} \ No newline at end of file diff --git a/tests/fixtures/jinja_tests/file_tests.yml b/tests/fixtures/jinja_tests/file_tests.yml new file mode 100644 index 00000000..a0067b10 --- /dev/null +++ b/tests/fixtures/jinja_tests/file_tests.yml @@ -0,0 +1 @@ +test: here \ No newline at end of file diff --git a/tests/test_copier.py b/tests/test_copier.py index 2589a79c..4d6034e8 100644 --- a/tests/test_copier.py +++ b/tests/test_copier.py @@ -17,34 +17,27 @@ def tearDown(self): @patch("moban.reporter.report_copying") def test_copy_files(self, reporter): copier = Copier([os.path.join("tests", "fixtures")]) - file_list = [{ - "/tmp/test": "copier-test01.csv" - }] + file_list = [{"/tmp/test": "copier-test01.csv"}] copier.copy_files(file_list) self.fake_copy.assert_called() @patch("moban.reporter.report_error_message") def test_copy_files_file_not_found(self, reporter): copier = Copier([os.path.join("tests", "fixtures")]) - file_list = [{ - "/tmp/test": "copier-test-not-found.csv" - }] + file_list = [{"/tmp/test": "copier-test-not-found.csv"}] copier.copy_files(file_list) reporter.assert_called_with( - "copier-test-not-found.csv cannot be found") + "copier-test-not-found.csv cannot be found" + ) def test_number_of_files(self): copier = Copier([os.path.join("tests", "fixtures")]) - file_list = [{ - "/tmp/test": "copier-test01.csv" - }] + file_list = [{"/tmp/test": "copier-test01.csv"}] copier.copy_files(file_list) eq_(copier.number_of_copied_files(), 1) def test_handle_copy(self): tmpl_dirs = [os.path.join("tests", "fixtures")] - copy_config = [{ - "/tmp/test": "copier-test01.csv" - }] + copy_config = [{"/tmp/test": "copier-test01.csv"}] count = handle_copy(tmpl_dirs, copy_config) eq_(count, 1) diff --git a/tests/test_docs.py b/tests/test_docs.py index c46e897e..12e6dddf 100644 --- a/tests/test_docs.py +++ b/tests/test_docs.py @@ -1,5 +1,8 @@ import os import sys + +from nose.tools import eq_ + from mock import patch from moban.main import main @@ -76,6 +79,14 @@ def test_level_6(self): folder = "level-6-complex-configuration" self._raw_moban(["moban"], folder, expected, "a.output2") + def test_level_7(self): + expected = """Hello, you are in level 7 example + +Hello, you are not in level 7 +""" + folder = "level-7-use-custom-jinja2-filter-test-n-global" + self._raw_moban(["moban"], folder, expected, "test.output") + def _moban(self, folder, expected): args = ["moban", "-c", "data.yml", "-t", "a.template"] self._raw_moban(args, folder, expected, "moban.output") @@ -96,4 +107,4 @@ def tearDown(self): def _verify_content(file_name, expected): with open(file_name, "r") as f: content = f.read() - assert content == expected + eq_(content, expected) diff --git a/tests/test_engine.py b/tests/test_engine.py index bd04bfdc..26f60552 100644 --- a/tests/test_engine.py +++ b/tests/test_engine.py @@ -1,6 +1,8 @@ -from nose.tools import raises +import os +from nose.tools import raises, eq_ from moban.engine import EngineFactory, Engine, Context import moban.exceptions as exceptions +from moban.extensions import jinja_global def test_default_template_type(): @@ -31,3 +33,27 @@ def test_non_existent_config_directries(): @raises(exceptions.DirectoryNotFound) def test_non_existent_ctx_directries(): Context(["abc"]) + + +def test_file_tests(): + output = "test.txt" + path = os.path.join("tests", "fixtures", "jinja_tests") + engine = Engine([path], path) + engine.render_to_file("file_tests.template", "file_tests.yml", output) + with open(output, "r") as output_file: + content = output_file.read() + eq_(content, "yes\nhere") + os.unlink(output) + + +def test_globals(): + output = "globals.txt" + test_dict = dict(hello="world") + jinja_global("test", test_dict) + path = os.path.join("tests", "fixtures", "globals") + engine = Engine([path], path) + engine.render_to_file("basic.template", "basic.yml", output) + with open(output, "r") as output_file: + content = output_file.read() + eq_(content, "world\n\ntest") + os.unlink(output) diff --git a/tests/test_filter_repr.py b/tests/test_filter_repr.py new file mode 100644 index 00000000..02a62bce --- /dev/null +++ b/tests/test_filter_repr.py @@ -0,0 +1,14 @@ +from moban.filters.repr import repr_function +from nose.tools import eq_ + + +def test_string(): + me = "abc" + expected = repr_function(me) + eq_(expected, "'abc'") + + +def test_list(): + me = [1, 2, 3] + expected = repr_function(me) + eq_(expected, ["'1'", "'2'", "'3'"])