Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 | 1282x 484x 484x 484x 414x 336x 359x 328x 702x 63x 63x 63x 63x 63x 8x 78x 78x 16x 62x 32x 30x 30x 30x 30x 440x 394x 364x 370x 41x 4x | import { WILDCARD } from './constants';
/**
* A trigram names an Application Context: the thing (term), the operation on
* it (action), and the perspective of the interaction (orient). Short
* (`t`/`a`/`o`) and long (`term`/`action`/`orient`) keys are interchangeable
* — supply one style per part. A missing, empty, or `'*'` part is a wildcard.
*
* @typedef {Object} Trigram
* @property {string} [t] - the term (short key)
* @property {string} [term] - the term: the domain thing
* @property {string} [a] - the action (short key)
* @property {string} [action] - the action: the operation on the term
* @property {string} [o] - the orient (short key)
* @property {string} [orient] - the orient: perspective / role / surface
*/
/**
* Whether a single trigram part is wild (missing, empty, or the WILDCARD).
* @param {string} [val] - the trigram part
* @returns {boolean}
*/
function isPartWild(val) {
return !val || WILDCARD === val;
}
/**
* Base of the trigram-keyed classes: holds the three parts (missing parts
* become WILDCARD) and answers wildcard / matching questions. Key format:
* `` `${term}|${action}|${orient}` ``.
*/
export default class AppCtxRoot {
/**
* @param {string} [term] - the term (missing = WILDCARD)
* @param {string} [action] - the action (missing = WILDCARD)
* @param {string} [orient] - the orient (missing = WILDCARD)
*/
constructor(term, action, orient) {
this._term = term || WILDCARD;
this._action = action || WILDCARD;
this._orient = orient || WILDCARD;
}
/** The `term|action|orient` key for this trigram. @returns {string} */
get key() {
return AppCtxRoot.getKey(this._term, this._action, this._orient);
}
/** The term. @returns {string} */
get t() {
return this._term;
}
/** The action. @returns {string} */
get a() {
return this._action;
}
/** The orient. @returns {string} */
get o() {
return this._orient;
}
/**
* Build the `term|action|orient` key; missing parts become WILDCARD.
* @param {string} [term]
* @param {string} [action]
* @param {string} [orient]
* @returns {string}
*/
static getKey(term, action, orient) {
return `${term || WILDCARD}|${action || WILDCARD}|${orient || WILDCARD}`;
}
/**
* Whether any part of a trigram is wild (missing, empty, or WILDCARD).
* Both key styles are accepted; short keys win when both are present.
* @param {Trigram} [ac]
* @returns {boolean}
*/
// static isWildcard({ term = WILDCARD, action = WILDCARD, orient = WILDCARD } = {}) {
static isWildcard(ac = {}) {
const { t, term, a, action, o, orient } = ac;
const checkT = t || term;
const checkA = a || action;
const checkO = o || orient;
return (
!checkT ||
!checkA ||
!checkO ||
!checkT.length ||
!checkA.length ||
!checkO.length ||
checkT === WILDCARD ||
checkA === WILDCARD ||
checkO === WILDCARD
);
}
/**
* Whether every part of a trigram is concrete (no wildcards).
* @param {Trigram} [ac]
* @returns {boolean}
*/
static isConcrete(ac = {}) {
return !AppCtxRoot.isWildcard(ac);
}
/**
* Whether an AppCtx(-like) matches a trigram, honoring wildcards on both
* sides unless `exact`. NOTE: `trigram` is read with short keys
* (`t`/`a`/`o`) only — long keys are not consulted here, so a
* long-key-only trigram is treated as all-wild.
*
* @param {AppCtxRoot|Trigram} ac - the context being tested (both key styles accepted)
* @param {{t: (string|undefined), a: (string|undefined), o: (string|undefined)}} trigram - the trigram to match against (short keys only)
* @param {boolean} [exact=false] - require exact key equality (wildcards only match wildcards)
* @returns {boolean}
*/
// TODO: write TESTS for this
static isMatch(ac, trigram, exact = false) {
// Stryker disable next-line ConditionalExpression: re-wrapping an AppCtxRoot is observationally identical
const root =
ac instanceof AppCtxRoot
? ac
: new AppCtxRoot(ac.t || ac.term, ac.a || ac.action, ac.o || ac.orient);
if (root.key === AppCtxRoot.getKey(trigram.t, trigram.a, trigram.o)) {
return true;
}
if (exact) {
return false;
}
const matchTerm =
root.isTermWild || isPartWild(trigram.t) || root.t === trigram.t;
const matchAction =
root.isActionWild || isPartWild(trigram.a) || root.a === trigram.a;
const matchOrient =
root.isOrientWild || isPartWild(trigram.o) || root.o === trigram.o;
return matchTerm && matchAction && matchOrient;
}
/** Whether the term is wild. @returns {boolean} */
get isTermWild() {
return isPartWild(this._term);
}
/** Whether the action is wild. @returns {boolean} */
get isActionWild() {
return isPartWild(this._action);
}
/** Whether the orient is wild. @returns {boolean} */
get isOrientWild() {
return isPartWild(this._orient);
}
/** Whether any part is wild. @returns {boolean} */
get isWildcard() {
return this.isTermWild || this.isActionWild || this.isOrientWild;
}
/** Whether every part is concrete. @returns {boolean} */
get isConcrete() {
return !this.isWildcard;
}
/**
* Instance form of {@link AppCtxRoot.isMatch} with this as the context.
* @param {{t: (string|undefined), a: (string|undefined), o: (string|undefined)}} trigram - the trigram to match against (short keys only)
* @param {boolean} [exact=false]
* @returns {boolean}
*/
isMatch(trigram, exact = false) {
return AppCtxRoot.isMatch(this, trigram, exact);
}
}
|