manyfest 1.0.30 → 1.0.32
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/debug/Harness.js +12 -14
- package/dist/manyfest.compatible.js +502 -66
- package/dist/manyfest.compatible.min.js +1 -1
- package/dist/manyfest.compatible.min.js.map +1 -1
- package/dist/manyfest.js +491 -54
- package/dist/manyfest.min.js +1 -1
- package/dist/manyfest.min.js.map +1 -1
- package/package.json +1 -1
- package/source/Manyfest-ObjectAddress-CheckAddressExists.js +109 -13
- package/source/Manyfest-ObjectAddress-DeleteValue.js +0 -2
- package/source/Manyfest-ObjectAddress-GetValue.js +136 -10
- package/source/Manyfest-ObjectAddress-Parser.js +298 -0
- package/source/Manyfest-ParseConditionals.js +10 -12
- package/test/Manyfest_Embedded_Solvers_tests.js +18 -16
- package/test/Manyfest_ObjectAddress_Parser_tests.js +160 -0
- package/test/Manyfest_Object_CheckExistence_tests.js +54 -0
- package/test/Manyfest_Object_Read_tests.js +126 -0
|
@@ -0,0 +1,298 @@
|
|
|
1
|
+
// TODO: This is an inelegant solution to delay the rewrite of Manyfest.
|
|
2
|
+
|
|
3
|
+
// Fable 3.0 has a service for data formatting that deals well with nested enclosures.
|
|
4
|
+
|
|
5
|
+
// The Manyfest library predates fable 3.0 and the services structure of it, so the functions
|
|
6
|
+
// are more or less pure javascript and as functional as they can be made to be.
|
|
7
|
+
|
|
8
|
+
// Until we shift Manyfest to be a fable service, these three functions were pulled out of
|
|
9
|
+
// fable to aid in parsing functions with nested enclosures.
|
|
10
|
+
|
|
11
|
+
module.exports = {
|
|
12
|
+
/**
|
|
13
|
+
* Count the number of segments in a string, respecting enclosures
|
|
14
|
+
*
|
|
15
|
+
* @param {string} pString
|
|
16
|
+
* @param {string} pSeparator
|
|
17
|
+
* @param {object} pEnclosureStartSymbolMap
|
|
18
|
+
* @param {object} pEnclosureEndSymbolMap
|
|
19
|
+
* @returns the count of segments in the string as a number
|
|
20
|
+
*/
|
|
21
|
+
stringCountSegments: (pString, pSeparator, pEnclosureStartSymbolMap, pEnclosureEndSymbolMap) =>
|
|
22
|
+
{
|
|
23
|
+
let tmpString = (typeof(pString) == 'string') ? pString : '';
|
|
24
|
+
|
|
25
|
+
let tmpSeparator = (typeof(pSeparator) == 'string') ? pSeparator : '.';
|
|
26
|
+
|
|
27
|
+
let tmpEnclosureStartSymbolMap = (typeof(pEnclosureStartSymbolMap) == 'object') ? pEnclosureStart : { '{': 0, '[': 1, '(': 2 };
|
|
28
|
+
let tmpEnclosureEndSymbolMap = (typeof(pEnclosureEndSymbolMap) == 'object') ? pEnclosureEnd : { '}': 0, ']': 1, ')': 2 };
|
|
29
|
+
|
|
30
|
+
if (pString.length < 1)
|
|
31
|
+
{
|
|
32
|
+
return 0;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
let tmpSegmentCount = 1;
|
|
36
|
+
let tmpEnclosureStack = [];
|
|
37
|
+
|
|
38
|
+
for (let i = 0; i < tmpString.length; i++)
|
|
39
|
+
{
|
|
40
|
+
// IF This is the start of a segment
|
|
41
|
+
if ((tmpString[i] == tmpSeparator)
|
|
42
|
+
// AND we are not in a nested portion of the string
|
|
43
|
+
&& (tmpEnclosureStack.length == 0))
|
|
44
|
+
{
|
|
45
|
+
// Increment the segment count
|
|
46
|
+
tmpSegmentCount++;
|
|
47
|
+
}
|
|
48
|
+
// IF This is the start of an enclosure
|
|
49
|
+
else if (tmpEnclosureStartSymbolMap.hasOwnProperty(tmpString[i]))
|
|
50
|
+
{
|
|
51
|
+
// Add it to the stack!
|
|
52
|
+
tmpEnclosureStack.push(tmpEnclosureStartSymbolMap[tmpString[i]]);
|
|
53
|
+
}
|
|
54
|
+
// IF This is the end of an enclosure
|
|
55
|
+
else if (tmpEnclosureEndSymbolMap.hasOwnProperty(tmpString[i])
|
|
56
|
+
// AND it matches the current nest level symbol
|
|
57
|
+
&& tmpEnclosureEndSymbolMap[tmpString[i]] == tmpEnclosureStack[tmpEnclosureStack.length - 1])
|
|
58
|
+
{
|
|
59
|
+
// Pop it off the stack!
|
|
60
|
+
tmpEnclosureStack.pop();
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
return tmpSegmentCount;
|
|
65
|
+
},
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* Get the first segment in a string, respecting enclosures
|
|
69
|
+
*
|
|
70
|
+
* @param {string} pString
|
|
71
|
+
* @param {string} pSeparator
|
|
72
|
+
* @param {object} pEnclosureStartSymbolMap
|
|
73
|
+
* @param {object} pEnclosureEndSymbolMap
|
|
74
|
+
* @returns the first segment in the string as a string
|
|
75
|
+
*/
|
|
76
|
+
stringGetFirstSegment: (pString, pSeparator, pEnclosureStartSymbolMap, pEnclosureEndSymbolMap) =>
|
|
77
|
+
{
|
|
78
|
+
let tmpString = (typeof(pString) == 'string') ? pString : '';
|
|
79
|
+
|
|
80
|
+
let tmpSeparator = (typeof(pSeparator) == 'string') ? pSeparator : '.';
|
|
81
|
+
|
|
82
|
+
let tmpEnclosureStartSymbolMap = (typeof(pEnclosureStartSymbolMap) == 'object') ? pEnclosureStart : { '{': 0, '[': 1, '(': 2 };
|
|
83
|
+
let tmpEnclosureEndSymbolMap = (typeof(pEnclosureEndSymbolMap) == 'object') ? pEnclosureEnd : { '}': 0, ']': 1, ')': 2 };
|
|
84
|
+
|
|
85
|
+
if (pString.length < 1)
|
|
86
|
+
{
|
|
87
|
+
return 0;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
let tmpEnclosureStack = [];
|
|
91
|
+
|
|
92
|
+
for (let i = 0; i < tmpString.length; i++)
|
|
93
|
+
{
|
|
94
|
+
// IF This is the start of a segment
|
|
95
|
+
if ((tmpString[i] == tmpSeparator)
|
|
96
|
+
// AND we are not in a nested portion of the string
|
|
97
|
+
&& (tmpEnclosureStack.length == 0))
|
|
98
|
+
{
|
|
99
|
+
// Return the segment
|
|
100
|
+
return tmpString.substring(0, i);
|
|
101
|
+
}
|
|
102
|
+
// IF This is the start of an enclosure
|
|
103
|
+
else if (tmpEnclosureStartSymbolMap.hasOwnProperty(tmpString[i]))
|
|
104
|
+
{
|
|
105
|
+
// Add it to the stack!
|
|
106
|
+
tmpEnclosureStack.push(tmpEnclosureStartSymbolMap[tmpString[i]]);
|
|
107
|
+
}
|
|
108
|
+
// IF This is the end of an enclosure
|
|
109
|
+
else if (tmpEnclosureEndSymbolMap.hasOwnProperty(tmpString[i])
|
|
110
|
+
// AND it matches the current nest level symbol
|
|
111
|
+
&& tmpEnclosureEndSymbolMap[tmpString[i]] == tmpEnclosureStack[tmpEnclosureStack.length - 1])
|
|
112
|
+
{
|
|
113
|
+
// Pop it off the stack!
|
|
114
|
+
tmpEnclosureStack.pop();
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
return tmpString;
|
|
119
|
+
},
|
|
120
|
+
|
|
121
|
+
/**
|
|
122
|
+
* Get all segments in a string, respecting enclosures
|
|
123
|
+
*
|
|
124
|
+
* @param {string} pString
|
|
125
|
+
* @param {string} pSeparator
|
|
126
|
+
* @param {object} pEnclosureStartSymbolMap
|
|
127
|
+
* @param {object} pEnclosureEndSymbolMap
|
|
128
|
+
* @returns the first segment in the string as a string
|
|
129
|
+
*/
|
|
130
|
+
stringGetSegments: (pString, pSeparator, pEnclosureStartSymbolMap, pEnclosureEndSymbolMap)=>
|
|
131
|
+
{
|
|
132
|
+
let tmpString = (typeof(pString) == 'string') ? pString : '';
|
|
133
|
+
|
|
134
|
+
let tmpSeparator = (typeof(pSeparator) == 'string') ? pSeparator : '.';
|
|
135
|
+
|
|
136
|
+
let tmpEnclosureStartSymbolMap = (typeof(pEnclosureStartSymbolMap) == 'object') ? pEnclosureStart : { '{': 0, '[': 1, '(': 2 };
|
|
137
|
+
let tmpEnclosureEndSymbolMap = (typeof(pEnclosureEndSymbolMap) == 'object') ? pEnclosureEnd : { '}': 0, ']': 1, ')': 2 };
|
|
138
|
+
|
|
139
|
+
let tmpCurrentSegmentStart = 0;
|
|
140
|
+
let tmpSegmentList = [];
|
|
141
|
+
|
|
142
|
+
if (pString.length < 1)
|
|
143
|
+
{
|
|
144
|
+
return tmpSegmentList;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
let tmpEnclosureStack = [];
|
|
148
|
+
|
|
149
|
+
for (let i = 0; i < tmpString.length; i++)
|
|
150
|
+
{
|
|
151
|
+
// IF This is the start of a segment
|
|
152
|
+
if ((tmpString[i] == tmpSeparator)
|
|
153
|
+
// AND we are not in a nested portion of the string
|
|
154
|
+
&& (tmpEnclosureStack.length == 0))
|
|
155
|
+
{
|
|
156
|
+
// Return the segment
|
|
157
|
+
tmpSegmentList.push(tmpString.substring(tmpCurrentSegmentStart, i));
|
|
158
|
+
tmpCurrentSegmentStart = i+1;
|
|
159
|
+
}
|
|
160
|
+
// IF This is the start of an enclosure
|
|
161
|
+
else if (tmpEnclosureStartSymbolMap.hasOwnProperty(tmpString[i]))
|
|
162
|
+
{
|
|
163
|
+
// Add it to the stack!
|
|
164
|
+
tmpEnclosureStack.push(tmpEnclosureStartSymbolMap[tmpString[i]]);
|
|
165
|
+
}
|
|
166
|
+
// IF This is the end of an enclosure
|
|
167
|
+
else if (tmpEnclosureEndSymbolMap.hasOwnProperty(tmpString[i])
|
|
168
|
+
// AND it matches the current nest level symbol
|
|
169
|
+
&& tmpEnclosureEndSymbolMap[tmpString[i]] == tmpEnclosureStack[tmpEnclosureStack.length - 1])
|
|
170
|
+
{
|
|
171
|
+
// Pop it off the stack!
|
|
172
|
+
tmpEnclosureStack.pop();
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
if (tmpCurrentSegmentStart < tmpString.length)
|
|
177
|
+
{
|
|
178
|
+
tmpSegmentList.push(tmpString.substring(tmpCurrentSegmentStart));
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
return tmpSegmentList;
|
|
182
|
+
},
|
|
183
|
+
|
|
184
|
+
/**
|
|
185
|
+
* Count the number of enclosures in a string based on the start and end characters.
|
|
186
|
+
*
|
|
187
|
+
* If no start or end characters are specified, it will default to parentheses. If the string is not a string, it will return 0.
|
|
188
|
+
*
|
|
189
|
+
* @param {string} pString
|
|
190
|
+
* @param {string} pEnclosureStart
|
|
191
|
+
* @param {string} pEnclosureEnd
|
|
192
|
+
* @returns the count of full in the string
|
|
193
|
+
*/
|
|
194
|
+
stringCountEnclosures: (pString, pEnclosureStart, pEnclosureEnd) =>
|
|
195
|
+
{
|
|
196
|
+
let tmpString = (typeof(pString) == 'string') ? pString : '';
|
|
197
|
+
let tmpEnclosureStart = (typeof(pEnclosureStart) == 'string') ? pEnclosureStart : '(';
|
|
198
|
+
let tmpEnclosureEnd = (typeof(pEnclosureEnd) == 'string') ? pEnclosureEnd : ')';
|
|
199
|
+
|
|
200
|
+
let tmpEnclosureCount = 0;
|
|
201
|
+
let tmpEnclosureDepth = 0;
|
|
202
|
+
for (let i = 0; i < tmpString.length; i++)
|
|
203
|
+
{
|
|
204
|
+
// This is the start of an enclosure
|
|
205
|
+
if (tmpString[i] == tmpEnclosureStart)
|
|
206
|
+
{
|
|
207
|
+
if (tmpEnclosureDepth == 0)
|
|
208
|
+
{
|
|
209
|
+
tmpEnclosureCount++;
|
|
210
|
+
}
|
|
211
|
+
tmpEnclosureDepth++;
|
|
212
|
+
}
|
|
213
|
+
else if (tmpString[i] == tmpEnclosureEnd)
|
|
214
|
+
{
|
|
215
|
+
tmpEnclosureDepth--;
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
return tmpEnclosureCount;
|
|
220
|
+
},
|
|
221
|
+
|
|
222
|
+
|
|
223
|
+
/**
|
|
224
|
+
* Get the value of the enclosure at the specified index.
|
|
225
|
+
*
|
|
226
|
+
* If the index is not a number, it will default to 0. If the string is not a string, it will return an empty string. If the enclosure is not found, it will return an empty string. If the enclosure
|
|
227
|
+
*
|
|
228
|
+
* @param {string} pString
|
|
229
|
+
* @param {number} pEnclosureIndexToGet
|
|
230
|
+
* @param {string} pEnclosureStart
|
|
231
|
+
* @param {string}} pEnclosureEnd
|
|
232
|
+
* @returns {string}
|
|
233
|
+
*/
|
|
234
|
+
stringGetEnclosureValueByIndex: (pString, pEnclosureIndexToGet, pEnclosureStart, pEnclosureEnd) =>
|
|
235
|
+
{
|
|
236
|
+
let tmpString = (typeof(pString) == 'string') ? pString : '';
|
|
237
|
+
let tmpEnclosureIndexToGet = (typeof(pEnclosureIndexToGet) == 'number') ? pEnclosureIndexToGet : 0;
|
|
238
|
+
let tmpEnclosureStart = (typeof(pEnclosureStart) == 'string') ? pEnclosureStart : '(';
|
|
239
|
+
let tmpEnclosureEnd = (typeof(pEnclosureEnd) == 'string') ? pEnclosureEnd : ')';
|
|
240
|
+
|
|
241
|
+
let tmpEnclosureCount = 0;
|
|
242
|
+
let tmpEnclosureDepth = 0;
|
|
243
|
+
|
|
244
|
+
let tmpMatchedEnclosureIndex = false;
|
|
245
|
+
let tmpEnclosedValueStartIndex = 0;
|
|
246
|
+
let tmpEnclosedValueEndIndex = 0;
|
|
247
|
+
|
|
248
|
+
for (let i = 0; i < tmpString.length; i++)
|
|
249
|
+
{
|
|
250
|
+
// This is the start of an enclosure
|
|
251
|
+
if (tmpString[i] == tmpEnclosureStart)
|
|
252
|
+
{
|
|
253
|
+
tmpEnclosureDepth++;
|
|
254
|
+
|
|
255
|
+
// Only count enclosures at depth 1, but still this parses both pairs of all of them.
|
|
256
|
+
if (tmpEnclosureDepth == 1)
|
|
257
|
+
{
|
|
258
|
+
tmpEnclosureCount++;
|
|
259
|
+
if (tmpEnclosureIndexToGet == (tmpEnclosureCount - 1))
|
|
260
|
+
{
|
|
261
|
+
// This is the start of *the* enclosure
|
|
262
|
+
tmpMatchedEnclosureIndex = true;
|
|
263
|
+
tmpEnclosedValueStartIndex = i;
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
// This is the end of an enclosure
|
|
268
|
+
else if (tmpString[i] == tmpEnclosureEnd)
|
|
269
|
+
{
|
|
270
|
+
tmpEnclosureDepth--;
|
|
271
|
+
|
|
272
|
+
// Again, only count enclosures at depth 1, but still this parses both pairs of all of them.
|
|
273
|
+
if ((tmpEnclosureDepth == 0) &&
|
|
274
|
+
tmpMatchedEnclosureIndex &&
|
|
275
|
+
(tmpEnclosedValueEndIndex <= tmpEnclosedValueStartIndex))
|
|
276
|
+
{
|
|
277
|
+
tmpEnclosedValueEndIndex = i;
|
|
278
|
+
tmpMatchedEnclosureIndex = false;
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
if (tmpEnclosureCount <= tmpEnclosureIndexToGet)
|
|
284
|
+
{
|
|
285
|
+
// Return an empty string if the enclosure is not found
|
|
286
|
+
return '';
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
if ((tmpEnclosedValueEndIndex > 0) && (tmpEnclosedValueEndIndex > tmpEnclosedValueStartIndex))
|
|
290
|
+
{
|
|
291
|
+
return tmpString.substring(tmpEnclosedValueStartIndex+1, tmpEnclosedValueEndIndex);
|
|
292
|
+
}
|
|
293
|
+
else
|
|
294
|
+
{
|
|
295
|
+
return tmpString.substring(tmpEnclosedValueStartIndex+1);
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
}
|
|
@@ -18,7 +18,7 @@ const _ConditionalStanzaEnd = '?~>>';
|
|
|
18
18
|
const _ConditionalStanzaEndLength = _ConditionalStanzaEnd.length;
|
|
19
19
|
|
|
20
20
|
// Ugh dependency injection. Can't wait to make these all fable services.
|
|
21
|
-
let libObjectAddressCheckAddressExists = new (require('./Manyfest-ObjectAddress-CheckAddressExists.js'))();
|
|
21
|
+
//let libObjectAddressCheckAddressExists = new (require('./Manyfest-ObjectAddress-CheckAddressExists.js'))();
|
|
22
22
|
|
|
23
23
|
// Test the condition of a value in a record
|
|
24
24
|
const testCondition = (pManyfest, pRecord, pSearchAddress, pSearchComparator, pValue) =>
|
|
@@ -61,17 +61,15 @@ const testCondition = (pManyfest, pRecord, pSearchAddress, pSearchComparator, pV
|
|
|
61
61
|
break;
|
|
62
62
|
}
|
|
63
63
|
break;
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
return !libObjectAddressCheckAddressExists.checkAddressExists(pRecord, pSearchAddress);
|
|
74
|
-
break;
|
|
64
|
+
// TODO: Welcome to dependency hell. This fixes itself when we move to fable services.
|
|
65
|
+
// case 'EX':
|
|
66
|
+
// case 'EXISTS':
|
|
67
|
+
// return libObjectAddressCheckAddressExists.checkAddressExists(pRecord, pSearchAddress);
|
|
68
|
+
// break;
|
|
69
|
+
// case 'DNEX':
|
|
70
|
+
// case 'DOES_NOT_EXIST':
|
|
71
|
+
// return !libObjectAddressCheckAddressExists.checkAddressExists(pRecord, pSearchAddress);
|
|
72
|
+
// break;
|
|
75
73
|
case '!=':
|
|
76
74
|
return (pManyfest.getValueAtAddress(pRecord, pSearchAddress) != pValue);
|
|
77
75
|
break;
|
|
@@ -59,10 +59,11 @@ suite
|
|
|
59
59
|
Scope:'Archive.org',
|
|
60
60
|
Descriptors:
|
|
61
61
|
{
|
|
62
|
-
|
|
63
|
-
'files[]<<~?length,
|
|
64
|
-
'files[]<<~?length,DNEX
|
|
65
|
-
|
|
62
|
+
// TODO: STRICKEN OUT BY DEPENDENCY HELL
|
|
63
|
+
//'files[]<<~?length,EXISTS?~>>': {Name:'Files With a length Property', Hash:'FilesWithLength'},
|
|
64
|
+
// 'files[]<<~?length,DNEX?~>>': {Name:'Files Without a length Property', Hash:'FilesWithoutLength'},
|
|
65
|
+
// 'files[]<<~?length,DNEX?~>><<~?source,==,original?~>>': {Name:'Original Files With a length Property', Hash:'OriginalFilesWithLength'},
|
|
66
|
+
// 'files[]<<~?thumbnail,EXISTS?~>>': {Name:'Thumbnail Bit is Explicitly Set', Hash:'ThumbnailExplicitlySet'},
|
|
66
67
|
'files[]<<~?thumbnail,TRUE?~>>': {Name:'Thumbnail Files', Hash:'ThumbnailFiles'},
|
|
67
68
|
'files[]<<~?thumbnail,FALSE?~>>': {Name:'Not Thumbnail Files', Hash:'NotThumbnailFiles'},
|
|
68
69
|
'files[]<<~?format,LENGTH_LESS_THAN,8?~>>': {Name:'Short Format Files', Hash:'ShortFormatFiles'}
|
|
@@ -79,21 +80,22 @@ suite
|
|
|
79
80
|
Expect(tmpNotThumbnailFiles).to.be.an('array');
|
|
80
81
|
Expect(tmpNotThumbnailFiles.length).to.equal(1);
|
|
81
82
|
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
Expect(tmpFilesWithLength
|
|
83
|
+
// TODO: Dependencies are the wurst
|
|
84
|
+
// let tmpFilesWithLength = _Manyfest.getValueByHash(_SampleDataArchiveOrgFrankenberry, 'FilesWithLength');
|
|
85
|
+
// Expect(tmpFilesWithLength).to.be.an('array');
|
|
86
|
+
// Expect(tmpFilesWithLength.length).to.equal(3);
|
|
85
87
|
|
|
86
|
-
let tmpOGFilesWithLength = _Manyfest.getValueByHash(_SampleDataArchiveOrgFrankenberry, 'OriginalFilesWithLength');
|
|
87
|
-
Expect(tmpOGFilesWithLength).to.be.an('array');
|
|
88
|
-
Expect(tmpOGFilesWithLength.length).to.equal(2);
|
|
88
|
+
// let tmpOGFilesWithLength = _Manyfest.getValueByHash(_SampleDataArchiveOrgFrankenberry, 'OriginalFilesWithLength');
|
|
89
|
+
// Expect(tmpOGFilesWithLength).to.be.an('array');
|
|
90
|
+
// Expect(tmpOGFilesWithLength.length).to.equal(2);
|
|
89
91
|
|
|
90
|
-
let tmpFilesWithoutLength = _Manyfest.getValueByHash(_SampleDataArchiveOrgFrankenberry, 'FilesWithoutLength');
|
|
91
|
-
Expect(tmpFilesWithoutLength).to.be.an('array');
|
|
92
|
-
Expect(tmpFilesWithoutLength.length).to.equal(14);
|
|
92
|
+
// let tmpFilesWithoutLength = _Manyfest.getValueByHash(_SampleDataArchiveOrgFrankenberry, 'FilesWithoutLength');
|
|
93
|
+
// Expect(tmpFilesWithoutLength).to.be.an('array');
|
|
94
|
+
// Expect(tmpFilesWithoutLength.length).to.equal(14);
|
|
93
95
|
|
|
94
|
-
let tmpExplicitlyExists = _Manyfest.getValueByHash(_SampleDataArchiveOrgFrankenberry, 'ThumbnailExplicitlySet');
|
|
95
|
-
Expect(tmpExplicitlyExists).to.be.an('array');
|
|
96
|
-
Expect(tmpExplicitlyExists.length).to.equal(2);
|
|
96
|
+
// let tmpExplicitlyExists = _Manyfest.getValueByHash(_SampleDataArchiveOrgFrankenberry, 'ThumbnailExplicitlySet');
|
|
97
|
+
// Expect(tmpExplicitlyExists).to.be.an('array');
|
|
98
|
+
// Expect(tmpExplicitlyExists.length).to.equal(2);
|
|
97
99
|
|
|
98
100
|
let tmpShortFormatFiles = _Manyfest.getValueByHash(_SampleDataArchiveOrgFrankenberry, 'ShortFormatFiles');
|
|
99
101
|
Expect(tmpShortFormatFiles).to.be.an('array');
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Unit tests for Mock Fable behaviors
|
|
3
|
+
*
|
|
4
|
+
* Shamelessly ripped from fable until we can get the fable service structure in place.
|
|
5
|
+
*
|
|
6
|
+
* @license MIT
|
|
7
|
+
*
|
|
8
|
+
* @author Steven Velozo <steven@velozo.com>
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
var libFableDataFormatInjector = require('../source/Manyfest-ObjectAddress-Parser.js');
|
|
12
|
+
|
|
13
|
+
var Chai = require("chai");
|
|
14
|
+
var Expect = Chai.expect;
|
|
15
|
+
|
|
16
|
+
suite
|
|
17
|
+
(
|
|
18
|
+
'DataArithmatic String Tokenization',
|
|
19
|
+
function()
|
|
20
|
+
{
|
|
21
|
+
setup (()=> {} );
|
|
22
|
+
|
|
23
|
+
suite
|
|
24
|
+
(
|
|
25
|
+
'Manipulate Strings',
|
|
26
|
+
()=>
|
|
27
|
+
{
|
|
28
|
+
|
|
29
|
+
test
|
|
30
|
+
(
|
|
31
|
+
'Test counting enclosures',
|
|
32
|
+
(fTestComplete)=>
|
|
33
|
+
{
|
|
34
|
+
//let testFable = new libFable({LogStreams: false});
|
|
35
|
+
let _DataFormat = libFableDataFormatInjector;
|
|
36
|
+
Expect(_DataFormat
|
|
37
|
+
.stringCountEnclosures('Dogs (are) cool'))
|
|
38
|
+
.to.equal(1);
|
|
39
|
+
Expect(_DataFormat
|
|
40
|
+
.stringCountEnclosures('Dogs are cool'))
|
|
41
|
+
.to.equal(0);
|
|
42
|
+
// It should not count nested enclosures.
|
|
43
|
+
// Although with getEnclosureValueByIndex and recalling this, you can recursively get them.
|
|
44
|
+
Expect(_DataFormat
|
|
45
|
+
.stringCountEnclosures('There (are (many)) of these (things)'))
|
|
46
|
+
.to.equal(2);
|
|
47
|
+
Expect(_DataFormat
|
|
48
|
+
.stringCountEnclosures('There [are (many)] of these (things)'))
|
|
49
|
+
.to.equal(2);
|
|
50
|
+
// You can also specify the enclosure characters
|
|
51
|
+
Expect(_DataFormat
|
|
52
|
+
.stringCountEnclosures('There [are (many)] of these (things)', '[', ']'))
|
|
53
|
+
.to.equal(1);
|
|
54
|
+
// It does not *require* a closing character and still counts the enclosure.
|
|
55
|
+
// Hotly debated topic. A setting could be added to change this behavior.
|
|
56
|
+
Expect(_DataFormat
|
|
57
|
+
.stringCountEnclosures('There [are (many) of these (things)', '[', ']'))
|
|
58
|
+
.to.equal(1);
|
|
59
|
+
return fTestComplete();
|
|
60
|
+
}
|
|
61
|
+
);
|
|
62
|
+
test
|
|
63
|
+
(
|
|
64
|
+
'Test getting an enclosure value by index',
|
|
65
|
+
(fTestComplete)=>
|
|
66
|
+
{
|
|
67
|
+
//let testFable = new libFable({LogStreams: false});
|
|
68
|
+
let _DataFormat = libFableDataFormatInjector;
|
|
69
|
+
Expect(_DataFormat
|
|
70
|
+
.stringGetEnclosureValueByIndex('Dogs (are) cool', 0))
|
|
71
|
+
.to.equal('are');
|
|
72
|
+
Expect(_DataFormat
|
|
73
|
+
.stringGetEnclosureValueByIndex('Dogs are cool', 0))
|
|
74
|
+
.to.equal('');
|
|
75
|
+
Expect(_DataFormat
|
|
76
|
+
.stringGetEnclosureValueByIndex('There (are (many)) of these (things)', 0))
|
|
77
|
+
.to.equal('are (many)');
|
|
78
|
+
Expect(_DataFormat
|
|
79
|
+
.stringGetEnclosureValueByIndex('There [are (many)] of these (things)', 1))
|
|
80
|
+
.to.equal('things');
|
|
81
|
+
Expect(_DataFormat
|
|
82
|
+
.stringGetEnclosureValueByIndex('There [are (many)] of these (things)', 2))
|
|
83
|
+
.to.equal('');
|
|
84
|
+
Expect(_DataFormat
|
|
85
|
+
.stringGetEnclosureValueByIndex('(This enclosure is the whole string)', 0))
|
|
86
|
+
.to.equal('This enclosure is the whole string');
|
|
87
|
+
// You can also specify the enclosure characters
|
|
88
|
+
Expect(_DataFormat
|
|
89
|
+
.stringGetEnclosureValueByIndex('There [are (many)] of these (things)', 0, '[', ']'))
|
|
90
|
+
.to.equal('are (many)');
|
|
91
|
+
Expect(_DataFormat
|
|
92
|
+
.stringGetEnclosureValueByIndex('There [are (many) of these (things)', 0, '[', ']'))
|
|
93
|
+
.to.equal('are (many) of these (things)');
|
|
94
|
+
Expect(_DataFormat
|
|
95
|
+
.stringGetEnclosureValueByIndex('There (are (many) of these (things))', 0))
|
|
96
|
+
.to.equal('are (many) of these (things)');
|
|
97
|
+
return fTestComplete();
|
|
98
|
+
}
|
|
99
|
+
);
|
|
100
|
+
|
|
101
|
+
test
|
|
102
|
+
(
|
|
103
|
+
'Test counting segments and respecting enclosures',
|
|
104
|
+
(fTestComplete)=>
|
|
105
|
+
{
|
|
106
|
+
//let testFable = new libFable({LogStreams: false});
|
|
107
|
+
let _DataFormat = libFableDataFormatInjector;
|
|
108
|
+
Expect(_DataFormat
|
|
109
|
+
.stringCountSegments('Dogs.are.cool'))
|
|
110
|
+
.to.equal(3);
|
|
111
|
+
Expect(_DataFormat
|
|
112
|
+
.stringCountSegments('Dogs.are.cool'))
|
|
113
|
+
.to.equal(3);
|
|
114
|
+
Expect(_DataFormat
|
|
115
|
+
.stringCountSegments('Dogs.are(.)cool'))
|
|
116
|
+
.to.equal(2);
|
|
117
|
+
Expect(_DataFormat
|
|
118
|
+
.stringCountSegments('Dogs.are(.[....])co.(.)ol'))
|
|
119
|
+
.to.equal(3);
|
|
120
|
+
Expect(_DataFormat
|
|
121
|
+
.stringCountSegments('Dogs.are(.[....]),co.(.)ol', ','))
|
|
122
|
+
.to.equal(2);
|
|
123
|
+
return fTestComplete();
|
|
124
|
+
}
|
|
125
|
+
);
|
|
126
|
+
test
|
|
127
|
+
(
|
|
128
|
+
'Get the first segment of a string',
|
|
129
|
+
(fTestComplete)=>
|
|
130
|
+
{
|
|
131
|
+
//let testFable = new libFable({LogStreams: false});
|
|
132
|
+
let _DataFormat = libFableDataFormatInjector;
|
|
133
|
+
Expect(_DataFormat
|
|
134
|
+
.stringGetFirstSegment('Dogs.are.cool'))
|
|
135
|
+
.to.equal('Dogs');
|
|
136
|
+
Expect(_DataFormat
|
|
137
|
+
.stringGetFirstSegment('Dogs().are.cool'))
|
|
138
|
+
.to.equal('Dogs()');
|
|
139
|
+
Expect(_DataFormat
|
|
140
|
+
.stringGetFirstSegment('Dogs[This.That(),Equals(THEM)].are(.)cool'))
|
|
141
|
+
.to.equal('Dogs[This.That(),Equals(THEM)]');
|
|
142
|
+
Expect(_DataFormat
|
|
143
|
+
.stringGetFirstSegment('Dogs(.are(.[....])co.(.)ol'))
|
|
144
|
+
.to.equal('Dogs(.are(.[....])co.(.)ol');
|
|
145
|
+
Expect(_DataFormat
|
|
146
|
+
.stringGetFirstSegment('Dogs(.are(,[....])co.(.)ol', ','))
|
|
147
|
+
.to.equal('Dogs(.are(,[....])co.(.)ol');
|
|
148
|
+
Expect(_DataFormat
|
|
149
|
+
.stringGetFirstSegment('Dogs.are(,[....]),co.(.)ol', ','))
|
|
150
|
+
.to.equal('Dogs.are(,[....])');
|
|
151
|
+
Expect(_DataFormat
|
|
152
|
+
.stringGetFirstSegment('..Dogs.are(,[....]),co.(.)ol', '.'))
|
|
153
|
+
.to.equal('');
|
|
154
|
+
return fTestComplete();
|
|
155
|
+
}
|
|
156
|
+
);
|
|
157
|
+
}
|
|
158
|
+
);
|
|
159
|
+
}
|
|
160
|
+
);
|
|
@@ -64,6 +64,60 @@ suite
|
|
|
64
64
|
fTestComplete();
|
|
65
65
|
}
|
|
66
66
|
);
|
|
67
|
+
test
|
|
68
|
+
(
|
|
69
|
+
'Elements exist in function return values ... yiiiiikes.',
|
|
70
|
+
(fTestComplete)=>
|
|
71
|
+
{
|
|
72
|
+
// Create a compmlex mock object to check metadata on.
|
|
73
|
+
let _MockObject = (
|
|
74
|
+
{
|
|
75
|
+
"Name": "Yadda",
|
|
76
|
+
"TheFunction": (pValue) => { return `Value is: ${pValue}`; },
|
|
77
|
+
"ComplexFunction": (pValue, pOutput) => { return `Value is: ${pValue} and would output as ${pOutput}`; },
|
|
78
|
+
"Behaviors":
|
|
79
|
+
{
|
|
80
|
+
"Value": 0,
|
|
81
|
+
"Increment": function ()
|
|
82
|
+
{
|
|
83
|
+
this.Value++; return this.Value;
|
|
84
|
+
},
|
|
85
|
+
"SillyObject": function()
|
|
86
|
+
{
|
|
87
|
+
return { Cost: 1.00, Name: 'Beanie Baby', Stores: ['Aberdeen', 'Seattle', 'Tacoma'] }
|
|
88
|
+
},
|
|
89
|
+
"FormatOutput": function () { return `My magic value is: ${this.Value}`; }
|
|
90
|
+
},
|
|
91
|
+
"Manyfest":
|
|
92
|
+
{
|
|
93
|
+
Scope:'Function.Mock',
|
|
94
|
+
Descriptors:
|
|
95
|
+
{
|
|
96
|
+
"metadata.creator":
|
|
97
|
+
{
|
|
98
|
+
Name:'Creator',
|
|
99
|
+
Hash:'Creator'
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
},
|
|
103
|
+
"Data": _SampleDataArchiveOrgFrankenberry
|
|
104
|
+
});
|
|
105
|
+
let _Manyfest = new libManyfest(_MockObject.Manyfest);
|
|
106
|
+
|
|
107
|
+
// Function existence should just work
|
|
108
|
+
Expect(_Manyfest.checkAddressExists(_MockObject, 'Behaviors.SillyObject')).to.equal(true);
|
|
109
|
+
// If it is a function we can ask manyfest if it's a function and it will be true
|
|
110
|
+
Expect(_Manyfest.checkAddressExists(_MockObject, 'Behaviors.SillyObject()')).to.equal(true);
|
|
111
|
+
// Non functions will return false even if they exist.
|
|
112
|
+
Expect(_Manyfest.checkAddressExists(_MockObject, 'Behaviors.Value')).to.equal(true);
|
|
113
|
+
Expect(_Manyfest.checkAddressExists(_MockObject, 'Behaviors.Value()')).to.equal(false);
|
|
114
|
+
|
|
115
|
+
Expect(_Manyfest.checkAddressExists(_MockObject, 'Behaviors.SillyObject().Stores')).to.equal(true);
|
|
116
|
+
Expect(_Manyfest.checkAddressExists(_MockObject, 'Behaviors.SillyObject().Stores[0]')).to.equal(true);
|
|
117
|
+
|
|
118
|
+
fTestComplete();
|
|
119
|
+
}
|
|
120
|
+
);
|
|
67
121
|
}
|
|
68
122
|
);
|
|
69
123
|
}
|