aboutsummaryrefslogtreecommitdiff
path: root/src/test/java/org
diff options
context:
space:
mode:
authorMichael Williamson <mike@zwobble.org>2025-01-01 01:39:18 +0000
committerMichael Williamson <mike@zwobble.org>2025-01-01 09:45:58 +0000
commitb65c719e2b65a9662b6170b0b53dfed9f1a3edcd (patch)
tree6700b1a717d01a83b644dd06eb508e12a43b492c /src/test/java/org
parent0df6725da8a0953c5643c5692c5244826e448d09 (diff)
Use JSON5 instead of TOML for config
Diffstat (limited to 'src/test/java/org')
-rw-r--r--src/test/java/org/shedlang/compiler/config/BinConfigTests.java24
-rw-r--r--src/test/java/org/shedlang/compiler/config/GcConfigTests.java28
-rw-r--r--src/test/java/org/shedlang/compiler/config/GcMarkAndSweepConfigTests.java14
-rw-r--r--src/test/java/org/shedlang/compiler/config/ProfileConfigTests.java24
-rw-r--r--src/test/java/org/shedlang/compiler/config/ProjectConfigTests.java164
-rw-r--r--src/test/java/org/shedlang/compiler/config/json/Json5ObjectWithSourceTests.java406
-rw-r--r--src/test/java/org/shedlang/compiler/config/toml/TomlTableWithSourceTests.java325
7 files changed, 539 insertions, 446 deletions
diff --git a/src/test/java/org/shedlang/compiler/config/BinConfigTests.java b/src/test/java/org/shedlang/compiler/config/BinConfigTests.java
index aead8546..d909bb84 100644
--- a/src/test/java/org/shedlang/compiler/config/BinConfigTests.java
+++ b/src/test/java/org/shedlang/compiler/config/BinConfigTests.java
@@ -2,7 +2,7 @@ package org.shedlang.compiler.config;
import org.junit.jupiter.api.Test;
import org.shedlang.compiler.config.errors.ConfigError;
-import org.shedlang.compiler.config.toml.TomlTableWithSource;
+import org.shedlang.compiler.config.json.Json5ObjectWithSource;
import org.shedlang.compiler.sources.Sources;
import org.shedlang.compiler.types.NamespaceName;
@@ -14,11 +14,13 @@ public class BinConfigTests {
@Test
public void canParseBinConfigWithNameAndMainNamespace() {
var source = Sources.string("""
- name = "one"
- main-namespace = "A/B"
+ {
+ name: "one",
+ mainNamespace: "A/B",
+ }
""");
- var config = BinConfig.fromToml(TomlTableWithSource.parse(source));
+ var config = BinConfig.fromJson5(Json5ObjectWithSource.parse(source));
assertThat(config, allOf(
has("name", x -> x.name(), equalTo("one")),
@@ -28,13 +30,15 @@ public class BinConfigTests {
@Test
public void whenMainNamespaceHasSyntaxErrorThenErrorIsThrown() {
var source = Sources.string("""
- name = "one"
- main-namespace = "A.B"
+ {
+ name: "one",
+ mainNamespace: "A.B",
+ }
""");
var error = assertThrows(
ConfigError.class,
- () -> BinConfig.fromToml(TomlTableWithSource.parse(source))
+ () -> BinConfig.fromJson5(Json5ObjectWithSource.parse(source))
);
assertThat(error.getMessage(), equalTo("""
@@ -46,8 +50,8 @@ public class BinConfigTests {
A.B
^"""));
assertThat(error.source().describe(), equalTo("""
- <string>:2:1
- main-namespace = "A.B"
- ^"""));
+ <string>:3:20
+ mainNamespace: "A.B",
+ ^"""));
}
}
diff --git a/src/test/java/org/shedlang/compiler/config/GcConfigTests.java b/src/test/java/org/shedlang/compiler/config/GcConfigTests.java
index 6803cf70..351d3d5b 100644
--- a/src/test/java/org/shedlang/compiler/config/GcConfigTests.java
+++ b/src/test/java/org/shedlang/compiler/config/GcConfigTests.java
@@ -1,7 +1,7 @@
package org.shedlang.compiler.config;
import org.junit.jupiter.api.Test;
-import org.shedlang.compiler.config.toml.TomlTableWithSource;
+import org.shedlang.compiler.config.json.Json5ObjectWithSource;
import org.shedlang.compiler.sources.Sources;
import java.util.OptionalLong;
@@ -14,12 +14,14 @@ public class GcConfigTests {
@Test
public void whenNameIsUnrecognisedThenErrorIsThrown() {
var source = Sources.string("""
- name = "huh"
+ {
+ name: "huh",
+ }
""");
var error = assertThrows(
IllegalArgumentException.class,
- () -> GcConfig.fromToml(TomlTableWithSource.parse(source))
+ () -> GcConfig.fromJson5(Json5ObjectWithSource.parse(source))
);
assertThat(error.getMessage(), equalTo("Unrecognised GC name: \"huh\""));
@@ -28,10 +30,12 @@ public class GcConfigTests {
@Test
public void canParseConfigForBump() {
var source = Sources.string("""
- name = "bump"
+ {
+ "name": "bump",
+ }
""");
- var config = GcConfig.fromToml(TomlTableWithSource.parse(source));
+ var config = GcConfig.fromJson5(Json5ObjectWithSource.parse(source));
assertThat(config, instanceOf(GcBumpConfig.class));
}
@@ -39,10 +43,12 @@ public class GcConfigTests {
@Test
public void canParseMinimalConfigForMarkAndSweep() {
var source = Sources.string("""
- name = "mark-and-sweep"
+ {
+ name: "mark-and-sweep",
+ }
""");
- var config = GcConfig.fromToml(TomlTableWithSource.parse(source));
+ var config = GcConfig.fromJson5(Json5ObjectWithSource.parse(source));
assertThat(config, instanceOf(GcMarkAndSweepConfig.class));
}
@@ -50,11 +56,13 @@ public class GcConfigTests {
@Test
public void additionalFieldsCanBeUsedBySpecificGcConfig() {
var source = Sources.string("""
- name = "mark-and-sweep"
- collect-interval = 10000
+ {
+ name: "mark-and-sweep",
+ collectInterval: 10000,
+ }
""");
- var config = GcConfig.fromToml(TomlTableWithSource.parse(source));
+ var config = GcConfig.fromJson5(Json5ObjectWithSource.parse(source));
assertThat(config, instanceOf(
GcMarkAndSweepConfig.class,
diff --git a/src/test/java/org/shedlang/compiler/config/GcMarkAndSweepConfigTests.java b/src/test/java/org/shedlang/compiler/config/GcMarkAndSweepConfigTests.java
index 91d0d234..551c29d6 100644
--- a/src/test/java/org/shedlang/compiler/config/GcMarkAndSweepConfigTests.java
+++ b/src/test/java/org/shedlang/compiler/config/GcMarkAndSweepConfigTests.java
@@ -1,7 +1,7 @@
package org.shedlang.compiler.config;
import org.junit.jupiter.api.Test;
-import org.shedlang.compiler.config.toml.TomlTableWithSource;
+import org.shedlang.compiler.config.json.Json5ObjectWithSource;
import org.shedlang.compiler.sources.Sources;
import java.util.OptionalLong;
@@ -13,9 +13,9 @@ import static org.zwobble.precisely.Matchers.has;
public class GcMarkAndSweepConfigTests {
@Test
public void collectIntervalCanBeMissing() {
- var source = Sources.string("");
+ var source = Sources.string("{}");
- var config = GcMarkAndSweepConfig.fromToml(TomlTableWithSource.parse(source));
+ var config = GcMarkAndSweepConfig.fromJson5(Json5ObjectWithSource.parse(source));
assertThat(config, has(
"collectInterval",
@@ -27,11 +27,13 @@ public class GcMarkAndSweepConfigTests {
@Test
public void additionalFieldsCanBeUsedBySpecificGcConfig() {
var source = Sources.string("""
- name = "mark-and-sweep"
- collect-interval = 10000
+ {
+ name: "mark-and-sweep",
+ collectInterval: 10000,
+ }
""");
- var config = GcMarkAndSweepConfig.fromToml(TomlTableWithSource.parse(source));
+ var config = GcMarkAndSweepConfig.fromJson5(Json5ObjectWithSource.parse(source));
assertThat(config, has(
"collectInterval",
diff --git a/src/test/java/org/shedlang/compiler/config/ProfileConfigTests.java b/src/test/java/org/shedlang/compiler/config/ProfileConfigTests.java
index 7e779252..d7e5ac6f 100644
--- a/src/test/java/org/shedlang/compiler/config/ProfileConfigTests.java
+++ b/src/test/java/org/shedlang/compiler/config/ProfileConfigTests.java
@@ -1,7 +1,7 @@
package org.shedlang.compiler.config;
import org.junit.jupiter.api.Test;
-import org.shedlang.compiler.config.toml.TomlTableWithSource;
+import org.shedlang.compiler.config.json.Json5ObjectWithSource;
import org.shedlang.compiler.sources.Sources;
import static org.zwobble.precisely.AssertThat.assertThat;
@@ -11,10 +11,12 @@ public class ProfileConfigTests {
@Test
public void canParseProfileConfigWithName() {
var source = Sources.string("""
- name = "one"
+ {
+ name: "one",
+ }
""");
- var config = ProfileConfig.fromToml(TomlTableWithSource.parse(source));
+ var config = ProfileConfig.fromJson5(Json5ObjectWithSource.parse(source));
assertThat(config, has("name", x -> x.name(), equalTo("one")));
}
@@ -22,10 +24,12 @@ public class ProfileConfigTests {
@Test
public void canParseProfileConfigWithoutGc() {
var source = Sources.string("""
- name = "one"
+ {
+ name: "one",
+ }
""");
- var config = ProfileConfig.fromToml(TomlTableWithSource.parse(source));
+ var config = ProfileConfig.fromJson5(Json5ObjectWithSource.parse(source));
assertThat(config, has("name", x -> x.gc(), isOptionalEmpty()));
}
@@ -33,11 +37,15 @@ public class ProfileConfigTests {
@Test
public void canParseProfileConfigWithGc() {
var source = Sources.string("""
- name = "one"
- gc.name = "bump"
+ {
+ name: "one",
+ gc: {
+ "name": "bump",
+ },
+ }
""");
- var config = ProfileConfig.fromToml(TomlTableWithSource.parse(source));
+ var config = ProfileConfig.fromJson5(Json5ObjectWithSource.parse(source));
assertThat(config, has(
"gc",
diff --git a/src/test/java/org/shedlang/compiler/config/ProjectConfigTests.java b/src/test/java/org/shedlang/compiler/config/ProjectConfigTests.java
index 10397acf..f0deac1e 100644
--- a/src/test/java/org/shedlang/compiler/config/ProjectConfigTests.java
+++ b/src/test/java/org/shedlang/compiler/config/ProjectConfigTests.java
@@ -2,7 +2,7 @@ package org.shedlang.compiler.config;
import org.junit.jupiter.api.Test;
import org.shedlang.compiler.config.errors.ConfigError;
-import org.shedlang.compiler.config.errors.TomlSyntaxConfigError;
+import org.shedlang.compiler.config.errors.Json5SyntaxConfigError;
import org.shedlang.compiler.types.NamespaceName;
import java.nio.file.Path;
@@ -17,14 +17,14 @@ public class ProjectConfigTests {
@Test
public void whenProjectConfigHasSyntaxErrorsOnFirstLineThenErrorIsThrown() {
var error = assertThrows(
- TomlSyntaxConfigError.class,
- () -> ProjectConfig.fromString(PROJECT_PATH, "[x] ]x")
+ Json5SyntaxConfigError.class,
+ () -> ProjectConfig.fromString(PROJECT_PATH, "[1] ]1")
);
- assertThat(error.getMessage(), equalTo("Unexpected ']', expected a newline or end-of-input"));
+ assertThat(error.getMessage(), equalTo("Expected end of document, but was ']'"));
assertThat(error.source().describe(), equalTo("""
<string>:1:5
- [x] ]x
+ [1] ]1
^"""
));
}
@@ -32,38 +32,21 @@ public class ProjectConfigTests {
@Test
public void whenProjectConfigHasSyntaxErrorsOnNonFirstLineThenErrorIsThrown() {
var error = assertThrows(
- TomlSyntaxConfigError.class,
- () -> ProjectConfig.fromString(PROJECT_PATH, "[a]\n[x] ]x")
+ Json5SyntaxConfigError.class,
+ () -> ProjectConfig.fromString(PROJECT_PATH, "[\n1\n]\n 2")
);
- assertThat(error.getMessage(), equalTo("Unexpected ']', expected a newline or end-of-input"));
+ assertThat(error.getMessage(), equalTo("Expected end of document, but was number '2'"));
assertThat(error.source().describe(), equalTo("""
- <string>:2:5
- [x] ]x
- ^"""
- ));
- }
-
- @Test
- public void whenProjectConfigHasShedThatArentArrayThenErrorIsThrown() {
- var error = assertThrows(
- ConfigError.class,
- () -> ProjectConfig.fromString(PROJECT_PATH, """
- shed = true"""
- )
- );
-
- assertThat(error.getMessage(), equalTo("Expected shed to be a table, but was Boolean"));
- assertThat(error.source().describe(), equalTo("""
- <string>:1:1
- shed = true
- ^"""
+ <string>:4:3
+ 2
+ ^"""
));
}
@Test
public void canParseProjectConfigWithNoBins() {
- var config = ProjectConfig.fromString(PROJECT_PATH, "");
+ var config = ProjectConfig.fromString(PROJECT_PATH, "{}");
assertThat(config.bins(), isSequence());
}
@@ -71,13 +54,18 @@ public class ProjectConfigTests {
@Test
public void canParseProjectConfigWithBins() {
var config = ProjectConfig.fromString(PROJECT_PATH, """
- [[shed.bins]]
- name = "one"
- main-namespace = "One"
-
- [[shed.bins]]
- name = "two"
- main-namespace = "Two"
+ {
+ bins: [
+ {
+ name: "one",
+ mainNamespace: "One",
+ },
+ {
+ name: "two",
+ mainNamespace: "Two",
+ },
+ ],
+ }
""");
assertThat(config.bins(), isSequence(
@@ -99,40 +87,40 @@ public class ProjectConfigTests {
var error = assertThrows(
ConfigError.class,
() -> ProjectConfig.fromString(PROJECT_PATH, """
- [shed]
- bins = true"""
+ {bins: true}"""
)
);
- assertThat(error.getMessage(), equalTo("Expected shed.bins to be an array, but was Boolean"));
+ assertThat(error.getMessage(), equalTo("Expected bins to be array, but was boolean"));
assertThat(error.source().describe(), equalTo("""
- <string>:2:1
- bins = true
- ^"""
+ <string>:1:8
+ {bins: true}
+ ^"""
));
}
@Test
- public void whenProjectConfigHasBinThatIsntTableThenErrorIsThrown() {
+ public void whenProjectConfigHasBinThatIsntObjectThenErrorIsThrown() {
var error = assertThrows(
ConfigError.class,
() -> ProjectConfig.fromString(PROJECT_PATH, """
- [shed]
- bins = [1]"""
+ {
+ bins: [1],
+ }"""
)
);
- assertThat(error.getMessage(), equalTo("Expected shed.bins[0] to be a table, but was Long"));
+ assertThat(error.getMessage(), equalTo("Expected bins[0] to be object, but was finite number"));
assertThat(error.source().describe(), equalTo("""
- <string>:2:9
- bins = [1]
- ^"""
+ <string>:2:12
+ bins: [1],
+ ^"""
));
}
@Test
public void canParseProjectConfigWithNoExamples() {
- var config = ProjectConfig.fromString(PROJECT_PATH, "");
+ var config = ProjectConfig.fromString(PROJECT_PATH, "{}");
assertThat(config.examples(), isSequence());
}
@@ -140,11 +128,12 @@ public class ProjectConfigTests {
@Test
public void canParseProjectConfigWithExamples() {
var config = ProjectConfig.fromString(PROJECT_PATH, """
- [[shed.examples]]
- bin = "one"
-
- [[shed.examples]]
- bin = "two"
+ {
+ examples: [
+ {bin: "one"},
+ {bin: "two"},
+ ],
+ }
""");
assertThat(config.examples(), isSequence(
@@ -164,40 +153,40 @@ public class ProjectConfigTests {
var error = assertThrows(
ConfigError.class,
() -> ProjectConfig.fromString(PROJECT_PATH, """
- [shed]
- examples = true"""
+ {examples: true}"""
)
);
- assertThat(error.getMessage(), equalTo("Expected shed.examples to be an array, but was Boolean"));
+ assertThat(error.getMessage(), equalTo("Expected examples to be array, but was boolean"));
assertThat(error.source().describe(), equalTo("""
- <string>:2:1
- examples = true
- ^"""
+ <string>:1:12
+ {examples: true}
+ ^"""
));
}
@Test
- public void whenProjectConfigHasExampleThatIsntTableThenErrorIsThrown() {
+ public void whenProjectConfigHasExampleThatIsntObjectThenErrorIsThrown() {
var error = assertThrows(
ConfigError.class,
() -> ProjectConfig.fromString(PROJECT_PATH, """
- [shed]
- examples = [1]"""
+ {
+ examples: [1],
+ }"""
)
);
- assertThat(error.getMessage(), equalTo("Expected shed.examples[0] to be a table, but was Long"));
+ assertThat(error.getMessage(), equalTo("Expected examples[0] to be object, but was finite number"));
assertThat(error.source().describe(), equalTo("""
- <string>:2:13
- examples = [1]
- ^"""
+ <string>:2:16
+ examples: [1],
+ ^"""
));
}
@Test
public void canParseProjectConfigWithNoProfiles() {
- var config = ProjectConfig.fromString(PROJECT_PATH, "");
+ var config = ProjectConfig.fromString(PROJECT_PATH, "{}");
assertThat(config.profiles(), isSequence());
}
@@ -205,11 +194,12 @@ public class ProjectConfigTests {
@Test
public void canParseProjectConfigWithProfiles() {
var config = ProjectConfig.fromString(PROJECT_PATH, """
- [[shed.profiles]]
- name = "one"
-
- [[shed.profiles]]
- name = "two"
+ {
+ profiles: [
+ {name: "one"},
+ {name: "two"},
+ ],
+ }
""");
assertThat(config.profiles(), isSequence(
@@ -229,34 +219,34 @@ public class ProjectConfigTests {
var error = assertThrows(
ConfigError.class,
() -> ProjectConfig.fromString(PROJECT_PATH, """
- [shed]
- profiles = true"""
+ {profiles: true}"""
)
);
- assertThat(error.getMessage(), equalTo("Expected shed.profiles to be an array, but was Boolean"));
+ assertThat(error.getMessage(), equalTo("Expected profiles to be array, but was boolean"));
assertThat(error.source().describe(), equalTo("""
- <string>:2:1
- profiles = true
- ^"""
+ <string>:1:12
+ {profiles: true}
+ ^"""
));
}
@Test
- public void whenProjectConfigHasProfileThatIsntTableThenErrorIsThrown() {
+ public void whenProjectConfigHasProfileThatIsntObjectThenErrorIsThrown() {
var error = assertThrows(
ConfigError.class,
() -> ProjectConfig.fromString(PROJECT_PATH, """
- [shed]
- profiles = [1]"""
+ {
+ profiles: [1],
+ }"""
)
);
- assertThat(error.getMessage(), equalTo("Expected shed.profiles[0] to be a table, but was Long"));
+ assertThat(error.getMessage(), equalTo("Expected profiles[0] to be object, but was finite number"));
assertThat(error.source().describe(), equalTo("""
- <string>:2:13
- profiles = [1]
- ^"""
+ <string>:2:16
+ profiles: [1],
+ ^"""
));
}
}
diff --git a/src/test/java/org/shedlang/compiler/config/json/Json5ObjectWithSourceTests.java b/src/test/java/org/shedlang/compiler/config/json/Json5ObjectWithSourceTests.java
new file mode 100644
index 00000000..ad7f7c1c
--- /dev/null
+++ b/src/test/java/org/shedlang/compiler/config/json/Json5ObjectWithSourceTests.java
@@ -0,0 +1,406 @@
+package org.shedlang.compiler.config.json;
+
+import org.junit.jupiter.api.Test;
+import org.shedlang.compiler.config.errors.ConfigError;
+import org.shedlang.compiler.sources.Sources;
+
+import java.util.Optional;
+import java.util.OptionalLong;
+
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.zwobble.precisely.AssertThat.assertThat;
+import static org.zwobble.precisely.Matchers.*;
+
+public class Json5ObjectWithSourceTests {
+ @Test
+ public void whenMemberIsMissingThenGetLongThrowsError() {
+ var source = Sources.string("""
+ {
+ a: {
+ b: [
+ {x: 1},
+ {},
+ ],
+ },
+ }
+ """);
+ var object = Json5ObjectWithSource.parse(source);
+
+ var error = assertThrows(
+ ConfigError.class,
+ () -> object
+ .getObject("a")
+ .orElseThrow()
+ .getArrayOfObjects("b")
+ .orElseThrow()
+ .get(1)
+ .getLong("x")
+ );
+
+ assertThat(error.getMessage(), equalTo("a.b[1] is missing x"));
+ assertThat(error.source().describe(), equalTo("""
+ <string>:5:13
+ {},
+ ^"""
+ ));
+ }
+
+ @Test
+ public void whenMemberIsNotNumberFiniteThenGetLongThrowsError() {
+ var source = Sources.string("""
+ {
+ a: {
+ b: [
+ {x: 1},
+ {x: true},
+ ],
+ },
+ }
+ """);
+ var object = Json5ObjectWithSource.parse(source);
+
+ var error = assertThrows(
+ ConfigError.class,
+ () -> object
+ .getObject("a")
+ .orElseThrow()
+ .getArrayOfObjects("b")
+ .orElseThrow()
+ .get(1)
+ .getLong("x")
+ );
+
+ assertThat(error.getMessage(), equalTo("Expected a.b[1].x to be finite number, but was boolean"));
+ assertThat(error.source().describe(), equalTo("""
+ <string>:5:17
+ {x: true},
+ ^"""
+ ));
+ }
+
+ @Test
+ public void whenMemberIsFiniteNumberButIsNotLongThenGetLongThrowsError() {
+ var source = Sources.string("""
+ {
+ a: {
+ b: [
+ {x: 1},
+ {x: 1.2},
+ ],
+ },
+ }
+ """);
+ var object = Json5ObjectWithSource.parse(source);
+
+ var error = assertThrows(
+ ConfigError.class,
+ () -> object
+ .getObject("a")
+ .orElseThrow()
+ .getArrayOfObjects("b")
+ .orElseThrow()
+ .get(1)
+ .getLong("x")
+ );
+
+ assertThat(error.getMessage(), equalTo("a.b[1].x must be a 64-bit integer"));
+ assertThat(error.source().describe(), equalTo("""
+ <string>:5:17
+ {x: 1.2},
+ ^"""
+ ));
+ }
+
+ @Test
+ public void whenMemberIsLongThenGetLongReturnsValue() {
+ var source = Sources.string("""
+ {
+ a: {
+ b: [
+ {x: 1},
+ {x : 2},
+ ],
+ },
+ }
+ """);
+ var object = Json5ObjectWithSource.parse(source);
+
+ var result = object
+ .getObject("a")
+ .orElseThrow()
+ .getArrayOfObjects("b")
+ .orElseThrow()
+ .get(1)
+ .getLong("x");
+
+ assertThat(result, equalTo(2L));
+ }
+ @Test
+ public void whenMemberIsMissingThenGetLongOrNoneReturnsEmptyOptional() {
+ var source = Sources.string("""
+ {
+ a: {
+ b: [
+ {x: 1},
+ {},
+ ],
+ },
+ }
+ """);
+ var object = Json5ObjectWithSource.parse(source);
+
+ var result = object
+ .getObject("a")
+ .orElseThrow()
+ .getArrayOfObjects("b")
+ .orElseThrow()
+ .get(1)
+ .getLongOrNone("x");
+
+ assertThat(result, equalTo(OptionalLong.empty()));
+ }
+
+ @Test
+ public void whenMemberIsNotLongThenGetLongOrNoneThrowsError() {
+ var source = Sources.string("""
+ {
+ a: {
+ b: [
+ {x: 1},
+ {x: true},
+ ],
+ },
+ }
+ """);
+ var object = Json5ObjectWithSource.parse(source);
+
+ var error = assertThrows(
+ ConfigError.class,
+ () -> object
+ .getObject("a")
+ .orElseThrow()
+ .getArrayOfObjects("b")
+ .orElseThrow()
+ .get(1)
+ .getLongOrNone("x")
+ );
+
+ assertThat(error.getMessage(), equalTo("Expected a.b[1].x to be finite number, but was boolean"));
+ assertThat(error.source().describe(), equalTo("""
+ <string>:5:17
+ {x: true},
+ ^"""
+ ));
+ }
+
+ @Test
+ public void whenMemberIsLongOrNoneThenGetLongReturnsValue() {
+ var source = Sources.string("""
+ {
+ a: {
+ b: [
+ {x: 1},
+ {x: 2},
+ ],
+ },
+ }
+ """);
+ var object = Json5ObjectWithSource.parse(source);
+
+ var result = object
+ .getObject("a")
+ .orElseThrow()
+ .getArrayOfObjects("b")
+ .orElseThrow()
+ .get(1)
+ .getLongOrNone("x");
+
+ assertThat(result, equalTo(OptionalLong.of(2L)));
+ }
+
+ @Test
+ public void whenMemberIsMissingThenGetStringThrowsError() {
+ var source = Sources.string("""
+ {
+ shed: {
+ bins: [
+ {name: "one"},
+ {},
+ ],
+ },
+ }
+ """);
+ var object = Json5ObjectWithSource.parse(source);
+
+ var error = assertThrows(
+ ConfigError.class,
+ () -> object
+ .getObject("shed")
+ .orElseThrow()
+ .getArrayOfObjects("bins")
+ .orElseThrow()
+ .get(1)
+ .getString("name")
+ );
+
+ assertThat(error.getMessage(), equalTo("shed.bins[1] is missing name"));
+ assertThat(error.source().describe(), equalTo("""
+ <string>:5:13
+ {},
+ ^"""
+ ));
+ }
+
+ @Test
+ public void whenMemberIsNotStringThenGetStringThrowsError() {
+ var source = Sources.string("""
+ {
+ shed: {
+ bins: [
+ {name: "one"},
+ {name: true},
+ ],
+ },
+ }
+ """);
+ var object = Json5ObjectWithSource.parse(source);
+
+ var error = assertThrows(
+ ConfigError.class,
+ () -> object
+ .getObject("shed")
+ .orElseThrow()
+ .getArrayOfObjects("bins")
+ .orElseThrow()
+ .get(1)
+ .getString("name")
+ );
+
+ assertThat(error.getMessage(), equalTo("Expected shed.bins[1].name to be string, but was boolean"));
+ assertThat(error.source().describe(), equalTo("""
+ <string>:5:20
+ {name: true},
+ ^"""
+ ));
+ }
+
+ @Test
+ public void whenMemberIsStringThenGetStringReturnsValue() {
+ var source = Sources.string("""
+ {
+ shed: {
+ bins: [
+ {name: "one"},
+ {name: "two"},
+ ],
+ },
+ }
+ """);
+ var object = Json5ObjectWithSource.parse(source);
+
+ var result = object
+ .getObject("shed")
+ .orElseThrow()
+ .getArrayOfObjects("bins")
+ .orElseThrow()
+ .get(1)
+ .getString("name");
+
+ assertThat(result.value(), equalTo("two"));
+ assertThat(result.source().describe(), equalTo(
+ """
+ <string>:5:20
+ {name: "two"},
+ ^"""
+ ));
+ }
+
+ @Test
+ public void whenMemberIsMissingThenGetStringOrNoneReturnsEmptyOptional() {
+ var source = Sources.string("""
+ {
+ shed: {
+ bins: [
+ {name: "one"},
+ {},
+ ],
+ },
+ }
+ """);
+ var object = Json5ObjectWithSource.parse(source);
+
+ var result = object
+ .getObject("shed")
+ .orElseThrow()
+ .getArrayOfObjects("bins")
+ .orElseThrow()
+ .get(1)
+ .getStringOrNone("name");
+
+ assertThat(result, equalTo(Optional.empty()));
+ }
+
+ @Test
+ public void whenMemberIsNotStringThenGetStringOrNoneThrowsError() {
+ var source = Sources.string("""
+ {
+ shed: {
+ bins: [
+ {name: "one"},
+ {name: true},
+ ],
+ },
+ }
+ """);
+ var object = Json5ObjectWithSource.parse(source);
+
+ var error = assertThrows(
+ ConfigError.class,
+ () -> object
+ .getObject("shed")
+ .orElseThrow()
+ .getArrayOfObjects("bins")
+ .orElseThrow()
+ .get(1)
+ .getStringOrNone("name")
+ );
+
+ assertThat(error.getMessage(), equalTo("Expected shed.bins[1].name to be string, but was boolean"));
+ assertThat(error.source().describe(), equalTo("""
+ <string>:5:20
+ {name: true},
+ ^"""
+ ));
+ }
+
+ @Test
+ public void whenMemberIsStringThenGetStringOrNoneReturnsValue() {
+ var source = Sources.string("""
+ {
+ shed: {
+ bins: [
+ {name: "one"},
+ {name: "two"},
+ ],
+ },
+ }
+ """);
+ var object = Json5ObjectWithSource.parse(source);
+
+ var result = object
+ .getObject("shed")
+ .orElseThrow()
+ .getArrayOfObjects("bins")
+ .orElseThrow()
+ .get(1)
+ .getStringOrNone("name");
+
+ assertThat(result.orElseThrow().value(), equalTo("two"));
+ assertThat(result.orElseThrow().source().describe(), equalTo(
+ """
+ <string>:5:20
+ {name: "two"},
+ ^"""
+ ));
+ }
+}
diff --git a/src/test/java/org/shedlang/compiler/config/toml/TomlTableWithSourceTests.java b/src/test/java/org/shedlang/compiler/config/toml/TomlTableWithSourceTests.java
deleted file mode 100644
index 1086671c..00000000
--- a/src/test/java/org/shedlang/compiler/config/toml/TomlTableWithSourceTests.java
+++ /dev/null
@@ -1,325 +0,0 @@
-package org.shedlang.compiler.config.toml;
-
-import org.junit.jupiter.api.Test;
-import org.shedlang.compiler.config.errors.ConfigError;
-import org.shedlang.compiler.sources.Sources;
-
-import java.util.Optional;
-import java.util.OptionalLong;
-
-import static org.junit.jupiter.api.Assertions.assertThrows;
-import static org.zwobble.precisely.AssertThat.assertThat;
-import static org.zwobble.precisely.Matchers.equalTo;
-
-public class TomlTableWithSourceTests {
- @Test
- public void whenKeyIsMissingThenGetLongThrowsError() {
- var source = Sources.string("""
- [[a.b]]
- x = 1
-
- [[a.b]]
- """);
- var table = TomlTableWithSource.parse(source);
-
- var error = assertThrows(
- ConfigError.class,
- () -> table
- .getTable("a")
- .orElseThrow()
- .getArrayOfTables("b")
- .orElseThrow()
- .get(1)
- .getLong("x")
- );
-
- assertThat(error.getMessage(), equalTo("a.b[1] is missing x"));
- assertThat(error.source().describe(), equalTo("""
- <string>:4:1
- [[a.b]]
- ^"""
- ));
- }
-
- @Test
- public void whenKeyIsNotLongThenGetLongThrowsError() {
- var source = Sources.string("""
- [[a.b]]
- x = 1
-
- [[a.b]]
- x = true
- """);
- var table = TomlTableWithSource.parse(source);
-
- var error = assertThrows(
- ConfigError.class,
- () -> table
- .getTable("a")
- .orElseThrow()
- .getArrayOfTables("b")
- .orElseThrow()
- .get(1)
- .getLong("x")
- );
-
- assertThat(error.getMessage(), equalTo("Expected a.b[1].x to be a long, but was Boolean"));
- assertThat(error.source().describe(), equalTo("""
- <string>:5:1
- x = true
- ^"""
- ));
- }
-
- @Test
- public void whenKeyIsLongThenGetLongReturnsValue() {
- var source = Sources.string("""
- [[a.b]]
- x = 1
-
- [[a.b]]
- x = 2
- """);
- var table = TomlTableWithSource.parse(source);
-
- var result = table
- .getTable("a")
- .orElseThrow()
- .getArrayOfTables("b")
- .orElseThrow()
- .get(1)
- .getLong("x");
-
- assertThat(result, equalTo(2L));
- }
- @Test
- public void whenKeyIsMissingThenGetLongOrNoneReturnsEmptyOptional() {
- var source = Sources.string("""
- [[a.b]]
- x = 1
-
- [[a.b]]
- """);
- var table = TomlTableWithSource.parse(source);
-
- var result = table
- .getTable("a")
- .orElseThrow()
- .getArrayOfTables("b")
- .orElseThrow()
- .get(1)
- .getLongOrNone("x");
-
- assertThat(result, equalTo(OptionalLong.empty()));
- }
-
- @Test
- public void whenKeyIsNotLongThenGetLongOrNoneThrowsError() {
- var source = Sources.string("""
- [[a.b]]
- x = 1
-
- [[a.b]]
- x = true
- """);
- var table = TomlTableWithSource.parse(source);
-
- var error = assertThrows(
- ConfigError.class,
- () -> table
- .getTable("a")
- .orElseThrow()
- .getArrayOfTables("b")
- .orElseThrow()
- .get(1)
- .getLongOrNone("x")
- );
-
- assertThat(error.getMessage(), equalTo("Expected a.b[1].x to be a long, but was Boolean"));
- assertThat(error.source().describe(), equalTo("""
- <string>:5:1
- x = true
- ^"""
- ));
- }
-
- @Test
- public void whenKeyIsLongOrNoneThenGetLongReturnsValue() {
- var source = Sources.string("""
- [[a.b]]
- x = 1
-
- [[a.b]]
- x = 2
- """);
- var table = TomlTableWithSource.parse(source);
-
- var result = table
- .getTable("a")
- .orElseThrow()
- .getArrayOfTables("b")
- .orElseThrow()
- .get(1)
- .getLongOrNone("x");
-
- assertThat(result, equalTo(OptionalLong.of(2L)));
- }
-
- @Test
- public void whenKeyIsMissingThenGetStringThrowsError() {
- var source = Sources.string("""
- [[shed.bins]]
- name = "one"
-
- [[shed.bins]]
- """);
- var table = TomlTableWithSource.parse(source);
-
- var error = assertThrows(
- ConfigError.class,
- () -> table
- .getTable("shed")
- .orElseThrow()
- .getArrayOfTables("bins")
- .orElseThrow()
- .get(1)
- .getString("name")
- );
-
- assertThat(error.getMessage(), equalTo("shed.bins[1] is missing name"));
- assertThat(error.source().describe(), equalTo("""
- <string>:4:1
- [[shed.bins]]
- ^"""
- ));
- }
-
- @Test
- public void whenKeyIsNotStringThenGetStringThrowsError() {
- var source = Sources.string("""
- [[shed.bins]]
- name = "one"
-
- [[shed.bins]]
- name = true
- """);
- var table = TomlTableWithSource.parse(source);
-
- var error = assertThrows(
- ConfigError.class,
- () -> table
- .getTable("shed")
- .orElseThrow()
- .getArrayOfTables("bins")
- .orElseThrow()
- .get(1)
- .getString("name")
- );
-
- assertThat(error.getMessage(), equalTo("Expected shed.bins[1].name to be a string, but was Boolean"));
- assertThat(error.source().describe(), equalTo("""
- <string>:5:1
- name = true
- ^"""
- ));
- }
-
- @Test
- public void whenKeyIsStringThenGetStringReturnsValue() {
- var source = Sources.string("""
- [[shed.bins]]
- name = "one"
-
- [[shed.bins]]
- name = "two"
- """);
- var table = TomlTableWithSource.parse(source);
-
- var result = table
- .getTable("shed")
- .orElseThrow()
- .getArrayOfTables("bins")
- .orElseThrow()
- .get(1)
- .getString("name");
-
- assertThat(result, equalTo(
- new TomlString("two", source.at(42, 42))
- ));
- }
-
- @Test
- public void whenKeyIsMissingThenGetStringOrNoneReturnsEmptyOptional() {
- var source = Sources.string("""
- [[shed.bins]]
- name = "one"
-
- [[shed.bins]]
- """);
- var table = TomlTableWithSource.parse(source);
-
- var result = table
- .getTable("shed")
- .orElseThrow()
- .getArrayOfTables("bins")
- .orElseThrow()
- .get(1)
- .getStringOrNone("name");
-
- assertThat(result, equalTo(Optional.empty()));
- }
-
- @Test
- public void whenKeyIsNotStringThenGetStringOrNoneThrowsError() {
- var source = Sources.string("""
- [[shed.bins]]
- name = "one"
-
- [[shed.bins]]
- name = true
- """);
- var table = TomlTableWithSource.parse(source);
-
- var error = assertThrows(
- ConfigError.class,
- () -> table
- .getTable("shed")
- .orElseThrow()
- .getArrayOfTables("bins")
- .orElseThrow()
- .get(1)
- .getStringOrNone("name")
- );
-
- assertThat(error.getMessage(), equalTo("Expected shed.bins[1].name to be a string, but was Boolean"));
- assertThat(error.source().describe(), equalTo("""
- <string>:5:1
- name = true
- ^"""
- ));
- }
-
- @Test
- public void whenKeyIsStringThenGetStringOrNoneReturnsValue() {
- var source = Sources.string("""
- [[shed.bins]]
- name = "one"
-
- [[shed.bins]]
- name = "two"
- """);
- var table = TomlTableWithSource.parse(source);
-
- var result = table
- .getTable("shed")
- .orElseThrow()
- .getArrayOfTables("bins")
- .orElseThrow()
- .get(1)
- .getStringOrNone("name");
-
- assertThat(result, equalTo(Optional.of(
- new TomlString("two", source.at(42, 42))
- )));
- }
-}