Mercurial > code > home > repos > streamed-graph
changeset 11:1988ad250036
suffixLabels test runswith 'inv test'
author | drewp@localhost |
---|---|
date | Fri, 06 Dec 2019 16:41:19 -0800 |
parents | 1c3a39057b11 |
children | 091a03abd6cb |
files | src/suffixLabels.js src/suffixLabels.ts src/suffixLabels_test.html src/suffixLabels_test.ts |
diffstat | 4 files changed, 148 insertions(+), 163 deletions(-) [+] |
line wrap: on
line diff
--- a/src/suffixLabels.js Fri Dec 06 09:21:49 2019 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,72 +0,0 @@ -class SuffixLabels { - constructor() { - this.displayNodes = new Map(); // internal string : { label, link } - this.usedSuffixes = {usedBy: null, children: new Map()}; - } - - planDisplayForNode(node) { - const uri = node.nominalValue; - this._planDisplayForUri(uri); - }; - - _planDisplayForUri(uri) { - if (this.displayNodes.has(uri)) { - return; - } - - const segments = uri.split('/'); - let curs = this.usedSuffixes; - let label = null; - - for (let i = segments.length - 1; i >= 0; i--) { - const seg = segments[i]; - if (curs.usedBy && curs.usedBy != uri) { - this._prependClashingUri(curs); - } - - if (!curs.children.has(seg)) { - const child = {usedBy: null, children: new Map()}; - curs.children.set(seg, child); - - if (label === null ) { - label = SuffixLabels._tailSegments(uri, segments.length - i); - child.usedBy = uri; - } - } - curs = curs.children.get(seg); - } - this.displayNodes.set(uri, {label: label}); - } - - _prependClashingUri(curs) { - // Claim: When a clash is discovered, only 1 uri needs to - // change its length, and there will be only one child node to - // follow, and the clashing uri can be changed to prepend that - // one child (since we'll see it again if that one wasn't - // enough). - const clashNode = this.displayNodes.get(curs.usedBy); - const nextLeftSeg = curs.children.entries().next().value; - if (nextLeftSeg[1].usedBy) { - throw new Error("unexpected"); - } - - clashNode.label = nextLeftSeg[0] + '/' + clashNode.label; - nextLeftSeg[1].usedBy = curs.usedBy; - curs.usedBy = null; - - } - - getLabelForNode(node) { - return this.displayNodes.get(node.nominalValue).label; - } - - static _tailSegments(uri, n) { - let i = uri.length; - for (let rep = 0; rep < n; rep++) { - i = uri.lastIndexOf('/', i - 1); - } - return uri.substr(i + 1); - } -}; - -export { SuffixLabels }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/suffixLabels.ts Fri Dec 06 16:41:19 2019 -0800 @@ -0,0 +1,78 @@ +import { Term } from 'n3'; + +type SuffixesNode = { usedBy: null | string, children: Map<string, SuffixesNode> }; +type DisplayNode = { label: string | null, link?: string }; +class SuffixLabels { + displayNodes: Map<string, DisplayNode>; + usedSuffixes: SuffixesNode; + constructor() { + this.displayNodes = new Map(); + this.usedSuffixes = { usedBy: null, children: new Map() }; + } + + planDisplayForNode(node: Term) { + const uri = node.value; + this._planDisplayForUri(uri); + }; + + _planDisplayForUri(uri: string) { + if (this.displayNodes.has(uri)) { + return; + } + + const segments = uri.split('/'); + let curs = this.usedSuffixes; + let label = null; + + for (let i = segments.length - 1; i >= 0; i--) { + const seg = segments[i]; + if (curs.usedBy && curs.usedBy != uri) { + this._prependClashingUri(curs); + } + + if (!curs.children.has(seg)) { + const child = { usedBy: null, children: new Map() }; + curs.children.set(seg, child); + + if (label === null) { + label = SuffixLabels._tailSegments(uri, segments.length - i); + child.usedBy = uri; + } + } + curs = curs.children.get(seg); + } + this.displayNodes.set(uri, { label: label }); + } + + _prependClashingUri(curs: SuffixesNode) { + // Claim: When a clash is discovered, only 1 uri needs to + // change its length, and there will be only one child node to + // follow, and the clashing uri can be changed to prepend that + // one child (since we'll see it again if that one wasn't + // enough). + const clashNode: DisplayNode = this.displayNodes.get(curs.usedBy); + const nextLeftSeg = curs.children.entries().next().value; + if (nextLeftSeg[1].usedBy) { + throw new Error("unexpected"); + } + + clashNode.label = nextLeftSeg[0] + '/' + clashNode.label; + nextLeftSeg[1].usedBy = curs.usedBy; + curs.usedBy = null; + + } + + getLabelForNode(node: string) { + return this.displayNodes.get(node).label; + } + + static _tailSegments(uri: string, n: number) { + let i = uri.length; + for (let rep = 0; rep < n; rep++) { + i = uri.lastIndexOf('/', i - 1); + } + return uri.substr(i + 1); + } +}; + +export { SuffixLabels }
--- a/src/suffixLabels_test.html Fri Dec 06 09:21:49 2019 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,91 +0,0 @@ -<!doctype html> -<html> - <head> - <title>suffixLabels_test</title> - <meta charset="utf-8" /> - <link rel="shortcut icon" type="image/png" href="/lib/jasmine/3.4.0/jasmine_favicon.png"> - <link rel="stylesheet" type="text/css" href="/lib/jasmine/3.4.0/jasmine.css"> - - <script type="text/javascript" src="/lib/jasmine/3.4.0/jasmine.js"></script> - <script type="text/javascript" src="/lib/jasmine/3.4.0/jasmine-html.js"></script> - <script type="text/javascript" src="/lib/jasmine/3.4.0/boot.js"></script> - - <script type="module"> - - import { SuffixLabels } from './suffixLabels.js'; - - describe("_tailSegments", function() { - it("returns right amount", function() { - expect(SuffixLabels._tailSegments('http://foo/a/bb', 0)).toEqual(''); - expect(SuffixLabels._tailSegments('http://foo/a/bb', 1)).toEqual('bb'); - expect(SuffixLabels._tailSegments('http://foo/a/bb', 2)).toEqual('a/bb'); - expect(SuffixLabels._tailSegments('http://foo/a/bb', 3)).toEqual('foo/a/bb'); - expect(SuffixLabels._tailSegments('http://foo/a/bb', 4)).toEqual('/foo/a/bb'); - expect(SuffixLabels._tailSegments('http://foo/a/bb', 5)).toEqual('http://foo/a/bb'); - }); - it("ok with trailing slash", function() { - expect(SuffixLabels._tailSegments('http://foo/', 0)).toEqual(''); - expect(SuffixLabels._tailSegments('http://foo/', 1)).toEqual(''); - expect(SuffixLabels._tailSegments('http://foo/', 2)).toEqual('foo/'); - }); - }); - - describe("suffixLabels", function() { - const fakeNode = (uri) => { return { nominalValue: uri } }; - - it("returns whole url segments", function() { - const suf = new SuffixLabels(); - suf._planDisplayForUri('http://a/b/c/dd'); - suf._planDisplayForUri('http://a/b/c/ee'); - - expect(suf.getLabelForNode(fakeNode('http://a/b/c/dd'))).toEqual('dd'); - expect(suf.getLabelForNode(fakeNode('http://a/b/c/ee'))).toEqual('ee'); - }); - - it("doesn't treat a repeated uri as a name clash", function() { - const suf = new SuffixLabels(); - suf._planDisplayForUri('http://a/b/c'); - suf._planDisplayForUri('http://a/b/c'); - - expect(suf.getLabelForNode(fakeNode('http://a/b/c'))).toEqual('c'); - }); - - it("moves to two segments when needed", function() { - const suf = new SuffixLabels(); - suf._planDisplayForUri('http://a/b/c/d'); - suf._planDisplayForUri('http://a/b/f/d'); - - expect(suf.getLabelForNode(fakeNode('http://a/b/c/d'))).toEqual('c/d'); - expect(suf.getLabelForNode(fakeNode('http://a/b/f/d'))).toEqual('f/d'); - }); - - it("is ok with clashes at different segment positions", function() { - const suf = new SuffixLabels(); - suf._planDisplayForUri('http://z/z/z/a/b/c'); - suf._planDisplayForUri('http://a/b/c'); - - expect(suf.getLabelForNode(fakeNode('http://z/z/z/a/b/c'))).toEqual('z/a/b/c'); - expect(suf.getLabelForNode(fakeNode('http://a/b/c'))).toEqual('/a/b/c'); - }); - - it("uses appropriately long suffixes per uri", function() { - const suf = new SuffixLabels(); - suf._planDisplayForUri('http://a/b/c/d/e'); - suf._planDisplayForUri('http://a/b/f/d/e'); - suf._planDisplayForUri('http://a/b/c/g'); - suf._planDisplayForUri('http://a/z'); - - expect(suf.getLabelForNode(fakeNode('http://a/b/c/d/e'))).toEqual('c/d/e'); - expect(suf.getLabelForNode(fakeNode('http://a/b/f/d/e'))).toEqual('f/d/e'); - expect(suf.getLabelForNode(fakeNode('http://a/b/c/g'))).toEqual('g'); - expect(suf.getLabelForNode(fakeNode('http://a/z'))).toEqual('z'); - }); - - }); - </script> - - </head> - <body> - - </body> -</html>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/suffixLabels_test.ts Fri Dec 06 16:41:19 2019 -0800 @@ -0,0 +1,70 @@ +import { SuffixLabels } from './suffixLabels'; + +describe("_tailSegments", () => { + it("returns right amount", () => { + expect(SuffixLabels._tailSegments('http://foo/a/bb', 0)).toEqual(''); + expect(SuffixLabels._tailSegments('http://foo/a/bb', 1)).toEqual('bb'); + expect(SuffixLabels._tailSegments('http://foo/a/bb', 2)).toEqual('a/bb'); + expect(SuffixLabels._tailSegments('http://foo/a/bb', 3)).toEqual('foo/a/bb'); + expect(SuffixLabels._tailSegments('http://foo/a/bb', 4)).toEqual('/foo/a/bb'); + expect(SuffixLabels._tailSegments('http://foo/a/bb', 5)).toEqual('http://foo/a/bb'); + }); + it("ok with trailing slash", () => { + expect(SuffixLabels._tailSegments('http://foo/', 0)).toEqual(''); + expect(SuffixLabels._tailSegments('http://foo/', 1)).toEqual(''); + expect(SuffixLabels._tailSegments('http://foo/', 2)).toEqual('foo/'); + }); +}); + +describe("suffixLabels", () => { + const fakeNode = (uri: string) => { return { nominalValue: uri } }; + + it("returns whole url segments", () => { + const suf = new SuffixLabels(); + suf._planDisplayForUri('http://a/b/c/dd'); + suf._planDisplayForUri('http://a/b/c/ee'); + + expect(suf.getLabelForNode('http://a/b/c/dd')).toEqual('dd'); + expect(suf.getLabelForNode('http://a/b/c/ee')).toEqual('ee'); + }); + + it("doesn't treat a repeated uri as a name clash", () => { + const suf = new SuffixLabels(); + suf._planDisplayForUri('http://a/b/c'); + suf._planDisplayForUri('http://a/b/c'); + + expect(suf.getLabelForNode('http://a/b/c')).toEqual('c'); + }); + + it("moves to two segments when needed", () => { + const suf = new SuffixLabels(); + suf._planDisplayForUri('http://a/b/c/d'); + suf._planDisplayForUri('http://a/b/f/d'); + + expect(suf.getLabelForNode('http://a/b/c/d')).toEqual('c/d'); + expect(suf.getLabelForNode('http://a/b/f/d')).toEqual('f/d'); + }); + + it("is ok with clashes at different segment positions", () => { + const suf = new SuffixLabels(); + suf._planDisplayForUri('http://z/z/z/a/b/c'); + suf._planDisplayForUri('http://a/b/c'); + + expect(suf.getLabelForNode('http://z/z/z/a/b/c')).toEqual('z/a/b/c'); + expect(suf.getLabelForNode('http://a/b/c')).toEqual('/a/b/c'); + }); + + it("uses appropriately long suffixes per uri", () => { + const suf = new SuffixLabels(); + suf._planDisplayForUri('http://a/b/c/d/e'); + suf._planDisplayForUri('http://a/b/f/d/e'); + suf._planDisplayForUri('http://a/b/c/g'); + suf._planDisplayForUri('http://a/z'); + + expect(suf.getLabelForNode('http://a/b/c/d/e')).toEqual('c/d/e'); + expect(suf.getLabelForNode('http://a/b/f/d/e')).toEqual('f/d/e'); + expect(suf.getLabelForNode('http://a/b/c/g')).toEqual('g'); + expect(suf.getLabelForNode('http://a/z')).toEqual('z'); + }); + +}); \ No newline at end of file