functionalscript 0.0.270 → 0.0.275
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 +1 -1
- package/commonjs/package/index.js +2 -2
- package/commonjs/path/index.js +77 -29
- package/commonjs/path/test.js +128 -4
- package/package.json +1 -1
- package/test.js +4 -3
- package/types/list/index.js +5 -0
- package/types/list/test.js +21 -1
package/README.md
CHANGED
|
@@ -161,7 +161,7 @@ Expressions could fall under these categories:
|
|
|
161
161
|
- Relations Operators: `in`, `instanceof`.
|
|
162
162
|
- Member Operators: `.`, `[]`.
|
|
163
163
|
|
|
164
|
-
Note: the `.` member operator has prohibitted property names, such as `constructor` and `push`. To access such properties, it's recommeded to use the
|
|
164
|
+
Note: the `.` member operator has prohibitted property names, such as `constructor` and `push`. To access such properties, it's recommeded to use the [Object.getOwnPropertyDescriptor](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Reflect/getOwnPropertyDescriptor) function.
|
|
165
165
|
|
|
166
166
|
## 4. Arrow Functions
|
|
167
167
|
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
const json = require('../../json')
|
|
2
2
|
const dependencies = require('./dependencies')
|
|
3
3
|
|
|
4
|
-
/**
|
|
4
|
+
/**
|
|
5
5
|
* @typedef {{
|
|
6
6
|
* readonly name: string
|
|
7
7
|
* readonly version: string
|
|
8
8
|
* readonly dependencies?: dependencies.DependenciesJson
|
|
9
|
-
* }} PackageJson
|
|
9
|
+
* }} PackageJson
|
|
10
10
|
*/
|
|
11
11
|
|
|
12
12
|
/** @type {(j: json.Unknown) => j is PackageJson} */
|
package/commonjs/path/index.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
const
|
|
1
|
+
const list = require("../../types/list")
|
|
2
2
|
const option = require("../../types/option")
|
|
3
3
|
const { compose } = require("../../types/function")
|
|
4
|
-
const
|
|
5
|
-
const
|
|
6
|
-
|
|
4
|
+
const { todo } = require("../../dev")
|
|
5
|
+
const package_ = require("../package")
|
|
6
|
+
const module_ = require("../module")
|
|
7
7
|
|
|
8
8
|
/** @typedef {readonly string[]} Items */
|
|
9
9
|
|
|
@@ -18,55 +18,62 @@ const { at } = require("../../types/object")
|
|
|
18
18
|
/** @type {(path: string) => readonly string[]} */
|
|
19
19
|
const split = path => path.split('/')
|
|
20
20
|
|
|
21
|
-
/** @
|
|
21
|
+
/** @typedef {readonly[list.List<string>] | undefined} OptionList */
|
|
22
|
+
|
|
23
|
+
/** @type {(s: OptionList) => (items: string) => OptionList} */
|
|
22
24
|
const normItemsOp = prior => item => {
|
|
23
25
|
if (prior === undefined) { return undefined }
|
|
26
|
+
const priorList = prior[0]
|
|
24
27
|
switch (item) {
|
|
25
28
|
case '': case '.': { return prior }
|
|
26
29
|
case '..': {
|
|
27
|
-
const result =
|
|
30
|
+
const result = list.next(priorList)
|
|
28
31
|
if (result === undefined) { return undefined }
|
|
29
|
-
return result.tail
|
|
32
|
+
return [result.tail]
|
|
30
33
|
}
|
|
31
34
|
default: {
|
|
32
|
-
return
|
|
35
|
+
return [list.nonEmpty(item)(priorList)]
|
|
33
36
|
}
|
|
34
37
|
}
|
|
35
38
|
}
|
|
36
39
|
|
|
37
|
-
/** @type {(items:
|
|
38
|
-
const normItems =
|
|
40
|
+
/** @type {(items: list.List<string>) => OptionList} */
|
|
41
|
+
const normItems = items => {
|
|
42
|
+
const result = list.reduce(normItemsOp)([undefined])(items)
|
|
43
|
+
if (result === undefined) { return result }
|
|
44
|
+
return [list.reverse(result[0])]
|
|
45
|
+
}
|
|
39
46
|
|
|
40
47
|
/** @type {(local: string) => (path: string) => LocalPath|undefined} */
|
|
41
48
|
const parseLocal = local => {
|
|
42
|
-
/** @type {(path: string) => readonly[boolean,
|
|
49
|
+
/** @type {(path: string) => readonly[boolean, boolean, list.List<string>]} */
|
|
43
50
|
const fSeq = path => {
|
|
44
51
|
const pathSeq = split(path)
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
52
|
+
const dir = [undefined, '', '.', '..'].includes(pathSeq[pathSeq.length - 1])
|
|
53
|
+
return /** @type {readonly (string|undefined)[]} */(['.', '..']).includes(list.first(undefined)(pathSeq)) ?
|
|
54
|
+
[false, dir, list.flat([split(local), pathSeq])] :
|
|
55
|
+
[true, dir, pathSeq]
|
|
49
56
|
}
|
|
50
57
|
/** @type {(path: string) => LocalPath|undefined} */
|
|
51
58
|
const f = path => {
|
|
52
|
-
const [external, items] = fSeq(path)
|
|
59
|
+
const [external, dir, items] = fSeq(path)
|
|
53
60
|
const n = normItems(items)
|
|
54
61
|
if (n === undefined) { return undefined }
|
|
55
62
|
return {
|
|
56
63
|
external,
|
|
57
|
-
dir
|
|
58
|
-
items:
|
|
64
|
+
dir,
|
|
65
|
+
items: list.toArray(n[0])
|
|
59
66
|
}
|
|
60
67
|
}
|
|
61
68
|
return f
|
|
62
69
|
}
|
|
63
70
|
|
|
64
|
-
/** @typedef {readonly[string,
|
|
71
|
+
/** @typedef {readonly[string, list.List<string>]} IdPath */
|
|
65
72
|
|
|
66
|
-
/** @type {(prior: readonly[string|undefined,
|
|
73
|
+
/** @type {(prior: readonly[string|undefined, list.List<string>]) => list.Thunk<IdPath>} */
|
|
67
74
|
const variants = prior => () => {
|
|
68
75
|
const [a, b] = prior
|
|
69
|
-
const r =
|
|
76
|
+
const r = list.next(b)
|
|
70
77
|
if (r === undefined) { return undefined }
|
|
71
78
|
const { first, tail } = r
|
|
72
79
|
/** @type {IdPath} */
|
|
@@ -82,35 +89,74 @@ const mapDependency = d => ([external, internal]) => {
|
|
|
82
89
|
|
|
83
90
|
/**
|
|
84
91
|
* @typedef {{
|
|
85
|
-
* readonly
|
|
92
|
+
* readonly packageId: string,
|
|
86
93
|
* readonly items: Items,
|
|
87
94
|
* readonly dir: boolean,
|
|
88
95
|
* }} Path
|
|
89
96
|
*/
|
|
90
97
|
|
|
91
|
-
/**
|
|
98
|
+
/**
|
|
99
|
+
* @type {(d: (local: string) => string|undefined) =>
|
|
100
|
+
* (dir: boolean) =>
|
|
101
|
+
* (items: list.List<string>) =>
|
|
102
|
+
* Path|undefined}
|
|
103
|
+
*/
|
|
92
104
|
const parseGlobal = d => dir => items => {
|
|
93
105
|
const v = variants([undefined, items])
|
|
94
|
-
const r =
|
|
106
|
+
const r = list.first(undefined)(list.filterMap(mapDependency(d))(v))
|
|
95
107
|
if (r === undefined) { return undefined }
|
|
96
|
-
return {
|
|
108
|
+
return { packageId: r[0], items: list.toArray(r[1]), dir }
|
|
97
109
|
}
|
|
98
110
|
|
|
99
111
|
/**
|
|
100
|
-
* @type {(
|
|
112
|
+
* @type {(packageId: string) =>
|
|
101
113
|
* (dependencies: (local: string) => string|undefined) =>
|
|
102
114
|
* (local: string) =>
|
|
103
115
|
* (path: string) =>
|
|
104
116
|
* Path|undefined }
|
|
105
117
|
*/
|
|
106
|
-
const parse =
|
|
118
|
+
const parse = packageId => dependencies => local => path => {
|
|
107
119
|
const parsed = parseLocal(local)(path)
|
|
108
120
|
if (parsed === undefined) { return undefined }
|
|
109
|
-
const {external, dir, items} = parsed
|
|
110
|
-
if (!external) { return {
|
|
121
|
+
const {external, dir, items } = parsed
|
|
122
|
+
if (!external) { return { packageId, items, dir } }
|
|
111
123
|
return parseGlobal(dependencies)(dir)(items)
|
|
112
124
|
}
|
|
113
125
|
|
|
126
|
+
/**
|
|
127
|
+
* @typedef {{
|
|
128
|
+
* readonly package: string
|
|
129
|
+
* readonly file: string
|
|
130
|
+
* readonly source: string
|
|
131
|
+
* }| undefined} Result
|
|
132
|
+
*/
|
|
133
|
+
|
|
134
|
+
/**
|
|
135
|
+
* @type {(packageGet: package_.Get) =>
|
|
136
|
+
* (packageId: string) =>
|
|
137
|
+
* (local: string) =>
|
|
138
|
+
* (path: string) =>
|
|
139
|
+
* Result
|
|
140
|
+
* }
|
|
141
|
+
*/
|
|
142
|
+
const parseAndFind = packageGet => packageId => local => path => {
|
|
143
|
+
const currentPack = packageGet(packageId)
|
|
144
|
+
if (currentPack === undefined) { return undefined }
|
|
145
|
+
const p = parse(packageId)(currentPack.dependency)(local)(path)
|
|
146
|
+
if (p === undefined) { return undefined }
|
|
147
|
+
const pack = packageGet(p.packageId)
|
|
148
|
+
if (pack === undefined) { return undefined }
|
|
149
|
+
/** @type {(file: string) => Result } */
|
|
150
|
+
const tryFile = file => {
|
|
151
|
+
const source = pack.file(file)
|
|
152
|
+
return source === undefined ? undefined : { package: p.packageId, file, source }
|
|
153
|
+
}
|
|
154
|
+
const file = p.items.join('/')
|
|
155
|
+
const indexJs = list.join('/')(list.concat(p.items)(['index.js']))
|
|
156
|
+
const fileList = p.dir || list.isEmpty(p.items) ? [indexJs] : [file, `${file}.js`, indexJs]
|
|
157
|
+
return list.first(undefined)(list.filterMap(tryFile)(fileList))
|
|
158
|
+
}
|
|
159
|
+
|
|
114
160
|
module.exports = {
|
|
115
161
|
/** @readonly */
|
|
116
162
|
parseLocal,
|
|
@@ -118,4 +164,6 @@ module.exports = {
|
|
|
118
164
|
parseGlobal,
|
|
119
165
|
/** @readonly */
|
|
120
166
|
parse,
|
|
167
|
+
/** @readonly */
|
|
168
|
+
parseAndFind,
|
|
121
169
|
}
|
package/commonjs/path/test.js
CHANGED
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
const _ = require('.')
|
|
2
|
+
const { todo } = require('../../dev')
|
|
2
3
|
const json = require('../../json')
|
|
3
4
|
const { identity } = require('../../types/function')
|
|
5
|
+
const object = require('../../types/object')
|
|
4
6
|
const { at } = require('../../types/object')
|
|
7
|
+
const package_ = require('../package')
|
|
5
8
|
|
|
6
9
|
/** @type {(g: json.Unknown|undefined) => string} */
|
|
7
10
|
const stringify = g => {
|
|
@@ -27,7 +30,7 @@ const stringify = g => {
|
|
|
27
30
|
|
|
28
31
|
{
|
|
29
32
|
const result = _.parseLocal('a')('')
|
|
30
|
-
if (stringify(result) !== '{"external":true,"dir":
|
|
33
|
+
if (stringify(result) !== '{"external":true,"dir":true,"items":[]}') { throw result }
|
|
31
34
|
}
|
|
32
35
|
|
|
33
36
|
{
|
|
@@ -45,21 +48,142 @@ const stringify = g => {
|
|
|
45
48
|
if (stringify(result) !== '{"external":true,"dir":false,"items":["a","c"]}') { throw result }
|
|
46
49
|
}
|
|
47
50
|
|
|
51
|
+
{
|
|
52
|
+
const result = _.parseLocal('')('./x/..')
|
|
53
|
+
if (stringify(result) !== '{"external":false,"dir":true,"items":[]}') { throw result }
|
|
54
|
+
}
|
|
55
|
+
|
|
48
56
|
{
|
|
49
57
|
if (_.parseGlobal(() => undefined)(false)(['a', 'b']) !== undefined) { throw 'error' }
|
|
50
58
|
if (_.parseGlobal(() => undefined)(false)(['b']) !== undefined) { throw 'error' }
|
|
51
59
|
if (_.parseGlobal(d => at(d)({ b: 'x' }))(false)(['d']) !== undefined) { throw 'error' }
|
|
52
60
|
{
|
|
53
61
|
const result = stringify(_.parseGlobal(d => at(d)({ b: 'x' }))(false)(['b']))
|
|
54
|
-
if (result !== '
|
|
62
|
+
if (result !== '{"packageId":"x","items":[],"dir":false}') { throw result }
|
|
55
63
|
}
|
|
56
64
|
if (_.parseGlobal(d => at(d)({ 'b/r': 'x' }))(false)(['b']) !== undefined) { throw 'error' }
|
|
57
65
|
{
|
|
58
66
|
const result = stringify(_.parseGlobal(d => at(d)({ 'b/r': 'x' }))(false)(['b', 'r']))
|
|
59
|
-
if (result !== '
|
|
67
|
+
if (result !== '{"packageId":"x","items":[],"dir":false}') { throw result }
|
|
60
68
|
}
|
|
61
69
|
{
|
|
62
70
|
const result = stringify(_.parseGlobal(d => at(d)({ 'b/r': 'x' }))(false)(['b', 'r', 'd', 't']))
|
|
63
|
-
if (result !== '
|
|
71
|
+
if (result !== '{"packageId":"x","items":["d","t"],"dir":false}') { throw result }
|
|
72
|
+
}
|
|
73
|
+
{
|
|
74
|
+
const result = stringify(_.parseGlobal(d => at(d)({ 'b/r': 'x' }))(true)(['b', 'r', 'd', 't']))
|
|
75
|
+
if (result !== '{"packageId":"x","items":["d","t"],"dir":true}') { throw result }
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
{
|
|
80
|
+
/** @type {object.Map<package_.Package>} */
|
|
81
|
+
const packages = {
|
|
82
|
+
'': {
|
|
83
|
+
dependency: () => todo(),
|
|
84
|
+
file: path => at(path)({ 'a/c': 'return "a/c"' }),
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
const result = stringify(_.parseAndFind(p => at(p)(packages))('')('a/b')('../c'))
|
|
88
|
+
if (result !== '{"package":"","file":"a/c","source":"return \\"a/c\\""}') { throw result }
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
{
|
|
92
|
+
/** @type {object.Map<package_.Package>} */
|
|
93
|
+
const packages = {
|
|
94
|
+
'': {
|
|
95
|
+
dependency: x => {
|
|
96
|
+
const path = `node_modules/${x}`
|
|
97
|
+
return at(path)(packages) !== undefined ? path : undefined
|
|
98
|
+
},
|
|
99
|
+
file: path => at(path)({
|
|
100
|
+
'index.js': 'return "index.js"',
|
|
101
|
+
'x/index.js': 'return "x/index.js"',
|
|
102
|
+
'x.js': 'return "x.js"',
|
|
103
|
+
})
|
|
104
|
+
},
|
|
105
|
+
'node_modules/z': {
|
|
106
|
+
dependency: () => todo(),
|
|
107
|
+
file: path => at(path)({ 'a/c/index.js': 'return "a/c"' }),
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
{
|
|
111
|
+
const result = stringify(_.parseAndFind(p => at(p)(packages))('')('a/b')('z/a/c'))
|
|
112
|
+
if (result !== '{"package":"node_modules/z","file":"a/c/index.js","source":"return \\"a/c\\""}') { throw result }
|
|
113
|
+
}
|
|
114
|
+
{
|
|
115
|
+
const result = stringify(_.parseAndFind(p => at(p)(packages))('')('a/b')('../..'))
|
|
116
|
+
if (result !== '{"package":"","file":"index.js","source":"return \\"index.js\\""}') { throw result }
|
|
117
|
+
}
|
|
118
|
+
{
|
|
119
|
+
const result = stringify(_.parseAndFind(p => at(p)(packages))('')('')('./x'))
|
|
120
|
+
if (result !== '{"package":"","file":"x.js","source":"return \\"x.js\\""}') { throw result }
|
|
121
|
+
}
|
|
122
|
+
{
|
|
123
|
+
const result = stringify(_.parseAndFind(p => at(p)(packages))('')('')('./x.js'))
|
|
124
|
+
if (result !== '{"package":"","file":"x.js","source":"return \\"x.js\\""}') { throw result }
|
|
125
|
+
}
|
|
126
|
+
{
|
|
127
|
+
const result = stringify(_.parseAndFind(p => at(p)(packages))('')('')('./x/'))
|
|
128
|
+
if (result !== '{"package":"","file":"x/index.js","source":"return \\"x/index.js\\""}') { throw result }
|
|
129
|
+
}
|
|
130
|
+
{
|
|
131
|
+
const result = stringify(_.parseAndFind(p => at(p)(packages))('')('x/a')('../'))
|
|
132
|
+
if (result !== '{"package":"","file":"x/index.js","source":"return \\"x/index.js\\""}') { throw result }
|
|
133
|
+
}
|
|
134
|
+
{
|
|
135
|
+
const result = stringify(_.parseAndFind(p => at(p)(packages))('')('x/a')('..'))
|
|
136
|
+
if (result !== '{"package":"","file":"x/index.js","source":"return \\"x/index.js\\""}') { throw result }
|
|
64
137
|
}
|
|
65
138
|
}
|
|
139
|
+
|
|
140
|
+
{
|
|
141
|
+
/** @type {object.Map<package_.Package>} */
|
|
142
|
+
const packages = {
|
|
143
|
+
'': {
|
|
144
|
+
dependency: x => {
|
|
145
|
+
const path = `node_modules/${x}`
|
|
146
|
+
return at(path)(packages) !== undefined ? path : undefined
|
|
147
|
+
},
|
|
148
|
+
file: todo
|
|
149
|
+
},
|
|
150
|
+
'node_modules/z/a': {
|
|
151
|
+
dependency: () => todo(),
|
|
152
|
+
file: path => at(path)({
|
|
153
|
+
'c/index.js': 'return "c/index.js"',
|
|
154
|
+
'c.js': 'return "c.js"'
|
|
155
|
+
}),
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
{
|
|
159
|
+
const result = stringify(_.parseAndFind(p => at(p)(packages))('')('a/b')('z/a/c'))
|
|
160
|
+
if (result !== '{"package":"node_modules/z/a","file":"c.js","source":"return \\"c.js\\""}') { throw result }
|
|
161
|
+
}
|
|
162
|
+
{
|
|
163
|
+
const result = stringify(_.parseAndFind(p => at(p)(packages))('')('a/b')('z/a/c/'))
|
|
164
|
+
if (result !== '{"package":"node_modules/z/a","file":"c/index.js","source":"return \\"c/index.js\\""}') { throw result }
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
{
|
|
169
|
+
/** @type {object.Map<package_.Package>} */
|
|
170
|
+
const packages = {
|
|
171
|
+
'': {
|
|
172
|
+
dependency: x => {
|
|
173
|
+
const path = `node_modules/${x}`
|
|
174
|
+
return at(path)(packages) !== undefined ? path : undefined
|
|
175
|
+
},
|
|
176
|
+
file: todo
|
|
177
|
+
},
|
|
178
|
+
'node_modules/z/a/c': {
|
|
179
|
+
dependency: () => todo(),
|
|
180
|
+
file: path => at(path)({
|
|
181
|
+
'': 'throw',
|
|
182
|
+
'.js': 'throw',
|
|
183
|
+
'index.js': 'return "a/c"'
|
|
184
|
+
}),
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
const result = stringify(_.parseAndFind(p => at(p)(packages))('')('a/b')('z/a/c'))
|
|
188
|
+
if (result !== '{"package":"node_modules/z/a/c","file":"index.js","source":"return \\"a/c\\""}') { throw result }
|
|
189
|
+
}
|
package/package.json
CHANGED
package/test.js
CHANGED
|
@@ -7,6 +7,7 @@ require('./types/object/test')
|
|
|
7
7
|
require('./io/commonjs/test')
|
|
8
8
|
require('./commonjs/package/dependencies/test')
|
|
9
9
|
require('./commonjs/package/test')
|
|
10
|
+
require('./commonjs/path/test')
|
|
10
11
|
|
|
11
12
|
/** @type {() => never} */
|
|
12
13
|
const assert = () => { throw 'assert' }
|
|
@@ -100,12 +101,12 @@ const assert_if = c => { if (c) { throw 'assert_if' } }
|
|
|
100
101
|
//const c = o['__defineGetter__']
|
|
101
102
|
//const c = o['__defineSetter__']
|
|
102
103
|
//const c = o['__lookupGetter__']
|
|
103
|
-
//const c = o['__lookupSetter__']
|
|
104
|
-
//const c = o['hasOwnProperty']
|
|
104
|
+
//const c = o['__lookupSetter__']
|
|
105
|
+
//const c = o['hasOwnProperty']
|
|
105
106
|
//const c = o['isPrototypeOf']
|
|
106
107
|
//const c = o['propertyIsEnumerable']
|
|
107
108
|
//const c = o['toString']
|
|
108
|
-
const c = o['valueOf']
|
|
109
|
+
const c = o['valueOf']
|
|
109
110
|
//console.log(c)
|
|
110
111
|
}
|
|
111
112
|
|
package/types/list/index.js
CHANGED
|
@@ -199,6 +199,9 @@ const some = input => find
|
|
|
199
199
|
(/** @type {(_: boolean) => boolean} */(identity))
|
|
200
200
|
(input)
|
|
201
201
|
|
|
202
|
+
/** @type {<T>(input: List<T>) => boolean} */
|
|
203
|
+
const isEmpty = input => !some(map(() => true)(input))
|
|
204
|
+
|
|
202
205
|
/** @type {(input: List<boolean>) => boolean} */
|
|
203
206
|
const every = input => !some(map(logicalNot)(input))
|
|
204
207
|
|
|
@@ -336,6 +339,8 @@ module.exports = {
|
|
|
336
339
|
/** @readonly */
|
|
337
340
|
every,
|
|
338
341
|
/** @readonly */
|
|
342
|
+
isEmpty,
|
|
343
|
+
/** @readonly */
|
|
339
344
|
includes,
|
|
340
345
|
/** @readonly */
|
|
341
346
|
countdown,
|
package/types/list/test.js
CHANGED
|
@@ -58,6 +58,11 @@ const stringify = sequence => json.stringify(sort)(_.toArray(sequence))
|
|
|
58
58
|
if (result !== '[]') { throw result }
|
|
59
59
|
}
|
|
60
60
|
|
|
61
|
+
{
|
|
62
|
+
const result = _.find(undefined)(x => x % 2 === 0)([1, 3, 5, 7])
|
|
63
|
+
if (result !== undefined) { throw result }
|
|
64
|
+
}
|
|
65
|
+
|
|
61
66
|
{
|
|
62
67
|
const result = _.find(undefined)(x => x % 2 === 0)([1, 2, 3, 4])
|
|
63
68
|
if (result !== 2) { throw result }
|
|
@@ -119,6 +124,11 @@ const stringify = sequence => json.stringify(sort)(_.toArray(sequence))
|
|
|
119
124
|
if (result !== '') { throw result }
|
|
120
125
|
}
|
|
121
126
|
|
|
127
|
+
{
|
|
128
|
+
const result = _.join(' ')(['hello', 'world', '!'])
|
|
129
|
+
if (result !== 'hello world !') { throw result }
|
|
130
|
+
}
|
|
131
|
+
|
|
122
132
|
{
|
|
123
133
|
const result = stringify(_.entries([]))
|
|
124
134
|
if (result !== '[]') { throw result }
|
|
@@ -214,6 +224,16 @@ const stringify = sequence => json.stringify(sort)(_.toArray(sequence))
|
|
|
214
224
|
if (result !== 12) { throw result }
|
|
215
225
|
}
|
|
216
226
|
|
|
227
|
+
{
|
|
228
|
+
const result = _.isEmpty(() => [])
|
|
229
|
+
if (result !== true) { throw result }
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
{
|
|
233
|
+
const result = _.isEmpty(() => [2])
|
|
234
|
+
if (result !== false) { throw result }
|
|
235
|
+
}
|
|
236
|
+
|
|
217
237
|
// stress tests
|
|
218
238
|
|
|
219
239
|
const stress = () => {
|
|
@@ -319,7 +339,7 @@ const stress = () => {
|
|
|
319
339
|
}
|
|
320
340
|
}
|
|
321
341
|
|
|
322
|
-
stress()
|
|
342
|
+
// stress()
|
|
323
343
|
|
|
324
344
|
module.exports = {
|
|
325
345
|
|