Mypal/taskcluster/taskgraph/test/test_util_templates.py

233 lines
5.8 KiB
Python

# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
from __future__ import absolute_import, print_function, unicode_literals
import unittest
import mozunit
import textwrap
from taskgraph.util.templates import (
merge_to,
merge,
Templates,
TemplatesException
)
files = {}
files['/fixtures/circular.yml'] = textwrap.dedent("""\
$inherits:
from: 'circular_ref.yml'
variables:
woot: 'inherit'
""")
files['/fixtures/inherit.yml'] = textwrap.dedent("""\
$inherits:
from: 'templates.yml'
variables:
woot: 'inherit'
""")
files['/fixtures/extend_child.yml'] = textwrap.dedent("""\
list: ['1', '2', '3']
was_list: ['1']
obj:
level: 1
deeper:
woot: 'bar'
list: ['baz']
""")
files['/fixtures/circular_ref.yml'] = textwrap.dedent("""\
$inherits:
from: 'circular.yml'
""")
files['/fixtures/child_pass.yml'] = textwrap.dedent("""\
values:
- {{a}}
- {{b}}
- {{c}}
""")
files['/fixtures/inherit_pass.yml'] = textwrap.dedent("""\
$inherits:
from: 'child_pass.yml'
variables:
a: 'a'
b: 'b'
c: 'c'
""")
files['/fixtures/deep/2.yml'] = textwrap.dedent("""\
$inherits:
from: deep/1.yml
""")
files['/fixtures/deep/3.yml'] = textwrap.dedent("""\
$inherits:
from: deep/2.yml
""")
files['/fixtures/deep/4.yml'] = textwrap.dedent("""\
$inherits:
from: deep/3.yml
""")
files['/fixtures/deep/1.yml'] = textwrap.dedent("""\
variable: {{value}}
""")
files['/fixtures/simple.yml'] = textwrap.dedent("""\
is_simple: true
""")
files['/fixtures/templates.yml'] = textwrap.dedent("""\
content: 'content'
variable: '{{woot}}'
""")
files['/fixtures/extend_parent.yml'] = textwrap.dedent("""\
$inherits:
from: 'extend_child.yml'
list: ['4']
was_list:
replaced: true
obj:
level: 2
from_parent: true
deeper:
list: ['bar']
""")
class TemplatesTest(unittest.TestCase):
def setUp(self):
self.mocked_open = mozunit.MockedOpen(files)
self.mocked_open.__enter__()
self.subject = Templates('/fixtures')
def tearDown(self):
self.mocked_open.__exit__(None, None, None)
def test_invalid_path(self):
with self.assertRaisesRegexp(TemplatesException, 'must be a directory'):
Templates('/zomg/not/a/dir')
def test_no_templates(self):
content = self.subject.load('simple.yml', {})
self.assertEquals(content, {
'is_simple': True
})
def test_with_templates(self):
content = self.subject.load('templates.yml', {
'woot': 'bar'
})
self.assertEquals(content, {
'content': 'content',
'variable': 'bar'
})
def test_inheritance(self):
'''
The simple single pass inheritance case.
'''
content = self.subject.load('inherit.yml', {})
self.assertEqual(content, {
'content': 'content',
'variable': 'inherit'
})
def test_inheritance_implicat_pass(self):
'''
Implicitly pass parameters from the child to the ancestor.
'''
content = self.subject.load('inherit_pass.yml', {
'a': 'overriden'
})
self.assertEqual(content, {'values': ['overriden', 'b', 'c']})
def test_inheritance_circular(self):
'''
Circular reference handling.
'''
with self.assertRaisesRegexp(TemplatesException, 'circular'):
self.subject.load('circular.yml', {})
def test_deep_inheritance(self):
content = self.subject.load('deep/4.yml', {
'value': 'myvalue'
})
self.assertEqual(content, {'variable': 'myvalue'})
def test_inheritance_with_simple_extensions(self):
content = self.subject.load('extend_parent.yml', {})
self.assertEquals(content, {
'list': ['1', '2', '3', '4'],
'obj': {
'from_parent': True,
'deeper': {
'woot': 'bar',
'list': ['baz', 'bar']
},
'level': 2,
},
'was_list': {'replaced': True}
})
class MergeTest(unittest.TestCase):
def test_merge_to_dicts(self):
source = {'a': 1, 'b': 2}
dest = {'b': '20', 'c': 30}
expected = {
'a': 1, # source only
'b': 2, # source overrides dest
'c': 30, # dest only
}
self.assertEqual(merge_to(source, dest), expected)
self.assertEqual(dest, expected)
def test_merge_to_lists(self):
source = {'x': [3, 4]}
dest = {'x': [1, 2]}
expected = {'x': [1, 2, 3, 4]} # dest first
self.assertEqual(merge_to(source, dest), expected)
self.assertEqual(dest, expected)
def test_merge_diff_types(self):
source = {'x': [1, 2]}
dest = {'x': 'abc'}
expected = {'x': [1, 2]} # source wins
self.assertEqual(merge_to(source, dest), expected)
self.assertEqual(dest, expected)
def test_merge(self):
first = {'a': 1, 'b': 2, 'd': 11}
second = {'b': 20, 'c': 30}
third = {'c': 300, 'd': 400}
expected = {
'a': 1,
'b': 20,
'c': 300,
'd': 400,
}
self.assertEqual(merge(first, second, third), expected)
# inputs haven't changed..
self.assertEqual(first, {'a': 1, 'b': 2, 'd': 11})
self.assertEqual(second, {'b': 20, 'c': 30})
self.assertEqual(third, {'c': 300, 'd': 400})
if __name__ == '__main__':
mozunit.main()