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.
@@ -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
- case 'FALSE':
65
- return (pManyfest.getValueAtAddress(pRecord, pSearchAddress) === false);
66
- break;
67
- case 'EX':
68
- case 'EXISTS':
69
- return libObjectAddressCheckAddressExists.checkAddressExists(pRecord, pSearchAddress);
70
- break;
71
- case 'DNEX':
72
- case 'DOES_NOT_EXIST':
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
- 'files[]<<~?length,EXISTS?~>>': {Name:'Files With a length Property', Hash:'FilesWithLength'},
63
- 'files[]<<~?length,DNEX?~>>': {Name:'Files Without a length Property', Hash:'FilesWithoutLength'},
64
- 'files[]<<~?length,DNEX?~>><<~?source,==,original?~>>': {Name:'Original Files With a length Property', Hash:'OriginalFilesWithLength'},
65
- 'files[]<<~?thumbnail,EXISTS?~>>': {Name:'Thumbnail Bit is Explicitly Set', Hash:'ThumbnailExplicitlySet'},
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
- let tmpFilesWithLength = _Manyfest.getValueByHash(_SampleDataArchiveOrgFrankenberry, 'FilesWithLength');
83
- Expect(tmpFilesWithLength).to.be.an('array');
84
- Expect(tmpFilesWithLength.length).to.equal(3);
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
  }