This is an automated email from the ASF dual-hosted git repository. gerben pushed a commit to branch fragment-tests in repository https://gitbox.apache.org/repos/asf/incubator-annotator.git
commit 531d5e75d0ec61a4bdf095c96b73633c7fda80cd Author: Gerben <[email protected]> AuthorDate: Thu Apr 2 21:46:25 2020 +0200 Test fragment-identifier against spec examples Derived from earlier work: https://github.com/Treora/selector-state-frags/blob/51fe53df390301f768b6e876a670d12d1249b2b1/test/test.js --- packages/fragment-identifier/test/index.js | 55 +++++++ .../fragment-identifier/test/spec-examples.json | 180 +++++++++++++++++++++ 2 files changed, 235 insertions(+) diff --git a/packages/fragment-identifier/test/index.js b/packages/fragment-identifier/test/index.js new file mode 100644 index 0000000..761de0d --- /dev/null +++ b/packages/fragment-identifier/test/index.js @@ -0,0 +1,55 @@ +/** + * @license + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import { parse, stringify } from '../src'; + +// Test examples from the spec: https://www.w3.org/TR/2017/NOTE-selectors-states-20170223/#json-examples-converted-to-fragment-identifiers +import specExamplesRaw from './spec-examples.json'; + +// The JSON file has the full examples; pull out the parts we need. +const specExamples = Object.fromEntries(Object.entries(specExamplesRaw).map( + ([name, { uri, obj: { selector, state } }]) => + [name, { fragId: uri.split('#')[1], selector, state }] +)); + +describe('stringify', () => { + // Test examples in the spec, ignoring their URI encoding + for (const [name, example] of Object.entries(specExamples)) { + it(`should properly stringify (disregarding URI-encoding): '${name}'`, () => { + const result = stringify(example.selector || example.state); + assert.equal( + decodeURIComponent(result), + decodeURIComponent(example.fragId) + ); + }); + } +}); + +describe('parse', () => { + for (const [name, example] of Object.entries(specExamples)) { + it(`should properly parse: ${name}`, () => { + const expected = (example.selector !== undefined) + ? { selector: example.selector } + : { state: example.state }; + const result = parse(example.fragId); + assert.deepEqual(result, expected); + }); + } +}); diff --git a/packages/fragment-identifier/test/spec-examples.json b/packages/fragment-identifier/test/spec-examples.json new file mode 100644 index 0000000..832e02b --- /dev/null +++ b/packages/fragment-identifier/test/spec-examples.json @@ -0,0 +1,180 @@ +{ + "Example 2 <=> 16: Fragment selector": { + "uri": "http://example.org/video1#selector(type=FragmentSelector,conformsTo=http://www.w3.org/TR/media-frags/,value=t%3D30%2C60)", + "obj": { + "source": "http://example.org/video1", + "selector": { + "type": "FragmentSelector", + "conformsTo": "http://www.w3.org/TR/media-frags/", + "value": "t=30,60" + } + } + }, + + "Example 3 <=> 17: CSS selector": { + "uri": "http://example.org/page1.html#selector(type=CssSelector,value=%23elemid%20>%20.elemclass%20+%20p)", + "obj": { + "source": "http://example.org/page1.html", + "selector": { + "type": "CssSelector", + "value": "#elemid > .elemclass + p" + } + } + }, + + "Example 4 <=> 18: XPath selector": { + "uri": "http://example.org/page1.html#selector(type=XPathSelector,value=/html/body/p[2]/table/tr[2]/td[3]/span)", + "obj": { + "source": "http://example.org/page1.html", + "selector": { + "type": "XPathSelector", + "value": "/html/body/p[2]/table/tr[2]/td[3]/span" + } + } + }, + + "Example 5 <=> 19: TextQuote selector": { + "uri": "http://example.org/page1#selector(type=TextQuoteSelector,exact=annotation,prefix=this%20is%20an%20,suffix=%20that%20has%20some)", + "obj": { + "source": "http://example.org/page1", + "selector": { + "type": "TextQuoteSelector", + "exact": "annotation", + "prefix": "this is an ", + "suffix": " that has some" + } + } + }, + + "Example 6 <=> 20: TextPosition selector": { + "uri": "http://example.org/ebook1#selector(type=TextPositionSelector,start=412,end=795)", + "obj": { + "source": "http://example.org/ebook1", + "selector": { + "type": "TextPositionSelector", + "start": 412, + "end": 795 + } + } + }, + + "Example 7 <=> 21: Data position selector": { + "uri": "http://example.org/diskimg1#selector(type=DataPositionSelector,start=4096,end=4104)", + "obj": { + "source": "http://example.org/diskimg1", + "selector": { + "type": "DataPositionSelector", + "start": 4096, + "end": 4104 + } + } + }, + + "Example 8 <=> 22: SVG selector; external SVG": { + "uri": "http://example.org/map1#selector(type=SvgSelector,id=http://example.org/svg1)", + "obj": { + "source": "http://example.org/map1", + "selector": { + "type": "SvgSelector", + "id": "http://example.org/svg1" + } + } + }, + + "Example 9 <=> 23: SVG selector; embedded SVG": { + "uri": "http://example.org/map1#selector(type=SvgSelector,value=<svg:svg>%20...%20</svg:svg>)", + "obj": { + "source": "http://example.org/map1", + "selector": { + "type": "SvgSelector", + "value": "<svg:svg> ... </svg:svg>" + } + } + }, + + "Example 10 <=> 24: Range selector": { + "uri": "http://example.org/page1.html#selector(type=RangeSelector,startSelector=selector(type=XPathSelector,value=//table[1]/tr[1]/td[2]),endSelector=selector(type=XPathSelector,value=//table[1]/tr[1]/td[4]))", + "obj": { + "source": "http://example.org/page1.html", + "selector": { + "type": "RangeSelector", + "startSelector": { + "type": "XPathSelector", + "value": "//table[1]/tr[1]/td[2]" + }, + "endSelector": { + "type": "XPathSelector", + "value": "//table[1]/tr[1]/td[4]" + } + } + } + }, + + "Example 11 <=> 25: Selector refinement": { + "uri": "http://example.org/page1#selector(type=FragmentSelector,value=para5,refinedBy=selector(type=TextQuoteSelector,exact=Selected%20Text,prefix=text%20before%20the%20,suffix=%20and%20text%20after%20it))", + "obj": { + "source": "http://example.org/page1", + "selector": { + "type": "FragmentSelector", + "value": "para5", + "refinedBy": { + "type": "TextQuoteSelector", + "exact": "Selected Text", + "prefix": "text before the ", + "suffix": " and text after it" + } + } + } + }, + + "Example 13 <=> 26: Time state": { + "uri": "http://example.org/page1#state(type=TimeState,cached=http://archive.example.org/copy1,sourceDate=2015-07-20T13:30:00Z)", + "obj": { + "source": "http://example.org/page1", + "state": { + "type": "TimeState", + "cached": "http://archive.example.org/copy1", + "sourceDate": "2015-07-20T13:30:00Z" + } + } + }, + + "Example 14 <=> 27: HTTP request state": { + "uri": "http://example.org/resource1#state(type=HttpRequestState,value=Accept:%20application/pdf)", + "obj": { + "source": "http://example.org/resource1", + "state": { + "type": "HttpRequestState", + "value": "Accept: application/pdf" + } + } + }, + + "Example 15 <=> 28: Refinement of states": { + "uri": "http://example.org/ebook1#state(type=TimeState,sourceDate=2016-02-01T12:05:23Z,refinedBy=state(type=HttpRequestState,value=Accept:%20application/epub+zip))", + "obj": { + "source": "http://example.org/ebook1", + "state": { + "type": "TimeState", + "sourceDate": "2016-02-01T12:05:23Z", + "refinedBy": { + "type": "HttpRequestState", + "value": "Accept: application/epub+zip" + } + } + } + }, + + "Example 29: Serializing IRI to URL (and vice versa)": { + "uri": "http://jp.example.org/page1#selector(type=TextQuoteSelector,exact=%E3%83%9A%E3%83%B3%E3%82%92,prefix=%E7%A7%81%E3%81%AF%E3%80%81,suffix=%E6%8C%81%E3%81%A3%E3%81%A6%E3%81%84%E3%81%BE%E3%81%99)", + "obj": { + "source": "http://jp.example.org/page1", + "selector": { + "type": "TextQuoteSelector", + "exact": "ペンを", + "prefix": "私は、", + "suffix": "持っています" + } + } + } +}
