Skip to content

Commit e501479

Browse files
committed
Correct work with empty path segment in JSON pointer
1 parent 9fa6d4d commit e501479

File tree

4 files changed

+62
-13
lines changed

4 files changed

+62
-13
lines changed

src/commonMain/kotlin/io/github/optimumcode/json/pointer/JsonPointer.kt

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -33,9 +33,7 @@ public sealed class JsonPointer(
3333
buildString {
3434
val pointer = this@JsonPointer.toString()
3535
append(pointer)
36-
if (!pointer.endsWith(SEPARATOR)) {
37-
append(SEPARATOR)
38-
}
36+
append(SEPARATOR)
3937
append(index)
4038
},
4139
)
@@ -53,9 +51,7 @@ public sealed class JsonPointer(
5351
buildString {
5452
val pointer = this@JsonPointer.toString()
5553
append(pointer)
56-
if (!pointer.endsWith(SEPARATOR)) {
57-
append(SEPARATOR)
58-
}
54+
append(SEPARATOR)
5955
append(property)
6056
},
6157
)

src/commonMain/kotlin/io/github/optimumcode/json/pointer/extensions.kt

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -57,13 +57,8 @@ public operator fun JsonPointer.plus(otherPointer: JsonPointer): JsonPointer {
5757
}
5858
return JsonPointer(
5959
buildString {
60-
val pointer = this@plus.toString()
61-
append(pointer)
62-
if (pointer.endsWith(JsonPointer.SEPARATOR)) {
63-
setLength(length - 1)
64-
}
65-
val other = otherPointer.toString()
66-
append(other)
60+
append(this@plus.toString())
61+
append(otherPointer.toString())
6762
},
6863
)
6964
}

src/commonTest/kotlin/io/github/optimumcode/json/pointer/JsonPointerExtensionsTest.kt

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,21 @@ class JsonPointerExtensionsTest : FunSpec() {
1818
"prop",
1919
JsonPointer("/prop"),
2020
),
21+
TestCase(
22+
JsonPointer.ROOT,
23+
"",
24+
JsonPointer("/"),
25+
),
2126
TestCase(
2227
JsonPointer("/test"),
2328
"prop",
2429
JsonPointer("/test/prop"),
2530
),
31+
TestCase(
32+
JsonPointer("/test"),
33+
"",
34+
JsonPointer("/test/"),
35+
),
2636
).forEach { (initial, prop, result) ->
2737
test("$initial / $prop => $result") {
2838
(initial / prop) shouldBe result
@@ -40,6 +50,11 @@ class JsonPointerExtensionsTest : FunSpec() {
4050
0,
4151
JsonPointer("/test/0"),
4252
),
53+
TestCase(
54+
JsonPointer("/test/"),
55+
0,
56+
JsonPointer("/test//0"),
57+
),
4358
).forEach { (initial, prop, result) ->
4459
test("$initial [ $prop ] => $result") {
4560
(initial[prop]) shouldBe result
@@ -67,6 +82,11 @@ class JsonPointerExtensionsTest : FunSpec() {
6782
JsonPointer("/test2"),
6883
JsonPointer("/test1/test2"),
6984
),
85+
TestCase(
86+
JsonPointer("/test1/"),
87+
JsonPointer("/test2"),
88+
JsonPointer("/test1//test2"),
89+
),
7090
).forEach { (init, append, result) ->
7191
test("$init + $append => $result") {
7292
(init + append) shouldBe result
@@ -89,6 +109,11 @@ class JsonPointerExtensionsTest : FunSpec() {
89109
JsonPointer("/test/data"),
90110
JsonPointer("/data"),
91111
),
112+
TestCase(
113+
JsonPointer("/test"),
114+
JsonPointer("/test//data"),
115+
JsonPointer("//data")
116+
)
92117
).forEach { (base, relativeToBase, relativePath) ->
93118
test("relative path from '$base' to '$relativeToBase' is '$relativePath'") {
94119
base.relative(relativeToBase) shouldBe relativePath

src/commonTest/kotlin/io/github/optimumcode/json/pointer/JsonPointerTest.kt

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import io.kotest.assertions.asClue
44
import io.kotest.assertions.assertSoftly
55
import io.kotest.assertions.throwables.shouldThrow
66
import io.kotest.core.spec.style.FunSpec
7+
import io.kotest.matchers.nulls.shouldNotBeNull
78
import io.kotest.matchers.should
89
import io.kotest.matchers.shouldBe
910
import io.kotest.matchers.shouldNotBe
@@ -77,6 +78,38 @@ class JsonPointerTest : FunSpec() {
7778
val pointer = JsonPointer("/~")
7879
pointer.assertSegment(property = "~")
7980
}
81+
82+
test("empty segment in the end") {
83+
val pointer = JsonPointer("/test/")
84+
assertSoftly {
85+
pointer.assertSegment(property = "test")
86+
pointer.next
87+
.shouldNotBeNull()
88+
.assertSegment(property = "")
89+
pointer.toString() shouldBe "/test/"
90+
}
91+
}
92+
93+
test("empty segment in the beginning") {
94+
val pointer = JsonPointer("/")
95+
assertSoftly {
96+
pointer.assertSegment(property = "")
97+
pointer.next.shouldNotBeNull().shouldBe(EmptyPointer)
98+
pointer.toString() shouldBe "/"
99+
}
100+
}
101+
102+
test("empty segment in the middle") {
103+
val pointer = JsonPointer("/test1//test2")
104+
assertSoftly {
105+
pointer.assertSegment(property = "test1")
106+
var next = pointer.next.shouldNotBeNull()
107+
next.assertSegment(property = "")
108+
next = next.next.shouldNotBeNull()
109+
next.assertSegment(property = "test2")
110+
pointer.toString() shouldBe "/test1//test2"
111+
}
112+
}
80113
}
81114

82115
private fun JsonPointer.assertSegment(property: String, index: Int = -1) {

0 commit comments

Comments
 (0)