+ assertEquals(testee.setBackgroundColour(
+ Color.PINK),
+ new StructureCommand("bg_color", "0xffafaf"));
+ }
+
+ @Test(groups = "Functional")
+ public void testSetAttribute()
+ {
+ AtomSpecModel model = new AtomSpecModel();
+ model.addRange("1", 89, 92, "A");
+ model.addRange("2", 12, 20, "B");
+ model.addRange("2", 8, 9, "B");
+ assertEquals(testee.setAttribute("jv_kd", "27.3", model),
+ new StructureCommand("iterate", "1//A/89-92/ 2//B/8-9+12-20/",
+ "p.jv_kd='27.3'"));
+ }
+
+ @Test(groups = { "Functional" })
+ public void testSetAttributes()
+ {
+ /*
+ * make a map of { featureType, {featureValue, {residue range specification } } }
+ */
+ Map<String, Map<Object, AtomSpecModel>> featuresMap = new LinkedHashMap<>();
+ Map<Object, AtomSpecModel> featureValues = new HashMap<>();
+
+ /*
+ * start with just one feature/value...
+ */
+ featuresMap.put("chain", featureValues);
+ ChimeraCommands.addAtomSpecRange(featureValues, "X", "0", 8, 20, "A");
+
+ List<StructureCommandI> commands = testee.setAttributes(featuresMap);
+ assertEquals(commands.size(), 1);
+
+ /*
+ * feature name gets a jv_ namespace prefix
+ */
+ assertEquals(commands.get(0), new StructureCommand("iterate",
+ "0//A/8-20/", "p.jv_chain='X'"));
+
+ // add same feature value, overlapping range
+ ChimeraCommands.addAtomSpecRange(featureValues, "X", "0", 3, 9, "A");
+ // same feature value, contiguous range
+ ChimeraCommands.addAtomSpecRange(featureValues, "X", "0", 21, 25, "A");
+ commands = testee.setAttributes(featuresMap);
+ assertEquals(commands.size(), 1);
+ assertEquals(commands.get(0), new StructureCommand("iterate",
+ "0//A/3-25/", "p.jv_chain='X'"));
+
+ // same feature value and model, different chain
+ ChimeraCommands.addAtomSpecRange(featureValues, "X", "0", 21, 25, "B");
+ // same feature value and chain, different model
+ ChimeraCommands.addAtomSpecRange(featureValues, "X", "1", 26, 30, "A");
+ commands = testee.setAttributes(featuresMap);
+ assertEquals(commands.size(), 1);
+ StructureCommand expected1 = new StructureCommand("iterate",
+ "0//A/3-25/ 0//B/21-25/ 1//A/26-30/", "p.jv_chain='X'");
+ assertEquals(commands.get(0), expected1);
+
+ // same feature, different value
+ ChimeraCommands.addAtomSpecRange(featureValues, "Y", "0", 40, 50, "A");
+ commands = testee.setAttributes(featuresMap);
+ assertEquals(2, commands.size());
+ // commands are ordered by feature type but not by value
+ // so test for the expected command in either order
+ StructureCommandI cmd1 = commands.get(0);
+ StructureCommandI cmd2 = commands.get(1);
+ StructureCommand expected2 = new StructureCommand("iterate",
+ "0//A/40-50/", "p.jv_chain='Y'");
+ assertTrue(cmd1.equals(expected1) || cmd2.equals(expected1));
+ // String expected2 = "setattr #0/A:40-50 res jv_chain 'Y' create true";
+ assertTrue(cmd1.equals(expected2) || cmd2.equals(expected2));
+
+ featuresMap.clear();
+ featureValues.clear();
+ featuresMap.put("side-chain binding!", featureValues);
+ ChimeraCommands.addAtomSpecRange(featureValues,
+ "<html>metal <a href=\"http:a.b.c/x\"> 'ion!", "0", 7, 15, "A");
+ // feature names are sanitised to change non-alphanumeric to underscore
+ // feature values are sanitised to encode single quote characters
+ commands = testee.setAttributes(featuresMap);
+ assertEquals(commands.size(), 1);
+ StructureCommandI expected3 = new StructureCommand("iterate",
+ "0//A/7-15/",
+ "p.jv_side_chain_binding_='<html>metal <a href=\"http:a.b.c/x\"> 'ion!'");
+ assertEquals(commands.get(0), expected3);