示例#1
0
 def test_set_value(self, quiet_logger, yamlpath, value, tally, mustexist,
                    vformat, pathsep):
     yamldata = """---
     aliases:
       - &testAnchor Initial Value
     top_array:
       # Comment 1
       - 1
       # Comment 2
       - 2
     # Comment N
     top_scalar: Top-level plain scalar string
     """
     yaml = YAML()
     data = yaml.load(yamldata)
     processor = Processor(quiet_logger, data)
     processor.set_value(yamlpath,
                         value,
                         mustexist=mustexist,
                         value_format=vformat,
                         pathsep=pathsep)
     matchtally = 0
     for node in processor.get_nodes(yamlpath, mustexist=mustexist):
         assert node == value
         matchtally += 1
     assert matchtally == tally
示例#2
0
    def test_set_value(self, quiet_logger, yamlpath, value, tally, mustexist, vformat, pathsep):
        yamldata = """---
aliases:
  - &testAnchor Initial Value
top_array:
  # Comment 1
  - 1
  # Comment 2
  - 2
# Comment N
top_scalar: Top-level plain scalar string
top_hash:
  positive_float: 3.14159265358
  negative_float: -11.034
null_value:
        """
        yaml = YAML()
        data = yaml.load(yamldata)
        processor = Processor(quiet_logger, data)
        processor.set_value(yamlpath, value, mustexist=mustexist, value_format=vformat, pathsep=pathsep)
        matchtally = 0
        for node in processor.get_nodes(yamlpath, mustexist=mustexist):
            assert unwrap_node_coords(node) == value
            matchtally += 1
        assert matchtally == tally
示例#3
0
 def test_scalar_collectors(self, quiet_logger, yamlpath, results):
     yamldata = """---
     list1:
       - 1
       - 2
       - 3
     list2:
       - 4
       - 5
       - 6
     exclude:
       - 3
       - 4
     """
     yaml = YAML()
     processor = Processor(quiet_logger, yaml.load(yamldata))
     matchidx = 0
     # Note that Collectors deal with virtual DOMs, so mustexist must always
     # be set True.  Otherwise, ephemeral virtual nodes would be created and
     # discarded.  Is this desirable?  Maybe, but not today.  For now, using
     # Collectors without setting mustexist=True will be undefined behavior.
     for node in processor.get_nodes(yamlpath, mustexist=True):
         assert unwrap_node_coords(node) == results[matchidx]
         matchidx += 1
     assert len(results) == matchidx
示例#4
0
 def test_set_nonunique_values(self, quiet_logger, yamlpath, value, verifications):
     yamldata = """---
     aliases:
       - &alias_number 1
       - &alias_bool true
     number: 1
     bool: true
     alias_number: *alias_number
     alias_bool: *alias_bool
     hash:
       number: 1
       bool: true
       alias_number: *alias_number
       alias_bool: *alias_bool
     complex:
       hash:
         number: 1
         bool: true
         alias_number: *alias_number
         alias_bool: *alias_bool
     """
     yaml = YAML()
     data = yaml.load(yamldata)
     processor = Processor(quiet_logger, data)
     processor.set_value(yamlpath, value)
     for verification in verifications:
         for verify_node_coord in processor.get_nodes(verification[0]):
             assert unwrap_node_coords(verify_node_coord) == verification[1]
示例#5
0
    def test_get_every_data_type(self, quiet_logger):
        # Contributed by https://github.com/AndydeCleyre
        yamldata = """---
intthing: 6
floatthing: 6.8
yesthing: yes
nothing: no
truething: true
falsething: false
nullthing: null
nothingthing:
emptystring: ""
nullstring: "null"
        """

        results = [6, 6.8, "yes", "no", True, False, None, None, "", "null"]

        yaml = YAML()
        data = yaml.load(yamldata)
        processor = Processor(quiet_logger, data)
        yamlpath = YAMLPath("*")

        match_index = 0
        for node in processor.get_nodes(yamlpath):
            assert unwrap_node_coords(node) == results[match_index]
            match_index += 1
示例#6
0
    def test_key_anchor_changes(self, quiet_logger, yamlpath, value, tally, mustexist, vformat, pathsep):
        yamldata = """---
        anchorKeys:
          &keyOne aliasOne: 11A1
          &keyTwo aliasTwo: 22B2
          &recursiveAnchorKey subjectKey: *recursiveAnchorKey

        hash:
          *keyOne :
            subval: 1.1
          *keyTwo :
            subval: 2.2
          *recursiveAnchorKey :
            subval: 3.3
        """
        yaml = YAML()
        data = yaml.load(yamldata)
        processor = Processor(quiet_logger, data)

        yamlpath = YAMLPath(yamlpath)
        processor.set_value(yamlpath, value, mustexist=mustexist, value_format=vformat, pathsep=pathsep)
        matchtally = 0
        for node in processor.get_nodes(yamlpath):
            assert unwrap_node_coords(node) == value
            matchtally += 1
        assert matchtally == tally
示例#7
0
 def test_set_value_in_none_data(self, capsys, quiet_logger):
     import sys
     yaml = YAML()
     data = None
     processor = Processor(quiet_logger, data)
     processor._update_node(None, None, None, YAMLValueFormats.DEFAULT)
     yaml.dump(data, sys.stdout)
     assert -1 == capsys.readouterr().out.find("abc")
示例#8
0
 def test_none_data_to_get_nodes_by_path_segment(self, capsys, quiet_logger):
     import sys
     yamldata = ""
     yaml = YAML()
     data = yaml.load(yamldata)
     processor = Processor(quiet_logger, data)
     nodes = list(processor._get_nodes_by_path_segment(data, YAMLPath("abc"), 0))
     yaml.dump(data, sys.stdout)
     assert -1 == capsys.readouterr().out.find("abc")
示例#9
0
 def test_set_value_in_empty_data(self, capsys, quiet_logger):
     import sys
     yamldata = ""
     yaml = YAML()
     data = yaml.load(yamldata)
     processor = Processor(quiet_logger, data)
     processor.set_value("abc", "void")
     yaml.dump(data, sys.stdout)
     assert -1 == capsys.readouterr().out.find("abc")
示例#10
0
 def test_illegal_traversal_recursion(self, quiet_logger):
     yamldata = """---
     any: data
     """
     yaml = YAML()
     processor = Processor(quiet_logger, yaml.load(yamldata))
     with pytest.raises(YAMLPathException) as ex:
         nodes = list(processor.get_nodes("**.**"))
     assert -1 < str(ex.value).find("Repeating traversals are not allowed")
示例#11
0
 def test_enforce_pathsep(self, quiet_logger):
     yamldata = """---
     aliases:
       - &aliasAnchorOne Anchored Scalar Value
     """
     yaml = YAML()
     processor = Processor(quiet_logger, yaml.load(yamldata))
     yamlpath = YAMLPath("aliases[&aliasAnchorOne]")
     for node in processor.get_nodes(yamlpath, pathsep=PathSeperators.FSLASH):
         assert unwrap_node_coords(node) == "Anchored Scalar Value"
示例#12
0
    def test_cannot_set_nonexistent_required_node_error(self, quiet_logger):
        yamldata = """---
        key: value
        """
        yaml = YAML()
        data = yaml.load(yamldata)
        processor = Processor(quiet_logger, data)

        with pytest.raises(YAMLPathException) as ex:
            processor.set_value("abc", "void", mustexist=True)
        assert -1 < str(ex.value).find("No nodes matched")
示例#13
0
 def test_get_none_data_nodes(self, quiet_logger):
     processor = Processor(quiet_logger, None)
     yamlpath = YAMLPath("abc")
     matches = 0
     for node in processor.get_nodes(yamlpath, mustexist=False):
         matches += 1
     for node in processor.get_nodes(yamlpath, mustexist=True):
         matches += 1
     for node in processor._get_required_nodes(None, yamlpath):
         matches += 1
     assert matches == 0
示例#14
0
    def test_adjoined_collectors_error(self, quiet_logger):
        yamldata = """---
        key: value
        """
        yaml = YAML()
        data = yaml.load(yamldata)
        processor = Processor(quiet_logger, data)

        with pytest.raises(YAMLPathException) as ex:
            nodes = list(processor.get_nodes("(&arrayOfHashes.step)(disabled_steps)"))
        assert -1 < str(ex.value).find("has no meaning")
示例#15
0
    def test_null_docs_have_nothing_to_delete(self, capsys):
        args = SimpleNamespace(verbose=False, quiet=False, debug=True)
        logger = ConsolePrinter(args)
        processor = Processor(logger, None)

        deleted_nodes = []
        for nc in processor.delete_nodes("**"):
            deleted_nodes.append(nc)

        console = capsys.readouterr()
        assert "Refusing to delete nodes from a null document" in console.out
示例#16
0
    def test_no_attrs_to_arrays_error(self, quiet_logger):
        yamldata = """---
        array:
          - one
          - two
        """
        yaml = YAML()
        data = yaml.load(yamldata)
        processor = Processor(quiet_logger, data)

        with pytest.raises(YAMLPathException) as ex:
            nodes = list(processor.get_nodes("array.attr"))
        assert -1 < str(ex.value).find("Cannot add")
示例#17
0
    def test_get_nodes_array_impossible_type_error(self, quiet_logger):
        yamldata = """---
        array:
          - 1
          - 2
        """
        yaml = YAML()
        data = yaml.load(yamldata)
        processor = Processor(quiet_logger, data)

        with pytest.raises(YAMLPathException) as ex:
            nodes = list(processor.get_nodes(r"/array/(.=~/^.{3,4}$/)", default_value="New value"))
        assert -1 < str(ex.value).find("Cannot add")
示例#18
0
    def test_non_int_slice_error(self, quiet_logger):
        yamldata = """---
        - step: 1
        - step: 2
        - step: 3
        """
        yaml = YAML()
        data = yaml.load(yamldata)
        processor = Processor(quiet_logger, data)

        with pytest.raises(YAMLPathException) as ex:
            processor.set_value("[1:4F]", "")
        assert -1 < str(ex.value).find("is not an integer array slice")
示例#19
0
def extract_values(data: {}, path: str) -> []:
    class Args:
        debug = True
        verbose = False
        quiet = True

    args = Args()
    log = ConsolePrinter(args)

    try:
        processor = Processor(log, data)
        nodes = processor.get_nodes(path)
        return [n.node for n in nodes]
    except YAMLPathException as ex:
        print(ex)
示例#20
0
    def test_no_attrs_to_scalars_errors(self, quiet_logger):
        yamldata = """---
        scalar: value
        """
        yaml = YAML()
        data = yaml.load(yamldata)
        processor = Processor(quiet_logger, data)

        with pytest.raises(YAMLPathException) as ex:
            nodes = list(processor.get_nodes("scalar[6]"))
        assert -1 < str(ex.value).find("Cannot add")

        with pytest.raises(YAMLPathException) as ex:
            nodes = list(processor.get_nodes("scalar.key"))
        assert -1 < str(ex.value).find("Cannot add")
示例#21
0
    def _prepare_user_rules(self, proc: Processor, section: str,
                            collector: dict) -> None:
        """
        Identify DOM nodes matching user-defined diff rules.

        Parameters:
        1. proc (Processor) Reference to the DOM Processor.
        2. section (str) User-configuration file section defining the diff
           rules to apply.
        3. collector (dict) Storage collector for matching nodes.

        Returns:  N/A
        """
        if self.config is None or not section in self.config:
            self.log.warning(
                "User-specified configuration file has no {} section.".format(
                    section))
            return

        for rule_key in self.config[section]:
            rule_value = self.config[section][rule_key]

            if "=" in rule_value:
                # There were at least two = signs on the configuration line
                conf_line = rule_key + "=" + rule_value
                delim_pos = conf_line.rfind("=")
                rule_key = conf_line[0:delim_pos].strip()
                rule_value = conf_line[delim_pos + 1:].strip()
                self.log.debug(
                    "DifferConfig::_prepare_user_rules:  Reconstituted"
                    " configuration line '{}' to extract adjusted key '{}'"
                    " with value '{}'".format(conf_line, rule_key, rule_value))

            rule_path = YAMLPath(rule_key)
            yaml_path = YAMLPath(rule_path)
            self.log.debug(
                "DifferConfig::_prepare_user_rules:  Matching '{}' nodes to"
                " YAML Path '{}' from key, {}.".format(section, yaml_path,
                                                       rule_key))
            try:
                for node_coord in proc.get_nodes(yaml_path, mustexist=True):
                    self.log.debug(
                        "Node will have comparisons rule, {}:".format(
                            rule_value),
                        prefix="DifferConfig::_prepare_user_rules:  ",
                        data=node_coord.node)
                    collector[node_coord] = rule_value

            except YAMLPathException:
                self.log.warning("{} YAML Path matches no nodes:  {}".format(
                    section, yaml_path))

        self.log.debug("Matched rules to nodes:",
                       prefix="DifferConfig::_prepare_user_rules:  ")
        for node_coord, diff_rule in collector.items():
            self.log.debug("... RULE:  {}".format(diff_rule),
                           prefix="DifferConfig::_prepare_user_rules:  ")
            self.log.debug("... NODE:",
                           data=node_coord,
                           prefix="DifferConfig::_prepare_user_rules:  ")
示例#22
0
 def test_get_impossible_nodes_error(self, quiet_logger, yamlpath, mustexist):
     yamldata = """---
     ints:
       - 1
       - 2
       - 3
       - 4
       - 5
     floats:
       - 1.1
       - 2.2
       - 3.3
     """
     yaml = YAML()
     processor = Processor(quiet_logger, yaml.load(yamldata))
     with pytest.raises(YAMLPathException) as ex:
         nodes = list(processor.get_nodes(yamlpath, mustexist=mustexist))
     assert -1 < str(ex.value).find("does not match any nodes")
示例#23
0
    def test_nonexistant_path_search_method_error(self, quiet_logger):
        from enum import Enum
        from yamlpath.enums import PathSearchMethods
        names = [m.name for m in PathSearchMethods] + ['DNF']
        PathSearchMethods = Enum('PathSearchMethods', names)

        yamldata = """---
        top_scalar: value
        """
        yaml = YAML()
        data = yaml.load(yamldata)
        processor = Processor(quiet_logger, data)

        with pytest.raises(NotImplementedError):
            nodes = list(processor._get_nodes_by_search(
                data,
                SearchTerms(True, PathSearchMethods.DNF, ".", "top_scalar")
            ))
示例#24
0
    def test_no_index_to_hashes_error(self, quiet_logger):
        # Using [#] syntax is a disambiguated INDEX ELEMENT NUMBER.  In
        # DICTIONARY context, this would create an ambiguous request to access
        # either the #th value or a value whose key is the literal #.  As such,
        # an error is deliberately generated when [#] syntax is used against
        # dictionaries.  When you actually want a DICTIONARY KEY that happens
        # to be an integer, omit the square braces, [].
        yamldata = """---
        hash:
          key: value
        """
        yaml = YAML()
        data = yaml.load(yamldata)
        processor = Processor(quiet_logger, data)

        with pytest.raises(YAMLPathException) as ex:
            nodes = list(processor.get_nodes("hash[6]"))
        assert -1 < str(ex.value).find("Cannot add")
示例#25
0
    def test_delete_nodes(self, quiet_logger, delete_yamlpath, pathseperator, old_deleted_nodes, new_flat_data):
        yamldata = """---
aliases:
  - &alias_number 1
  - &alias_bool true
number: 1
bool: true
alias_number: *alias_number
alias_bool: *alias_bool
hash:
  number: 1
  bool: true
  alias_number: *alias_number
  alias_bool: *alias_bool
complex:
  hash:
    number: 1
    bool: true
    alias_number: *alias_number
    alias_bool: *alias_bool
records:
  - id: ABC
    data: 123
  - id: BCD
    data: 987
  - id: CDE
    data: 8B8
"""
        yaml = YAML()
        data = yaml.load(yamldata)
        processor = Processor(quiet_logger, data)

        # The return set must be received lest no nodes will be deleted
        deleted_nodes = []
        for nc in processor.delete_nodes(delete_yamlpath, pathsep=pathseperator):
            deleted_nodes.append(nc)

        for (test_value, verify_node_coord) in zip(old_deleted_nodes, deleted_nodes):
            assert test_value, unwrap_node_coords(verify_node_coord)

        for (test_value, verify_node_coord) in zip(new_flat_data, processor.get_nodes("**")):
            assert test_value, unwrap_node_coords(verify_node_coord)
示例#26
0
    def test_non_int_array_index_error(self, quiet_logger):
        from collections import deque
        yamldata = """---
        - 1
        """
        yaml = YAML()
        data = yaml.load(yamldata)
        path = YAMLPath("[0]")
        processor = Processor(quiet_logger, data)
        strp = str(path)

        path._escaped = deque([
            (PathSegmentTypes.INDEX, "0F"),
        ])
        path._unescaped = deque([
            (PathSegmentTypes.INDEX, "0F"),
        ])

        with pytest.raises(YAMLPathException) as ex:
            nodes = list(processor._get_nodes_by_index(data, path, 0))
        assert -1 < str(ex.value).find("is not an integer array index")
示例#27
0
    def test_cannot_add_novel_alias_keys(self, quiet_logger):
        yamldata = """---
        anchorKeys:
          &keyOne aliasOne: 1 1 Alpha 1
          &keyTwo aliasTwo: 2 2 Beta 2

        hash:
          *keyOne :
            subval: 1.1
          *keyTwo :
            subval: 2.2
        """
        yaml = YAML()
        data = yaml.load(yamldata)
        processor = Processor(quiet_logger, data)

        yamlpath = YAMLPath("hash[&keyThree].subval")
        newvalue = "Abort"
        with pytest.raises(YAMLPathException) as ex:
            nodes = list(processor.get_nodes(yamlpath))
        assert -1 < str(ex.value).find("Cannot add")
示例#28
0
    def test_get_nodes_by_unknown_path_segment_error(self, quiet_logger):
        from collections import deque
        from enum import Enum
        from yamlpath.enums import PathSegmentTypes
        names = [m.name for m in PathSegmentTypes] + ['DNF']
        PathSegmentTypes = Enum('PathSegmentTypes', names)

        yamldata = """---
        key: value
        """
        yaml = YAML()
        data = yaml.load(yamldata)
        processor = Processor(quiet_logger, data)
        path = YAMLPath("abc")
        stringified = str(path)     # Force Path to parse
        path._escaped = deque([
            (PathSegmentTypes.DNF, "abc"),
        ])

        with pytest.raises(NotImplementedError):
            nodes = list(processor._get_nodes_by_path_segment(data, path, 0))
示例#29
0
 def test_get_nodes(self, quiet_logger, yamlpath, results, mustexist,
                    default):
     yamldata = """---
     aliases:
       - &aliasAnchorOne Anchored Scalar Value
       - &aliasAnchorTwo Hey, Number Two!
     array_of_hashes: &arrayOfHashes
       - step: 1
         name: one
       - step: 2
         name: two
     rollback_hashes:
       on_condition:
         failure:
           - step: 3
             name: three
           - step: 4
             name: four
     disabled_steps:
       - 2
       - 3
     squads:
       alpha: 1.1
       bravo: 2.2
       charlie: 3.3
       delta: 4.4
     number_keys:
       1: one
       2: two
       3: three
     """
     yaml = YAML()
     processor = Processor(quiet_logger, yaml.load(yamldata))
     matchidx = 0
     for node in processor.get_nodes(yamlpath,
                                     mustexist=mustexist,
                                     default_value=default):
         assert node == results[matchidx]
         matchidx += 1
     assert len(results) == matchidx
示例#30
0
    def test_key_anchor_children(self, quiet_logger):
        yamldata = """---
        anchorKeys:
          &keyOne aliasOne: 1 1 Alpha 1
          &keyTwo aliasTwo: 2 2 Beta 2

        hash:
          *keyOne :
            subval: 1.1
          *keyTwo :
            subval: 2.2
        """
        yaml = YAML()
        data = yaml.load(yamldata)
        processor = Processor(quiet_logger, data)

        yamlpath = YAMLPath("hash[&keyTwo].subval")
        newvalue = "Mute audibles"
        processor.set_value(yamlpath, newvalue, mustexist=True)
        matchtally = 0
        for node in processor.get_nodes(yamlpath):
            assert unwrap_node_coords(node) == newvalue
            matchtally += 1
        assert matchtally == 1