From: James Procter Date: Tue, 12 Dec 2023 20:55:49 +0000 (+0000) Subject: Merge branch 'bug/JAL-4353_cannot_output_multiple_different_structure_images_for_one_... X-Git-Tag: Release_2_11_3_3~8^2~1^2 X-Git-Url: http://source.jalview.org/gitweb/?a=commitdiff_plain;h=ac7c83b360752f04362700dcd279b5524a559da9;hp=cf66eafda7511e40453e251e2dee3f2951cca183;p=jalview.git Merge branch 'bug/JAL-4353_cannot_output_multiple_different_structure_images_for_one_alignment_with_renderpatch' into bug/JAL-4353_cannot_output_multiple_different_structure_images_for_one_alignment --- diff --git a/src/jalview/bin/argparser/ArgValuesMap.java b/src/jalview/bin/argparser/ArgValuesMap.java index 8a28b87..219983f 100644 --- a/src/jalview/bin/argparser/ArgValuesMap.java +++ b/src/jalview/bin/argparser/ArgValuesMap.java @@ -225,6 +225,25 @@ public class ArgValuesMap return av == null ? null : av.getValue(); } + public List getValues(Arg a) + { + return toValues(getArgValueList(a)); + } + + public static List toValues(List avl) + { + if (avl == null) + { + return null; + } + List vl = new ArrayList<>(); + for (ArgValue av : avl) + { + vl.add(av.getValue()); + } + return vl; + } + public boolean containsArg(Arg a) { if (m == null || !m.containsKey(a)) diff --git a/test/jalview/bin/argparser/ArgParserTest.java b/test/jalview/bin/argparser/ArgParserTest.java index 442812e..89c034a 100644 --- a/test/jalview/bin/argparser/ArgParserTest.java +++ b/test/jalview/bin/argparser/ArgParserTest.java @@ -22,9 +22,13 @@ package jalview.bin.argparser; import java.io.File; import java.io.IOException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashSet; import java.util.List; import java.util.Properties; +import org.apache.logging.log4j.util.Strings; import org.testng.Assert; import org.testng.annotations.AfterClass; import org.testng.annotations.AfterMethod; @@ -32,6 +36,7 @@ import org.testng.annotations.DataProvider; import org.testng.annotations.Test; import jalview.bin.Cache; +import jalview.bin.Console; import jalview.gui.Desktop; @Test(singleThreaded = true) @@ -452,4 +457,366 @@ public class ArgParserTest }; } + @Test(groups = "Functional", dataProvider = "argsWithinTypesData") + public void checkArgsWithinTypesTest(String commandLineArgs, + Object[] stuff) + { + String linkedId = "JALVIEW:0"; + String[] args = commandLineArgs.split("\\s+"); + ArgParser argparser = new ArgParser(args); + ArgValuesMap avm = argparser.getLinkedArgs(linkedId); + + ArgAndValues avals = (ArgAndValues) stuff[0]; + + Object[] moreStuff = (Object[]) stuff[1]; + + ArgAndValues[] subAv = (ArgAndValues[]) moreStuff[0]; + + Object[] secondaryArgAndAuxStuff = (Object[]) stuff[2]; + + // Now look at the argparser + + Arg primaryArg = avals.arg; + + List parsed_ArgValues = avm.getArgValueList(primaryArg); + + Assert.assertTrue( + areEqualSets(avals.values, + ArgValuesMap.toValues(parsed_ArgValues)), + "Primary arg (" + primaryArg.toString() + + ") does not have the expected values. Expected " + + avals.values + " and got " + + ArgValuesMap.toValues(parsed_ArgValues)); + + for (int i = 0; i < parsed_ArgValues.size(); i++) + { + ArgValue parsed_ArgValue = parsed_ArgValues.get(i); + String value = avals.values.get(i); + + Console.debug("- primary arg '" + primaryArg + "' = '" + value + "'"); + + Assert.assertEquals(parsed_ArgValue.getValue(), value, + "Primary arg value not as expected"); + + ArgAndValues[] aux_avals = (ArgAndValues[]) moreStuff[i]; + + for (ArgAndValues aux_aval : aux_avals) + { + Arg auxArg = aux_aval.arg; + List auxValues = aux_aval.values; + + String parsed_auxValue = avm.getFromSubValArgOrPref(auxArg, + ArgValuesMap.Position.AFTER, parsed_ArgValue, null, null, + null, null); + + if (auxValues.isEmpty()) + { + Assert.assertTrue(parsed_auxValue == null, + "Not expecting to parse a value for '" + auxArg + + "' but found '" + parsed_auxValue + "'"); + } + + for (String auxValue : auxValues) + { + + Console.debug("- + primary aux arg '" + auxArg + "' = '" + + auxValue + "'"); + + Assert.assertEquals(parsed_auxValue, auxValue, + "Primary auxiliary arg (" + auxArg.toString() + + ") values do not match"); + + } + } + + // Now for the secondary args + Object[] secondaryStuff = (Object[]) secondaryArgAndAuxStuff[i]; + ArgAndValues secondaryArgAndValues = (ArgAndValues) secondaryStuff[0]; + Arg secondaryArg = secondaryArgAndValues.arg; + List secondaryValues = secondaryArgAndValues.values; + + List parsed_secondaryArgValues = avm + .getArgValueListFromSubValOrArg(parsed_ArgValue, secondaryArg, + null); + + Assert.assertTrue( + areEqualSets(secondaryValues, + ArgValuesMap.toValues(parsed_secondaryArgValues)), + "Secondary arg (" + secondaryArg.toString() + + ") does not have the expected values"); + + Object[] secondaryMoreStuff = (Object[]) secondaryStuff[1]; + + for (int j = 0; j < parsed_secondaryArgValues.size(); j++) + { + ArgValue parsed_secondaryArgValue = parsed_secondaryArgValues + .get(j); + String secondary_value = secondaryValues.get(j); + + Console.debug("-- secondary arg '" + secondaryArg + "' = '" + + secondary_value + "'"); + + Assert.assertEquals(parsed_secondaryArgValue.getValue(), + secondary_value, "Secondary arg value not as expected"); + + ArgAndValues[] secondary_aux_avals = (ArgAndValues[]) secondaryMoreStuff[j]; + + for (ArgAndValues secondary_aux_aval : secondary_aux_avals) + { + Arg secondary_auxArg = secondary_aux_aval.arg; + List secondary_auxValues = secondary_aux_aval.values; + + String parsed_secondary_auxValue = avm.getValueFromSubValOrArg( + parsed_secondaryArgValue, secondary_auxArg, null); + + if (secondary_auxValues.isEmpty()) + { + Assert.assertTrue(parsed_secondary_auxValue == null, + "Not expecting to parse a value for '" + + secondary_auxArg + "' but found '" + + parsed_secondary_auxValue + "'"); + } + + for (String secondary_auxValue : secondary_auxValues) + { + Console.debug("-- + secondary aux arg '" + secondary_auxArg + + "' for value '" + secondary_auxValue + "'"); + + Assert.assertEquals(parsed_secondary_auxValue, + secondary_auxValue, + "Secondary auxiliary arg (" + + secondary_auxArg.toString() + + ") values do not match"); + } + } + } + } + } + + @DataProvider(name = "argsWithinTypesData") + public Object[][] argsWithinTypesData() + { + return new Object[][] { + /* + * { cmdline args }, + * { + * { Primary Arg, Secondary Args }, + * { { Secondary Arg => { Values } } } + * }, + */ + /* + */ + { // + // commandLineArgs + "--open=alignment.fa --structure=structure0.pdb" + // structureimage0a and structureimage args + + " --structureimage=image0a.png --bgcolour=bg0a --imagecolour=col0a" + // structureimage0b and structureimage args + + " --structureimage=image0b.png --bgcolour=bg0b --imagecolour=col0b" + // more structure args + + " --structureviewer=sv0 --paematrix=pae0" // + // structure1 + + " --structure=structure1.pdb" + // structure args + + " --structureviewer=sv1 --paematrix=pae1" + // structureimage1a with NO structureimage args + // (see `--all --bgcolour=pineapple` later) + + " --structureimage=image1a.png" + // structureimage1b and structureimage args + + " --structureimage=image1b.png --bgcolour=bg1b --imagecolour=col1b" + // --all args, should apply to structureimage1a only + + " --all --bgcolour=pineapple" // + , + // stuff + new Object[] + { + // avals (0) and (1) + av(Arg.STRUCTURE, "structure0.pdb", "structure1.pdb"), + // moreStuff (0) and (1) + new ArgAndValues[][] + { // + { av(Arg.STRUCTUREVIEWER, "sv0"), + av(Arg.PAEMATRIX, "pae0") }, + { av(Arg.STRUCTUREVIEWER, "sv1"), + av(Arg.PAEMATRIX, "pae1") } // + }, + // secondaryArgAndAuxStuff + // (same size as values of avals) + new Object[][] + { + // secondaryStuff (0) + { + // secondaryArgAndValues (a) and (b) + av(Arg.STRUCTUREIMAGE, "image0a.png", + "image0b.png"), + // secondaryMoreStuff + // (same size as values of secondaryArgAndValues) + new ArgAndValues[][] + { + // secondary_aux_avals (a) + { av(Arg.BGCOLOUR, "bg0a"), + av(Arg.IMAGECOLOUR, "col0a") }, + // secondary_aux_avals (b) + { av(Arg.BGCOLOUR, "bg0b"), + av(Arg.IMAGECOLOUR, "col0b") }, // + }, // + }, + // secondaryStuff (1) + { + // secondaryArgAndValues (a) and (b) + av(Arg.STRUCTUREIMAGE, "image1a.png", + "image1b.png"), + // secondaryMoreStuff + new ArgAndValues[][] + { + // secondary_aux_avals (a) + { av(Arg.BGCOLOUR, "pineapple"), + av(Arg.IMAGECOLOUR) }, + // secondary_aux_avals (b) + { av(Arg.BGCOLOUR, "bg1b"), + av(Arg.IMAGECOLOUR, "col1b") }, // + }, // + }, // + } // + } // + }, // + { // + "--open=alignment.fa --wrap --colour=gecose-flower" + // structure0 + + " --structure=structure0.pdb" + + " --structureimage=image0a.png --bgcolour=bg0a --scale=3" + + " --structureimage=image0b.png --imagecolour=col0b --scale=4" + + " --structureviewer=sv0 --paematrix=pae0" // + + " --structureimage=image0c.png" + // structure1 + + " --structure=structure1.pdb" + + " --structureviewer=sv1 --paematrix=pae1" + + " --structureimage=image1a.png" + + " --structureimage=image1b.png --bgcolour=bg1b --imagecolour=col1b" + + " --structureimage=image1c.png --bgcolour=bg1c --imagecolour=col1c --scale=5" + + " --structureimage=image1d.png --imagecolour=col1d --scale=6" + + " --structureimage=image1e.png --bgcolour=bg1e" + // structure2 + + " --structure=structure2.pdb" + + " --structureimage=image2a.png --bgcolour=bg2a --scale=23" + + " --all --bgcolour=pineapple --imagecolour=banana --scale=2" // + , + // stuff + new Object[] + { av(Arg.STRUCTURE, "structure0.pdb", "structure1.pdb", + "structure2.pdb"), + new ArgAndValues[][] + { // + { av(Arg.STRUCTUREVIEWER, "sv0"), + av(Arg.PAEMATRIX, "pae0") }, + { av(Arg.STRUCTUREVIEWER, "sv1"), + av(Arg.PAEMATRIX, "pae1") }, + { av(Arg.STRUCTUREVIEWER), av(Arg.PAEMATRIX) } // + }, // + new Object[][] + { // + { // + av(Arg.STRUCTUREIMAGE, "image0a.png", "image0b.png", + "image0c.png"), // + new ArgAndValues[][] + { // + { av(Arg.BGCOLOUR, "bg0a"), + av(Arg.IMAGECOLOUR, "banana"), + av(Arg.SCALE, "3") }, + { av(Arg.BGCOLOUR, "pineapple"), + av(Arg.IMAGECOLOUR, "col0b"), + av(Arg.SCALE, "4") }, + { av(Arg.BGCOLOUR, "pineapple"), + av(Arg.IMAGECOLOUR, "banana"), + av(Arg.SCALE, "2") }, // + }, // + }, // + { // + av(Arg.STRUCTUREIMAGE, "image1a.png", "image1b.png", + "image1c.png", "image1d.png", + "image1e.png"), + new ArgAndValues[][] + { // + { av(Arg.BGCOLOUR, "pineapple"), + av(Arg.IMAGECOLOUR, "banana"), + av(Arg.SCALE, "2") }, + { av(Arg.BGCOLOUR, "bg1b"), + av(Arg.IMAGECOLOUR, "col1b"), + av(Arg.SCALE, "2") }, + { av(Arg.BGCOLOUR, "bg1c"), + av(Arg.IMAGECOLOUR, "col1c"), + av(Arg.SCALE, "5") }, + { av(Arg.BGCOLOUR, "pineapple"), + av(Arg.IMAGECOLOUR, "col1d"), + av(Arg.SCALE, "6") }, + { av(Arg.BGCOLOUR, "bg1e"), + av(Arg.IMAGECOLOUR, "banana"), + av(Arg.SCALE, "2") } // + }, // + }, // + { // + av(Arg.STRUCTUREIMAGE, "image2a.png"), + new ArgAndValues[][] + { // + { av(Arg.BGCOLOUR, "bg2a"), + av(Arg.IMAGECOLOUR, "banana"), + av(Arg.SCALE, "23") }, // + }, // + }, // + } // + } // + } // + }; + } + + protected ArgAndValues av(Arg a, String... vals) + { + return new ArgAndValues(a, vals); + } + + protected class ArgAndValues + { + protected Arg arg; + + protected List values; + + ArgAndValues(Arg a, String... vals) + { + arg = a; + values = vals == null ? new ArrayList() : Arrays.asList(vals); + } + + @Override + public String toString() + { + StringBuilder sb = new StringBuilder(); + sb.append(arg.argString()); + sb.append("\n"); + sb.append(Strings.join(values, ',')); + sb.append("\n"); + return sb.toString(); + } + } + + private static boolean areEqualSets(String[] strArray, + List strList) + { + return areEqualSets(Arrays.asList(strArray), strList); + } + + private static boolean areEqualSets(List l1, List l2) + { + if (l1 == null && l2 == null) + { + Console.info( + "Comparing null lists, should be okay but you might want to know"); + return true; + } + if (l1 == null || l2 == null) + { + return false; + } + return new HashSet(l1).equals(new HashSet(l2)); + } + } \ No newline at end of file