From ee5e9401ce27959ff7c345c7d4d339c78f615d6f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Candice=20Bent=C3=A9jac?= Date: Mon, 17 Mar 2025 18:34:21 +0100 Subject: [PATCH] [tests] Rewrite `test_nodeCommandLineFormatting` using test nodes The tests in that file were using AliceVision nodes, which are now out of Meshroom's repository. --- tests/test_nodeCommandLineFormatting.py | 218 +++++++++++++++++------- 1 file changed, 158 insertions(+), 60 deletions(-) diff --git a/tests/test_nodeCommandLineFormatting.py b/tests/test_nodeCommandLineFormatting.py index 8c85c9c5..e7f2adf7 100644 --- a/tests/test_nodeCommandLineFormatting.py +++ b/tests/test_nodeCommandLineFormatting.py @@ -1,78 +1,176 @@ #!/usr/bin/env python # coding:utf-8 -import meshroom.multiview -from meshroom.core.graph import Graph + +from meshroom.core.graph import Graph, loadGraph, executeGraph +from meshroom.core import desc, registerNodeType, unregisterNodeType +from meshroom.core.node import Node -def test_formatting_listOfFiles(): - meshroom.core.initNodes() +class NodeWithAttributesNeedingFormatting(desc.Node): + """ + A node containing list, file, choice and group attributes in order to test the formatting of the command line. + """ + inputs = [ + desc.ListAttribute( + name="images", + label="Images", + description="List of images.", + elementDesc=desc.File( + name="image", + label="Image", + description="Path to an image.", + value="", + ), + ), + desc.File( + name="input", + label="Input File", + description="An input file.", + value="", + ), + desc.ChoiceParam( + name="method", + label="Method", + description="Method to choose from a list of available methods.", + value="MethodC", + values=["MethodA", "MethodB", "MethodC"], + ), + desc.GroupAttribute( + name="firstGroup", + label="First Group", + description="Group with boolean and integer parameters.", + joinChar=":", + groupDesc=[ + desc.BoolParam( + name="enableFirstGroup", + label="Enable", + description="Enable other parameter in the group.", + value=False, + ), + desc.IntParam( + name="width", + label="Width", + description="Width setting.", + value=3, + range=(1, 10, 1), + enabled=lambda node: node.firstGroup.enableFirstGroup.value, + ), + ] + ), + desc.GroupAttribute( + name="secondGroup", + label="Second Group", + description="Group with boolean, choice and float parameters.", + joinChar=",", + groupDesc=[ + desc.BoolParam( + name="enableSecondGroup", + label="Enable", + description="Enable other parameters in the group.", + value=False, + ), + desc.ChoiceParam( + name="groupChoice", + label="Grouped Choice", + description="Value to choose from a group.", + value="second_value", + values=["first_value", "second_value", "third_value"], + enabled=lambda node: node.secondGroup.enableSecondGroup.value, + ), + desc.FloatParam( + name="floatWidth", + label="Width", + description="Width setting (but with a float).", + value=3.0, + range=(1.0, 10.0, 0.5), + enabled=lambda node: node.secondGroup.enableSecondGroup.value, + ), + ], + ), + ] - inputImages = ['/non/existing/fileA', '/non/existing/with space/fileB'] + outputs = [ + desc.File( + name="output", + label="Output", + description="Output file.", + value="{nodeCacheFolder}", + ), + ] - graph = Graph('') - n1 = graph.addNewNode('CameraInit') - n1.viewpoints.extend([{'path': image} for image in inputImages]) - # viewId, poseId, path, intrinsicId, rigId, subPoseId, metadata - assert n1.viewpoints.getValueStr() == \ - '-1 -1 "/non/existing/fileA" -1 -1 -1 "" -1 -1 "/non/existing/with space/fileB" -1 -1 -1 ""' +class TestCommandLineFormatting: + @classmethod + def setup_class(cls): + registerNodeType(NodeWithAttributesNeedingFormatting) - graph = Graph('') - n1 = graph.addNewNode('ImageMatching') - assert n1.featuresFolders.getValueStr() == '' + @classmethod + def teardown_class(cls): + unregisterNodeType(NodeWithAttributesNeedingFormatting) - n1.featuresFolders.extend("single value with space") - assert n1.featuresFolders.getValueStr() == '"single value with space"' + def test_formatting_listOfFiles(self): + inputImages = ["/non/existing/fileA", "/non/existing/with space/fileB"] - n1.featuresFolders.resetToDefaultValue() - assert n1.featuresFolders.getValueStr() == '' + graph = Graph("") + node = graph.addNewNode("NodeWithAttributesNeedingFormatting") - n1.featuresFolders.extend(inputImages) - assert n1.featuresFolders.getValueStr() == '"/non/existing/fileA" "/non/existing/with space/fileB"' + # Assert that an empty list gives an empty string + assert node.images.getValueStr() == "" - n1._buildCmdVars() # prepare vars for command line creation - # and check some values - name = 'featuresFolders' - assert n1._cmdVars[name + 'Value'] == '/non/existing/fileA /non/existing/with space/fileB' + # Assert that values in a list a correctly concatenated + node.images.extend([i for i in inputImages]) + assert node.images.getValueStr() == '"/non/existing/fileA" "/non/existing/with space/fileB"' + # Reset list content and add a single value that contains spaces + node.images.resetToDefaultValue() + assert node.images.getValueStr() == "" # The value has been correctly reset + node.images.extend("single value with space") + assert node.images.getValueStr() == '"single value with space"' -def test_formatting_strings(): - meshroom.core.initNodes() + # Assert that extending values when the list is not empty is working + node.images.extend(inputImages) + assert node.images.getValueStr() == '"single value with space" "{}" "{}"'.format(inputImages[0], + inputImages[1]) - graph = Graph('') - n1 = graph.addNewNode('ImageMatching') - name = 'weights' - assert n1.weights.getValueStr() == '""' # Empty string should generate empty quotes - assert n1._cmdVars[name + 'Value'] == '' - name = 'method' - assert n1.method.getValueStr() == '"SequentialAndVocabularyTree"' - assert n1._cmdVars[name + 'Value'] == 'SequentialAndVocabularyTree' + # Values are not retrieved as strings in the command line, so quotes around them are not expected + assert node._cmdVars["imagesValue"] == 'single value with space {} {}'.format(inputImages[0], + inputImages[1]) - n2 = graph.addNewNode('ImageMatching') - n2._buildCmdVars() # prepare vars for command line creation - name = 'featuresFolders' - assert n2._cmdVars[name + 'Value'] == '', 'Empty list should become fully empty' - n2.featuresFolders.extend('') - n2._buildCmdVars() # prepare vars for command line creation - assert n2.featuresFolders.getValueStr() == '""', 'A list with one empty string should generate empty quotes' - assert n2._cmdVars[name + 'Value'] == '', 'The Value is always only the value, so empty here' - n2.featuresFolders.extend('') - n2._buildCmdVars() # prepare vars for command line creation - assert n2.featuresFolders.getValueStr() == '"" ""', 'A list with 2 empty strings should generate quotes' - assert n2._cmdVars[name + 'Value'] == ' ', \ - 'The Value is always only the value, so 2 empty with the space separator in the middle' + def test_formatting_strings(self): + graph = Graph("") + node = graph.addNewNode("NodeWithAttributesNeedingFormatting") + node._buildCmdVars() + # Assert an empty File attribute generates empty quotes when requesting its value as a string + assert node.input.getValueStr() == '""' + assert node._cmdVars["inputValue"] == "" -def test_formatting_groups(): - meshroom.core.initNodes() + # Assert a Choice attribute with a non-empty default value is surrounded with quotes when requested as a string + assert node.method.getValueStr() == '"MethodC"' + assert node._cmdVars["methodValue"] == "MethodC" - graph = Graph('') - n3 = graph.addNewNode('ImageProcessing') - n3._buildCmdVars() # prepare vars for command line creation - name = 'sharpenFilter' - assert n3.sharpenFilter.getValueStr() == '"False:3:1.0:0.0"' - assert n3._cmdVars[name + 'Value'] == 'False:3:1.0:0.0', 'The Value is always only the value, so no quotes' - name = 'fillHoles' - assert n3._cmdVars[name + 'Value'] == 'False', 'Booleans' - name = 'noiseFilter' - assert n3.noiseFilter.getValueStr() == '"False:uniform:0.0:1.0:True"' - assert n3._cmdVars[name + 'Value'] == 'False:uniform:0.0:1.0:True' + # Assert that the empty list is really empty (no quotes) + assert node.images.getValueStr() == "" + assert node._cmdVars["imagesValue"] == "", "Empty list should become fully empty" + + # Assert that the list with one empty value generates empty quotes + node.images.extend("") + assert node.images.getValueStr() == '""', "A list with one empty string should generate empty quotes" + assert node._cmdVars["imagesValue"] == "", "The value is always only the value, so empty here" + + # Assert that a list with 2 empty strings generates quotes + node.images.extend("") + assert node.images.getValueStr() == '"" ""', "A list with 2 empty strings should generate quotes" + assert node._cmdVars["imagesValue"] == ' ', \ + "The value is always only the value, so 2 empty strings with the space separator in the middle" + + def test_formatting_groups(self): + graph = Graph("") + node = graph.addNewNode("NodeWithAttributesNeedingFormatting") + node._buildCmdVars() + + assert node.firstGroup.getValueStr() == '"False:3"' + assert node._cmdVars["firstGroupValue"] == 'False:3', \ + "There should be no quotes here as the value is not formatted as a string" + + assert node.secondGroup.getValueStr() == '"False,second_value,3.0"' + assert node._cmdVars["secondGroupValue"] == 'False,second_value,3.0'