Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add more tests to ensure proper handling of undefined #131

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 48 additions & 0 deletions test.js
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,54 @@ describe('xpath', () => {
assert.strictEqual('JKR', xpath.selectWithResolver('//ns:field[@ns:type="author"]/text()', doc, resolver)[0].nodeValue);
});

it('should select empty set with undefined xpath, using a resolver', () => {
var xml = '<book xmlns:testns="http://example.com/test"><testns:title>Harry Potter</testns:title><testns:field testns:type="author">JKR</testns:field></book>';
var doc = parseXml(xml);
var resolver = {
mappings: {
'ns': 'http://example.com/test'
},
lookupNamespaceURI: function (prefix) {
return this.mappings[prefix];
}
}
var nodes = xpath.selectWithResolver(undefined, doc, resolver);
assert.deepStrictEqual(nodes, []);

var node = xpath.selectWithResolver(undefined, doc, resolver, true);
assert.strictEqual(node, undefined);
});

it('should throw if undefined doc, using a resolver', () => {
var resolver = {
mappings: {
'ns': 'http://example.com/test'
},
lookupNamespaceURI: function (prefix) {
return this.mappings[prefix];
}
}
assert.throws(() => xpath.selectWithResolver(undefined, undefined, resolver));
});

it('should select empty set with undefined resolver', () => {
var xml = '<book xmlns:testns="http://example.com/test"><testns:title>Harry Potter</testns:title><testns:field testns:type="author">JKR</testns:field></book>';
var doc = parseXml(xml);
var resolver = {
mappings: {
'ns': 'http://example.com/test'
},
lookupNamespaceURI: function (prefix) {
return this.mappings[prefix];
}
}
var nodes = xpath.selectWithResolver(undefined, doc, undefined);
assert.deepStrictEqual(nodes, []);

var node = xpath.selectWithResolver(undefined, doc, undefined, true);
assert.strictEqual(node, undefined);
});

it('should select with namespaces, using namespace mappings', () => {
var xml = '<book xmlns:testns="http://example.com/test"><testns:title>Harry Potter</testns:title><testns:field testns:type="author">JKR</testns:field></book>';
var doc = parseXml(xml);
Expand Down
26 changes: 17 additions & 9 deletions xpath.d.ts
Original file line number Diff line number Diff line change
@@ -1,34 +1,42 @@
/// <reference lib="dom" />

export type SelectedValue = Node | string | number | boolean | null;
export type ScalarValue = string | number | boolean;

export type SelectReturnType = Array<Node> | SelectedValue;
export type SelectSingleReturnType = SelectedValue;
export type SelectReturnType = Array<Node> | ScalarValue;
export type SelectSingleReturnType = ScalarValue | Node | undefined;

type Nullable<T> = T | null | undefined;

export interface XPathSelect {
(expression: Nullable<undefined>, node: Node): [];
(expression: Nullable<undefined>, node: Node, single: false): [];
(expression: string, node: Node): SelectReturnType;
(expression: string, node: Node, single: false): SelectReturnType;
(expression: string, node: Node, single: true): SelectSingleReturnType;
(expression: Nullable<string>, node: Node, single: true): SelectSingleReturnType;
}

/**
* Evaluate an XPath expression against a DOM node.
*/
export function select(expression: Nullable<undefined>, node: Node): [];
export function select(expression: Nullable<undefined>, node: Node, single: false): [];
export function select(expression: string, node: Node): SelectReturnType;
export function select(expression: string, node: Node, single: false): SelectReturnType;
export function select(expression: string, node: Node, single: true): SelectSingleReturnType;
export function select(expression: Nullable<string>, node: Node, single: true): SelectSingleReturnType;

/**
* Evaluate an xpath expression against a DOM node, returning the first result only.
*/
export function select1(expression: string, node: Node): SelectSingleReturnType;
export function select1(expression: Nullable<string>, node: Node): SelectSingleReturnType;

/**
* Evaluate an XPath expression against a DOM node using a given namespace resolver.
*/
export function selectWithResolver(expression: string, node: Node, resolver?: XPathNSResolver | null): SelectReturnType;
export function selectWithResolver(expression: string, node: Node, resolver: XPathNSResolver | null, single: false): SelectReturnType;
export function selectWithResolver(expression: string, node: Node, resolver: XPathNSResolver | null, single: true): SelectSingleReturnType;
export function selectWithResolver(expression: Nullable<undefined>, node: Node, resolver?: Nullable<XPathNSResolver>): [];
export function selectWithResolver(expression: Nullable<undefined>, node: Node, resolver: Nullable<XPathNSResolver>, single: false): [];
export function selectWithResolver(expression: string, node: Node, resolver?: Nullable<XPathNSResolver>): SelectReturnType;
export function selectWithResolver(expression: string, node: Node, resolver: Nullable<XPathNSResolver>, single: false): SelectReturnType;
export function selectWithResolver(expression: string, node: Node, resolver: Nullable<XPathNSResolver>, single: true): SelectSingleReturnType;

/**
* Creates a `select` function that uses the given namespace prefix to URI mappings when evaluating queries.
Expand Down