blob: 8a87579eb8d1cd2a7cd5dbe328e40cc3042cbf70 [file]
/*
* 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.
*/
/*
* Portions of this code are based on the Chai Assertion Library
* at https://www.chaijs.com/, which is licensed under the MIT License.
* The functions deepMembersById, flag, and isSubsetOf are adapted from
* Chai's source code.
* See licenses/chai for full license.
*/
import { Assertion } from 'chai';
import deepEqual from 'deep-eql';
import { Edge, Vertex, VertexProperty } from '../../lib/structure/graph.js';
function isElement(obj) {
return obj instanceof Edge || obj instanceof Vertex || obj instanceof VertexProperty;
}
export const opt = {comparator: compareElements};
function isSubsetOf(subset, superset, cmp, contains, ordered) {
if (!contains) {
if (subset.length !== superset.length) return false;
superset = superset.slice();
}
return subset.every(function(elem, idx) {
if (ordered) return cmp ? cmp(elem, superset[idx], opt) : elem === superset[idx];
if (!cmp) {
var matchIdx = superset.indexOf(elem);
if (matchIdx === -1) return false;
// Remove match from superset so not counted twice if duplicate in subset.
if (!contains) superset.splice(matchIdx, 1);
return true;
}
return superset.some(function(elem2, matchIdx) {
if (!cmp(elem, elem2, opt)) return false;
// Remove match from superset so not counted twice if duplicate in subset.
if (!contains) superset.splice(matchIdx, 1);
return true;
});
});
}
function flag(obj, key, value) {
var flags = obj.__flags || (obj.__flags = Object.create(null));
if (arguments.length === 3) {
flags[key] = value;
} else {
return flags[key];
}
};
export function deepMembersById (subset, msg) {
if (msg) flag(this, 'message', msg);
var obj = flag(this, 'object')
, flagMsg = flag(this, 'message')
, ssfi = flag(this, 'ssfi');
new Assertion(obj, flagMsg, ssfi, true).to.be.an('array');
new Assertion(subset, flagMsg, ssfi, true).to.be.an('array');
var contains = flag(this, 'contains');
var ordered = flag(this, 'ordered');
var subject, failMsg, failNegateMsg;
if (contains) {
subject = ordered ? 'an ordered superset' : 'a superset';
failMsg = 'expected #{this} to be ' + subject + ' of #{exp}';
failNegateMsg = 'expected #{this} to not be ' + subject + ' of #{exp}';
} else {
subject = ordered ? 'ordered members' : 'members';
failMsg = 'expected #{this} to have the same ' + subject + ' as #{exp}';
failNegateMsg = 'expected #{this} to not have the same ' + subject + ' as #{exp}';
}
var cmp = flag(this, 'deep') ? deepEqual : undefined;
this.assert(
isSubsetOf(subset, obj, cmp, contains, ordered)
, failMsg
, failNegateMsg
, subset
, obj
, true
);
}
export function compareElements(a, b) {
if (!isElement(a) || !isElement(b)) {
return null;
} else {
return a.constructor === b.constructor && a.id === b.id;
}
}