fable 3.0.30 → 3.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/README.md +33 -63
- package/debug/Harness.js +16 -2
- package/dist/fable.compatible.js +314 -272
- package/dist/fable.compatible.min.js +21 -21
- package/dist/fable.compatible.min.js.map +1 -1
- package/dist/fable.js +280 -238
- package/dist/fable.min.js +20 -20
- package/dist/fable.min.js.map +1 -1
- package/package.json +1 -1
- package/source/Fable-ServiceManager.js +7 -0
- package/source/Fable.js +3 -5
- package/source/services/Fable-Service-DataFormat.js +638 -0
- package/source/services/Fable-Service-RestClient.js +81 -3
- package/source/services/Fable-Service-Utility.js +70 -0
- package/test/DataFormat-StringDateFormatting_tests.js +109 -0
- package/test/{FableDataArithmatic_tests.js → DataFormat-StringManipulation_tests.js} +88 -46
- package/test/DataFormat-StringNumberFormatting_tests.js +110 -0
- package/test/DataFormat-StringTokenization_tests.js +167 -0
- package/test/RestClient_test.js +54 -0
- package/test/{FableUtility_tests.js → Utility_tests.js} +13 -0
- /package/test/{FableOperations_tests.js → FableOperation_tests.js} +0 -0
- /package/test/{FableMetaTemplating_tests.js → MetaTemplating_tests.js} +0 -0
|
@@ -6,11 +6,89 @@ class FableServiceRestClient extends libFableServiceBase
|
|
|
6
6
|
{
|
|
7
7
|
constructor(pFable, pOptions, pServiceHash)
|
|
8
8
|
{
|
|
9
|
-
|
|
9
|
+
super(pFable, pOptions, pServiceHash);
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
this.TraceLog = false;
|
|
12
|
+
if (this.options.TraceLog || this.fable.TraceLog)
|
|
13
|
+
{
|
|
14
|
+
this.TraceLog = true;
|
|
15
|
+
}
|
|
12
16
|
|
|
13
|
-
|
|
17
|
+
this.dataFormat = this.fable.defaultServices.DataFormat;
|
|
18
|
+
|
|
19
|
+
this.serviceType = 'RestClient';
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
getJSON(pOptionsOrURL, fCallback)
|
|
23
|
+
{
|
|
24
|
+
return this.getRaw(pOptionsOrURL,
|
|
25
|
+
(pError, pResponse, pResult) =>
|
|
26
|
+
{
|
|
27
|
+
if (pError)
|
|
28
|
+
{
|
|
29
|
+
return fCallback(pError, pResponse, pResult);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
if (pResponse.statusCode != 200)
|
|
33
|
+
{
|
|
34
|
+
return fCallback(new Error(`Invalid status code ${pResponse.statusCode}`), pResponse, pResult);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
return fCallback(pError, pResponse, JSON.parse(pResult));
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
getRaw(pOptionsOrURL, fCallback)
|
|
42
|
+
{
|
|
43
|
+
let tmpRequestOptions = (typeof(pOptions) == 'object') ? pOptions : {};
|
|
44
|
+
if (typeof(pOptionsOrURL) == 'string')
|
|
45
|
+
{
|
|
46
|
+
tmpRequestOptions.url = pOptionsOrURL;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
let tmpRequestStartTime = this.fable.log.getTimeStamp();
|
|
50
|
+
if (this.TraceLog)
|
|
51
|
+
{
|
|
52
|
+
let tmpConnectTime = this.fable.log.getTimeStamp();
|
|
53
|
+
this.fable.log.debug(`Beginning GET request to ${tmpRequestOptions.url} at ${tmpRequestStartTime}`);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
libSimpleGet.get(tmpRequestOptions,
|
|
57
|
+
(pError, pResponse)=>
|
|
58
|
+
{
|
|
59
|
+
if (pError)
|
|
60
|
+
{
|
|
61
|
+
return fCallback(pError, pResponse, tmpRequestOptions);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
if (this.TraceLog)
|
|
65
|
+
{
|
|
66
|
+
let tmpConnectTime = this.fable.log.getTimeStamp();
|
|
67
|
+
this.fable.log.debug(`--> GET connected in ${this.dataFormat.formatTimeDelta(tmpRequestStartTime, tmpConnectTime)}ms code ${pResponse.statusCode}`);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
let tmpData = '';
|
|
71
|
+
|
|
72
|
+
pResponse.on('data', (pChunk)=>
|
|
73
|
+
{
|
|
74
|
+
if (this.TraceLog)
|
|
75
|
+
{
|
|
76
|
+
let tmpChunkTime = this.fable.log.getTimeStamp();
|
|
77
|
+
this.fable.log.debug(`--> GET data chunk size ${pChunk.length}b received in ${this.dataFormat.formatTimeDelta(tmpRequestStartTime, tmpChunkTime)}ms`);
|
|
78
|
+
}
|
|
79
|
+
tmpData += pChunk;
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
pResponse.on('end', ()=>
|
|
83
|
+
{
|
|
84
|
+
if (this.TraceLog)
|
|
85
|
+
{
|
|
86
|
+
let tmpCompletionTime = this.fable.log.getTimeStamp();
|
|
87
|
+
this.fable.log.debug(`==> GET completed data size ${tmpData.length}b received in ${this.dataFormat.formatTimeDelta(tmpRequestStartTime, tmpCompletionTime)}ms`);
|
|
88
|
+
}
|
|
89
|
+
return fCallback(pError, pResponse, tmpData);
|
|
90
|
+
});
|
|
91
|
+
});
|
|
14
92
|
}
|
|
15
93
|
}
|
|
16
94
|
|
|
@@ -77,6 +77,76 @@ class FableServiceUtility extends libFableServiceBase
|
|
|
77
77
|
|
|
78
78
|
return tmpChunkCache;
|
|
79
79
|
}
|
|
80
|
+
|
|
81
|
+
// Convert an ISO string to a javascript date object
|
|
82
|
+
// Adapted from https://stackoverflow.com/a/54751179
|
|
83
|
+
//
|
|
84
|
+
// Takes strings like: 2022-11-04T11:34:45.000Z
|
|
85
|
+
// and: 1986-06-11T09:34:46.012Z+0200
|
|
86
|
+
// ... and converts them into javascript timestamps, following the directions of the timezone stuff.
|
|
87
|
+
//
|
|
88
|
+
// This is not meant to replace the more complex libraries.
|
|
89
|
+
// This *is* meant to be a simple, small, and fast way to convert ISO strings to dates in engines with limited JS capabilities.
|
|
90
|
+
isoStringToDate (pISOString)
|
|
91
|
+
{
|
|
92
|
+
|
|
93
|
+
// Split the string into an array based on the digit groups.
|
|
94
|
+
var tmpDateParts = pISOString.split( /\D+/ );
|
|
95
|
+
|
|
96
|
+
// Set up a date object with the current time.
|
|
97
|
+
var tmpReturnDate = new Date();
|
|
98
|
+
|
|
99
|
+
// Manually parse the parts of the string and set each part for the
|
|
100
|
+
// date. Note: Using the UTC versions of these functions is necessary
|
|
101
|
+
// because we're manually adjusting for time zones stored in the
|
|
102
|
+
// string.
|
|
103
|
+
tmpReturnDate.setUTCFullYear( parseInt( tmpDateParts[ 0 ] ) );
|
|
104
|
+
|
|
105
|
+
// The month numbers are one "off" from what normal humans would expect
|
|
106
|
+
// because January == 0.
|
|
107
|
+
tmpReturnDate.setUTCMonth( parseInt( tmpDateParts[ 1 ] - 1 ) );
|
|
108
|
+
tmpReturnDate.setUTCDate( parseInt( tmpDateParts[ 2 ] ) );
|
|
109
|
+
|
|
110
|
+
// Set the time parts of the date object.
|
|
111
|
+
tmpReturnDate.setUTCHours( parseInt( tmpDateParts[ 3 ] ) );
|
|
112
|
+
tmpReturnDate.setUTCMinutes( parseInt( tmpDateParts[ 4 ] ) );
|
|
113
|
+
tmpReturnDate.setUTCSeconds( parseInt( tmpDateParts[ 5 ] ) );
|
|
114
|
+
tmpReturnDate.setUTCMilliseconds( parseInt( tmpDateParts[ 6 ] ) );
|
|
115
|
+
|
|
116
|
+
// Track the number of hours we need to adjust the date by based on the timezone.
|
|
117
|
+
var tmpTimeZoneOffsetInHours = 0;
|
|
118
|
+
|
|
119
|
+
// If there's a value for either the hours or minutes offset.
|
|
120
|
+
if (tmpDateParts[ 7 ] || tmpDateParts[ 8 ])
|
|
121
|
+
{
|
|
122
|
+
|
|
123
|
+
// Track the number of minutes we need to adjust the date by based on the timezone.
|
|
124
|
+
var tmpTimeZoneOffsetInMinutes = 0;
|
|
125
|
+
|
|
126
|
+
// If there's a value for the minutes offset.
|
|
127
|
+
if (tmpDateParts[8])
|
|
128
|
+
{
|
|
129
|
+
// Convert the minutes value into an hours value.
|
|
130
|
+
tmpTimeZoneOffsetInMinutes = parseInt(tmpDateParts[8]) / 60;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
// Add the hours and minutes values to get the total offset in hours.
|
|
134
|
+
tmpTimeZoneOffsetInHours = parseInt(tmpDateParts[7]) + tmpTimeZoneOffsetInMinutes;
|
|
135
|
+
|
|
136
|
+
// If the sign for the timezone is a plus to indicate the timezone is ahead of UTC time.
|
|
137
|
+
if (pISOString.substr( -6, 1 ) == "+")
|
|
138
|
+
{
|
|
139
|
+
// Make the offset negative since the hours will need to be subtracted from the date.
|
|
140
|
+
tmpTimeZoneOffsetInHours *= -1;
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
// Get the current hours for the date and add the offset to get the correct time adjusted for timezone.
|
|
145
|
+
tmpReturnDate.setHours( tmpReturnDate.getHours() + tmpTimeZoneOffsetInHours );
|
|
146
|
+
|
|
147
|
+
// Return the Date object calculated from the string.
|
|
148
|
+
return tmpReturnDate;
|
|
149
|
+
}
|
|
80
150
|
}
|
|
81
151
|
|
|
82
152
|
module.exports = FableServiceUtility;
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Unit tests for DataArithmatic
|
|
3
|
+
*
|
|
4
|
+
* @license MIT
|
|
5
|
+
*
|
|
6
|
+
* @author Steven Velozo <steven@velozo.com>
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
var libFable = require('../source/Fable.js');
|
|
10
|
+
|
|
11
|
+
var Chai = require("chai");
|
|
12
|
+
var Expect = Chai.expect;
|
|
13
|
+
|
|
14
|
+
suite
|
|
15
|
+
(
|
|
16
|
+
'DataArithmatic Date',
|
|
17
|
+
function()
|
|
18
|
+
{
|
|
19
|
+
setup (()=> {} );
|
|
20
|
+
|
|
21
|
+
suite
|
|
22
|
+
(
|
|
23
|
+
'Format Dates and Times',
|
|
24
|
+
()=>
|
|
25
|
+
{
|
|
26
|
+
test
|
|
27
|
+
(
|
|
28
|
+
'Format a time span in milliseconds to a human readable string',
|
|
29
|
+
(fTestComplete)=>
|
|
30
|
+
{
|
|
31
|
+
let testFable = new libFable({LogStreams: false});
|
|
32
|
+
let _DataFormat = testFable.defaultServices.DataFormat;
|
|
33
|
+
Expect(_DataFormat
|
|
34
|
+
.formatTimeSpan(1000))
|
|
35
|
+
.to.equal('00:00:01.000');
|
|
36
|
+
Expect(_DataFormat
|
|
37
|
+
.formatTimeSpan(100243231))
|
|
38
|
+
.to.equal('27:50:43.231');
|
|
39
|
+
Expect(_DataFormat
|
|
40
|
+
.formatTimeSpan(100299211))
|
|
41
|
+
.to.equal('27:51:39.211');
|
|
42
|
+
Expect(_DataFormat
|
|
43
|
+
.formatTimeSpan())
|
|
44
|
+
.to.equal('');
|
|
45
|
+
return fTestComplete();
|
|
46
|
+
}
|
|
47
|
+
);
|
|
48
|
+
test
|
|
49
|
+
(
|
|
50
|
+
'Format a time delta in milliseconds to a human readable string',
|
|
51
|
+
(fTestComplete) =>
|
|
52
|
+
{
|
|
53
|
+
let testFable = new libFable({LogStreams: false});
|
|
54
|
+
let _DataFormat = testFable.defaultServices.DataFormat;
|
|
55
|
+
Expect(_DataFormat
|
|
56
|
+
.formatTimeDelta(1000, 2000))
|
|
57
|
+
.to.equal('00:00:01.000');
|
|
58
|
+
Expect(_DataFormat
|
|
59
|
+
.formatTimeDelta(10000, 20234320230))
|
|
60
|
+
.to.equal('5620:38:30.230');
|
|
61
|
+
Expect(_DataFormat
|
|
62
|
+
.formatTimeDelta(10000))
|
|
63
|
+
.to.equal('');
|
|
64
|
+
Expect(_DataFormat
|
|
65
|
+
.formatTimeDelta())
|
|
66
|
+
.to.equal('');
|
|
67
|
+
fTestComplete();
|
|
68
|
+
}
|
|
69
|
+
);
|
|
70
|
+
test
|
|
71
|
+
(
|
|
72
|
+
'Get a month string from a date',
|
|
73
|
+
(fTestComplete) =>
|
|
74
|
+
{
|
|
75
|
+
let testFable = new libFable();
|
|
76
|
+
let _DataFormat = testFable.defaultServices.DataFormat;
|
|
77
|
+
Expect(_DataFormat
|
|
78
|
+
.getMonthFromDate(new Date('10/20/1988')))
|
|
79
|
+
.to.equal('October');
|
|
80
|
+
Expect(_DataFormat
|
|
81
|
+
.getMonthFromDate(new Date('3/20/1988')))
|
|
82
|
+
.to.equal('March');
|
|
83
|
+
Expect(_DataFormat
|
|
84
|
+
.getMonthAbbreviatedFromDate(new Date('3/20/1988')))
|
|
85
|
+
.to.equal('Mar');
|
|
86
|
+
// TODO: Unsure if this is how we want to deal with these.
|
|
87
|
+
Expect(_DataFormat
|
|
88
|
+
.getMonthAbbreviatedFromDate(new Date('13/20/1988')))
|
|
89
|
+
.to.equal(undefined);
|
|
90
|
+
return fTestComplete();
|
|
91
|
+
}
|
|
92
|
+
);
|
|
93
|
+
test
|
|
94
|
+
(
|
|
95
|
+
'Get a sortable string from a date',
|
|
96
|
+
(fTestComplete) =>
|
|
97
|
+
{
|
|
98
|
+
let testFable = new libFable();
|
|
99
|
+
let _DataFormat = testFable.defaultServices.DataFormat;
|
|
100
|
+
Expect(_DataFormat
|
|
101
|
+
.formatSortableStringFromDate(new Date('10/20/1986')))
|
|
102
|
+
.to.equal('19860920');
|
|
103
|
+
return fTestComplete();
|
|
104
|
+
}
|
|
105
|
+
)
|
|
106
|
+
}
|
|
107
|
+
);
|
|
108
|
+
}
|
|
109
|
+
);
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Unit tests for
|
|
2
|
+
* Unit tests for DataArithmatic
|
|
3
3
|
*
|
|
4
4
|
* @license MIT
|
|
5
5
|
*
|
|
@@ -29,11 +29,11 @@ suite
|
|
|
29
29
|
(fTestComplete)=>
|
|
30
30
|
{
|
|
31
31
|
let testFable = new libFable({LogStreams: false});
|
|
32
|
-
let
|
|
33
|
-
Expect(
|
|
32
|
+
let _DataFormat = testFable.defaultServices.DataFormat;
|
|
33
|
+
Expect(_DataFormat
|
|
34
34
|
.stringReverse('Dogs'))
|
|
35
35
|
.to.equal('sgoD');
|
|
36
|
-
Expect(
|
|
36
|
+
Expect(_DataFormat
|
|
37
37
|
.stringReverse('Florence and the Machine'))
|
|
38
38
|
.to.equal('enihcaM eht dna ecnerolF');
|
|
39
39
|
return fTestComplete();
|
|
@@ -45,18 +45,18 @@ suite
|
|
|
45
45
|
(fTestComplete)=>
|
|
46
46
|
{
|
|
47
47
|
let testFable = new libFable({LogStreams: false});
|
|
48
|
-
let
|
|
49
|
-
Expect(
|
|
48
|
+
let _DataFormat = testFable.defaultServices.DataFormat;
|
|
49
|
+
Expect(_DataFormat
|
|
50
50
|
.insecureStringHash('Dogs'))
|
|
51
51
|
.to.equal('HSH2135767');
|
|
52
|
-
Expect(
|
|
52
|
+
Expect(_DataFormat
|
|
53
53
|
.insecureStringHash('Dogs1'))
|
|
54
54
|
.to.equal('HSH66208826');
|
|
55
|
-
Expect(
|
|
55
|
+
Expect(_DataFormat
|
|
56
56
|
.insecureStringHash('This string is longer'))
|
|
57
57
|
.to.equal('HSH53260210');
|
|
58
58
|
// This repeat is intentional, to ensure stable hash generation after multiple runs.
|
|
59
|
-
Expect(
|
|
59
|
+
Expect(_DataFormat
|
|
60
60
|
.insecureStringHash('Dogs'))
|
|
61
61
|
.to.equal('HSH2135767');
|
|
62
62
|
return fTestComplete();
|
|
@@ -68,29 +68,29 @@ suite
|
|
|
68
68
|
(fTestComplete)=>
|
|
69
69
|
{
|
|
70
70
|
let testFable = new libFable({LogStreams: false});
|
|
71
|
-
let
|
|
71
|
+
let _DataFormat = testFable.defaultServices.DataFormat;
|
|
72
72
|
// Test the enclosure cleaning function
|
|
73
|
-
Expect(
|
|
73
|
+
Expect(_DataFormat
|
|
74
74
|
.cleanEnclosureWrapCharacters('`', '`Dogs`'))
|
|
75
75
|
.to.equal('Dogs');
|
|
76
76
|
// Tests a cleaning where the enclosure is not wrapped with the expected character
|
|
77
|
-
Expect(
|
|
77
|
+
Expect(_DataFormat
|
|
78
78
|
.cleanEnclosureWrapCharacters('"', '`Cats`'))
|
|
79
79
|
.to.equal('`Cats`');
|
|
80
80
|
// Tests a cleaning where the enclosure is not wrapped with the expected character
|
|
81
|
-
Expect(
|
|
81
|
+
Expect(_DataFormat
|
|
82
82
|
.cleanEnclosureWrapCharacters('"', '"Dogs"'))
|
|
83
83
|
.to.equal('Dogs');
|
|
84
84
|
// Test cleaning an enclosure with multiple enclosures of the same type which are expected to stay intact
|
|
85
|
-
Expect(
|
|
85
|
+
Expect(_DataFormat
|
|
86
86
|
.cleanEnclosureWrapCharacters('[', '[Array[with]weird other] Dogs in it['))
|
|
87
87
|
.to.equal('Array[with]weird other] Dogs in it');
|
|
88
88
|
// Test cleaning a string where the enclosure character is on one side but not the other
|
|
89
|
-
Expect(
|
|
89
|
+
Expect(_DataFormat
|
|
90
90
|
.cleanEnclosureWrapCharacters('"', '"Dogs'))
|
|
91
91
|
.to.equal('"Dogs');
|
|
92
92
|
// Test cleaning a string where the enclosure character is on one side but not the other
|
|
93
|
-
Expect(
|
|
93
|
+
Expect(_DataFormat
|
|
94
94
|
.cleanEnclosureWrapCharacters('"', 'Dogs"'))
|
|
95
95
|
.to.equal('Dogs"');
|
|
96
96
|
return fTestComplete();
|
|
@@ -102,17 +102,17 @@ suite
|
|
|
102
102
|
(fTestComplete)=>
|
|
103
103
|
{
|
|
104
104
|
let testFable = new libFable({LogStreams: false});
|
|
105
|
-
let
|
|
106
|
-
Expect(
|
|
105
|
+
let _DataFormat = testFable.defaultServices.DataFormat;
|
|
106
|
+
Expect(_DataFormat
|
|
107
107
|
.stringStartsWith('Dogs', 'Do'))
|
|
108
108
|
.to.equal(true);
|
|
109
|
-
Expect(
|
|
109
|
+
Expect(_DataFormat
|
|
110
110
|
.stringStartsWith('Bats', 'Bats'))
|
|
111
111
|
.to.equal(true);
|
|
112
|
-
Expect(
|
|
112
|
+
Expect(_DataFormat
|
|
113
113
|
.stringStartsWith('Dogs', 'Dogs are cool'))
|
|
114
114
|
.to.equal(false);
|
|
115
|
-
Expect(
|
|
115
|
+
Expect(_DataFormat
|
|
116
116
|
.stringStartsWith('Dogs', 'Cats'))
|
|
117
117
|
.to.equal(false);
|
|
118
118
|
return fTestComplete();
|
|
@@ -124,18 +124,18 @@ suite
|
|
|
124
124
|
(fTestComplete)=>
|
|
125
125
|
{
|
|
126
126
|
let testFable = new libFable({LogStreams: false});
|
|
127
|
-
let
|
|
128
|
-
|
|
129
|
-
Expect(
|
|
127
|
+
let _DataFormat = testFable.defaultServices.DataFormat;
|
|
128
|
+
_DataFormat._UseEngineStringStartsWith = false;
|
|
129
|
+
Expect(_DataFormat
|
|
130
130
|
.stringStartsWith('Dogs', 'Do'))
|
|
131
131
|
.to.equal(true);
|
|
132
|
-
Expect(
|
|
132
|
+
Expect(_DataFormat
|
|
133
133
|
.stringStartsWith('Bats', 'Bats'))
|
|
134
134
|
.to.equal(true);
|
|
135
|
-
Expect(
|
|
135
|
+
Expect(_DataFormat
|
|
136
136
|
.stringStartsWith('Dogs', 'Dogs are cool'))
|
|
137
137
|
.to.equal(false);
|
|
138
|
-
Expect(
|
|
138
|
+
Expect(_DataFormat
|
|
139
139
|
.stringStartsWith('Dogs', 'Cats'))
|
|
140
140
|
.to.equal(false);
|
|
141
141
|
return fTestComplete();
|
|
@@ -147,17 +147,17 @@ suite
|
|
|
147
147
|
(fTestComplete)=>
|
|
148
148
|
{
|
|
149
149
|
let testFable = new libFable({LogStreams: false});
|
|
150
|
-
let
|
|
151
|
-
Expect(
|
|
150
|
+
let _DataFormat = testFable.defaultServices.DataFormat;
|
|
151
|
+
Expect(_DataFormat
|
|
152
152
|
.stringEndsWith('Dogs', 'gs'))
|
|
153
153
|
.to.equal(true);
|
|
154
|
-
Expect(
|
|
154
|
+
Expect(_DataFormat
|
|
155
155
|
.stringEndsWith('Bats', 'Bats'))
|
|
156
156
|
.to.equal(true);
|
|
157
|
-
Expect(
|
|
157
|
+
Expect(_DataFormat
|
|
158
158
|
.stringEndsWith('Dogs', 'Dogs are cool'))
|
|
159
159
|
.to.equal(false);
|
|
160
|
-
Expect(
|
|
160
|
+
Expect(_DataFormat
|
|
161
161
|
.stringEndsWith('Dogs', 'Cats'))
|
|
162
162
|
.to.equal(false);
|
|
163
163
|
return fTestComplete();
|
|
@@ -169,25 +169,25 @@ suite
|
|
|
169
169
|
(fTestComplete)=>
|
|
170
170
|
{
|
|
171
171
|
let testFable = new libFable({LogStreams: false});
|
|
172
|
-
let
|
|
173
|
-
|
|
174
|
-
Expect(
|
|
172
|
+
let _DataFormat = testFable.defaultServices.DataFormat;
|
|
173
|
+
_DataFormat._UseEngineStringEndsWith = false;
|
|
174
|
+
Expect(_DataFormat
|
|
175
175
|
.stringEndsWith('Dogs', 'gs'))
|
|
176
176
|
.to.equal(true);
|
|
177
|
-
Expect(
|
|
177
|
+
Expect(_DataFormat
|
|
178
178
|
.stringEndsWith('Bats', 'Bats'))
|
|
179
179
|
.to.equal(true);
|
|
180
|
-
Expect(
|
|
180
|
+
Expect(_DataFormat
|
|
181
181
|
.stringEndsWith('Dogs', 'Dogs are cool'))
|
|
182
182
|
.to.equal(false);
|
|
183
183
|
// We should be able to tell it a midpoint to "end" the string at
|
|
184
|
-
Expect(
|
|
184
|
+
Expect(_DataFormat
|
|
185
185
|
.stringEndsWith('Start from a median point', 'median', 19))
|
|
186
186
|
.to.equal(true);
|
|
187
|
-
Expect(
|
|
187
|
+
Expect(_DataFormat
|
|
188
188
|
.stringEndsWith('Start from a median point', 'median', 20))
|
|
189
189
|
.to.equal(false);
|
|
190
|
-
Expect(
|
|
190
|
+
Expect(_DataFormat
|
|
191
191
|
.stringEndsWith('Dogs', 'Cats'))
|
|
192
192
|
.to.equal(false);
|
|
193
193
|
return fTestComplete();
|
|
@@ -199,24 +199,66 @@ suite
|
|
|
199
199
|
(fTestComplete)=>
|
|
200
200
|
{
|
|
201
201
|
let testFable = new libFable({LogStreams: false});
|
|
202
|
-
let
|
|
203
|
-
Expect(
|
|
202
|
+
let _DataFormat = testFable.defaultServices.DataFormat;
|
|
203
|
+
Expect(_DataFormat
|
|
204
204
|
.cleanNonAlphaCharacters('Dogs'))
|
|
205
205
|
.to.equal('Dogs');
|
|
206
|
-
Expect(
|
|
206
|
+
Expect(_DataFormat
|
|
207
207
|
.cleanNonAlphaCharacters('Dogs are cool'))
|
|
208
208
|
.to.equal('Dogs_are_cool');
|
|
209
|
-
Expect(
|
|
209
|
+
Expect(_DataFormat
|
|
210
210
|
.cleanNonAlphaCharacters('Dogs are cool!'))
|
|
211
211
|
.to.equal('Dogs_are_cool_');
|
|
212
212
|
// Test cleaning with no character
|
|
213
|
-
|
|
214
|
-
Expect(
|
|
213
|
+
_DataFormat._Value_Clean_formatterCleanNonAlpha = '';
|
|
214
|
+
Expect(_DataFormat
|
|
215
215
|
.cleanNonAlphaCharacters('Dogs are cool!'))
|
|
216
216
|
.to.equal('Dogsarecool');
|
|
217
217
|
return fTestComplete();
|
|
218
218
|
}
|
|
219
219
|
);
|
|
220
|
+
test
|
|
221
|
+
(
|
|
222
|
+
'Pad the beginning of a string',
|
|
223
|
+
(fTestComplete)=>
|
|
224
|
+
{
|
|
225
|
+
let testFable = new libFable({LogStreams: false});
|
|
226
|
+
let _DataFormat = testFable.defaultServices.DataFormat;
|
|
227
|
+
// The usual use case (e.g. for zero padding dates)
|
|
228
|
+
Expect(_DataFormat.stringPadStart('9', 2, '0'))
|
|
229
|
+
.to.equal('09');
|
|
230
|
+
Expect(_DataFormat.stringPadStart('11', 2, '0'))
|
|
231
|
+
.to.equal('11');
|
|
232
|
+
// Try some longer paddings
|
|
233
|
+
Expect(_DataFormat.stringPadStart('8675309', 20, '0'))
|
|
234
|
+
.to.equal('00000000000008675309');
|
|
235
|
+
// Should not be destructive
|
|
236
|
+
Expect(_DataFormat.stringPadStart('8675309', 1, '0'))
|
|
237
|
+
.to.equal('8675309');
|
|
238
|
+
// Pad with a longer filler string with shifting data
|
|
239
|
+
Expect(_DataFormat.stringPadStart('ning', 20, 'aaaaw'))
|
|
240
|
+
.to.equal('aaaawaaaawaaaawaning');
|
|
241
|
+
// Table of contents?
|
|
242
|
+
Expect(_DataFormat.stringPadStart('Chapter 1', 20, '.'))
|
|
243
|
+
.to.equal('...........Chapter 1');
|
|
244
|
+
|
|
245
|
+
return fTestComplete();
|
|
246
|
+
}
|
|
247
|
+
);
|
|
248
|
+
test
|
|
249
|
+
(
|
|
250
|
+
'Pad the end of a string',
|
|
251
|
+
(fTestComplete)=>
|
|
252
|
+
{
|
|
253
|
+
let testFable = new libFable({LogStreams: false});
|
|
254
|
+
let _DataFormat = testFable.defaultServices.DataFormat;
|
|
255
|
+
// The usual use case (e.g. for left justifying text in fixed-width scenarios)
|
|
256
|
+
Expect(_DataFormat.stringPadEnd('Bob', 10, ' '))
|
|
257
|
+
.to.equal('Bob ');
|
|
258
|
+
|
|
259
|
+
return fTestComplete();
|
|
260
|
+
}
|
|
261
|
+
)
|
|
220
262
|
}
|
|
221
263
|
);
|
|
222
264
|
}
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Unit tests for DataArithmatic
|
|
3
|
+
*
|
|
4
|
+
* @license MIT
|
|
5
|
+
*
|
|
6
|
+
* @author Steven Velozo <steven@velozo.com>
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
var libFable = require('../source/Fable.js');
|
|
10
|
+
|
|
11
|
+
var Chai = require("chai");
|
|
12
|
+
var Expect = Chai.expect;
|
|
13
|
+
|
|
14
|
+
suite
|
|
15
|
+
(
|
|
16
|
+
'DataArithmatic Number',
|
|
17
|
+
function()
|
|
18
|
+
{
|
|
19
|
+
setup (()=> {} );
|
|
20
|
+
|
|
21
|
+
suite
|
|
22
|
+
(
|
|
23
|
+
'Format Number Strings',
|
|
24
|
+
()=>
|
|
25
|
+
{
|
|
26
|
+
test
|
|
27
|
+
(
|
|
28
|
+
'Test adding commas to a number',
|
|
29
|
+
(fTestComplete)=>
|
|
30
|
+
{
|
|
31
|
+
let testFable = new libFable({LogStreams: false});
|
|
32
|
+
let _DataFormat = testFable.defaultServices.DataFormat;
|
|
33
|
+
Expect(_DataFormat
|
|
34
|
+
.formatterAddCommasToNumber(1000))
|
|
35
|
+
.to.equal('1,000');
|
|
36
|
+
Expect(_DataFormat
|
|
37
|
+
.formatterAddCommasToNumber('This is not a number'))
|
|
38
|
+
.to.equal('This is not a number');
|
|
39
|
+
Expect(_DataFormat
|
|
40
|
+
.formatterAddCommasToNumber(102931021))
|
|
41
|
+
.to.equal('102,931,021');
|
|
42
|
+
Expect(_DataFormat
|
|
43
|
+
.formatterAddCommasToNumber(-100000000.7333312))
|
|
44
|
+
.to.equal('-100,000,000.7333312');
|
|
45
|
+
Expect(_DataFormat
|
|
46
|
+
.formatterAddCommasToNumber(`$8675309.75`))
|
|
47
|
+
.to.equal('$8675309.75');
|
|
48
|
+
return fTestComplete();
|
|
49
|
+
}
|
|
50
|
+
);
|
|
51
|
+
test
|
|
52
|
+
(
|
|
53
|
+
'Test formatting dollars',
|
|
54
|
+
(fTestComplete)=>
|
|
55
|
+
{
|
|
56
|
+
let testFable = new libFable({LogStreams: false});
|
|
57
|
+
let _DataFormat = testFable.defaultServices.DataFormat;
|
|
58
|
+
Expect(_DataFormat
|
|
59
|
+
.formatterDollars(1000))
|
|
60
|
+
.to.equal('$1,000.00');
|
|
61
|
+
Expect(_DataFormat
|
|
62
|
+
.formatterDollars('Not dollars!'))
|
|
63
|
+
.to.equal('--');
|
|
64
|
+
Expect(_DataFormat
|
|
65
|
+
.formatterDollars(10000))
|
|
66
|
+
.to.equal('$10,000.00');
|
|
67
|
+
Expect(_DataFormat
|
|
68
|
+
.formatterDollars(-8675309.75))
|
|
69
|
+
.to.equal('$-8,675,309.75');
|
|
70
|
+
Expect(_DataFormat
|
|
71
|
+
.formatterDollars(72.3198))
|
|
72
|
+
.to.equal('$72.32');
|
|
73
|
+
Expect(_DataFormat
|
|
74
|
+
.formatterDollars(72.3119))
|
|
75
|
+
.to.equal('$72.31');
|
|
76
|
+
return fTestComplete();
|
|
77
|
+
}
|
|
78
|
+
);
|
|
79
|
+
test
|
|
80
|
+
(
|
|
81
|
+
'Test rounding numbers',
|
|
82
|
+
(fTestComplete)=>
|
|
83
|
+
{
|
|
84
|
+
let testFable = new libFable({LogStreams: false});
|
|
85
|
+
let _DataFormat = testFable.defaultServices.DataFormat;
|
|
86
|
+
Expect(_DataFormat
|
|
87
|
+
.formatterRoundNumber(1000, 2))
|
|
88
|
+
.to.equal('1000.00');
|
|
89
|
+
Expect(_DataFormat
|
|
90
|
+
.formatterRoundNumber(1000.129, 2))
|
|
91
|
+
.to.equal('1000.13');
|
|
92
|
+
Expect(_DataFormat
|
|
93
|
+
.formatterRoundNumber(1000.781))
|
|
94
|
+
.to.equal('1000.78');
|
|
95
|
+
Expect(_DataFormat
|
|
96
|
+
.formatterRoundNumber(867.5309, 3))
|
|
97
|
+
.to.equal('867.531');
|
|
98
|
+
Expect(_DataFormat
|
|
99
|
+
.formatterRoundNumber(-732.777, 2))
|
|
100
|
+
.to.equal('-732.78');
|
|
101
|
+
Expect(_DataFormat
|
|
102
|
+
.formatterRoundNumber('Not a number'))
|
|
103
|
+
.to.equal('0.00');
|
|
104
|
+
return fTestComplete();
|
|
105
|
+
}
|
|
106
|
+
);
|
|
107
|
+
}
|
|
108
|
+
);
|
|
109
|
+
}
|
|
110
|
+
);
|