From 417bf1c80534e2de2ccb9e5e0b6fd13a6e0b5654 Mon Sep 17 00:00:00 2001 From: Toshio Kuratomi Date: Wed, 2 Sep 2015 08:52:03 -0700 Subject: [PATCH] Unittest the _count_trailing_newlines function --- lib/ansible/template/__init__.py | 34 +++++++++---------- ...ackslash.py => test_template_utilities.py} | 29 +++++++++++++++- 2 files changed, 45 insertions(+), 18 deletions(-) rename test/units/template/{test_jinja_backslash.py => test_template_utilities.py} (74%) diff --git a/lib/ansible/template/__init__.py b/lib/ansible/template/__init__.py index f805223d7dd..190948bb0f2 100644 --- a/lib/ansible/template/__init__.py +++ b/lib/ansible/template/__init__.py @@ -90,6 +90,21 @@ def _preserve_backslashes(data, jinja_env): return data +def _count_newlines_from_end(in_str): + ''' + Counts the number of newlines at the end of a string. This is used during + the jinja2 templating to ensure the count matches the input, since some newlines + may be thrown away during the templating. + ''' + + i = len(in_str) + while i > 0: + if in_str[i-1] != '\n': + break + i -= 1 + + return len(in_str) - i + class Templar: ''' The main class for templating, with the main entry-point of template(). @@ -130,21 +145,6 @@ class Templar: self.SINGLE_VAR = re.compile(r"^%s\s*(\w*)\s*%s$" % (self.environment.variable_start_string, self.environment.variable_end_string)) - def _count_newlines_from_end(self, in_str): - ''' - Counts the number of newlines at the end of a string. This is used during - the jinja2 templating to ensure the count matches the input, since some newlines - may be thrown away during the templating. - ''' - - i = len(in_str) - while i > 0: - if in_str[i-1] != '\n': - break - i -= 1 - - return len(in_str) - i - def _get_filters(self): ''' Returns filter plugins, after loading and caching them if need be @@ -318,7 +318,7 @@ class Templar: # For preserving the number of input newlines in the output (used # later in this method) - data_newlines = self._count_newlines_from_end(data) + data_newlines = _count_newlines_from_end(data) if fail_on_undefined is None: fail_on_undefined = self._fail_on_undefined_errors @@ -389,7 +389,7 @@ class Templar: # that version being present, modify our code to set that when # initializing self.environment and remove a single trailing # newline here if preserve_newlines is False. - res_newlines = self._count_newlines_from_end(res) + res_newlines = _count_newlines_from_end(res) if data_newlines > res_newlines: res += '\n' * (data_newlines - res_newlines) diff --git a/test/units/template/test_jinja_backslash.py b/test/units/template/test_template_utilities.py similarity index 74% rename from test/units/template/test_jinja_backslash.py rename to test/units/template/test_template_utilities.py index 58e4d0f47be..2f85a2f3b19 100644 --- a/test/units/template/test_jinja_backslash.py +++ b/test/units/template/test_template_utilities.py @@ -22,8 +22,10 @@ __metaclass__ = type import jinja2 from ansible.compat.tests import unittest -from ansible.template import _preserve_backslashes +from ansible.template import _preserve_backslashes, _count_newlines_from_end +# These are internal utility functions only needed for templating. They're +# algorithmic so good candidates for unittesting by themselves class TestBackslashEscape(unittest.TestCase): @@ -83,3 +85,28 @@ class TestBackslashEscape(unittest.TestCase): args = test['args'] self.assertEquals(template.render(**args), test['expectation']) +class TestCountNewlines(unittest.TestCase): + + def setUp(self): + pass + + def tearDown(self): + pass + + def test_short_string(self): + self.assertEquals(_count_newlines_from_end('The quick\n'), 1) + + def test_one_newline(self): + self.assertEquals(_count_newlines_from_end('The quick brown fox jumped over the lazy dog' * 1000 + '\n'), 1) + + def test_multiple_newlines(self): + self.assertEquals(_count_newlines_from_end('The quick brown fox jumped over the lazy dog' * 1000 + '\n\n\n'), 3) + + def test_zero_newlines(self): + self.assertEquals(_count_newlines_from_end('The quick brown fox jumped over the lazy dog' * 1000 + '\n\n\n'), 3) + + def test_all_newlines(self): + self.assertEquals(_count_newlines_from_end('\n' * 10), 10) + + def test_mostly_newlines(self): + self.assertEquals(_count_newlines_from_end('The quick brown fox jumped over the lazy dog' + '\n' * 1000), 1000)