qunitx 0.8.2 → 0.8.3

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/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "qunitx",
3
3
  "type": "module",
4
- "version": "0.8.2",
4
+ "version": "0.8.3",
5
5
  "description": "A universal test framework for testing any js file on node.js, browser or deno with QUnit API",
6
6
  "author": "Izel Nakri",
7
7
  "license": "MIT",
@@ -1,6 +1,6 @@
1
1
  import { AssertionError as DenoAssertionError, assertRejects, assertThrows } from "https://deno.land/std@0.192.0/testing/asserts.ts";
2
2
  import '../../vendor/qunit.js';
3
- import { objectValuesSubset } from '../shared/index.js';
3
+ import { objectValues, objectValuesSubset, validateExpectedExceptionArgs, validateException } from '../shared/index.js';
4
4
  import util from 'node:util';
5
5
 
6
6
  export class AssertionError extends DenoAssertionError {
@@ -62,7 +62,7 @@ export default {
62
62
  }
63
63
  },
64
64
  true(state, message) {
65
- if (state === true) {
65
+ if (state !== true) {
66
66
  throw new AssertionError({
67
67
  actual: state,
68
68
  expected: true,
@@ -72,7 +72,7 @@ export default {
72
72
  }
73
73
  },
74
74
  false(state, message) {
75
- if (state === false) {
75
+ if (state !== false) {
76
76
  throw new AssertionError({
77
77
  actual: state,
78
78
  expected: true,
@@ -82,7 +82,7 @@ export default {
82
82
  }
83
83
  },
84
84
  equal(actual, expected, message) {
85
- if (actual == expected) {
85
+ if (actual != expected) {
86
86
  throw new AssertionError({
87
87
  actual,
88
88
  expected,
@@ -93,7 +93,7 @@ export default {
93
93
  }
94
94
  },
95
95
  notEqual(actual, expected, message) {
96
- if (actual != expected) {
96
+ if (actual == expected) {
97
97
  throw new AssertionError({
98
98
  actual,
99
99
  expected,
@@ -106,7 +106,7 @@ export default {
106
106
  propEqual(actual, expected, message) {
107
107
  let targetActual = objectValues(actual);
108
108
  let targetExpected = objectValues(expected);
109
- if (!window.QUnit.window.QUnit.equiv(targetActual, targetExpected)) {
109
+ if (!window.QUnit.equiv(targetActual, targetExpected)) {
110
110
  throw new AssertionError({
111
111
  actual: targetActual,
112
112
  expected: targetExpected,
@@ -195,23 +195,73 @@ export default {
195
195
  });
196
196
  }
197
197
  },
198
- throws: assertThrows,
199
- rejects: assertRejects,
200
- };
198
+ throws(blockFn, expectedInput, assertionMessage) {
199
+ let [expected, message] = validateExpectedExceptionArgs(expectedInput, assertionMessage, 'rejects');
200
+ if (typeof blockFn !== 'function') {
201
+ throw new AssertionError({
202
+ actual: blockFn,
203
+ expected: Function,
204
+ message: 'The value provided to `assert.throws` was not a function.',
205
+ stackStartFn: this.throws,
206
+ });
207
+ }
201
208
 
202
- function objectValues(obj) {
203
- let allowArray = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
204
- let vals = allowArray && is('array', obj) ? [] : {};
209
+ try {
210
+ blockFn();
211
+ } catch (error) {
212
+ let validation = validateException(error, expected, message);
213
+ if (validation.result === false) {
214
+ throw new AssertionError({
215
+ actual: validation.result,
216
+ expected: validation.expected,
217
+ message: validation.message,
218
+ stackStartFn: this.throws,
219
+ });
220
+ }
205
221
 
206
- for (var key in obj) {
207
- if (hasOwn$1.call(obj, key)) {
208
- let val = obj[key];
209
- vals[key] = val === Object(val) ? objectValues(val, allowArray) : val;
222
+ return;
210
223
  }
211
- }
212
224
 
213
- return vals;
214
- }
225
+ throw new AssertionError({
226
+ actual: blockFn,
227
+ expected: expected,
228
+ message: 'Function passed to `assert.throws` did not throw an exception!',
229
+ stackStartFn: this.throws,
230
+ });
231
+ },
232
+ async rejects(promise, expectedInput, assertionMessage) {
233
+ let [expected, message] = validateExpectedExceptionArgs(expectedInput, assertionMessage, 'rejects');
234
+ let then = promise && promise.then;
235
+ if (typeof then !== 'function') {
236
+ throw new AssertionError({
237
+ actual: promise,
238
+ expected: expected,
239
+ message: 'The value provided to `assert.rejects` was not a promise!',
240
+ stackStartFn: this.rejects,
241
+ });
242
+ }
243
+
244
+ try {
245
+ await promise;
246
+ throw new AssertionError({
247
+ actual: promise,
248
+ expected: expected,
249
+ message: 'The promise returned by the `assert.rejects` callback did not reject!',
250
+ stackStartFn: this.rejects,
251
+ });
252
+ } catch (error) {
253
+ let validation = validateException(error, expected, message);
254
+ if (validation.result === false) {
255
+ throw new AssertionError({
256
+ actual: validation.result,
257
+ expected: validation.expected,
258
+ message: validation.message,
259
+ stackStartFn: this.rejects,
260
+ });
261
+ }
262
+ }
263
+ }
264
+ };
215
265
 
216
266
  function defaultMessage(actual, description, expected) {
217
267
  return `
@@ -226,3 +276,4 @@ ${inspect(expected)}`
226
276
  function inspect(value) {
227
277
  return util.inspect(value, { depth: 10, colors: true, compact: false });
228
278
  }
279
+
@@ -1,5 +1,5 @@
1
1
  import QUnit from '../../vendor/qunit.js';
2
- import { objectValuesSubset } from '../shared/index.js';
2
+ import { objectValues, objectValuesSubset, validateExpectedExceptionArgs, validateException } from '../shared/index.js';
3
3
  import assert, { AssertionError } from 'node:assert';
4
4
  import util from 'node:util';
5
5
 
@@ -56,7 +56,7 @@ export default {
56
56
  }
57
57
  },
58
58
  true(state, message) {
59
- if (state === true) {
59
+ if (state !== true) {
60
60
  throw new AssertionError({
61
61
  actual: state,
62
62
  expected: true,
@@ -66,7 +66,7 @@ export default {
66
66
  }
67
67
  },
68
68
  false(state, message) {
69
- if (state === false) {
69
+ if (state !== false) {
70
70
  throw new AssertionError({
71
71
  actual: state,
72
72
  expected: true,
@@ -76,7 +76,7 @@ export default {
76
76
  }
77
77
  },
78
78
  equal(actual, expected, message) {
79
- if (actual == expected) {
79
+ if (actual != expected) {
80
80
  throw new AssertionError({
81
81
  actual,
82
82
  expected,
@@ -87,7 +87,7 @@ export default {
87
87
  }
88
88
  },
89
89
  notEqual(actual, expected, message) {
90
- if (actual != expected) {
90
+ if (actual == expected) {
91
91
  throw new AssertionError({
92
92
  actual,
93
93
  expected,
@@ -189,23 +189,73 @@ export default {
189
189
  });
190
190
  }
191
191
  },
192
- throws: assert.throws,
193
- rejects: assert.rejects,
194
- };
192
+ throws(blockFn, expectedInput, assertionMessage) {
193
+ let [expected, message] = validateExpectedExceptionArgs(expectedInput, assertionMessage, 'rejects');
194
+ if (typeof blockFn !== 'function') {
195
+ throw new AssertionError({
196
+ actual: blockFn,
197
+ expected: Function,
198
+ message: 'The value provided to `assert.throws` was not a function.',
199
+ stackStartFn: this.throws,
200
+ });
201
+ }
195
202
 
196
- function objectValues(obj) {
197
- let allowArray = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
198
- let vals = allowArray && is('array', obj) ? [] : {};
203
+ try {
204
+ blockFn();
205
+ } catch (error) {
206
+ let validation = validateException(error, expected, message);
207
+ if (validation.result === false) {
208
+ throw new AssertionError({
209
+ actual: validation.result,
210
+ expected: validation.expected,
211
+ message: validation.message,
212
+ stackStartFn: this.throws,
213
+ });
214
+ }
199
215
 
200
- for (var key in obj) {
201
- if (hasOwn$1.call(obj, key)) {
202
- let val = obj[key];
203
- vals[key] = val === Object(val) ? objectValues(val, allowArray) : val;
216
+ return;
204
217
  }
205
- }
206
218
 
207
- return vals;
208
- }
219
+ throw new AssertionError({
220
+ actual: blockFn,
221
+ expected: expected,
222
+ message: 'Function passed to `assert.throws` did not throw an exception!',
223
+ stackStartFn: this.throws,
224
+ });
225
+ },
226
+ async rejects(promise, expectedInput, assertionMessage) {
227
+ let [expected, message] = validateExpectedExceptionArgs(expectedInput, assertionMessage, 'rejects');
228
+ let then = promise && promise.then;
229
+ if (typeof then !== 'function') {
230
+ throw new AssertionError({
231
+ actual: promise,
232
+ expected: expected,
233
+ message: 'The value provided to `assert.rejects` was not a promise!',
234
+ stackStartFn: this.rejects,
235
+ });
236
+ }
237
+
238
+ try {
239
+ await promise;
240
+ throw new AssertionError({
241
+ actual: promise,
242
+ expected: expected,
243
+ message: 'The promise returned by the `assert.rejects` callback did not reject!',
244
+ stackStartFn: this.rejects,
245
+ });
246
+ } catch (error) {
247
+ let validation = validateException(error, expected, message);
248
+ if (validation.result === false) {
249
+ throw new AssertionError({
250
+ actual: validation.result,
251
+ expected: validation.expected,
252
+ message: validation.message,
253
+ stackStartFn: this.rejects,
254
+ });
255
+ }
256
+ }
257
+ }
258
+ };
209
259
 
210
260
  function defaultMessage(actual, description, expected) {
211
261
  return `
@@ -1,4 +1,67 @@
1
+ const hasOwn = Object.prototype.hasOwnProperty
2
+
3
+ function _typeof(obj) {
4
+ "@babel/helpers - typeof";
5
+
6
+ return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (obj) {
7
+ return typeof obj;
8
+ } : function (obj) {
9
+ return obj && "function" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj;
10
+ }, _typeof(obj);
11
+ }
12
+
13
+ export function objectType(obj) {
14
+ if (typeof obj === 'undefined') {
15
+ return 'undefined';
16
+ }
17
+
18
+ // Consider: typeof null === object
19
+ if (obj === null) {
20
+ return 'null';
21
+ }
22
+ var match = toString.call(obj).match(/^\[object\s(.*)\]$/);
23
+ var type = match && match[1];
24
+ switch (type) {
25
+ case 'Number':
26
+ if (isNaN(obj)) {
27
+ return 'nan';
28
+ }
29
+ return 'number';
30
+ case 'String':
31
+ case 'Boolean':
32
+ case 'Array':
33
+ case 'Set':
34
+ case 'Map':
35
+ case 'Date':
36
+ case 'RegExp':
37
+ case 'Function':
38
+ case 'Symbol':
39
+ return type.toLowerCase();
40
+ default:
41
+ return _typeof(obj);
42
+ }
43
+ }
44
+
45
+ function is(type, obj) {
46
+ return objectType(obj) === type;
47
+ }
48
+
49
+ export function objectValues(obj) {
50
+ let allowArray = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
51
+ let vals = allowArray && is('array', obj) ? [] : {};
52
+
53
+ for (var key in obj) {
54
+ if (hasOwn.call(obj, key)) {
55
+ let val = obj[key];
56
+ vals[key] = val === Object(val) ? objectValues(val, allowArray) : val;
57
+ }
58
+ }
59
+
60
+ return vals;
61
+ }
62
+
1
63
  /**
64
+ *
2
65
  * Recursively clone an object into a plain object, taking only the
3
66
  * subset of own enumerable properties that exist a given model.
4
67
  *
@@ -19,11 +82,91 @@ export function objectValuesSubset(obj, model) {
19
82
  // This enables subsetting [20, 30] with {1: 30}.
20
83
  var subset = {};
21
84
  for (var key in model) {
22
- if (hasOwn$1.call(model, key) && hasOwn$1.call(obj, key)) {
85
+ if (hasOwn.call(model, key) && hasOwn.call(obj, key)) {
23
86
  subset[key] = objectValuesSubset(obj[key], model[key]);
24
87
  }
25
88
  }
26
89
  return subset;
27
90
  }
28
91
 
29
- export default { objectValuesSubset };
92
+ export function validateExpectedExceptionArgs(expected, message, assertionMethod) {
93
+ var expectedType = objectType(expected);
94
+
95
+ // 'expected' is optional unless doing string comparison
96
+ if (expectedType === 'string') {
97
+ if (message === undefined) {
98
+ message = expected;
99
+ expected = undefined;
100
+ return [expected, message];
101
+ } else {
102
+ throw new Error('assert.' + assertionMethod + ' does not accept a string value for the expected argument.\n' + 'Use a non-string object value (e.g. RegExp or validator function) ' + 'instead if necessary.');
103
+ }
104
+ }
105
+ var valid = !expected ||
106
+ // TODO: be more explicit here
107
+ expectedType === 'regexp' || expectedType === 'function' || expectedType === 'object';
108
+ if (!valid) {
109
+ throw new Error('Invalid expected value type (' + expectedType + ') ' + 'provided to assert.' + assertionMethod + '.');
110
+ }
111
+ return [expected, message];
112
+ }
113
+
114
+ export function validateException(actual, expected, message) {
115
+ var result = false;
116
+ var expectedType = objectType(expected);
117
+
118
+ // These branches should be exhaustive, based on validation done in validateExpectedException
119
+
120
+ // We don't want to validate
121
+ if (!expected) {
122
+ result = true;
123
+
124
+ // Expected is a regexp
125
+ } else if (expectedType === 'regexp') {
126
+ result = expected.test(errorString(actual));
127
+
128
+ // Log the string form of the regexp
129
+ expected = String(expected);
130
+
131
+ // Expected is a constructor, maybe an Error constructor.
132
+ // Note the extra check on its prototype - this is an implicit
133
+ // requirement of "instanceof", else it will throw a TypeError.
134
+ } else if (expectedType === 'function' && expected.prototype !== undefined && actual instanceof expected) {
135
+ result = true;
136
+
137
+ // Expected is an Error object
138
+ } else if (expectedType === 'object') {
139
+ result = actual instanceof expected.constructor && actual.name === expected.name && actual.message === expected.message;
140
+
141
+ // Log the string form of the Error object
142
+ expected = errorString(expected);
143
+
144
+ // Expected is a validation function which returns true if validation passed
145
+ } else if (expectedType === 'function') {
146
+ // protect against accidental semantics which could hard error in the test
147
+ try {
148
+ result = expected.call({}, actual) === true;
149
+ expected = null;
150
+ } catch (e) {
151
+ // assign the "expected" to a nice error string to communicate the local failure to the user
152
+ expected = errorString(e);
153
+ }
154
+ }
155
+ return [result, expected, message];
156
+ }
157
+
158
+ function errorString(error) {
159
+ // Use String() instead of toString() to handle non-object values like undefined or null.
160
+ var resultErrorString = String(error);
161
+
162
+ // If the error wasn't a subclass of Error but something like
163
+ // an object literal with name and message properties...
164
+ if (resultErrorString.slice(0, 7) === '[object') {
165
+ // Based on https://es5.github.io/#x15.11.4.4
166
+ return (error.name || 'Error') + (error.message ? ": ".concat(error.message) : '');
167
+ } else {
168
+ return resultErrorString;
169
+ }
170
+ }
171
+
172
+ export default { objectValues, objectValuesSubset, validateExpectedExceptionArgs, validateException };