Skip to content

Commit

Permalink
fix: handle circular references in traverseMore
Browse files Browse the repository at this point in the history
  • Loading branch information
bergos committed Jan 14, 2024
1 parent a23b577 commit 51ec08a
Show file tree
Hide file tree
Showing 3 changed files with 70 additions and 0 deletions.
8 changes: 8 additions & 0 deletions Processor.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import TermSet from '@rdfjs/term-set'
import Edge from './Edge.js'
import * as ns from './lib/namespaces.js'

Expand Down Expand Up @@ -248,6 +249,7 @@ class Processor {
static traverseMore ({ ptrs, end, start, subjects, predicates, objects, graphs, callback } = {}) {
let result = [...ptrs]
let current
let last

do {
current = []
Expand All @@ -259,8 +261,14 @@ class Processor {
]
}

if (last) {
current = current.filter(ptr => !last.has(ptr.term))
}

ptrs = current
result = [...result, ...current]

last = new TermSet(result.map(ptr => ptr.term))
} while (current.length > 0)

return result
Expand Down
32 changes: 32 additions & 0 deletions test/Processor.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -499,6 +499,38 @@ describe('Processor', () => {

grapoiEqual(result, expectedQuads)
})

it('should stop traversing if the start and end of an edge are the same', () => {
const { expectedQuads, predicates, ptr } = datasets.traverseZeroOrMoreSelfRef()

const result = Processor.traverseMore({
ptrs: [ptr],
end: 'object',
start: 'subject',
subjects: [null],
predicates,
objects: [null],
graphs: [null]
})

grapoiEqual(result, expectedQuads)
})

it('should stop traversing if the end of an edge has been previously seen', () => {
const { expectedQuads, predicates, ptr } = datasets.traverseZeroOrMoreSelfRef2()

const result = Processor.traverseMore({
ptrs: [ptr],
end: 'object',
start: 'subject',
subjects: [null],
predicates,
objects: [null],
graphs: [null]
})

grapoiEqual(result, expectedQuads)
})
})

describe('.traverseOne', () => {
Expand Down
30 changes: 30 additions & 0 deletions test/support/datasets.single.js
Original file line number Diff line number Diff line change
Expand Up @@ -592,6 +592,36 @@ single.traverseZeroOrMore = () => {
return { ...others, dataset, edges, expectedQuads }
}

single.traverseZeroOrMoreSelfRef = () => {
const { dataset, edges, ...others } = createPathDataset([
[ns.ex.start, ns.ex.propertyA, ns.ex.end],
[ns.ex.end, ns.ex.propertyB, ns.ex.end]
])

const expectedQuads = [
new Path({ dataset, term: edges[0].startTerm }),
new Path({ edges: [edges[0]] })
]

return { ...others, dataset, edges, expectedQuads }
}

single.traverseZeroOrMoreSelfRef2 = () => {
const { dataset, edges, ...others } = createPathDataset([
[ns.ex.start, ns.ex.propertyA, ns.ex.end1],
[ns.ex.end1, ns.ex.propertyB, ns.ex.end2],
[ns.ex.end2, ns.ex.propertyB, ns.ex.start]
])

const expectedQuads = [
new Path({ dataset, term: edges[0].startTerm }),
new Path({ edges: [edges[0]] }),
new Path({ edges: [edges[0], edges[1]] })
]

return { ...others, dataset, edges, expectedQuads }
}

single.traverseZeroOrOne = () => {
const { dataset, edges, ...others } = createPathDataset([
[ns.ex.start, ns.ex.propertyA, ns.ex.end1],
Expand Down

0 comments on commit 51ec08a

Please sign in to comment.