def fake_context_on_root_node(fake_tree: XsdTree, fake_xml_doc: XmlDocument) -> XmlContext: fake_node = XmlElement() fake_node.end_tag_open_offset = 10 fake_node.end_tag_close_offset = 15 fake_node.name = fake_tree.root.name fake_context = XmlContext(fake_xml_doc, fake_tree.root, fake_node) return fake_context
def _build_input_tree(self, inputs: XmlElement, parent: InputNode) -> None: """Given the XML element containing the inputs of the tool, this method recursively builds an expanded input tree. Args: inputs (XmlElement): The XML element corresponding to the inputs. parent (InputNode): The node that will hold all the inputs. """ parent.params = inputs.get_children_with_name(PARAM) conditionals = inputs.get_children_with_name(CONDITIONAL) for conditional in conditionals: self._build_conditional_input_tree(conditional, parent) repeats = inputs.get_children_with_name(REPEAT) for repeat in repeats: repeat_node = self._build_repeat_input_tree(repeat) if repeat_node: parent.repeats.append(repeat_node) sections = inputs.get_children_with_name(SECTION) for section in sections: section_node = self._build_section_input_tree(section) if section_node: parent.sections.append(section_node)
def test_context_with_tag_token_type_returns_is_tag( self, fake_xsd_tree: XsdTree, fake_xml_doc: XmlDocument) -> None: context = XmlContext(fake_xml_doc, fake_xsd_tree.root, XmlElement()) assert context.is_tag assert not context.is_attribute_key assert not context.is_attribute_value
def test_context_with_attr_value_token_type_returns_is_attr_value( self, fake_xsd_tree: XsdTree, fake_xml_doc: XmlDocument) -> None: fake_attr = XmlAttribute("attr", 0, 0, XmlElement()) context = XmlContext(fake_xml_doc, fake_xsd_tree.root, XmlAttributeValue("val", 0, 0, fake_attr)) assert not context.is_tag assert not context.is_attribute_key assert context.is_attribute_value
def sort_param_attributes( self, param: XmlElement, xml_document: XmlDocument) -> Optional[ReplaceTextRangeResult]: if param and param.name == PARAM and param.has_attributes: attribute_names = param.get_attribute_names() sorted_attribute_names = self._sort_attribute_names( attribute_names) if attribute_names == sorted_attribute_names: return None sorted_attributes_text = self._get_param_attributes_as_text_sorted( param, sorted_attribute_names) start, end = param.get_attributes_offsets() return ReplaceTextRangeResult( replace_range=convert_document_offsets_to_range( xml_document.document, start, end), text=sorted_attributes_text, ) return None
def _build_param_test_element( self, input_param: XmlElement, value: Optional[str] = None) -> etree._Element: """Builds a <param> XML element to be used in a <test> code snippet from a given input <param> XML element. Args: input_param (XmlElement): The XML element of a <param> in the tool <inputs> section. value (Optional[str], optional): The optional value that will be assigned to the <param>. Defaults to None. Returns: etree._Element: The XML element representing a <param> in the <test> code snippet. """ param = etree.Element(PARAM) argument_attr = input_param.get_attribute(ARGUMENT) name_attr = input_param.get_attribute(NAME) if not name_attr and argument_attr: name_attr = self._extract_name_from_argument(argument_attr) if name_attr: param.attrib[NAME] = name_attr default_value = input_param.get_attribute(VALUE) if value: param.attrib[VALUE] = value elif default_value: param.attrib[VALUE] = self._get_next_tabstop_with_placeholder( default_value) else: type_attr = input_param.get_attribute(TYPE) if type_attr: if type_attr == BOOLEAN: default_value = input_param.get_attribute(CHECKED) param.attrib[VALUE] = self._get_next_tabstop_with_options( BOOLEAN_OPTIONS, default_value) elif type_attr == SELECT or type_attr == TEXT: try: options = self._get_options_from_param(input_param) param.attrib[ VALUE] = self._get_next_tabstop_with_options( options, default_value) except BaseException: param.attrib[VALUE] = self._get_next_tabstop() else: param.attrib[VALUE] = self._get_next_tabstop() return param
def _add_output_collection_to_test(self, output_collection: XmlElement, test_element: etree._Element) -> None: """Adds the 'output_collection' XML element to the 'test_element' with a default <element>. Args: output_collection (XmlElement): The <collection> XML element. test_element (etree._Element): The <test> XML element. """ name = output_collection.get_attribute(NAME) if name: output_element = etree.Element(OUTPUT_COLLECTION) output_element.attrib[NAME] = name type_attr = output_collection.get_attribute(TYPE) if type_attr: output_element.attrib[TYPE] = type_attr element = etree.Element(ELEMENT) element.attrib[NAME] = self._get_next_tabstop() self._add_default_asserts_to_output(element) output_element.append(element) test_element.append(output_element)
def _build_repeat_input_tree(self, repeat: XmlElement) -> Optional[RepeatInputNode]: """Builds and returns a RepeatInputNode from a 'repeat' XML tag with the minimum number of repetitions defined. Args: repeat (XmlElement): The XML repeat tag. Returns: Optional[RepeatInputNode]: The resulting RepeatInputNode with it's own input children. """ name = repeat.get_attribute(NAME) if name: min = 1 min_attr = repeat.get_attribute(MIN) if min_attr and min_attr.isdigit: min = int(min_attr) repeat_node = RepeatInputNode(name, min, repeat) self._build_input_tree(repeat, repeat_node) return repeat_node return None
def _get_options_from_param(self, param: XmlElement) -> List[str]: """Gets the list of children elements of type <option> from the given 'param' XML element. Args: param (XmlElement): The <param> XML element. Returns: List[str]: The list of <option> in this 'param' or an empty list. """ option_elements = param.get_children_with_name(OPTION) options = [o.get_attribute(VALUE) for o in option_elements] return list(filter(None, options))
def _add_output_to_test(self, data: XmlElement, test_element: etree._Element) -> None: """Converts the given 'data' (<data>) XML element in an output XML element and adds it to the given <test> element. Args: output (XmlElement): The test_element (etree._Element): [description] """ name = data.get_attribute(NAME) if name: output_element = etree.Element(OUTPUT) output_element.attrib[NAME] = name self._add_default_asserts_to_output(output_element) test_element.append(output_element)
def test_get_completion_at_context_with_closing_tag_invoke_returns_none( self, fake_tree: XsdTree, fake_xml_doc: XmlDocument, fake_definitions_provider: DocumentDefinitionsProvider, ) -> None: fake_element = XmlElement() fake_context = XmlContext(fake_xml_doc, fake_tree.root, fake_element) fake_completion_context = CompletionContext(trigger_kind=CompletionTriggerKind.Invoked) service = XmlCompletionService(fake_tree, fake_definitions_provider) actual = service.get_completion_at_context(fake_context, fake_completion_context) assert not actual
def _param_to_cheetah(self, param: XmlElement, name_path: Optional[str] = None, indent_level: int = 0) -> str: """Converts the given param element to it's Cheetah representation.""" indentation = self._get_indentation(indent_level) argument_attr = param.get_attribute(ARGUMENT) name_attr = param.get_attribute(NAME) if not name_attr and argument_attr: name_attr = argument_attr.lstrip(DASH).replace(DASH, UNDERSCORE) type_attr = param.get_attribute(TYPE) if name_path: name_attr = f"{name_path}.{name_attr}" if type_attr == BOOLEAN: return f"{indentation}\\${name_attr}" if type_attr in [INTEGER, FLOAT]: if param.get_attribute(OPTIONAL) == "true": return ( f"{indentation}#if str(\\${name_attr}):\n" f"{indentation}{self.indent_spaces}{self._get_argument_safe(argument_attr)} \\${name_attr}" f"{indentation}#end if") if type_attr in [TEXT, DATA]: return f"{indentation}{self._get_argument_safe(argument_attr)} '\\${name_attr}'" return f"{indentation}{self._get_argument_safe(argument_attr)} \\${name_attr}"
def _build_section_input_tree(self, section: XmlElement) -> Optional[SectionInputNode]: """Builds and returns a SectionInputNode from a 'section' XML tag. Args: section (XmlElement): The XML section tag. Returns: Optional[SectionInputNode]: The resulting SectionInputNode with it's own input children. """ name = section.get_attribute(NAME) if name: section_node = SectionInputNode(name, section) self._build_input_tree(section, section_node) return section_node return None
def test_return_valid_attribute_value_completion_when_enum_context( self, fake_tree: XsdTree, fake_xml_doc: XmlDocument, fake_definitions_provider: DocumentDefinitionsProvider, ) -> None: fake_attr = XmlAttribute("attr", 0, 0, XmlElement()) fake_attr.set_value(None, 0, 0) fake_context = XmlContext(fake_xml_doc, fake_tree.root, fake_attr.value) service = XmlCompletionService(fake_tree, fake_definitions_provider) actual = service.get_attribute_value_completion(fake_context) assert len(actual.items) == 2
def test_get_completion_at_context_with_open_tag_trigger_returns_expected_node( self, fake_tree: XsdTree, fake_xml_doc: XmlDocument, fake_definitions_provider: DocumentDefinitionsProvider, ) -> None: fake_context = XmlContext(fake_xml_doc, fake_tree.root, XmlElement()) fake_completion_context = CompletionContext(trigger_kind=CompletionTriggerKind.TriggerCharacter, trigger_character="<") service = XmlCompletionService(fake_tree, fake_definitions_provider) actual = service.get_completion_at_context(fake_context, fake_completion_context) assert actual assert len(actual.items) == 2 assert actual.items[0].label == "child" assert actual.items[0].kind == CompletionItemKind.Class assert actual.items[1].label == "expand" assert actual.items[1].kind == CompletionItemKind.Class
def _build_conditional_option_branch( self, conditional: XmlElement, parent: InputNode, option_value: Optional[str] = None ) -> None: """Builds a conditional branch in the input tree with the given 'option_value'. Args: conditional (XmlElement): The <conditional> XML element. parent (InputNode): The input node that will contain this branch. option_value (str): The value of the option selected in this conditional branch. """ name = conditional.get_attribute(NAME) if name and option_value: conditional_node = ConditionalInputNode(name, option_value, element=conditional, parent=parent) when = find( conditional, filter_=lambda el: el.name == WHEN and el.get_attribute(VALUE) == option_value, maxlevel=2 ) when = cast(XmlElement, when) if when: self._build_input_tree(when, conditional_node)
def test_init_sets_properties(self, fake_xsd_tree: XsdTree, fake_xml_doc: XmlDocument) -> None: expected_xsd_element = fake_xsd_tree.root expected_token = XmlElement() expected_line_content = "test" expected_position = Position(line=0, character=0) context = XmlContext( fake_xml_doc, expected_xsd_element, expected_token, line_text=expected_line_content, position=expected_position, ) assert context.node == expected_token assert context.xsd_element == expected_xsd_element assert context.line_text == expected_line_content assert context.position == expected_position assert not context.is_empty
def _output_to_cheetah(self, output: XmlElement) -> Optional[str]: """Converts the given output element to it's Cheetah representation wrapped in single quotes.""" name = output.get_attribute(NAME) if name: return f"'\\${name}'" return None
def test_completion_node_reached_max_occurs_return_expected( self, fake_tree: XsdTree, fake_xml_doc: XmlDocument, fake_definitions_provider: DocumentDefinitionsProvider, ) -> None: fake_root = XmlElement() fake_root.name = fake_tree.root.name fake_root.end_tag_open_offset = 10 fake_root.end_tag_close_offset = 15 fake_child = XmlElement() fake_child.name = "child" fake_child.parent = fake_root fake_child = XmlElement() fake_child.parent = fake_root fake_context = XmlContext(fake_xml_doc, fake_tree.root, fake_root) service = XmlCompletionService(fake_tree, fake_definitions_provider) actual = service.get_node_completion(fake_context) assert len(actual.items) == 1 assert actual.items[0].label == "expand"