@naanlang/naan 1.0.0

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.
Files changed (98) hide show
  1. package/LICENSE.md +21 -0
  2. package/README.md +46 -0
  3. package/dist/env_web.js +431 -0
  4. package/dist/naan.min.js +73 -0
  5. package/frameworks/browser/browser.nlg +30 -0
  6. package/frameworks/browser/pouchdb/pouchdb.min.js +7 -0
  7. package/frameworks/browser/spark-md5/spark-md5.min.js +1 -0
  8. package/frameworks/browser/sworker.js +192 -0
  9. package/frameworks/browser/terminals.nlg +787 -0
  10. package/frameworks/browser/workers.nlg +386 -0
  11. package/frameworks/client/apiclient.nlg +183 -0
  12. package/frameworks/client/client.nlg +29 -0
  13. package/frameworks/client/psm_client.nlg +572 -0
  14. package/frameworks/common/common.nlg +464 -0
  15. package/frameworks/common/preferences.nlg +131 -0
  16. package/frameworks/common/repltools.nlg +100 -0
  17. package/frameworks/common/watching.nlg +97 -0
  18. package/frameworks/node/apiserver.nlg +399 -0
  19. package/frameworks/node/filesystem.nlg +1012 -0
  20. package/frameworks/node/gitter.nlg +234 -0
  21. package/frameworks/node/node.nlg +81 -0
  22. package/frameworks/node/psm_server.nlg +465 -0
  23. package/frameworks/node/worker.nlg +560 -0
  24. package/frameworks/project/build.nlg +1229 -0
  25. package/frameworks/project/jszip.js +30 -0
  26. package/frameworks/project/jszip.nlg +87 -0
  27. package/frameworks/project/proj_cliser.nlg +139 -0
  28. package/frameworks/project/proj_console.nlg +137 -0
  29. package/frameworks/project/proj_folder.nlg +143 -0
  30. package/frameworks/project/proj_lambda.nlg +137 -0
  31. package/frameworks/project/proj_static.nlg +138 -0
  32. package/frameworks/project/project.nlg +29 -0
  33. package/frameworks/project/projects.nlg +587 -0
  34. package/frameworks/project/uglifyjs.js +1 -0
  35. package/frameworks/project/uglifyjs.nlg +79 -0
  36. package/frameworks/running/debugcom.nlg +163 -0
  37. package/frameworks/running/debugnub.nlg +565 -0
  38. package/frameworks/running/debugutil.nlg +510 -0
  39. package/frameworks/running/executors.nlg +767 -0
  40. package/frameworks/running/running.nlg +151 -0
  41. package/frameworks/running/sourcecode.nlg +346 -0
  42. package/frameworks/running/taskexec.nlg +196 -0
  43. package/frameworks/storage/dbt_pouch.nlg +773 -0
  44. package/frameworks/storage/file_manager.nlg +772 -0
  45. package/frameworks/storage/psm.nlg +326 -0
  46. package/frameworks/storage/psm_dbtables.nlg +814 -0
  47. package/frameworks/storage/resources.nlg +445 -0
  48. package/frameworks/storage/storage.nlg +52 -0
  49. package/lib/browser/env_web.js +431 -0
  50. package/lib/browser/env_webworker.js +146 -0
  51. package/lib/browser/require.js +1653 -0
  52. package/lib/core/naanlib.js +73 -0
  53. package/lib/env_node.js +282 -0
  54. package/lib/env_nodeworker.js +165 -0
  55. package/lib/node_repl.js +25 -0
  56. package/lib/node_repl_init.nlg +52 -0
  57. package/package.json +13 -0
  58. package/plugins/gitClient/clientops.nlg +317 -0
  59. package/plugins/gitClient/gitClient.nlg +63 -0
  60. package/plugins/gitClient/gitutils.nlg +1331 -0
  61. package/plugins/gitClient/minimatch.js +945 -0
  62. package/plugins/gitClient/minimatch_license.txt +15 -0
  63. package/plugins/gitClient/minimatch_readme.md +208 -0
  64. package/plugins/nodeLib/nodeLib.nlg +26 -0
  65. package/plugins/nodeLib/node_cp.nlg +65 -0
  66. package/plugins/nodeLib/node_fs.nlg +137 -0
  67. package/plugins/nodeLib/node_https.nlg +172 -0
  68. package/plugins/nodeLib/node_util.nlg +180 -0
  69. package/plugins/serviceAws/aws/aws-sdk.min.js +88 -0
  70. package/plugins/serviceAws/aws/lambda_rest_index.js +122 -0
  71. package/plugins/serviceAws/aws/lambda_rest_init.nlg +58 -0
  72. package/plugins/serviceAws/aws/lambda_ws_index.js +498 -0
  73. package/plugins/serviceAws/aws/lambda_ws_init.nlg +49 -0
  74. package/plugins/serviceAws/aws_cloudwatchlogs.nlg +122 -0
  75. package/plugins/serviceAws/aws_cognito.nlg +76 -0
  76. package/plugins/serviceAws/aws_dynamo.nlg +509 -0
  77. package/plugins/serviceAws/aws_lambda.nlg +95 -0
  78. package/plugins/serviceAws/aws_s3.nlg +134 -0
  79. package/plugins/serviceAws/aws_utils.nlg +86 -0
  80. package/plugins/serviceAws/dbt_aws.nlg +769 -0
  81. package/plugins/serviceAws/lambda_naan_control.nlg +175 -0
  82. package/plugins/serviceAws/psm_aws.nlg +258 -0
  83. package/plugins/serviceAws/serviceAws.nlg +38 -0
  84. package/plugins/serviceGitHub/gitops.nlg +522 -0
  85. package/plugins/serviceGitHub/psm_github.nlg +205 -0
  86. package/plugins/serviceGitHub/serviceGitHub.nlg +65 -0
  87. package/plugins/serviceGitLab/gitops.nlg +528 -0
  88. package/plugins/serviceGitLab/psm_gitlab.nlg +205 -0
  89. package/plugins/serviceGitLab/serviceGitLab.nlg +65 -0
  90. package/test/harness.nlg +312 -0
  91. package/test/node_test.js +33 -0
  92. package/test/test_01_core.nlg +768 -0
  93. package/test/test_02_context.nlg +269 -0
  94. package/test/test_03_jsinterop.nlg +137 -0
  95. package/test/test_04_numerics.nlg +450 -0
  96. package/test/test_05_strings.nlg +63 -0
  97. package/test/test_06_lingoparse.nlg +500 -0
  98. package/test/test_07_lingo.nlg +623 -0
@@ -0,0 +1,205 @@
1
+ /*
2
+ * psm_gitlab.nlg
3
+ * serviceGitLab
4
+ *
5
+ * PSM connector for GitLab for browser and NodeJS.
6
+ *
7
+ * column positioning: // // !
8
+ *
9
+ * Copyright (c) 2021 by Richard C. Zulch
10
+ *
11
+ */
12
+
13
+
14
+ /*
15
+ * plabConnector
16
+ *
17
+ * Make a PSM connector for GitLab access.
18
+ *
19
+ */
20
+
21
+ closure plabConnector(psm, local connClassID, connector, watch) {
22
+ connClassID = "GLAB"
23
+ require("plugins/serviceGitLab/gitops.nlg")
24
+ connector = new(object, this)
25
+ connector.psm = psm
26
+ connector.vault = psm.vault(connClassID)
27
+ connector.label = "GitLab"
28
+ watch = psm.watchable(connector)
29
+
30
+ // uifields
31
+ //
32
+ // Report the UI fields we need to add a resource
33
+ connector.uifields = function uifields() {
34
+ [{
35
+ label: "Username"
36
+ placeholder: "GitLab username or email"
37
+ key: "userName" },
38
+ {
39
+ label: "Password"
40
+ placeholder: "Personal Access Token"
41
+ key: "userPat"
42
+ type: "password" }
43
+ ]
44
+ }
45
+
46
+ // hashResourceID
47
+ //
48
+ // Make a stable hash based on the resource credentials that we can persist or share between
49
+ // different domains accessing the same resource.
50
+ connector.hashResourceID = function hashResourceID(resource, local ident) {
51
+ ident = resource.userName
52
+ if resource.label
53
+ ident = ident.concat(resource.label)
54
+ HashSHA256(ident)
55
+ }
56
+
57
+ // findResource
58
+ //
59
+ // Find a resource with the specified contents, returning the resID or false. The loose criteria
60
+ // is: if added, would the specified contents be redundant to an existing resource?
61
+ connector.findResource = function findResource(resource, local resID, creds) {
62
+ for resID in listResources().1 {
63
+ creds = access(resID).1
64
+ if resource.userName == creds.userName
65
+ return (resID)
66
+ }
67
+ false
68
+ }
69
+
70
+ // addResource
71
+ //
72
+ // Add credentials for a named resource. The label is a string. The resource is a dictionary
73
+ // comprising these keys:
74
+ // label - [optional] label we use for this resource
75
+ // userName - GitLab user name
76
+ // userPat - GitLab Personal Access Token
77
+ // hidden - [optional] don't enumerate to user
78
+ // locked - [optional] don't allow user delete
79
+ // The return value is (error, result) tuple. Error, if non-false, is a dictionary of field
80
+ // keys and error diagnostic strings. The special key "label" refers to the label string.
81
+ connector.addResource = function addResource(resource, local label, errors, creds, error, resID, data) {
82
+ function badField(str) { !string(str) || str.trim().length == 0 }
83
+ creds = {
84
+ userName: resource.userName,
85
+ userPat: resource.userPat
86
+ }
87
+ errors = { }
88
+ if resource.label
89
+ creds.label = resource.label
90
+ else
91
+ creds.label = resource.region.concat("-", resource.bucketName)
92
+ if badField(creds.label)
93
+ errors.label = "invalid label"
94
+ if badField(resource.userName)
95
+ errors.userName = "required field"
96
+ if badField(resource.userPat)
97
+ errors.userPat = "required field"
98
+ if length(errors) > 0
99
+ error = errors
100
+ else {
101
+ if resource.hidden
102
+ creds.hidden = resource.hidden
103
+ if resource.locked
104
+ creds.locked = resource.locked
105
+ resID = hashResourceID(resource)
106
+ `(error, data) = connector.vault.addResource(resID, creds)
107
+ if data {
108
+ watch.notify(connClassID, { added: [resID] })
109
+ data = resID }
110
+ }
111
+ list(error, data)
112
+ }
113
+
114
+ // deleteResource
115
+ //
116
+ // Delete credentials for a resource
117
+ connector.deleteResource = function deleteResource(resID) {
118
+ connector.vault.deleteResource(resID)
119
+ watch.notify(connClassID, { deleted: [resID] })
120
+ list(false, { ok: true})
121
+ }
122
+
123
+ // listResources
124
+ //
125
+ // List saved resources in our database
126
+ connector.listResources = function listResources() {
127
+ connector.vault.listResources()
128
+ }
129
+
130
+ // info
131
+ //
132
+ // Return info for a resource.
133
+ connector.info = function info(resID, local error, creds, info) {
134
+ info = {
135
+ classID: "GitLab"
136
+ type: "GitLab"
137
+ services: ["GitAPI"]
138
+ }
139
+ `(error, creds) = connector.vault.accessResource(resID)
140
+ if creds {
141
+ if creds.label
142
+ info.name = creds.label
143
+ if creds.locked
144
+ info.locked = true
145
+ if creds.hidden
146
+ info.hidden = true
147
+ info.where = creds.userName
148
+ }
149
+ list(false, info)
150
+ }
151
+
152
+ // access
153
+ //
154
+ // Return an access object.
155
+
156
+ connector.access = function access(resID, local error, creds, glab) {
157
+ `(error, creds) = connector.vault.accessResource(resID)
158
+ if error
159
+ return (list(error)) // can't access that resource
160
+ glab = {
161
+ userName: creds.userName,
162
+ userPat: creds.userPat }
163
+ list(false, glab)
164
+ }
165
+
166
+ // connect
167
+ //
168
+ // Connect to an GitLab filesystem.
169
+
170
+ connector.connect = function connect(resID, service, args, local error, glab, gitremote, table) {
171
+ `(error, glab) = connector.access(resID)
172
+ if !error
173
+ `(error, gitremote) = GitLabOps(glab) // get GitLab as a git remote
174
+ if error
175
+ list(error)
176
+ else if service == "GitAPI"
177
+ list(false, gitremote)
178
+ else
179
+ list(Error("unsupported service", service))
180
+ }
181
+
182
+ // finis
183
+
184
+ psm.register(connClassID, connector)
185
+ connector
186
+ };
187
+
188
+
189
+ /*
190
+ * plabInit
191
+ *
192
+ * Initialize the GitLab module.
193
+ *
194
+ */
195
+
196
+ function plabInit(local manifest) {
197
+
198
+ manifest = `(plabConnector, plabInit)
199
+
200
+ Naan.module.build(module.id, "psm_gitlab", function(modobj, compobj) {
201
+ compobj.manifest = manifest
202
+ modobj.exports.GitLabConnector = plabConnector
203
+ require("./serviceGitLab.nlg")
204
+ })
205
+ } ();
@@ -0,0 +1,65 @@
1
+ /*
2
+ * serviceGitLab.nlg
3
+ * serviceGitLab
4
+ *
5
+ * GitLab access for browser and NodeJS.
6
+ *
7
+ * column positioning: // // !
8
+ *
9
+ * Copyright (c) 2021 by Richard C. Zulch
10
+ *
11
+ */
12
+
13
+
14
+ /*
15
+ * glabReload
16
+ *
17
+ */
18
+
19
+ function glabReload() {
20
+ jspath = js.r("path")
21
+ if js.w {
22
+ hashMD5 = function browserMD5(text) {
23
+ js.w.SparkMD5.hash(text) }
24
+ hashMD5_base64 = function browserMD5_base64(text) {
25
+ js.w.btoa(js.w.SparkMD5.hash(text, true)) }
26
+ textEncoder = js.w.TextEncoder
27
+ textDecoder = js.w.TextDecoder
28
+ atob = js.w.atob
29
+ btoa = js.w.btoa
30
+ encodeURIComponent = js.w.encodeURIComponent
31
+ JSON = js.w.JSON }
32
+ else if js.g {
33
+ if !crypto
34
+ crypto = js.r("crypto")
35
+ hashMD5 = function nodejsMD5(text) {
36
+ crypto.createHash("MD5").update(text).digest("hex") }
37
+ hashMD5_base64 = function nodejsMD5_base64(text) {
38
+ crypto.createHash("MD5").update(text).digest("base64") }
39
+ textEncoder = js.g.TextEncoder
40
+ textDecoder = js.g.TextDecoder
41
+ atob = js.g.atob
42
+ btoa = js.g.btoa
43
+ encodeURIComponent = js.g.encodeURIComponent
44
+ JSON = js.g.JSON }
45
+ LoadNotify(glabReload)
46
+ }();
47
+
48
+
49
+ /*
50
+ * glabInit
51
+ *
52
+ * Initialize the GitLab module.
53
+ *
54
+ */
55
+
56
+ function glabInit(local manifest) {
57
+
58
+ manifest = `(glabReload, glabInit)
59
+
60
+ Naan.module.build(module.id, "serviceGitLab", function(modobj, compobj) {
61
+ compobj.manifest = manifest
62
+ })
63
+ require("frameworks/common", { in: naanlib }).LiveImport()
64
+ require("./psm_gitlab.nlg").GitLabConnector(App.psm)
65
+ } ();
@@ -0,0 +1,312 @@
1
+ /*
2
+ * harness.nlg
3
+ * Test
4
+ *
5
+ * Perform basic unit tests for Naan.
6
+ *
7
+ * column positioning: // // !
8
+ *
9
+ * Copyright (c) 2020-2021 by Richard C. Zulch
10
+ *
11
+ */
12
+
13
+
14
+
15
+ /*
16
+ * initPreload
17
+ *
18
+ */
19
+
20
+ loglevel(2);;
21
+ Naan.module.chns("Play");;
22
+
23
+
24
+ /*
25
+ * Parsenv
26
+ *
27
+ * Create a parsing environment.
28
+ *
29
+ */
30
+
31
+ closure Parsenv(name, local penv, gohome, saveOperators, lingo, libns, naansym) {
32
+ penv = new(object, this)
33
+ gohome = makeActivator()
34
+ sleep(1)
35
+ lingo = Dialect
36
+ penv.lib = Naan.module.modlist().Lib.exports
37
+ penv.parser = lingo.parser
38
+ penv.unparser = lingo.unparser
39
+ lingo.defsym(`("#e", "#i", "#pi"))
40
+ penv.ns = new(namespace, name)
41
+ if !penv.ns {
42
+ debuglog("parnParsenv: can't create namespace")
43
+ return (false)
44
+ }
45
+ if penv.naansym {
46
+ naansym = letlocal(Naan).0
47
+ assign(naansym, car(penv.naansym))
48
+ }
49
+ nsactive(cons(penv.ns, lingo.info().namespace, nsactive().-2))
50
+ penv.gons = makeActivator()
51
+ gohome()
52
+
53
+
54
+ // parse
55
+ //
56
+ // Parse the specified text into our environment, returning the following dictionary:
57
+ // {
58
+ // errors: <array of errors, if any>
59
+ // text: <array of output text, if any>
60
+ // exprs: <array of expressions that we have parsed>
61
+ // results: <array of evaluation results for the expressions>
62
+ // pretty: <array of pretty-printed results>
63
+ // }
64
+
65
+ penv.parse = function parse(text, local output, curns, source, xchan, errors, error, expr, savex, outext) {
66
+ output = {
67
+ errors: []
68
+ text: []
69
+ exprs: []
70
+ results: []
71
+ pretty: []
72
+ }
73
+ curns = nsactive()
74
+ source = new(textstream, text, `string)
75
+ xchan = textstreams(list(source, source))
76
+ try {
77
+ penv.gons()
78
+ loop {
79
+ try {
80
+ savex = `exception.proc
81
+ sudo(putproc(`exception, false)) // don't enter debugger during test
82
+ `(errors, expr) = lingo.parse(source)
83
+ for error in errors
84
+ output.errors.push(penv.lib.ParseErrorString(error))
85
+ if expr {
86
+ output.exprs.push(expr)
87
+ expr = function() { evalactive(expr) }() // return here if return executed outside procedure
88
+ output.results.push(expr)
89
+ if source.tokenlast().atom == `;>
90
+ output.pretty.push(tostring(expr, { quote: true }))
91
+ else if source.tokenlast().atom != `;;
92
+ output.pretty.push(lingo.print(expr))
93
+ }
94
+ } finally {
95
+ sudo(putproc(`exception, savex)) }
96
+ }
97
+ } catch {
98
+ if true {
99
+ if tostring(car(exception)) == "internal" and tostring(second(exception)) == "end-of-file"
100
+ { }
101
+ else if tostring(car(exception)) == "internal" and string(second(exception))
102
+ output.errors.push(second(exception))
103
+ else
104
+ output.errors.push("exception: ".concat(exception))
105
+ }
106
+ } finally {
107
+ gohome()
108
+ textstreams(xchan)
109
+ outext = source.taketext().trim()
110
+ if outext.length > 0
111
+ output.text = new(outext.split("\n"))
112
+ }
113
+ output
114
+ }
115
+
116
+ // unparse
117
+ //
118
+ // Unparse our environment into text.
119
+
120
+ penv.unparse = function unparse(local options, text, sym, didprop, key) {
121
+ options = {
122
+ wrapMaxCol: 240
123
+ }
124
+ text = ""
125
+ for sym in symlist(penv.ns) {
126
+ if !(sym eq car(sym))
127
+ text = text.concat(sym, " = ", car(sym), ";;\n\n")
128
+ didprop = false
129
+ for key in sym@*
130
+ if key.charAt(0) != "." {
131
+ didprop = true
132
+ text = text.concat(sym, "@", key, " = ", sym@[key], ";;\n") }
133
+ if didprop
134
+ text = text.concat("\n")
135
+ if sym.proc.1.namespace eq penv.ns
136
+ text = text.concat(lingo.print(sym.proc, options), ";\n\n")
137
+ }
138
+ text
139
+ }
140
+
141
+ // destroy
142
+ //
143
+ // Destroy our environment to reclaim the namespace.
144
+
145
+ penv.destroy = function destroy() {
146
+ penv.ns = delete(penv.ns)
147
+ }
148
+
149
+ // finis
150
+
151
+ penv
152
+ };;
153
+
154
+
155
+ /*
156
+ * RegisterTestCategory
157
+ *
158
+ * Register a test category to run later.
159
+ *
160
+ */
161
+
162
+ testsToRun = [];;
163
+
164
+ function RegisterTestCategory(name, tests) {
165
+ testsToRun.push({
166
+ name: name
167
+ tests: tests
168
+ })
169
+ };;
170
+
171
+
172
+ /*
173
+ * Load tests
174
+ *
175
+ */
176
+
177
+ nodeparse("test_01_core.nlg");;
178
+ nodeparse("test_02_context.nlg");;
179
+ nodeparse("test_03_jsinterop.nlg");;
180
+ nodeparse("test_04_numerics.nlg");;
181
+ nodeparse("test_05_strings.nlg");;
182
+ nodeparse("test_06_lingoparse.nlg");;
183
+ nodeparse("test_07_lingo.nlg");;
184
+
185
+
186
+ /*
187
+ * RunTests
188
+ *
189
+ * Run all our tests and produce a total summary at the end.
190
+ *
191
+ */
192
+
193
+ function RunTests(local totalTestCount, totalPassCount, totalTimeMS) {
194
+ totalTestCount = 0
195
+ totalPassCount = 0
196
+ totalTimeMS = 0
197
+ printline("Running Naan unit test suite")
198
+ printline("============================")
199
+
200
+
201
+ //
202
+ // testOneLocation
203
+ //
204
+ //
205
+ function testOneLocation(name, tests, local testCounter, successCounter, bannered,
206
+ parsenv, test, textout, elapsedMS) {
207
+ testCounter = 0
208
+ successCounter = 0
209
+ bannered = false
210
+ parsenv = Parsenv("Test-".concat(name))
211
+ textout = ""
212
+
213
+ function banner()
214
+ {
215
+ if !bannered {
216
+ textout = textout.concat("While running ", name, "...\n")
217
+ textout = textout.concat("-----\n") }
218
+ bannered = true
219
+ }
220
+
221
+ function testOne(cmd, expect, local result, response, type, break1, break2)
222
+ {
223
+ if string(cmd)
224
+ result = parsenv.parse(cmd.concat("\n"))
225
+ else
226
+ return ("invalid cmd at test ".concat(testCounter, ": ", typeof(cmd), "\n"))
227
+ if string(expect) {
228
+ if result.errors.length > 0
229
+ return (strcat("test(\"", cmd, "\") failed:\n ", result.errors.join("|"), "\n"))
230
+ else
231
+ response = result.text.concat(result.pretty).join("|")
232
+ } else if dictionary(expect) {
233
+ for type in expect {
234
+ response = result[type].map(function(item){
235
+ if string(item)
236
+ item
237
+ else
238
+ tostring(item, { quote: true, nonamespace: true })})
239
+ response = response.join("|")
240
+ if response != expect[type]
241
+ break
242
+ }
243
+ if !expect.errors && result.errors.length > 0
244
+ return (strcat("test(\"", cmd, "\") unexpected errors = \"", result.errors.join("|"), "\"\n"))
245
+ if !expect.text && result.text.length > 0
246
+ return (strcat("test(\"", cmd, "\") unexpected text = \"", result.text.join("|"), "\"\n"))
247
+ expect = expect[type]
248
+ } else
249
+ return (strcat("test(\"", cmd, "\"): invalid response type ", typeof(expect), "\n"))
250
+ if response != expect {
251
+ break1 = ""
252
+ break2 = ", "
253
+ if cmd.length > 10 || result.length > 20 {
254
+ break1 = "\n "
255
+ break2 = "\n " }
256
+ return (strcat("test(\"", cmd, "\") ", break1, "reported \"", response, "\"", break2, "expected \"", expect, "\"", "\n")) }
257
+
258
+ ++totalAllSuccess
259
+ return ("")
260
+ }
261
+
262
+ function rrTest(cmd, expect, local error)
263
+ {
264
+ ++testCounter
265
+ if ((error = testOne(cmd, expect)) == "")
266
+ ++successCounter
267
+ else
268
+ {
269
+ banner()
270
+ textout = textout.concat(error)
271
+ }
272
+ }
273
+
274
+ elapsedMS = Date.now()
275
+ for test in tests
276
+ rrTest(test.0, test.1)
277
+ elapsedMS = Date.now() - elapsedMS
278
+ parsenv.destroy()
279
+
280
+ if (bannered) {
281
+ print(textout)
282
+ printline("-----") }
283
+ printline(prepad(name, 18).concat(": ", prepad(successCounter, 3), " of ", prepad(testCounter, 3), " tests ran successfully in ", (elapsedMS/1000.0).toFixed(3), " seconds"))
284
+ totalTestCount += testCounter
285
+ totalPassCount += successCounter
286
+ totalTimeMS += elapsedMS
287
+ { ok: true }
288
+ }
289
+
290
+
291
+ //
292
+ // run registered tests
293
+ //
294
+
295
+ let(local categ) {
296
+ for categ in testsToRun
297
+ testOneLocation(categ.name, categ.tests)
298
+ }()
299
+
300
+
301
+ //
302
+ // report results
303
+ //
304
+
305
+ let () {
306
+ printline("============================")
307
+ printline(prepad(totalTestCount, 5), " tests in ", (totalTimeMS/1000.0).toFixed(3), " seconds")
308
+ printline(prepad(totalPassCount, 5), " succeeded")
309
+ printline(prepad(totalTestCount-totalPassCount, 5), " failed")
310
+ printline()
311
+ }()
312
+ }();;
@@ -0,0 +1,33 @@
1
+ /*
2
+ * node_test.js
3
+ * Naanlib
4
+ *
5
+ * Conduct unit tests using a Naan repl in Node.
6
+ *
7
+ * column positioning: // // !
8
+ *
9
+ * Copyright (c) 2021 by Richard C. Zulch
10
+ *
11
+ */
12
+
13
+ "use strict";
14
+
15
+
16
+ /*
17
+ * Begin
18
+ *
19
+ */
20
+
21
+ var NaanNodeREPL = require('../lib/env_node.js');
22
+ var jspath = require("path");
23
+
24
+ var naanrepl = new NaanNodeREPL({
25
+ replDisable: true
26
+ });
27
+
28
+ naanrepl.setDirectory(__dirname);
29
+
30
+ naanrepl.textCommand("body("
31
+ + "nodeparse('harness.nlg'),"
32
+ + "sleep(1),"
33
+ + "exec(quote(js.g.process.exit(0))));;\n");