[mathstuff] Get coverage into the 90% range (#68395)
Signed-off-by: Rick Elrod <rick@elrod.me>
This commit is contained in:
parent
913ee9119a
commit
01638e0ea2
2 changed files with 240 additions and 3 deletions
|
@ -209,7 +209,7 @@ def rekey_on_member(data, key, duplicates='error'):
|
||||||
raise AnsibleFilterError(to_native(e))
|
raise AnsibleFilterError(to_native(e))
|
||||||
|
|
||||||
# Note: if new_obj[key_elem] exists it will always be a non-empty dict (it will at
|
# Note: if new_obj[key_elem] exists it will always be a non-empty dict (it will at
|
||||||
# minimun contain {key: key_elem}
|
# minimum contain {key: key_elem}
|
||||||
if new_obj.get(key_elem, None):
|
if new_obj.get(key_elem, None):
|
||||||
if duplicates == 'error':
|
if duplicates == 'error':
|
||||||
raise AnsibleFilterError("Key {0} is not unique, cannot correctly turn into dict".format(key_elem))
|
raise AnsibleFilterError("Key {0} is not unique, cannot correctly turn into dict".format(key_elem))
|
||||||
|
|
|
@ -1,5 +1,179 @@
|
||||||
|
- name: Verify unique's fallback's exception throwing for case_sensitive=True
|
||||||
|
set_fact:
|
||||||
|
unique_fallback_exc1: '{{ [{"foo": "bar", "moo": "cow"}]|unique(case_sensitive=True) }}'
|
||||||
|
ignore_errors: true
|
||||||
|
tags: unique
|
||||||
|
register: unique_fallback_exc1_res
|
||||||
|
|
||||||
|
- name: Verify unique's fallback's exception throwing for a Hashable thing that triggers TypeError
|
||||||
|
set_fact:
|
||||||
|
unique_fallback_exc2: '{{ True|unique }}'
|
||||||
|
ignore_errors: true
|
||||||
|
tags: unique
|
||||||
|
register: unique_fallback_exc2_res
|
||||||
|
|
||||||
|
- name: Verify unique
|
||||||
|
tags: unique
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- '[1,2,3,4,4,3,2,1]|unique == [1,2,3,4]'
|
||||||
|
- '["a", "b", "a", "b"]|unique == ["a", "b"]'
|
||||||
|
- '[{"foo": "bar", "moo": "cow"}, {"foo": "bar", "moo": "cow"}, {"haha": "bar", "moo": "mar"}]|unique == [{"foo": "bar", "moo": "cow"}, {"haha": "bar", "moo": "mar"}]'
|
||||||
|
- '[{"foo": "bar", "moo": "cow"}, {"foo": "bar", "moo": "mar"}]|unique == [{"foo": "bar", "moo": "cow"}, {"foo": "bar", "moo": "mar"}]'
|
||||||
|
- '{"foo": "bar", "moo": "cow"}|unique == ["foo", "moo"]'
|
||||||
|
- '"foo"|unique|sort|join == "fo"'
|
||||||
|
- '[1,2,3,4,5]|unique == [1,2,3,4,5]'
|
||||||
|
- unique_fallback_exc1_res is failed
|
||||||
|
- unique_fallback_exc2_res is failed
|
||||||
|
- "\"'bool' object is not iterable\" in unique_fallback_exc2_res.msg"
|
||||||
|
|
||||||
|
# `unique` will fall back to a custom implementation if the Jinja2 version is
|
||||||
|
# too old to support `jinja2.filters.do_unique`. However, the built-in fallback
|
||||||
|
# is quite different by default. Namely, it ignores the case-sensitivity
|
||||||
|
# setting. This means running:
|
||||||
|
# ['a', 'b', 'A', 'B']|unique
|
||||||
|
# ... will give a different result for someone running Jinja 2.9 vs 2.10 when
|
||||||
|
# do_unique was added. So here, we do a test to see if we have `do_unique`. If
|
||||||
|
# we do, then we do another test to make sure attribute and case_sensitive
|
||||||
|
# work on it.
|
||||||
|
- name: Test for do_unique
|
||||||
|
shell: "{{ansible_python_interpreter}} -c 'from jinja2 import filters; print(\"do_unique\" in dir(filters))'"
|
||||||
|
tags: unique
|
||||||
|
register: do_unique_res
|
||||||
|
|
||||||
|
- name: Verify unique some more
|
||||||
|
tags: unique
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- '["a", "b", "A", "B"]|unique(case_sensitive=True) == ["a", "b", "A", "B"]'
|
||||||
|
- '[{"foo": "bar", "moo": "cow"}, {"foo": "bar", "moo": "mar"}]|unique(attribute="foo") == [{"foo": "bar", "moo": "cow"}]'
|
||||||
|
- '["a", "b", "A", "B"]|unique == ["a", "b"]' # defaults to case_sensitive=False
|
||||||
|
- "'cannot fall back' in unique_fallback_exc1_res.msg"
|
||||||
|
when: do_unique_res.stdout == 'True'
|
||||||
|
|
||||||
|
- name: Verify unique some more
|
||||||
|
tags: unique
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- "'does not support case_sensitive' in unique_fallback_exc1_res.msg"
|
||||||
|
when: do_unique_res.stdout == 'False'
|
||||||
|
|
||||||
|
- name: Verify intersect
|
||||||
|
tags: intersect
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- '[1,2,3]|intersect([4,5,6]) == []'
|
||||||
|
- '[1,2,3]|intersect([3,4,5,6]) == [3]'
|
||||||
|
- '[1,2,3]|intersect([3,2,1]) == [1,2,3]'
|
||||||
|
- '(1,2,3)|intersect((4,5,6))|list == []'
|
||||||
|
- '(1,2,3)|intersect((3,4,5,6))|list == [3]'
|
||||||
|
|
||||||
|
- name: Verify difference
|
||||||
|
tags: difference
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- '[1,2,3]|difference([4,5,6]) == [1,2,3]'
|
||||||
|
- '[1,2,3]|difference([3,4,5,6]) == [1,2]'
|
||||||
|
- '[1,2,3]|difference([3,2,1]) == []'
|
||||||
|
- '(1,2,3)|difference((4,5,6))|list == [1,2,3]'
|
||||||
|
- '(1,2,3)|difference((3,4,5,6))|list == [1,2]'
|
||||||
|
|
||||||
|
- name: Verify symmetric_difference
|
||||||
|
tags: symmetric_difference
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- '[1,2,3]|symmetric_difference([4,5,6]) == [1,2,3,4,5,6]'
|
||||||
|
- '[1,2,3]|symmetric_difference([3,4,5,6]) == [1,2,4,5,6]'
|
||||||
|
- '[1,2,3]|symmetric_difference([3,2,1]) == []'
|
||||||
|
- '(1,2,3)|symmetric_difference((4,5,6))|list == [1,2,3,4,5,6]'
|
||||||
|
- '(1,2,3)|symmetric_difference((3,4,5,6))|list == [1,2,4,5,6]'
|
||||||
|
|
||||||
|
- name: Verify union
|
||||||
|
tags: union
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- '[1,2,3]|union([4,5,6]) == [1,2,3,4,5,6]'
|
||||||
|
- '[1,2,3]|union([3,4,5,6]) == [1,2,3,4,5,6]'
|
||||||
|
- '[1,2,3]|union([3,2,1]) == [1,2,3]'
|
||||||
|
- '(1,2,3)|union((4,5,6))|list == [1,2,3,4,5,6]'
|
||||||
|
- '(1,2,3)|union((3,4,5,6))|list == [1,2,3,4,5,6]'
|
||||||
|
|
||||||
|
- name: Verify min
|
||||||
|
tags: min
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- '[1000,-99]|min == -99'
|
||||||
|
- '[0,4]|min == 0'
|
||||||
|
|
||||||
|
- name: Verify max
|
||||||
|
tags: max
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- '[1000,-99]|max == 1000'
|
||||||
|
- '[0,4]|max == 4'
|
||||||
|
|
||||||
|
- name: Verify logarithm on a value of invalid type
|
||||||
|
set_fact:
|
||||||
|
logarithm_exc1: '{{ "yo"|log }}'
|
||||||
|
ignore_errors: true
|
||||||
|
tags: logarithm
|
||||||
|
register: logarithm_exc1_res
|
||||||
|
|
||||||
|
- name: Verify logarithm (which is passed to Jinja as "log" because consistency is boring)
|
||||||
|
tags: logarithm
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- '1|log == 0.0'
|
||||||
|
- '100|log(10) == 2.0'
|
||||||
|
- '100|log(10) == 2.0'
|
||||||
|
- '21|log(21) == 1.0'
|
||||||
|
- '(2.3|log(42)|string).startswith("0.222841")'
|
||||||
|
- '(21|log(42)|string).startswith("0.814550")'
|
||||||
|
- logarithm_exc1_res is failed
|
||||||
|
- '"can only be used on numbers" in logarithm_exc1_res.msg'
|
||||||
|
|
||||||
|
- name: Verify power on a value of invalid type
|
||||||
|
set_fact:
|
||||||
|
power_exc1: '{{ "yo"|pow(4) }}'
|
||||||
|
ignore_errors: true
|
||||||
|
tags: power
|
||||||
|
register: power_exc1_res
|
||||||
|
|
||||||
|
- name: Verify power (which is passed to Jinja as "pow" because consistency is boring)
|
||||||
|
tags: power
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- '2|pow(4) == 16.0'
|
||||||
|
- power_exc1_res is failed
|
||||||
|
- '"can only be used on numbers" in power_exc1_res.msg'
|
||||||
|
|
||||||
|
- name: Verify inversepower on a value of invalid type
|
||||||
|
set_fact:
|
||||||
|
inversepower_exc1: '{{ "yo"|root }}'
|
||||||
|
ignore_errors: true
|
||||||
|
tags: inversepower
|
||||||
|
register: inversepower_exc1_res
|
||||||
|
|
||||||
|
- name: Verify inversepower (which is passed to Jinja as "root" because consistency is boring)
|
||||||
|
tags: inversepower
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- '4|root == 2.0'
|
||||||
|
- '4|root(2) == 2.0'
|
||||||
|
- '9|root(1) == 9.0'
|
||||||
|
- '(9|root(6)|string).startswith("1.4422495")'
|
||||||
|
- inversepower_exc1_res is failed
|
||||||
|
- '"can only be used on numbers" in inversepower_exc1_res.msg'
|
||||||
|
|
||||||
|
- name: Verify human_readable on invalid input
|
||||||
|
set_fact:
|
||||||
|
human_readable_exc1: '{{ "monkeys"|human_readable }}'
|
||||||
|
ignore_errors: true
|
||||||
|
tags: human_readable
|
||||||
|
register: human_readable_exc1_res
|
||||||
|
|
||||||
- name: Verify human_readable
|
- name: Verify human_readable
|
||||||
tags: "human_readable"
|
tags: human_readable
|
||||||
assert:
|
assert:
|
||||||
that:
|
that:
|
||||||
- '"1.00 Bytes" == 1|human_readable'
|
- '"1.00 Bytes" == 1|human_readable'
|
||||||
|
@ -8,9 +182,11 @@
|
||||||
- '"97.66 MB" == 102400000|human_readable'
|
- '"97.66 MB" == 102400000|human_readable'
|
||||||
- '"0.10 GB" == 102400000|human_readable(unit="G")'
|
- '"0.10 GB" == 102400000|human_readable(unit="G")'
|
||||||
- '"0.10 Gb" == 102400000|human_readable(isbits=True, unit="G")'
|
- '"0.10 Gb" == 102400000|human_readable(isbits=True, unit="G")'
|
||||||
|
- human_readable_exc1_res is failed
|
||||||
|
- '"interpret following string" in human_readable_exc1_res.msg'
|
||||||
|
|
||||||
- name: Verify human_to_bytes
|
- name: Verify human_to_bytes
|
||||||
tags: "human_to_bytes"
|
tags: human_to_bytes
|
||||||
assert:
|
assert:
|
||||||
that:
|
that:
|
||||||
- "{{'0'|human_to_bytes}} == 0"
|
- "{{'0'|human_to_bytes}} == 0"
|
||||||
|
@ -35,6 +211,7 @@
|
||||||
that: "{{_human_bytes_test.failed}}"
|
that: "{{_human_bytes_test.failed}}"
|
||||||
|
|
||||||
- name: Verify that union can be chained
|
- name: Verify that union can be chained
|
||||||
|
tags: union
|
||||||
vars:
|
vars:
|
||||||
unions: '{{ [1,2,3]|union([4,5])|union([6,7]) }}'
|
unions: '{{ [1,2,3]|union([4,5])|union([6,7]) }}'
|
||||||
assert:
|
assert:
|
||||||
|
@ -43,9 +220,69 @@
|
||||||
- "unions|length == 7"
|
- "unions|length == 7"
|
||||||
|
|
||||||
- name: Test union with unhashable item
|
- name: Test union with unhashable item
|
||||||
|
tags: union
|
||||||
vars:
|
vars:
|
||||||
unions: '{{ [1,2,3]|union([{}]) }}'
|
unions: '{{ [1,2,3]|union([{}]) }}'
|
||||||
assert:
|
assert:
|
||||||
that:
|
that:
|
||||||
- "unions|type_debug == 'list'"
|
- "unions|type_debug == 'list'"
|
||||||
- "unions|length == 4"
|
- "unions|length == 4"
|
||||||
|
|
||||||
|
- name: Verify rekey_on_member with invalid "duplicates" kwarg
|
||||||
|
set_fact:
|
||||||
|
rekey_on_member_exc1: '{{ []|rekey_on_member("asdf", duplicates="boo") }}'
|
||||||
|
ignore_errors: true
|
||||||
|
tags: rekey_on_member
|
||||||
|
register: rekey_on_member_exc1_res
|
||||||
|
|
||||||
|
- name: Verify rekey_on_member with invalid data
|
||||||
|
set_fact:
|
||||||
|
rekey_on_member_exc2: '{{ "minkeys"|rekey_on_member("asdf") }}'
|
||||||
|
ignore_errors: true
|
||||||
|
tags: rekey_on_member
|
||||||
|
register: rekey_on_member_exc2_res
|
||||||
|
|
||||||
|
- name: Verify rekey_on_member with partially invalid data (list item is not dict)
|
||||||
|
set_fact:
|
||||||
|
rekey_on_member_exc3: '{{ [True]|rekey_on_member("asdf") }}'
|
||||||
|
ignore_errors: true
|
||||||
|
tags: rekey_on_member
|
||||||
|
register: rekey_on_member_exc3_res
|
||||||
|
|
||||||
|
- name: Verify rekey_on_member with partially invalid data (key not in all dicts)
|
||||||
|
set_fact:
|
||||||
|
rekey_on_member_exc4: '{{ [{"foo": "bar", "baz": "buzz"}, {"hello": 8, "different": "haha"}]|rekey_on_member("foo") }}'
|
||||||
|
ignore_errors: true
|
||||||
|
tags: rekey_on_member
|
||||||
|
register: rekey_on_member_exc4_res
|
||||||
|
|
||||||
|
- name: Verify rekey_on_member with duplicates and duplicates=error
|
||||||
|
set_fact:
|
||||||
|
rekey_on_member_exc5: '{{ [{"proto": "eigrp", "state": "enabled"}, {"proto": "eigrp", "state": "enabled"}]|rekey_on_member("proto", duplicates="error") }}'
|
||||||
|
ignore_errors: true
|
||||||
|
tags: rekey_on_member
|
||||||
|
register: rekey_on_member_exc5_res
|
||||||
|
|
||||||
|
- name: Verify rekey_on_member
|
||||||
|
tags: rekey_on_member
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- rekey_on_member_exc1_res is failed
|
||||||
|
- '"duplicates parameter to rekey_on_member has unknown value" in rekey_on_member_exc1_res.msg'
|
||||||
|
- '[{"proto": "eigrp", "state": "enabled"}, {"proto": "ospf", "state": "enabled"}]|rekey_on_member("proto") == {"eigrp": {"proto": "eigrp", "state": "enabled"}, "ospf": {"proto": "ospf", "state": "enabled"}}'
|
||||||
|
- '{"a": {"proto": "eigrp", "state": "enabled"}, "b": {"proto": "ospf", "state": "enabled"}}|rekey_on_member("proto") == {"eigrp": {"proto": "eigrp", "state": "enabled"}, "ospf": {"proto": "ospf", "state": "enabled"}}'
|
||||||
|
- '[{"proto": "eigrp", "state": "enabled"}, {"proto": "eigrp", "state": "enabled"}]|rekey_on_member("proto", duplicates="overwrite") == {"eigrp": {"proto": "eigrp", "state": "enabled"}}'
|
||||||
|
- rekey_on_member_exc2_res is failed
|
||||||
|
- '"Type is not a valid list, set, or dict" in rekey_on_member_exc2_res.msg'
|
||||||
|
- rekey_on_member_exc3_res is failed
|
||||||
|
- '"List item is not a valid dict" in rekey_on_member_exc3_res.msg'
|
||||||
|
- rekey_on_member_exc4_res is failed
|
||||||
|
- '"was not found" in rekey_on_member_exc4_res.msg'
|
||||||
|
- rekey_on_member_exc5_res is failed
|
||||||
|
- '"is not unique, cannot correctly turn into dict" in rekey_on_member_exc5_res.msg'
|
||||||
|
|
||||||
|
# TODO: For some reason, the coverage tool isn't accounting for the last test
|
||||||
|
# so add another "last test" to fake it...
|
||||||
|
- assert:
|
||||||
|
that:
|
||||||
|
- true
|
||||||
|
|
Loading…
Reference in a new issue