Skip to content

Commit

Permalink
Extend NeoJSON findPath code
Browse files Browse the repository at this point in the history
  • Loading branch information
svenvc committed Aug 1, 2024
1 parent 17efabc commit f5652fb
Show file tree
Hide file tree
Showing 3 changed files with 29 additions and 16 deletions.
15 changes: 9 additions & 6 deletions repository/Neo-JSON-Core/NeoJSONArray.class.st
Original file line number Diff line number Diff line change
Expand Up @@ -76,9 +76,11 @@ NeoJSONArray >> findPath: conditionBlock [
"Find and return the first path to an object in the graph that I represent
for which conditionBlock holds. Return nil when not found."

self doWithIndex: [ :each :index |
(each isCollection and: [ each isString not ]) ifTrue: [
(each findPath: conditionBlock) ifNotNil: [ :subPath |
(conditionBlock value: self) ifTrue: [ ^ #(()) ].
self doWithIndex: [ :value :index |
(conditionBlock value: value) ifTrue: [ ^ { index } ].
(value isCollection and: [ value isString not ]) ifTrue: [
(value findPath: conditionBlock) ifNotNil: [ :subPath |
^ { index } , subPath ] ] ].
^ nil
]
Expand All @@ -90,9 +92,10 @@ NeoJSONArray >> findPaths: conditionBlock [

| found |
found := OrderedCollection new.
self doWithIndex: [ :each :index |
(each isCollection and: [ each isString not ]) ifTrue: [
(each findPaths: conditionBlock) do: [ :subPath |
self doWithIndex: [ :value :index |
(conditionBlock value: value) ifTrue: [ found add: { index } ].
(value isCollection and: [ value isString not ]) ifTrue: [
(value findPaths: conditionBlock) do: [ :subPath |
found add: { index } , subPath ] ] ].
^ found
]
Expand Down
5 changes: 3 additions & 2 deletions repository/Neo-JSON-Core/NeoJSONObject.class.st
Original file line number Diff line number Diff line change
Expand Up @@ -256,8 +256,9 @@ NeoJSONObject >> findPath: conditionBlock [
"Find and return the first path to an object in the graph that I represent
for which conditionBlock holds. Return nil when not found."

(conditionBlock value: self) ifTrue: [ ^ #() ].
(conditionBlock value: self) ifTrue: [ ^ #(()) ].
self keysAndValuesDo: [ :key :value |
(conditionBlock value: value) ifTrue: [ ^ { key } ].
(value isCollection and: [ value isString not ]) ifTrue: [
(value findPath: conditionBlock) ifNotNil: [ :subPath |
^ { key } , subPath ] ] ].
Expand All @@ -271,8 +272,8 @@ NeoJSONObject >> findPaths: conditionBlock [

| found |
found := OrderedCollection new.
(conditionBlock value: self) ifTrue: [ found add: #() ].
self keysAndValuesDo: [ :key :value |
(conditionBlock value: value) ifTrue: [ found add: { key } ].
(value isCollection and: [ value isString not ]) ifTrue: [
(value findPaths: conditionBlock) do: [ :subPath |
found add: { key } , subPath ] ] ].
Expand Down
25 changes: 17 additions & 8 deletions repository/Neo-JSON-Tests/NeoJSONObjectTests.class.st
Original file line number Diff line number Diff line change
Expand Up @@ -108,38 +108,47 @@ NeoJSONObjectTests >> testFindPath [
| json path |
json := self exampleJSONSchema.

path := json findPath: [ :object | (object at: '$anchor') = 'street_address' ].
path := json findPath: [ :object | object isDictionary and: [ (object at: '$anchor') = 'street_address' ] ].
self deny: path isNil.
self assert: path equals: #(properties street_address).
self assert: ((json atPath: path) at: '$anchor') equals: 'street_address'.

path := json findPath: [ :object | (object at: 'foo') = 'bar' ].
path := json findPath: [ :object | object isDictionary and: [ (object at: 'foo') = 'bar' ] ].
self assert: path isNil.

path := json findPath: [ :object | (object at: '$anchor') = 'country' ].
path := json findPath: [ :object | object isDictionary and: [ (object at: '$anchor') = 'country' ] ].
self deny: path isNil.
self assert: path equals: #('$defs' country).
self assert: ((json atPath: path) at: '$anchor') equals: 'country'
self assert: ((json atPath: path) at: '$anchor') equals: 'country'.

json := NeoJSONObject new at: '$anchor' put: 'top'; yourself.
self
assert: (json findPath: [ :object | object isDictionary and: [ (object at: '$anchor') = 'top' ] ])
equals: #(())
]

{ #category : #testing }
NeoJSONObjectTests >> testFindPaths [
| json paths |
json := self exampleJSONSchema.

paths := json findPaths: [ :object | object includesKey: '$anchor' ].
paths := json findPaths: [ :object | object isDictionary and: [ object includesKey: '$anchor' ] ].
self deny: paths isEmpty.
self assert: paths asArray equals: #((properties street_address) ('$defs' country)).
self assert: ((json atPath: paths first) at: '$anchor') equals: 'street_address'.
self assert: ((json atPath: paths second) at: '$anchor') equals: 'country'.

paths := json findPaths: [ :object | (object at: 'foo') = 'bar' ].
paths := json findPaths: [ :object | object isDictionary and: [ (object at: 'foo') = 'bar' ] ].
self assert: paths isEmpty.

paths := json findPaths: [ :object | object includesKey: #type ].
paths := json findPaths: [ :object | object isDictionary and: [ object includesKey: #type ] ].
self deny: paths isEmpty.
paths do: [ :path |
self assert: (#(string object) includes: ((json atPath: path) at: #type)) ]
self assert: (#(string object) includes: ((json atPath: path) at: #type)) ].

paths := json findPaths: [ :_ | true ].
paths do: [ :each |
self assert: (json atPath: each) notNil ]
]

{ #category : #testing }
Expand Down

0 comments on commit f5652fb

Please sign in to comment.