def testUnregister(self): # Without unregister root = moosesyntax.get_moose_syntax_tree(self.json) node = moosetree.find( root, lambda n: n.fullpath() == '/UserObjects/AreaPostprocessor') self.assertEqual(node['moose_base'], 'Postprocessor') self.assertEqual(node['parent_syntax'], 'UserObjects/*') self.assertFalse(node.removed) node = moosetree.find(root, lambda n: n.fullpath() == '/Bounds/ConstantAux') self.assertFalse(node.removed) # With unregister(objects should be removed) root = moosesyntax.get_moose_syntax_tree(self.json, unregister={ 'Postprocessor': 'UserObjects/*', 'AuxKernel': 'Bounds/*' }) node = moosetree.find( root, lambda n: n.fullpath() == '/UserObjects/AreaPostprocessor') self.assertTrue(node.removed) node = moosetree.find(root, lambda n: n.fullpath() == '/Bounds/ConstantAux') self.assertTrue(node.removed)
def postRender(self, result, page, meta): """Insert CSS/JS dependencies into html node tree.""" root = result.root def rel(path): """Helper to create relative paths for js/css dependencies.""" if path.startswith('http'): return path return os.path.relpath(path, os.path.dirname(page.local)) head = moosetree.find(root, lambda n: n.name == 'head') body = moosetree.find(root, lambda n: n.name == 'body') favicon = self.get('favicon') if favicon: html.Tag(head, 'link', rel="icon", type="image/x-icon", href=rel(favicon), \ sizes="16x16 32x32 64x64 128x128") # Add the extra-css, this is done here to make sure it shows up last for i, css in enumerate(self.get('extra-css')): key = 'extra-css-{}'.format(i) if key not in self.__css: self.addCSS(key, css) for name, kwargs in self.__css: html.Tag(head, 'link', href=rel(name), type="text/css", rel="stylesheet", **kwargs) for name, kwargs in self.__head_javascript: html.Tag(head, 'script', type="text/javascript", src=rel(name), **kwargs) for name, kwargs in self.__javascript: html.Tag(body.parent, 'script', type="text/javascript", src=rel(name), **kwargs)
def testNodes(self): root = moosesyntax.get_moose_syntax_tree(self.json) # SyntaxNode node = moosetree.find(root, lambda n: n.fullpath() == '/Adaptivity') self.assertEqual(node.name, 'Adaptivity') self.assertIsInstance(node, moosesyntax.SyntaxNode) self.assertEqual(node.hidden, False) self.assertEqual(node.removed, False) self.assertEqual(node.group, None) self.assertEqual(node.groups(), {'MooseApp'}) self.assertIn('SetAdaptivityOptionsAction', [action.name for action in node.actions()]) self.assertIn('Indicators', [syntax.name for syntax in node.syntax()]) node = moosetree.find(root, lambda n: n.fullpath() == '/Adaptivity/Markers') self.assertIn('BoxMarker', [obj.name for obj in node.objects()]) # MooseObjectNode node = moosetree.find( root, lambda n: n.fullpath() == '/Functions/ParsedFunction') self.assertEqual(node.name, 'ParsedFunction') self.assertIsInstance(node, moosesyntax.MooseObjectNode) self.assertEqual(node.hidden, False) self.assertEqual(node.removed, False) self.assertEqual(node.alias, None) self.assertEqual(node.group, 'MooseApp') self.assertEqual(node.classname, 'MooseParsedFunction') self.assertIn('Function', node.description) self.assertTrue( node.source.endswith( 'framework/src/functions/MooseParsedFunction.C')) self.assertTrue( node.header.endswith( 'framework/include/functions/MooseParsedFunction.h')) self.assertIsInstance(node.parameters, dict) self.assertIn('value', node.parameters) # ActionNode node = moosetree.find( root, lambda n: n.fullpath() == '/Outputs/CommonOutputAction') self.assertEqual(node.name, 'CommonOutputAction') self.assertIsInstance(node, moosesyntax.ActionNode) self.assertEqual(node.hidden, False) self.assertEqual(node.removed, False) self.assertEqual(node.group, 'MooseApp') self.assertIn('common_output', node.tasks) # MooseObjectActionNode node = moosetree.find( root, lambda n: n.fullpath() == '/Outputs/AddOutputAction') self.assertEqual(node.name, 'AddOutputAction') self.assertIsInstance(node, moosesyntax.ActionNode) self.assertEqual(node.hidden, False) self.assertEqual(node.removed, False) self.assertEqual(node.group, 'MooseApp') self.assertIn('add_output', node.tasks)
def testFind(self): root = build_tree() node = moosetree.find(root, lambda n: n.name.endswith('AB')) self.assertEqual(node.name, 'AB') node = moosetree.find(root, lambda n: n.name.endswith('not this')) self.assertIs(node, None) node = moosetree.find(root, lambda n: n.get('year') == 2013) self.assertEqual(node.name, 'ABCAB')
def testAllowTestObjects(self): root = moosesyntax.get_moose_syntax_tree(self.json) node = moosetree.find( root, lambda n: n.fullpath() == '/UserObjects/TestCSVReader') self.assertTrue(node.removed) root = moosesyntax.get_moose_syntax_tree(self.json, allow_test_objects=True) node = moosetree.find( root, lambda n: n.fullpath() == '/UserObjects/TestCSVReader') self.assertFalse(node.removed)
def testRemove(self): location = os.path.join(MooseDocs.MOOSE_DIR, 'modules', 'combined') exe = mooseutils.find_moose_executable(location) root = app_syntax(exe, remove=['/Variables/InitialCondition']) node = moosetree.find(root, lambda n: n.fullpath == '/Variables/InitialCondition/AddICAction') self.assertEqual(node.name, 'AddICAction') self.assertTrue(node.removed) node = moosetree.find(root, lambda n: n.fullpath == '/Variables/InitialCondition/BoundingBoxIC') self.assertTrue(node.removed)
def test(self): # MOOSEDOCS:example-begin # Load the packages import pyhit import moosetree # Read the file root = pyhit.load('input.i') # Locate and modify "x_max" parameter for the mesh mesh = moosetree.find(root, func=lambda n: n.fullpath == '/Mesh/gen') mesh["x_max"] = 4 # Set the comment on altered parameter mesh.setComment("x_max", "Changed from 3 to 4") # Write the modified file pyhit.write("input_modified.i", root) # MOOSEDOCS:example-end self.assertEqual(mesh["x_max"], 4) self.assertEqual(mesh.comment("x_max"), "Changed from 3 to 4") out = mesh.render() self.assertIn("x_max = 4", out) self.assertIn("Changed from 3 to 4", out)
def _addSearch(self, parent, page): # Search button btn = html.Tag(parent, 'a', class_="modal-trigger", href="#moose-search") html.Tag(btn, 'i', string='search', class_="material-icons") # Search modal div = html.Tag(moosetree.find(parent.root, lambda n: n.name == 'header'), 'div', id_="moose-search", class_="modal modal-fixed-footer moose-search-modal") container = html.Tag( div, 'div', class_="modal-content container moose-search-modal-content") html.Tag(container, 'div', class_='gcse-search') footer = html.Tag(div, 'div', class_="modal-footer") html.Tag(footer, 'a', href='#!', class_="modal-close btn-flat", string=u'Close')
def testRemoveTestApp(self): location = os.path.join(MooseDocs.MOOSE_DIR, 'modules', 'combined') exe = mooseutils.find_moose_executable(location) root = app_syntax(exe) node = moosetree.find(root, lambda n: n.fullpath == '/UserObjects/TestDistributionPostprocessor') self.assertTrue(node.removed) self.assertIn('MiscTestApp', root.groups)
def testADObject(self): location = os.path.join(MooseDocs.MOOSE_DIR, 'test') exe = mooseutils.find_moose_executable(location) root = app_syntax(exe) node = moosetree.find(root, lambda n: n.fullpath == '/Kernels/ADDiffusion') self.assertEqual(node.fullpath, '/Kernels/ADDiffusion')
def _addSearch(self, parent, page): # Search button btn = html.Tag(parent, 'a', class_="modal-trigger", href="#moose-search") html.Tag(btn, 'i', string='search', class_="material-icons") # Search modal div = html.Tag(moosetree.find(parent.root, lambda n: n.name == 'header'), 'div', id_="moose-search", class_="modal modal-fixed-footer moose-search-modal") container = html.Tag(div, 'div', class_="modal-content container moose-search-modal-content") cx = self.get('google-cse', None) if cx is not None: html.Tag(container, 'div', class_='gcse-search') elif self.get('search', False): row = html.Tag(container, 'div', class_="row") col = html.Tag(row, 'div', class_="col l12") box_div = html.Tag(col, 'div', class_="input-field") html.Tag(box_div, 'input', type_='text', id_="moose-search-box", onkeyup="mooseSearch()", placeholder=self.get('home')) result_wrapper = html.Tag(row, 'div') html.Tag(result_wrapper, 'div', id_="moose-search-results", class_="col s12") footer = html.Tag(div, 'div', class_="modal-footer") html.Tag(footer, 'a', href='#!', class_="modal-close btn-flat", string=u'Close')
def _addMegaMenu(self, parent, filename, page): """Create a "mega menu" by parsing the *.menu.md file.""" id_ = uuid.uuid4() header = moosetree.find(parent.root, lambda n: n.name == 'header') div = html.Tag(header, 'div', id_=id_) div.addClass('moose-mega-menu-content') parent['data-target'] = id_ node = self.translator.findPage(filename) # The "mega" menus appear on every page so the results of the rendered the mega menu # page(s) and cache the results. When the CIVET/SQA extensions are # enabled 7000+ pages are generated, thus this cache becomes very important. key = (os.path.dirname(page.local), node.local) # cache on current directory and menu name if key not in self.__menu_cache: wrap = html.Tag(div, 'div', class_='moose-mega-menu-wrapper') ast = tokens.Token(None) content = self.translator.reader.read(node) self.translator.reader.tokenize(ast, content, page) self.translator.renderer.render(wrap, ast, page) self.__menu_cache[key] = wrap.copy() else: wrap = self.__menu_cache[key].copy() wrap.parent = div
def check(self, location): # List of errors messages = [] # Load the test spec and create a list of PythonUnitTest files tested = set() spec = os.path.join(location, 'tests') if not os.path.exists(spec): if glob.glob(os.path.join(spec, '*.py')): messages.append("Missing a test spec file in '{}'".format(os.path.dirname(spec))) else: node = pyhit.load(os.path.join(location, 'tests')) for block in moosetree.find(node, lambda n: n.name=='Tests'): if block['type'] == 'PythonUnitTest': tested.add(block['input']) # Loop through python files in this directory for filename in glob.glob(os.path.join(location, '*.py')): # Local filename base = os.path.basename(filename) # Load the module (tried this with os.chdir, but that didn't work) sys.path.append(location) mod = __import__(base[:-3]) sys.path.remove(location) # Get a lit of unittest.TestCase objects, if they exist this file should be in spec tests = get_parent_objects(mod, unittest.TestCase) if tests and (base not in tested): msg = "The test script '{}' is not included in the tests spec '{}'." messages.append(msg.format(base, spec)) return messages
def postRender(self, page, result): """Called after rendering is complete.""" if not isinstance(self.translator.renderer, renderers.MaterializeRenderer): return root = result.root header = moosetree.find(root, lambda n: n.name == 'header') nav = html.Tag(html.Tag(header, 'nav'), 'div', class_='nav-wrapper container') container = moosetree.find(root, lambda n: n.name == 'main').children[0] row = container(0) col = container(0)(0) self._addTopNavigation(nav, page) self._addSideNavigation(nav, page) if self.getConfig(page, 'breadcrumbs'): self._addBreadcrumbs(container, page) if self.getConfig(page, 'sections'): self._addSections(col, page) if self.getConfig(page, 'scrollspy'): col.addClass('col', 's12', 'm12', 'l10') toc = html.Tag(row, 'div', class_="col hide-on-med-and-down l2") self._addContents(toc, col, page) else: col.addClass('col', 's12', 'm12', 'l12') if (self.getConfig(page, 'google-cse') is not None) or self.getConfig( page, 'search'): self._addSearch(nav, page) repo = self.get('repo', None) if repo is not None: self._addRepo(nav, page) head = moosetree.find(root, lambda n: n.name == 'head') self._addTitle(head, root, page) self._addName(nav, page)
def postRender(self, page, result): """Insert CSS/JS dependencies into html node tree.""" def rel(path): """Helper to create relative paths for js/css dependencies.""" if path.startswith('http'): return path return os.path.relpath(path, os.path.dirname(page.local)) # get the parent nodes to tag root = result.root head = moosetree.find(root, lambda n: n.name == 'head') body = moosetree.find(root, lambda n: n.name == 'body') favicon = self.get('favicon') if favicon: html.Tag(head, 'link', rel="icon", type="image/x-icon", href=rel(favicon), \ sizes="16x16 32x32 64x64 128x128") # Add the extra-css, this is done here to make sure it shows up last files = {**self.__global_files, **page.get('renderer_files', dict())} for i, css in enumerate(self.get('extra-css')): files[('extra-css-{}'.format(i), 'css')] = (css, {}) for (key, context) in sorted(files, key=(lambda f: f[1])): name, kwargs = files.pop((key, context)) if context == 'css': html.Tag(head, 'link', href=rel(name), type="text/css", rel="stylesheet", **kwargs) elif context == 'head_javascript': html.Tag(head, 'script', type="text/javascript", src=rel(name), **kwargs) elif context == 'javascript': html.Tag(body.parent, 'script', type="text/javascript", src=rel(name), **kwargs)
def testMarkdown(self): root = moosesyntax.get_moose_syntax_tree( self.json, markdown={ '/AuxKernels/ADMaterialRealAux': 'auxkernels/ADMaterialRealAux.md' }) node = moosetree.find( root, lambda n: n.fullpath() == '/AuxKernels/ADMaterialRealAux') self.assertEqual(node.markdown, 'auxkernels/ADMaterialRealAux.md')
def testAlias(self): location = os.path.join(MooseDocs.MOOSE_DIR, 'test') exe = mooseutils.find_moose_executable(location) alias = dict() alias['/VectorPostprocessors/VolumeHistogram'] = '/VPP/VolumeHistogram' root = app_syntax(exe, alias=alias) node = moosetree.find(root, lambda n: n.fullpath == '/VectorPostprocessors/VolumeHistogram') self.assertEqual(node.fullpath, '/VectorPostprocessors/VolumeHistogram') self.assertEqual(node.alias, '/VPP/VolumeHistogram')
def extractInputBlocks(filename, blocks): """Read input file block(s)""" hit = pyhit.load(filename) out = [] for block in blocks.split(): node = moosetree.find(hit, lambda n: n.fullpath.endswith(block.strip('/'))) if node is None: msg = "Unable to find block '{}' in {}." raise exceptions.MooseDocsException(msg, block, filename) out.append(str(node.render())) return pyhit.parse('\n'.join(out)) if out else hit
def find(self, name, fuzzy=True): """ Locate first occurrence of a node by name starting from this node. Inputs: name[str]: The name to search for within the tree. fuzzy[bool]: When True (the default) a "fuzzy" search is performed, meaning that the provide name must be in the node name. If this is set to False the names must match exact. """ func = lambda n: (fuzzy and name in n.fullpath) or (not fuzzy and name == n.fullpath) return moosetree.find(self, func, method=moosetree.IterMethod.PRE_ORDER)
def _addMegaMenu(self, parent, filename, page): """Create a "mega menu" by parsing the *.menu.md file.""" id_ = uuid.uuid4() header = moosetree.find(parent.root, lambda n: n.name == 'header') div = html.Tag(header, 'div', id_=id_) div.addClass('moose-mega-menu-content') parent['data-target'] = id_ wrap = html.Tag(div, 'div', class_='moose-mega-menu-wrapper') node = self.translator.findPage(filename) ast = self.translator.getSyntaxTree(node) #pylint: disable=no-member self.translator.renderer.render(wrap, ast, page) #pylint: disable=no-member
def testRemove(self): # Test with flat list root = moosesyntax.get_moose_syntax_tree( self.json, remove=['/Outputs', '/Kernels/Diffusion']) node = moosetree.find(root, lambda n: n.fullpath() == '/Outputs') self.assertTrue(all([n.removed for n in node])) # children should be marked node = moosetree.find(root, lambda n: n.fullpath() == '/Kernels') self.assertFalse(node.removed) node = moosetree.find(root, lambda n: n.fullpath() == '/Kernels/Diffusion') self.assertTrue(node.removed) node = moosetree.find(root, lambda n: n.fullpath() == '/Kernels/ADDiffusion') self.assertFalse(node.removed) # Test with dict of lists remove = dict(first=['/Outputs', '/Kernels/Diffusion'], second=['/Kernels/ADDiffusion']) root = moosesyntax.get_moose_syntax_tree(self.json, remove=remove) node = moosetree.find(root, lambda n: n.fullpath() == '/Outputs') self.assertTrue(all([n.removed for n in node])) # children should be marked node = moosetree.find(root, lambda n: n.fullpath() == '/Kernels') self.assertFalse(node.removed) node = moosetree.find(root, lambda n: n.fullpath() == '/Kernels/Diffusion') self.assertTrue(node.removed) node = moosetree.find(root, lambda n: n.fullpath() == '/Kernels/ADDiffusion') self.assertTrue(node.removed)
def testHide(self): # Test with flat list root = moosesyntax.get_moose_syntax_tree( self.json, hide=['/Outputs', '/Kernels/Diffusion']) node = moosetree.find(root, lambda n: n.fullpath() == '/Outputs') self.assertFalse(any([n.hidden for n in node])) # children should not be marked node = moosetree.find(root, lambda n: n.fullpath() == '/Kernels') self.assertFalse(node.hidden) node = moosetree.find(root, lambda n: n.fullpath() == '/Kernels/Diffusion') self.assertTrue(node.hidden) node = moosetree.find(root, lambda n: n.fullpath() == '/Kernels/ADDiffusion') self.assertFalse(node.hidden) # Test with dict of lists hide = dict(first=['/Outputs', '/Kernels/Diffusion'], second=['/Kernels/ADDiffusion']) root = moosesyntax.get_moose_syntax_tree(self.json, hide=hide) node = moosetree.find(root, lambda n: n.fullpath() == '/Outputs') self.assertFalse(any([n.hidden for n in node])) # children should not be marked node = moosetree.find(root, lambda n: n.fullpath() == '/Kernels') self.assertFalse(node.hidden) node = moosetree.find(root, lambda n: n.fullpath() == '/Kernels/Diffusion') self.assertTrue(node.hidden) node = moosetree.find(root, lambda n: n.fullpath() == '/Kernels/ADDiffusion') self.assertTrue(node.hidden)
def get_test_specification(filename, block): """ Create a TestSpecification object from the HIT file and block name. Input: filename[str]: Complete filename of a HIT file containing test specification(s) block[str]: The name of the block to use for creating the TestSpecification object This function exists to allow for requirements to be defined outside of the test specifications, but still reference tests for the purpose of SQA traceability. Support for this was added to allow for non-functional requirements to be defined outside of the test specifications. """ root = pyhit.load(filename) # Locate the desired block node = moosetree.find(root, lambda n: n.fullpath.endswith(block)) if node is None: raise KeyError("Unable to locate '{}' in {}".format(block, filename)) # Build/return TestSpecification object name = node.name if node.parent.parent.is_root else '{}/{}'.format(node.parent.name, node.name) return _create_specification(node, name, filename, mooseutils.git_root_dir(os.path.dirname(filename)))
def _createStubPage(self, node): """Copy template content to expected document location.""" # Determine the correct markdown filename filename = node['_md_path'] if isinstance(node, moosesyntax.ObjectNodeBase): filename = os.path.join(self.working_dir, node['_md_path']) elif isinstance(node, moosesyntax.SyntaxNode): action = moosetree.find( node, lambda n: isinstance(n, moosesyntax.ActionNode)) filename = os.path.join(self.working_dir, os.path.dirname(node['_md_path']), 'index.md') # Determine the source template tname = None if isinstance(node, moosesyntax.SyntaxNode): tname = 'moose_system.md.template' elif isinstance(node, moosesyntax.MooseObjectNode): tname = 'moose_object.md.template' elif isinstance(node, moosesyntax.ActionNode): tname = 'moose_action.md.template' else: raise Exception("Unexpected syntax node type.") # Template file tname = os.path.join(os.path.dirname(__file__), '..', '..', 'framework', 'doc', 'content', 'templates', 'stubs', tname) # Read template and apply node content with open(tname, 'r') as fid: content = fid.read() content = mooseutils.apply_template_arguments(content, name=node.name, syntax=node.fullpath()) # Write the content to the desired destination self._writeFile(filename, content)
def _renderField(self, parent, token, page, modal=None): """Helper to render tokens, the logic is the same across formats.""" # Locate the replacement key = token['key'] func = lambda n: (n.name == 'TemplateItem') and (n['key'] == key) replacement = moosetree.find(token.root, func) if replacement: # Add beginning TemplateSubField for child in token: if (child.name == 'TemplateSubField') and (child['command'] == 'field-begin'): self.renderer.render(parent, child, page) # Render TemplateItem self.renderer.render(parent, replacement, page) # Add ending TemplateSubField for child in token: if (child.name == 'TemplateSubField') and (child['command'] == 'field-end'): self.renderer.render(parent, child, page) # Remove the TemplateFieldItem, otherwise the content will be rendered again replacement.parent = None for child in replacement.children: child.parent = None elif not token['required']: tok = tokens.Token(None) token.copyToToken(tok) self.renderer.render(parent, tok, page) else: self._createFieldError(parent, token, page, modal)
def testTestApp(self): root = moosesyntax.get_moose_syntax_tree(self.json) node = moosetree.find(root, lambda n: n.fullpath() == '/Testing') self.assertTrue(node.removed) self.assertTrue(node(0).removed) self.assertTrue(node(0, 0).removed)
def _addRequirement(self, parent, info, page, req, requirements, category): reqname = "{}:{}".format(req.path, req.name) if req.path != '.' else req.name item = SQARequirementMatrixItem(parent, label=req.label, reqname=reqname, satisfied=req.satisfied) text = SQARequirementText(item) self.reader.tokenize(text, req.text, page, MarkdownReader.INLINE, info.line, report=False) for token in moosetree.iterate(item): if token.name == 'ErrorToken': msg = common.report_error("Failed to tokenize SQA requirement.", req.filename, req.text_line, req.text, token['traceback'], 'SQA TOKENIZE ERROR') LOG.critical(msg) if req.details: details = SQARequirementDetails(item) for detail in req.details: ditem = SQARequirementDetailItem(details) text = SQARequirementText(ditem) self.reader.tokenize(text, detail.text, page, MarkdownReader.INLINE, info.line, \ report=False) if self.settings['link']: if self.settings['link-spec']: p = SQARequirementSpecification(item, spec_path=req.path, spec_name=req.name) hit_root = pyhit.load(req.filename) h = moosetree.find(hit_root, lambda n: n.name==req.name) content = h.render() floats.create_modal_link(p, title=reqname, string=reqname, content=core.Code(None, language='text', content=content)) if self.settings['link-design'] and req.design: p = SQARequirementDesign(item, filename=req.filename, design=req.design, line=req.design_line) if self.settings['link-issues'] and req.issues: p = SQARequirementIssues(item, filename=req.filename, issues=req.issues, line=req.issues_line, url=self.extension.remote(category)) if self.settings.get('link-prerequisites', False) and req.prerequisites: labels = [] for prereq in req.prerequisites: for other in requirements: if (other.name == prereq) and (other.path == req.path): labels.append((other.path, other.name, other.label)) for detail in other.details: if (detail.name == prereq) and (detail.path == req.path): labels.append((other.path, other.name, other.label)) SQARequirementPrequisites(item, specs=labels) if self.settings.get('link-results', False): keys = list() for detail in req.details: keys.append('{}.{}/{}'.format(req.path, req.name, detail.name)) if not keys: keys.append('{}.{}'.format(req.path, req.name)) if self.extension.hasCivetExtension(): civet.CivetTestBadges(item, tests=keys)
def testAlias(self): root = moosesyntax.get_moose_syntax_tree( self.json, alias={'/Kernels/Diffusion': '/Physics/Diffusion'}) node = moosetree.find(root, lambda n: n.fullpath() == '/Kernels/Diffusion') self.assertIn(node.alias, '/Physics/Diffusion')
def postRender(self, page, results): parent = moosetree.find(results.root, lambda n: n.name == 'div' and 'moose-content' in n['class']) for div in self.__modals.get(page.uid, list()): div.parent = parent