mirror of
https://github.com/lightbend/config.git
synced 2025-03-22 15:20:26 +08:00
Add new subclasses of ConfigNodeComplexValue
Add three new classes, ConfigNodeObject, ConfigNodeArray, and ConfigNodeConcatenation, to differentiate the three types of complex nodes. Disallow setting values outside of ConfigNodeObjects.
This commit is contained in:
parent
d3b33cc6c2
commit
c44ef1c6f7
@ -178,7 +178,7 @@ final class ConfigDocumentParser {
|
|||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
return new ConfigNodeComplexValue(values);
|
return new ConfigNodeConcatenation(values);
|
||||||
}
|
}
|
||||||
|
|
||||||
private ConfigException parseError(String message) {
|
private ConfigException parseError(String message) {
|
||||||
@ -500,7 +500,7 @@ final class ConfigDocumentParser {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return new ConfigNodeComplexValue(objectNodes);
|
return new ConfigNodeObject(objectNodes);
|
||||||
}
|
}
|
||||||
|
|
||||||
private ConfigNodeComplexValue parseArray() {
|
private ConfigNodeComplexValue parseArray() {
|
||||||
@ -521,7 +521,7 @@ final class ConfigDocumentParser {
|
|||||||
if (t == Tokens.CLOSE_SQUARE) {
|
if (t == Tokens.CLOSE_SQUARE) {
|
||||||
arrayCount -= 1;
|
arrayCount -= 1;
|
||||||
children.add(new ConfigNodeSingleToken(t));
|
children.add(new ConfigNodeSingleToken(t));
|
||||||
return new ConfigNodeComplexValue(children);
|
return new ConfigNodeArray(children);
|
||||||
} else if (Tokens.isValue(t) || t == Tokens.OPEN_CURLY
|
} else if (Tokens.isValue(t) || t == Tokens.OPEN_CURLY
|
||||||
|| t == Tokens.OPEN_SQUARE || Tokens.isUnquotedText(t)
|
|| t == Tokens.OPEN_SQUARE || Tokens.isUnquotedText(t)
|
||||||
|| Tokens.isSubstitution(t)) {
|
|| Tokens.isSubstitution(t)) {
|
||||||
@ -547,7 +547,7 @@ final class ConfigDocumentParser {
|
|||||||
if (t == Tokens.CLOSE_SQUARE) {
|
if (t == Tokens.CLOSE_SQUARE) {
|
||||||
arrayCount -= 1;
|
arrayCount -= 1;
|
||||||
children.add(new ConfigNodeSingleToken(t));
|
children.add(new ConfigNodeSingleToken(t));
|
||||||
return new ConfigNodeComplexValue(children);
|
return new ConfigNodeArray(children);
|
||||||
} else {
|
} else {
|
||||||
throw parseError(addKeyName("List should have ended with ] or had a comma, instead had token: "
|
throw parseError(addKeyName("List should have ended with ] or had a comma, instead had token: "
|
||||||
+ t
|
+ t
|
||||||
@ -616,7 +616,10 @@ final class ConfigDocumentParser {
|
|||||||
ArrayList<AbstractConfigNode> children = new ArrayList<AbstractConfigNode>(((ConfigNodeComplexValue)result).children());
|
ArrayList<AbstractConfigNode> children = new ArrayList<AbstractConfigNode>(((ConfigNodeComplexValue)result).children());
|
||||||
t = nextTokenIgnoringWhitespace(children);
|
t = nextTokenIgnoringWhitespace(children);
|
||||||
if (t == Tokens.END) {
|
if (t == Tokens.END) {
|
||||||
return new ConfigNodeComplexValue(children);
|
if (result instanceof ConfigNodeArray) {
|
||||||
|
return new ConfigNodeArray(children);
|
||||||
|
}
|
||||||
|
return new ConfigNodeObject(children);
|
||||||
} else {
|
} else {
|
||||||
throw parseError("Document has trailing tokens after first object or array: "
|
throw parseError("Document has trailing tokens after first object or array: "
|
||||||
+ t);
|
+ t);
|
||||||
|
@ -0,0 +1,9 @@
|
|||||||
|
package com.typesafe.config.impl;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
|
||||||
|
final class ConfigNodeArray extends ConfigNodeComplexValue {
|
||||||
|
ConfigNodeArray(Collection<AbstractConfigNode> children) {
|
||||||
|
super(children);
|
||||||
|
}
|
||||||
|
}
|
@ -5,8 +5,8 @@ package com.typesafe.config.impl;
|
|||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
final class ConfigNodeComplexValue extends AbstractConfigNodeValue {
|
abstract class ConfigNodeComplexValue extends AbstractConfigNodeValue {
|
||||||
final private ArrayList<AbstractConfigNode> children;
|
final protected ArrayList<AbstractConfigNode> children;
|
||||||
|
|
||||||
ConfigNodeComplexValue(Collection<AbstractConfigNode> children) {
|
ConfigNodeComplexValue(Collection<AbstractConfigNode> children) {
|
||||||
this.children = new ArrayList(children);
|
this.children = new ArrayList(children);
|
||||||
@ -24,64 +24,4 @@ final class ConfigNodeComplexValue extends AbstractConfigNodeValue {
|
|||||||
}
|
}
|
||||||
return tokens;
|
return tokens;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected ConfigNodeComplexValue changeValueOnPath(Path desiredPath, AbstractConfigNodeValue value) {
|
|
||||||
ArrayList<AbstractConfigNode> childrenCopy = new ArrayList(children);
|
|
||||||
// Copy the value so we can change it to null but not modify the original parameter
|
|
||||||
AbstractConfigNodeValue valueCopy = value;
|
|
||||||
for (int i = children.size() - 1; i >= 0; i--) {
|
|
||||||
if (!(children.get(i) instanceof ConfigNodeField)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
ConfigNodeField node = (ConfigNodeField)children.get(i);
|
|
||||||
Path key = node.path().value();
|
|
||||||
if (key.equals(desiredPath)) {
|
|
||||||
if (valueCopy == null)
|
|
||||||
childrenCopy.remove(i);
|
|
||||||
else {
|
|
||||||
childrenCopy.set(i, node.replaceValue(value));
|
|
||||||
valueCopy = null;
|
|
||||||
}
|
|
||||||
} else if (desiredPath.startsWith(key)) {
|
|
||||||
if (node.value() instanceof ConfigNodeComplexValue) {
|
|
||||||
Path remainingPath = desiredPath.subPath(key.length());
|
|
||||||
childrenCopy.set(i, node.replaceValue(((ConfigNodeComplexValue) node.value()).changeValueOnPath(remainingPath, valueCopy)));
|
|
||||||
if (valueCopy != null && node.render() != children.get(i).render())
|
|
||||||
valueCopy = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return new ConfigNodeComplexValue(childrenCopy);
|
|
||||||
}
|
|
||||||
|
|
||||||
public ConfigNodeComplexValue setValueOnPath(String desiredPath, AbstractConfigNodeValue value) {
|
|
||||||
ConfigNodePath path = PathParser.parsePathNode(desiredPath);
|
|
||||||
return setValueOnPath(path, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
private ConfigNodeComplexValue setValueOnPath(ConfigNodePath desiredPath, AbstractConfigNodeValue value) {
|
|
||||||
ConfigNodeComplexValue node = changeValueOnPath(desiredPath.value(), value);
|
|
||||||
|
|
||||||
// If the desired Path did not exist, add it
|
|
||||||
if (node.render().equals(render())) {
|
|
||||||
ArrayList<AbstractConfigNode> childrenCopy = new ArrayList<AbstractConfigNode>(children);
|
|
||||||
ArrayList<AbstractConfigNode> newNodes = new ArrayList();
|
|
||||||
newNodes.add(new ConfigNodeSingleToken(Tokens.newLine(null)));
|
|
||||||
newNodes.add(desiredPath);
|
|
||||||
newNodes.add(new ConfigNodeSingleToken(Tokens.newIgnoredWhitespace(null, " ")));
|
|
||||||
newNodes.add(new ConfigNodeSingleToken(Tokens.COLON));
|
|
||||||
newNodes.add(new ConfigNodeSingleToken(Tokens.newIgnoredWhitespace(null, " ")));
|
|
||||||
newNodes.add(value);
|
|
||||||
newNodes.add(new ConfigNodeSingleToken(Tokens.newLine(null)));
|
|
||||||
childrenCopy.add(new ConfigNodeField(newNodes));
|
|
||||||
node = new ConfigNodeComplexValue(childrenCopy);
|
|
||||||
}
|
|
||||||
return node;
|
|
||||||
}
|
|
||||||
|
|
||||||
public ConfigNodeComplexValue removeValueOnPath(String desiredPath) {
|
|
||||||
Path path = PathParser.parsePath(desiredPath);
|
|
||||||
return changeValueOnPath(path, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,9 @@
|
|||||||
|
package com.typesafe.config.impl;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
|
||||||
|
final class ConfigNodeConcatenation extends ConfigNodeComplexValue {
|
||||||
|
ConfigNodeConcatenation(Collection<AbstractConfigNode> children) {
|
||||||
|
super(children);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,69 @@
|
|||||||
|
package com.typesafe.config.impl;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collection;
|
||||||
|
|
||||||
|
final class ConfigNodeObject extends ConfigNodeComplexValue {
|
||||||
|
ConfigNodeObject(Collection<AbstractConfigNode> children) {
|
||||||
|
super(children);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected ConfigNodeObject changeValueOnPath(Path desiredPath, AbstractConfigNodeValue value) {
|
||||||
|
ArrayList<AbstractConfigNode> childrenCopy = new ArrayList(super.children);
|
||||||
|
// Copy the value so we can change it to null but not modify the original parameter
|
||||||
|
AbstractConfigNodeValue valueCopy = value;
|
||||||
|
for (int i = super.children.size() - 1; i >= 0; i--) {
|
||||||
|
if (!(super.children.get(i) instanceof ConfigNodeField)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
ConfigNodeField node = (ConfigNodeField)super.children.get(i);
|
||||||
|
Path key = node.path().value();
|
||||||
|
if (key.equals(desiredPath)) {
|
||||||
|
if (valueCopy == null)
|
||||||
|
childrenCopy.remove(i);
|
||||||
|
else {
|
||||||
|
childrenCopy.set(i, node.replaceValue(value));
|
||||||
|
valueCopy = null;
|
||||||
|
}
|
||||||
|
} else if (desiredPath.startsWith(key)) {
|
||||||
|
if (node.value() instanceof ConfigNodeObject) {
|
||||||
|
Path remainingPath = desiredPath.subPath(key.length());
|
||||||
|
childrenCopy.set(i, node.replaceValue(((ConfigNodeObject)node.value()).changeValueOnPath(remainingPath, valueCopy)));
|
||||||
|
if (valueCopy != null && node.render() != super.children.get(i).render())
|
||||||
|
valueCopy = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return new ConfigNodeObject(childrenCopy);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ConfigNodeObject setValueOnPath(String desiredPath, AbstractConfigNodeValue value) {
|
||||||
|
ConfigNodePath path = PathParser.parsePathNode(desiredPath);
|
||||||
|
return setValueOnPath(path, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
private ConfigNodeObject setValueOnPath(ConfigNodePath desiredPath, AbstractConfigNodeValue value) {
|
||||||
|
ConfigNodeObject node = changeValueOnPath(desiredPath.value(), value);
|
||||||
|
|
||||||
|
// If the desired Path did not exist, add it
|
||||||
|
if (node.render().equals(render())) {
|
||||||
|
ArrayList<AbstractConfigNode> childrenCopy = new ArrayList<AbstractConfigNode>(super.children);
|
||||||
|
ArrayList<AbstractConfigNode> newNodes = new ArrayList();
|
||||||
|
newNodes.add(new ConfigNodeSingleToken(Tokens.newLine(null)));
|
||||||
|
newNodes.add(desiredPath);
|
||||||
|
newNodes.add(new ConfigNodeSingleToken(Tokens.newIgnoredWhitespace(null, " ")));
|
||||||
|
newNodes.add(new ConfigNodeSingleToken(Tokens.COLON));
|
||||||
|
newNodes.add(new ConfigNodeSingleToken(Tokens.newIgnoredWhitespace(null, " ")));
|
||||||
|
newNodes.add(value);
|
||||||
|
newNodes.add(new ConfigNodeSingleToken(Tokens.newLine(null)));
|
||||||
|
childrenCopy.add(new ConfigNodeField(newNodes));
|
||||||
|
node = new ConfigNodeObject(childrenCopy);
|
||||||
|
}
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ConfigNodeComplexValue removeValueOnPath(String desiredPath) {
|
||||||
|
Path path = PathParser.parsePath(desiredPath);
|
||||||
|
return changeValueOnPath(path, null);
|
||||||
|
}
|
||||||
|
}
|
@ -20,7 +20,7 @@ class ConfigNodeTest extends TestUtils {
|
|||||||
assertEquals(node.render(), token.tokenText())
|
assertEquals(node.render(), token.tokenText())
|
||||||
}
|
}
|
||||||
|
|
||||||
private def keyValueNodeTest(key: ConfigNodePath, value: AbstractConfigNodeValue, trailingWhitespace: ConfigNodeSingleToken, newValue: AbstractConfigNodeValue) {
|
private def fieldNodeTest(key: ConfigNodePath, value: AbstractConfigNodeValue, trailingWhitespace: ConfigNodeSingleToken, newValue: AbstractConfigNodeValue) {
|
||||||
val keyValNode = nodeKeyValuePair(key, value, trailingWhitespace)
|
val keyValNode = nodeKeyValuePair(key, value, trailingWhitespace)
|
||||||
assertEquals(key.render() + " : " + value.render() + trailingWhitespace.render(), keyValNode.render())
|
assertEquals(key.render() + " : " + value.render() + trailingWhitespace.render(), keyValNode.render())
|
||||||
assertEquals(key.render, keyValNode.path().render())
|
assertEquals(key.render, keyValNode.path().render())
|
||||||
@ -35,7 +35,7 @@ class ConfigNodeTest extends TestUtils {
|
|||||||
val complexNodeChildren = List(nodeOpenBrace,
|
val complexNodeChildren = List(nodeOpenBrace,
|
||||||
nodeKeyValuePair(nodeWhitespace(" "), configNodeKey(key),value, nodeWhitespace(" ")),
|
nodeKeyValuePair(nodeWhitespace(" "), configNodeKey(key),value, nodeWhitespace(" ")),
|
||||||
nodeCloseBrace)
|
nodeCloseBrace)
|
||||||
val complexNode = configNodeComplexValue(complexNodeChildren)
|
val complexNode = configNodeObject(complexNodeChildren)
|
||||||
val newNode = complexNode.setValueOnPath(key, newValue)
|
val newNode = complexNode.setValueOnPath(key, newValue)
|
||||||
val origText = "{ " + key + " : " + value.render() + " }"
|
val origText = "{ " + key + " : " + value.render() + " }"
|
||||||
val finalText = "{ " + key + " : " + newValue.render() + " }"
|
val finalText = "{ " + key + " : " + newValue.render() + " }"
|
||||||
@ -49,7 +49,7 @@ class ConfigNodeTest extends TestUtils {
|
|||||||
val keyValPair1 = nodeKeyValuePair(key, value1)
|
val keyValPair1 = nodeKeyValuePair(key, value1)
|
||||||
val keyValPair2 = nodeKeyValuePair(key, value2)
|
val keyValPair2 = nodeKeyValuePair(key, value2)
|
||||||
val keyValPair3 = nodeKeyValuePair(key, value3)
|
val keyValPair3 = nodeKeyValuePair(key, value3)
|
||||||
val complexNode = configNodeComplexValue(List(keyValPair1, keyValPair2, keyValPair3))
|
val complexNode = configNodeObject(List(keyValPair1, keyValPair2, keyValPair3))
|
||||||
val origText = keyValPair1.render() + keyValPair2.render() + keyValPair3.render()
|
val origText = keyValPair1.render() + keyValPair2.render() + keyValPair3.render()
|
||||||
val finalText = key.render() + " : 15"
|
val finalText = key.render() + " : 15"
|
||||||
|
|
||||||
@ -58,7 +58,7 @@ class ConfigNodeTest extends TestUtils {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private def nonExistentPathTest(value: AbstractConfigNodeValue) {
|
private def nonExistentPathTest(value: AbstractConfigNodeValue) {
|
||||||
val node = configNodeComplexValue(List(nodeKeyValuePair(configNodeKey("bar"), nodeInt(15))))
|
val node = configNodeObject(List(nodeKeyValuePair(configNodeKey("bar"), nodeInt(15))))
|
||||||
assertEquals("bar : 15", node.render())
|
assertEquals("bar : 15", node.render())
|
||||||
val newNode = node.setValueOnPath("foo", value)
|
val newNode = node.setValueOnPath("foo", value)
|
||||||
val finalText = "bar : 15\nfoo : " + value.render() + "\n"
|
val finalText = "bar : 15\nfoo : " + value.render() + "\n"
|
||||||
@ -109,14 +109,14 @@ class ConfigNodeTest extends TestUtils {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
def createConfigNodeKeyValue() {
|
def createConfigNodeField() {
|
||||||
// Supports Quoted and Unquoted keys
|
// Supports Quoted and Unquoted keys
|
||||||
keyValueNodeTest(configNodeKey("\"abc\""), nodeInt(123), nodeLine(1), nodeInt(245))
|
fieldNodeTest(configNodeKey("\"abc\""), nodeInt(123), nodeLine(1), nodeInt(245))
|
||||||
keyValueNodeTest(configNodeKey("abc"), nodeInt(123), nodeLine(1), nodeInt(245))
|
fieldNodeTest(configNodeKey("abc"), nodeInt(123), nodeLine(1), nodeInt(245))
|
||||||
|
|
||||||
// Can replace value with values of different types
|
// Can replace value with values of different types
|
||||||
keyValueNodeTest(configNodeKey("\"abc\""), nodeInt(123), nodeLine(1), nodeString("I am a string"))
|
fieldNodeTest(configNodeKey("\"abc\""), nodeInt(123), nodeLine(1), nodeString("I am a string"))
|
||||||
keyValueNodeTest(configNodeKey("\"abc\""), nodeInt(123), nodeLine(1), configNodeComplexValue(List(nodeOpenBrace, nodeCloseBrace)))
|
fieldNodeTest(configNodeKey("\"abc\""), nodeInt(123), nodeLine(1), configNodeObject(List(nodeOpenBrace, nodeCloseBrace)))
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@ -135,20 +135,30 @@ class ConfigNodeTest extends TestUtils {
|
|||||||
topLevelValueReplaceTest(nodeSubstitution(tokenUnquoted("a.b")), nodeInt(10))
|
topLevelValueReplaceTest(nodeSubstitution(tokenUnquoted("a.b")), nodeInt(10))
|
||||||
|
|
||||||
// Ensure arrays can be replaced
|
// Ensure arrays can be replaced
|
||||||
val array = configNodeComplexValue(List(nodeOpenBracket, nodeInt(10), nodeSpace, nodeComma, nodeSpace, nodeInt(15), nodeCloseBracket))
|
val array = configNodeArray(List(nodeOpenBracket, nodeInt(10), nodeSpace, nodeComma, nodeSpace, nodeInt(15), nodeCloseBracket))
|
||||||
topLevelValueReplaceTest(nodeInt(10), array)
|
topLevelValueReplaceTest(nodeInt(10), array)
|
||||||
topLevelValueReplaceTest(array, nodeInt(10))
|
topLevelValueReplaceTest(array, nodeInt(10))
|
||||||
topLevelValueReplaceTest(array, configNodeComplexValue(List(nodeOpenBrace, nodeCloseBrace)))
|
topLevelValueReplaceTest(array, configNodeObject(List(nodeOpenBrace, nodeCloseBrace)))
|
||||||
|
|
||||||
//Ensure maps can be replaced
|
// Ensure maps can be replaced
|
||||||
val nestedMap = configNodeComplexValue(List(nodeOpenBrace, configNodeKey("abc"),
|
val nestedMap = configNodeObject(List(nodeOpenBrace, configNodeKey("abc"),
|
||||||
nodeColon, configNodeSimpleValue(tokenString("a string")),
|
nodeColon, configNodeSimpleValue(tokenString("a string")),
|
||||||
nodeCloseBrace))
|
nodeCloseBrace))
|
||||||
topLevelValueReplaceTest(nestedMap, nodeInt(10))
|
topLevelValueReplaceTest(nestedMap, nodeInt(10))
|
||||||
topLevelValueReplaceTest(nodeInt(10), nestedMap)
|
topLevelValueReplaceTest(nodeInt(10), nestedMap)
|
||||||
topLevelValueReplaceTest(array, nestedMap)
|
topLevelValueReplaceTest(array, nestedMap)
|
||||||
topLevelValueReplaceTest(nestedMap, array)
|
topLevelValueReplaceTest(nestedMap, array)
|
||||||
topLevelValueReplaceTest(nestedMap, configNodeComplexValue(List(nodeOpenBrace, nodeCloseBrace)))
|
topLevelValueReplaceTest(nestedMap, configNodeObject(List(nodeOpenBrace, nodeCloseBrace)))
|
||||||
|
|
||||||
|
// Ensure concatenations can be replaced
|
||||||
|
val concatenation = configNodeConcatenation(List(nodeInt(10), nodeSpace, nodeString("Hello")))
|
||||||
|
topLevelValueReplaceTest(concatenation, nodeInt(12))
|
||||||
|
topLevelValueReplaceTest(nodeInt(12), concatenation)
|
||||||
|
topLevelValueReplaceTest(nestedMap, concatenation)
|
||||||
|
topLevelValueReplaceTest(concatenation, nestedMap)
|
||||||
|
topLevelValueReplaceTest(array, concatenation)
|
||||||
|
topLevelValueReplaceTest(concatenation, array)
|
||||||
|
|
||||||
|
|
||||||
//Ensure a key with format "a.b" will be properly replaced
|
//Ensure a key with format "a.b" will be properly replaced
|
||||||
topLevelValueReplaceTest(nodeInt(10), nestedMap, "foo.bar")
|
topLevelValueReplaceTest(nodeInt(10), nestedMap, "foo.bar")
|
||||||
@ -156,8 +166,8 @@ class ConfigNodeTest extends TestUtils {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
def removeDuplicates() {
|
def removeDuplicates() {
|
||||||
val emptyMapNode = configNodeComplexValue(List(nodeOpenBrace, nodeCloseBrace))
|
val emptyMapNode = configNodeObject(List(nodeOpenBrace, nodeCloseBrace))
|
||||||
val emptyArrayNode = configNodeComplexValue(List(nodeOpenBracket, nodeCloseBracket))
|
val emptyArrayNode = configNodeArray(List(nodeOpenBracket, nodeCloseBracket))
|
||||||
//Ensure duplicates of a key are removed from a map
|
//Ensure duplicates of a key are removed from a map
|
||||||
replaceDuplicatesTest(nodeInt(10), nodeTrue, nodeNull)
|
replaceDuplicatesTest(nodeInt(10), nodeTrue, nodeNull)
|
||||||
replaceDuplicatesTest(emptyMapNode, emptyMapNode, emptyMapNode)
|
replaceDuplicatesTest(emptyMapNode, emptyMapNode, emptyMapNode)
|
||||||
@ -168,8 +178,8 @@ class ConfigNodeTest extends TestUtils {
|
|||||||
@Test
|
@Test
|
||||||
def addNonExistentPaths() {
|
def addNonExistentPaths() {
|
||||||
nonExistentPathTest(nodeInt(10))
|
nonExistentPathTest(nodeInt(10))
|
||||||
nonExistentPathTest(configNodeComplexValue(List(nodeOpenBracket, nodeInt(15), nodeCloseBracket)))
|
nonExistentPathTest(configNodeArray(List(nodeOpenBracket, nodeInt(15), nodeCloseBracket)))
|
||||||
nonExistentPathTest(configNodeComplexValue(List(nodeOpenBrace, nodeKeyValuePair(configNodeKey("foo"), nodeDouble(3.14), nodeSpace))))
|
nonExistentPathTest(configNodeObject(List(nodeOpenBrace, nodeKeyValuePair(configNodeKey("foo"), nodeDouble(3.14), nodeSpace))))
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@ -177,21 +187,21 @@ class ConfigNodeTest extends TestUtils {
|
|||||||
// Test that all features of node replacement in a map work in a complex map containing nested maps
|
// Test that all features of node replacement in a map work in a complex map containing nested maps
|
||||||
val origText = "foo : bar\nbaz : {\n\t\"abc.def\" : 123\n\t//This is a comment about the below setting\n\n\tabc : {\n\t\t" +
|
val origText = "foo : bar\nbaz : {\n\t\"abc.def\" : 123\n\t//This is a comment about the below setting\n\n\tabc : {\n\t\t" +
|
||||||
"def : \"this is a string\"\n\t\tghi : ${\"a.b\"}\n\t}\n}\nbaz.abc.ghi : 52\nbaz.abc.ghi : 53\n}"
|
"def : \"this is a string\"\n\t\tghi : ${\"a.b\"}\n\t}\n}\nbaz.abc.ghi : 52\nbaz.abc.ghi : 53\n}"
|
||||||
val lowestLevelMap = configNodeComplexValue(List(nodeOpenBrace, nodeLine(6),
|
val lowestLevelMap = configNodeObject(List(nodeOpenBrace, nodeLine(6),
|
||||||
nodeKeyValuePair(nodeWhitespace("\t\t"), configNodeKey("def"), configNodeSimpleValue(tokenString("this is a string")), nodeLine(7)),
|
nodeKeyValuePair(nodeWhitespace("\t\t"), configNodeKey("def"), configNodeSimpleValue(tokenString("this is a string")), nodeLine(7)),
|
||||||
nodeKeyValuePair(nodeWhitespace("\t\t"), configNodeKey("ghi"), configNodeSimpleValue(tokenKeySubstitution("a.b")), nodeLine(8)),
|
nodeKeyValuePair(nodeWhitespace("\t\t"), configNodeKey("ghi"), configNodeSimpleValue(tokenKeySubstitution("a.b")), nodeLine(8)),
|
||||||
nodeWhitespace("\t"), nodeCloseBrace))
|
nodeWhitespace("\t"), nodeCloseBrace))
|
||||||
val higherLevelMap = configNodeComplexValue(List(nodeOpenBrace, nodeLine(2),
|
val higherLevelMap = configNodeObject(List(nodeOpenBrace, nodeLine(2),
|
||||||
nodeKeyValuePair(nodeWhitespace("\t"), configNodeKey("\"abc.def\""), configNodeSimpleValue(tokenInt(123)), nodeLine(3)),
|
nodeKeyValuePair(nodeWhitespace("\t"), configNodeKey("\"abc.def\""), configNodeSimpleValue(tokenInt(123)), nodeLine(3)),
|
||||||
nodeWhitespace("\t"), configNodeBasic(tokenCommentDoubleSlash("This is a comment about the below setting")),
|
nodeWhitespace("\t"), configNodeBasic(tokenCommentDoubleSlash("This is a comment about the below setting")),
|
||||||
nodeLine(4), nodeLine(5),
|
nodeLine(4), nodeLine(5),
|
||||||
nodeKeyValuePair(nodeWhitespace("\t"), configNodeKey("abc"), lowestLevelMap, nodeLine(9)), nodeWhitespace(""),
|
nodeKeyValuePair(nodeWhitespace("\t"), configNodeKey("abc"), lowestLevelMap, nodeLine(9)), nodeWhitespace(""),
|
||||||
nodeCloseBrace))
|
nodeCloseBrace))
|
||||||
val origNode = configNodeComplexValue(List(nodeKeyValuePair(configNodeKey("foo"), configNodeSimpleValue(tokenUnquoted("bar")), nodeLine(1)),
|
val origNode = configNodeObject(List(nodeKeyValuePair(configNodeKey("foo"), configNodeSimpleValue(tokenUnquoted("bar")), nodeLine(1)),
|
||||||
nodeKeyValuePair(configNodeKey("baz"), higherLevelMap, nodeLine(10)),
|
nodeKeyValuePair(configNodeKey("baz"), higherLevelMap, nodeLine(10)),
|
||||||
nodeKeyValuePair(configNodeKey("baz.abc.ghi"), configNodeSimpleValue(tokenInt(52)), nodeLine(11)),
|
nodeKeyValuePair(configNodeKey("baz.abc.ghi"), configNodeSimpleValue(tokenInt(52)), nodeLine(11)),
|
||||||
nodeKeyValuePair(configNodeKey("baz.abc.ghi"), configNodeSimpleValue(tokenInt(53)), nodeLine(12)),
|
nodeKeyValuePair(configNodeKey("baz.abc.ghi"), configNodeSimpleValue(tokenInt(53)), nodeLine(12)),
|
||||||
nodeCloseBrace))
|
nodeCloseBrace))
|
||||||
assertEquals(origText, origNode.render())
|
assertEquals(origText, origNode.render())
|
||||||
val finalText = "foo : bar\nbaz : {\n\t\"abc.def\" : true\n\t//This is a comment about the below setting\n\n\tabc : {\n\t\t" +
|
val finalText = "foo : bar\nbaz : {\n\t\"abc.def\" : true\n\t//This is a comment about the below setting\n\n\tabc : {\n\t\t" +
|
||||||
"def : false\n\t}\n}\nbaz.abc.ghi : randomunquotedString\n}\nbaz.abc.\"this.does.not.exist@@@+$#\".end : doesnotexist\n"
|
"def : false\n\t}\n}\nbaz.abc.ghi : randomunquotedString\n}\nbaz.abc.\"this.does.not.exist@@@+$#\".end : doesnotexist\n"
|
||||||
|
@ -673,8 +673,16 @@ abstract trait TestUtils {
|
|||||||
new ConfigNodeSingleToken(value: Token)
|
new ConfigNodeSingleToken(value: Token)
|
||||||
}
|
}
|
||||||
|
|
||||||
def configNodeComplexValue(nodes: List[AbstractConfigNode]) = {
|
def configNodeObject(nodes: List[AbstractConfigNode]) = {
|
||||||
new ConfigNodeComplexValue(nodes.asJavaCollection)
|
new ConfigNodeObject(nodes.asJavaCollection)
|
||||||
|
}
|
||||||
|
|
||||||
|
def configNodeArray(nodes: List[AbstractConfigNode]) = {
|
||||||
|
new ConfigNodeArray(nodes.asJavaCollection)
|
||||||
|
}
|
||||||
|
|
||||||
|
def configNodeConcatenation(nodes: List[AbstractConfigNode]) = {
|
||||||
|
new ConfigNodeConcatenation(nodes.asJavaCollection)
|
||||||
}
|
}
|
||||||
|
|
||||||
def nodeColon = new ConfigNodeSingleToken(Tokens.COLON)
|
def nodeColon = new ConfigNodeSingleToken(Tokens.COLON)
|
||||||
|
Loading…
Reference in New Issue
Block a user