chai 5.0.0 → 5.0.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/README.md +7 -25
- package/chai.js +98 -73
- package/lib/chai/assertion.js +1 -1
- package/lib/chai/core/assertions.js +59 -6
- package/lib/chai/interface/assert.js +17 -16
- package/package.json +7 -8
- package/bower.json +0 -26
- package/karma.conf.cjs +0 -35
- package/karma.sauce.js +0 -41
- package/sauce.browsers.js +0 -106
package/README.md
CHANGED
|
@@ -71,32 +71,12 @@ You can also use it within the browser; install via npm and use the `chai.js` fi
|
|
|
71
71
|
Import the library in your code, and then pick one of the styles you'd like to use - either `assert`, `expect` or `should`:
|
|
72
72
|
|
|
73
73
|
```js
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
var should = chai.should(); // Using Should style
|
|
78
|
-
```
|
|
79
|
-
|
|
80
|
-
### Pre-Native Modules Usage (_registers the chai testing style globally_)
|
|
81
|
-
|
|
82
|
-
```js
|
|
83
|
-
require('chai/register-assert'); // Using Assert style
|
|
84
|
-
require('chai/register-expect'); // Using Expect style
|
|
85
|
-
require('chai/register-should'); // Using Should style
|
|
86
|
-
```
|
|
87
|
-
|
|
88
|
-
### Pre-Native Modules Usage (_as local variables_)
|
|
89
|
-
|
|
90
|
-
```js
|
|
91
|
-
const { assert } = require('chai'); // Using Assert style
|
|
92
|
-
const { expect } = require('chai'); // Using Expect style
|
|
93
|
-
const { should } = require('chai'); // Using Should style
|
|
94
|
-
should(); // Modifies `Object.prototype`
|
|
95
|
-
|
|
96
|
-
const { expect, use } = require('chai'); // Creates local variables `expect` and `use`; useful for plugin use
|
|
74
|
+
import { assert } from 'chai'; // Using Assert style
|
|
75
|
+
import { expect } from 'chai'; // Using Expect style
|
|
76
|
+
import { should } from 'chai'; // Using Should style
|
|
97
77
|
```
|
|
98
78
|
|
|
99
|
-
###
|
|
79
|
+
### Register the chai testing style globally
|
|
100
80
|
|
|
101
81
|
```js
|
|
102
82
|
import 'chai/register-assert'; // Using Assert style
|
|
@@ -104,13 +84,15 @@ import 'chai/register-expect'; // Using Expect style
|
|
|
104
84
|
import 'chai/register-should'; // Using Should style
|
|
105
85
|
```
|
|
106
86
|
|
|
107
|
-
###
|
|
87
|
+
### Import assertion styles as local variables
|
|
108
88
|
|
|
109
89
|
```js
|
|
110
90
|
import { assert } from 'chai'; // Using Assert style
|
|
111
91
|
import { expect } from 'chai'; // Using Expect style
|
|
112
92
|
import { should } from 'chai'; // Using Should style
|
|
113
93
|
should(); // Modifies `Object.prototype`
|
|
94
|
+
|
|
95
|
+
import { expect, use } from 'chai'; // Creates local variables `expect` and `use`; useful for plugin use
|
|
114
96
|
```
|
|
115
97
|
|
|
116
98
|
### Usage with Mocha
|
package/chai.js
CHANGED
|
@@ -142,7 +142,10 @@ __name(type, "type");
|
|
|
142
142
|
|
|
143
143
|
// node_modules/assertion-error/index.js
|
|
144
144
|
var canElideFrames = "captureStackTrace" in Error;
|
|
145
|
-
var AssertionError = class extends Error {
|
|
145
|
+
var AssertionError = class _AssertionError extends Error {
|
|
146
|
+
static {
|
|
147
|
+
__name(this, "AssertionError");
|
|
148
|
+
}
|
|
146
149
|
message;
|
|
147
150
|
get name() {
|
|
148
151
|
return "AssertionError";
|
|
@@ -154,7 +157,7 @@ var AssertionError = class extends Error {
|
|
|
154
157
|
super(message);
|
|
155
158
|
this.message = message;
|
|
156
159
|
if (canElideFrames) {
|
|
157
|
-
Error.captureStackTrace(this, ssf ||
|
|
160
|
+
Error.captureStackTrace(this, ssf || _AssertionError);
|
|
158
161
|
}
|
|
159
162
|
for (const key in props) {
|
|
160
163
|
if (!(key in this)) {
|
|
@@ -172,7 +175,6 @@ var AssertionError = class extends Error {
|
|
|
172
175
|
};
|
|
173
176
|
}
|
|
174
177
|
};
|
|
175
|
-
__name(AssertionError, "AssertionError");
|
|
176
178
|
|
|
177
179
|
// lib/chai/utils/expectTypes.js
|
|
178
180
|
function expectTypes(obj, types) {
|
|
@@ -372,11 +374,7 @@ function inspectArray(array, options) {
|
|
|
372
374
|
options.truncate -= listContents.length;
|
|
373
375
|
let propertyContents = "";
|
|
374
376
|
if (nonIndexProperties.length) {
|
|
375
|
-
propertyContents = inspectList(
|
|
376
|
-
nonIndexProperties.map((key) => [key, array[key]]),
|
|
377
|
-
options,
|
|
378
|
-
inspectProperty
|
|
379
|
-
);
|
|
377
|
+
propertyContents = inspectList(nonIndexProperties.map((key) => [key, array[key]]), options, inspectProperty);
|
|
380
378
|
}
|
|
381
379
|
return `[ ${listContents}${propertyContents ? `, ${propertyContents}` : ""} ]`;
|
|
382
380
|
}
|
|
@@ -410,11 +408,7 @@ function inspectTypedArray(array, options) {
|
|
|
410
408
|
}
|
|
411
409
|
let propertyContents = "";
|
|
412
410
|
if (nonIndexProperties.length) {
|
|
413
|
-
propertyContents = inspectList(
|
|
414
|
-
nonIndexProperties.map((key) => [key, array[key]]),
|
|
415
|
-
options,
|
|
416
|
-
inspectProperty
|
|
417
|
-
);
|
|
411
|
+
propertyContents = inspectList(nonIndexProperties.map((key) => [key, array[key]]), options, inspectProperty);
|
|
418
412
|
}
|
|
419
413
|
return `${name}[ ${output}${propertyContents ? `, ${propertyContents}` : ""} ]`;
|
|
420
414
|
}
|
|
@@ -434,11 +428,12 @@ __name(inspectDate, "inspectDate");
|
|
|
434
428
|
|
|
435
429
|
// node_modules/loupe/lib/function.js
|
|
436
430
|
function inspectFunction(func, options) {
|
|
431
|
+
const functionType = func[Symbol.toStringTag] || "Function";
|
|
437
432
|
const name = func.name;
|
|
438
433
|
if (!name) {
|
|
439
|
-
return options.stylize(
|
|
434
|
+
return options.stylize(`[${functionType}]`, "special");
|
|
440
435
|
}
|
|
441
|
-
return options.stylize(`[
|
|
436
|
+
return options.stylize(`[${functionType} ${truncate(name, options.truncate - 11)}]`, "special");
|
|
442
437
|
}
|
|
443
438
|
__name(inspectFunction, "inspectFunction");
|
|
444
439
|
|
|
@@ -524,10 +519,7 @@ function inspectSet(set2, options) {
|
|
|
524
519
|
__name(inspectSet, "inspectSet");
|
|
525
520
|
|
|
526
521
|
// node_modules/loupe/lib/string.js
|
|
527
|
-
var stringEscapeChars = new RegExp(
|
|
528
|
-
"['\\u0000-\\u001f\\u007f-\\u009f\\u00ad\\u0600-\\u0604\\u070f\\u17b4\\u17b5\\u200c-\\u200f\\u2028-\\u202f\\u2060-\\u206f\\ufeff\\ufff0-\\uffff]",
|
|
529
|
-
"g"
|
|
530
|
-
);
|
|
522
|
+
var stringEscapeChars = new RegExp("['\\u0000-\\u001f\\u007f-\\u009f\\u00ad\\u0600-\\u0604\\u070f\\u17b4\\u17b5\\u200c-\\u200f\\u2028-\\u202f\\u2060-\\u206f\\ufeff\\ufff0-\\uffff]", "g");
|
|
531
523
|
var escapeCharacters = {
|
|
532
524
|
"\b": "\\b",
|
|
533
525
|
" ": "\\t",
|
|
@@ -590,16 +582,8 @@ function inspectObject(object, options) {
|
|
|
590
582
|
return "[Circular]";
|
|
591
583
|
}
|
|
592
584
|
options.seen.push(object);
|
|
593
|
-
const propertyContents = inspectList(
|
|
594
|
-
|
|
595
|
-
options,
|
|
596
|
-
inspectProperty
|
|
597
|
-
);
|
|
598
|
-
const symbolContents = inspectList(
|
|
599
|
-
symbols.map((key) => [key, object[key]]),
|
|
600
|
-
options,
|
|
601
|
-
inspectProperty
|
|
602
|
-
);
|
|
585
|
+
const propertyContents = inspectList(properties.map((key) => [key, object[key]]), options, inspectProperty);
|
|
586
|
+
const symbolContents = inspectList(symbols.map((key) => [key, object[key]]), options, inspectProperty);
|
|
603
587
|
options.seen.pop();
|
|
604
588
|
let sep = "";
|
|
605
589
|
if (propertyContents && symbolContents) {
|
|
@@ -659,11 +643,7 @@ function inspectObject2(error, options) {
|
|
|
659
643
|
}
|
|
660
644
|
message = message ? `: ${message}` : "";
|
|
661
645
|
options.truncate -= message.length + 5;
|
|
662
|
-
const propertyContents = inspectList(
|
|
663
|
-
properties.map((key) => [key, error[key]]),
|
|
664
|
-
options,
|
|
665
|
-
inspectProperty
|
|
666
|
-
);
|
|
646
|
+
const propertyContents = inspectList(properties.map((key) => [key, error[key]]), options, inspectProperty);
|
|
667
647
|
return `${name}${message}${propertyContents ? ` { ${propertyContents} }` : ""}`;
|
|
668
648
|
}
|
|
669
649
|
__name(inspectObject2, "inspectObject");
|
|
@@ -691,12 +671,7 @@ function inspectHTML(element, options) {
|
|
|
691
671
|
let propertyContents = "";
|
|
692
672
|
if (properties.length > 0) {
|
|
693
673
|
propertyContents += " ";
|
|
694
|
-
propertyContents += inspectList(
|
|
695
|
-
properties.map((key) => [key, element.getAttribute(key)]),
|
|
696
|
-
options,
|
|
697
|
-
inspectAttribute,
|
|
698
|
-
" "
|
|
699
|
-
);
|
|
674
|
+
propertyContents += inspectList(properties.map((key) => [key, element.getAttribute(key)]), options, inspectAttribute, " ");
|
|
700
675
|
}
|
|
701
676
|
options.truncate -= propertyContents.length;
|
|
702
677
|
const truncate2 = options.truncate;
|
|
@@ -902,7 +877,30 @@ var config = {
|
|
|
902
877
|
* @param {Array}
|
|
903
878
|
* @api public
|
|
904
879
|
*/
|
|
905
|
-
proxyExcludedKeys: ["then", "catch", "inspect", "toJSON"]
|
|
880
|
+
proxyExcludedKeys: ["then", "catch", "inspect", "toJSON"],
|
|
881
|
+
/**
|
|
882
|
+
* ### config.deepEqual
|
|
883
|
+
*
|
|
884
|
+
* User configurable property, defines which a custom function to use for deepEqual
|
|
885
|
+
* comparisons.
|
|
886
|
+
* By default, the function used is the one from the `deep-eql` package without custom comparator.
|
|
887
|
+
*
|
|
888
|
+
* // use a custom comparator
|
|
889
|
+
* chai.config.deepEqual = (expected, actual) => {
|
|
890
|
+
* return chai.util.eql(expected, actual, {
|
|
891
|
+
* comparator: (expected, actual) => {
|
|
892
|
+
* // for non number comparison, use the default behavior
|
|
893
|
+
* if(typeof expected !== 'number') return null;
|
|
894
|
+
* // allow a difference of 10 between compared numbers
|
|
895
|
+
* return typeof actual === 'number' && Math.abs(actual - expected) < 10
|
|
896
|
+
* }
|
|
897
|
+
* })
|
|
898
|
+
* };
|
|
899
|
+
*
|
|
900
|
+
* @param {Function}
|
|
901
|
+
* @api public
|
|
902
|
+
*/
|
|
903
|
+
deepEqual: null
|
|
906
904
|
};
|
|
907
905
|
|
|
908
906
|
// lib/chai/utils/inspect.js
|
|
@@ -1356,6 +1354,7 @@ function Assertion(obj, msg, ssfi, lockSsfi) {
|
|
|
1356
1354
|
flag(this, "lockSsfi", lockSsfi);
|
|
1357
1355
|
flag(this, "object", obj);
|
|
1358
1356
|
flag(this, "message", msg);
|
|
1357
|
+
flag(this, "eql", config.deepEqual || deep_eql_default);
|
|
1359
1358
|
return proxify(this);
|
|
1360
1359
|
}
|
|
1361
1360
|
__name(Assertion, "Assertion");
|
|
@@ -1857,16 +1856,31 @@ Assertion.addProperty("all", function() {
|
|
|
1857
1856
|
flag2(this, "all", true);
|
|
1858
1857
|
flag2(this, "any", false);
|
|
1859
1858
|
});
|
|
1859
|
+
var functionTypes = {
|
|
1860
|
+
"function": ["function", "asyncfunction", "generatorfunction", "asyncgeneratorfunction"],
|
|
1861
|
+
"asyncfunction": ["asyncfunction", "asyncgeneratorfunction"],
|
|
1862
|
+
"generatorfunction": ["generatorfunction", "asyncgeneratorfunction"],
|
|
1863
|
+
"asyncgeneratorfunction": ["asyncgeneratorfunction"]
|
|
1864
|
+
};
|
|
1860
1865
|
function an(type3, msg) {
|
|
1861
1866
|
if (msg)
|
|
1862
1867
|
flag2(this, "message", msg);
|
|
1863
1868
|
type3 = type3.toLowerCase();
|
|
1864
1869
|
var obj = flag2(this, "object"), article = ~["a", "e", "i", "o", "u"].indexOf(type3.charAt(0)) ? "an " : "a ";
|
|
1865
|
-
|
|
1866
|
-
|
|
1867
|
-
|
|
1868
|
-
|
|
1869
|
-
|
|
1870
|
+
const detectedType = type(obj).toLowerCase();
|
|
1871
|
+
if (functionTypes["function"].includes(type3)) {
|
|
1872
|
+
this.assert(
|
|
1873
|
+
functionTypes[type3].includes(detectedType),
|
|
1874
|
+
"expected #{this} to be " + article + type3,
|
|
1875
|
+
"expected #{this} not to be " + article + type3
|
|
1876
|
+
);
|
|
1877
|
+
} else {
|
|
1878
|
+
this.assert(
|
|
1879
|
+
type3 === detectedType,
|
|
1880
|
+
"expected #{this} to be " + article + type3,
|
|
1881
|
+
"expected #{this} not to be " + article + type3
|
|
1882
|
+
);
|
|
1883
|
+
}
|
|
1870
1884
|
}
|
|
1871
1885
|
__name(an, "an");
|
|
1872
1886
|
Assertion.addChainableMethod("an", an);
|
|
@@ -1882,7 +1896,7 @@ __name(includeChainingBehavior, "includeChainingBehavior");
|
|
|
1882
1896
|
function include(val, msg) {
|
|
1883
1897
|
if (msg)
|
|
1884
1898
|
flag2(this, "message", msg);
|
|
1885
|
-
var obj = flag2(this, "object"), objType = type(obj).toLowerCase(), flagMsg = flag2(this, "message"), negate = flag2(this, "negate"), ssfi = flag2(this, "ssfi"), isDeep = flag2(this, "deep"), descriptor = isDeep ? "deep " : "";
|
|
1899
|
+
var obj = flag2(this, "object"), objType = type(obj).toLowerCase(), flagMsg = flag2(this, "message"), negate = flag2(this, "negate"), ssfi = flag2(this, "ssfi"), isDeep = flag2(this, "deep"), descriptor = isDeep ? "deep " : "", isEql = isDeep ? flag2(this, "eql") : SameValueZero;
|
|
1886
1900
|
flagMsg = flagMsg ? flagMsg + ": " : "";
|
|
1887
1901
|
var included = false;
|
|
1888
1902
|
switch (objType) {
|
|
@@ -1900,7 +1914,6 @@ function include(val, msg) {
|
|
|
1900
1914
|
included = obj.has(val);
|
|
1901
1915
|
break;
|
|
1902
1916
|
case "map":
|
|
1903
|
-
var isEql = isDeep ? deep_eql_default : SameValueZero;
|
|
1904
1917
|
obj.forEach(function(item) {
|
|
1905
1918
|
included = included || isEql(item, val);
|
|
1906
1919
|
});
|
|
@@ -1908,7 +1921,7 @@ function include(val, msg) {
|
|
|
1908
1921
|
case "set":
|
|
1909
1922
|
if (isDeep) {
|
|
1910
1923
|
obj.forEach(function(item) {
|
|
1911
|
-
included = included ||
|
|
1924
|
+
included = included || isEql(item, val);
|
|
1912
1925
|
});
|
|
1913
1926
|
} else {
|
|
1914
1927
|
included = obj.has(val);
|
|
@@ -1917,7 +1930,7 @@ function include(val, msg) {
|
|
|
1917
1930
|
case "array":
|
|
1918
1931
|
if (isDeep) {
|
|
1919
1932
|
included = obj.some(function(item) {
|
|
1920
|
-
return
|
|
1933
|
+
return isEql(item, val);
|
|
1921
1934
|
});
|
|
1922
1935
|
} else {
|
|
1923
1936
|
included = obj.indexOf(val) !== -1;
|
|
@@ -1982,6 +1995,22 @@ Assertion.addProperty("true", function() {
|
|
|
1982
1995
|
flag2(this, "negate") ? false : true
|
|
1983
1996
|
);
|
|
1984
1997
|
});
|
|
1998
|
+
Assertion.addProperty("callable", function() {
|
|
1999
|
+
const val = flag2(this, "object");
|
|
2000
|
+
const ssfi = flag2(this, "ssfi");
|
|
2001
|
+
const message = flag2(this, "message");
|
|
2002
|
+
const msg = message ? `${message}: ` : "";
|
|
2003
|
+
const negate = flag2(this, "negate");
|
|
2004
|
+
const assertionMessage = negate ? `${msg}expected ${inspect2(val)} not to be a callable function` : `${msg}expected ${inspect2(val)} to be a callable function`;
|
|
2005
|
+
const isCallable = ["Function", "AsyncFunction", "GeneratorFunction", "AsyncGeneratorFunction"].includes(type(val));
|
|
2006
|
+
if (isCallable && negate || !isCallable && !negate) {
|
|
2007
|
+
throw new AssertionError(
|
|
2008
|
+
assertionMessage,
|
|
2009
|
+
void 0,
|
|
2010
|
+
ssfi
|
|
2011
|
+
);
|
|
2012
|
+
}
|
|
2013
|
+
});
|
|
1985
2014
|
Assertion.addProperty("false", function() {
|
|
1986
2015
|
this.assert(
|
|
1987
2016
|
false === flag2(this, "object"),
|
|
@@ -2098,8 +2127,9 @@ Assertion.addMethod("eq", assertEqual);
|
|
|
2098
2127
|
function assertEql(obj, msg) {
|
|
2099
2128
|
if (msg)
|
|
2100
2129
|
flag2(this, "message", msg);
|
|
2130
|
+
var eql = flag2(this, "eql");
|
|
2101
2131
|
this.assert(
|
|
2102
|
-
|
|
2132
|
+
eql(obj, flag2(this, "object")),
|
|
2103
2133
|
"expected #{this} to deeply equal #{exp}",
|
|
2104
2134
|
"expected #{this} to not deeply equal #{exp}",
|
|
2105
2135
|
obj,
|
|
@@ -2411,7 +2441,7 @@ function assertProperty(name, val, msg) {
|
|
|
2411
2441
|
ssfi
|
|
2412
2442
|
);
|
|
2413
2443
|
}
|
|
2414
|
-
var isDeep = flag2(this, "deep"), negate = flag2(this, "negate"), pathInfo = isNested ? getPathInfo(obj, name) : null, value = isNested ? pathInfo.value : obj[name];
|
|
2444
|
+
var isDeep = flag2(this, "deep"), negate = flag2(this, "negate"), pathInfo = isNested ? getPathInfo(obj, name) : null, value = isNested ? pathInfo.value : obj[name], isEql = isDeep ? flag2(this, "eql") : (val1, val2) => val1 === val2;
|
|
2415
2445
|
var descriptor = "";
|
|
2416
2446
|
if (isDeep)
|
|
2417
2447
|
descriptor += "deep ";
|
|
@@ -2436,7 +2466,7 @@ function assertProperty(name, val, msg) {
|
|
|
2436
2466
|
}
|
|
2437
2467
|
if (arguments.length > 1) {
|
|
2438
2468
|
this.assert(
|
|
2439
|
-
hasProperty2 && (
|
|
2469
|
+
hasProperty2 && isEql(val, value),
|
|
2440
2470
|
"expected #{this} to have " + descriptor + inspect2(name) + " of #{exp}, but got #{act}",
|
|
2441
2471
|
"expected #{this} to not have " + descriptor + inspect2(name) + " of #{act}",
|
|
2442
2472
|
val,
|
|
@@ -2463,9 +2493,10 @@ function assertOwnPropertyDescriptor(name, descriptor, msg) {
|
|
|
2463
2493
|
flag2(this, "message", msg);
|
|
2464
2494
|
var obj = flag2(this, "object");
|
|
2465
2495
|
var actualDescriptor = Object.getOwnPropertyDescriptor(Object(obj), name);
|
|
2496
|
+
var eql = flag2(this, "eql");
|
|
2466
2497
|
if (actualDescriptor && descriptor) {
|
|
2467
2498
|
this.assert(
|
|
2468
|
-
|
|
2499
|
+
eql(descriptor, actualDescriptor),
|
|
2469
2500
|
"expected the own property descriptor for " + inspect2(name) + " on #{this} to match " + inspect2(descriptor) + ", got " + inspect2(actualDescriptor),
|
|
2470
2501
|
"expected the own property descriptor for " + inspect2(name) + " on #{this} to not match " + inspect2(descriptor),
|
|
2471
2502
|
descriptor,
|
|
@@ -2574,29 +2605,21 @@ function assertKeys(keys) {
|
|
|
2574
2605
|
if (!keys.length) {
|
|
2575
2606
|
throw new AssertionError(flagMsg + "keys required", void 0, ssfi);
|
|
2576
2607
|
}
|
|
2577
|
-
var len = keys.length, any = flag2(this, "any"), all = flag2(this, "all"), expected = keys;
|
|
2608
|
+
var len = keys.length, any = flag2(this, "any"), all = flag2(this, "all"), expected = keys, isEql = isDeep ? flag2(this, "eql") : (val1, val2) => val1 === val2;
|
|
2578
2609
|
if (!any && !all) {
|
|
2579
2610
|
all = true;
|
|
2580
2611
|
}
|
|
2581
2612
|
if (any) {
|
|
2582
2613
|
ok = expected.some(function(expectedKey) {
|
|
2583
2614
|
return actual.some(function(actualKey) {
|
|
2584
|
-
|
|
2585
|
-
return deep_eql_default(expectedKey, actualKey);
|
|
2586
|
-
} else {
|
|
2587
|
-
return expectedKey === actualKey;
|
|
2588
|
-
}
|
|
2615
|
+
return isEql(expectedKey, actualKey);
|
|
2589
2616
|
});
|
|
2590
2617
|
});
|
|
2591
2618
|
}
|
|
2592
2619
|
if (all) {
|
|
2593
2620
|
ok = expected.every(function(expectedKey) {
|
|
2594
2621
|
return actual.some(function(actualKey) {
|
|
2595
|
-
|
|
2596
|
-
return deep_eql_default(expectedKey, actualKey);
|
|
2597
|
-
} else {
|
|
2598
|
-
return expectedKey === actualKey;
|
|
2599
|
-
}
|
|
2622
|
+
return isEql(expectedKey, actualKey);
|
|
2600
2623
|
});
|
|
2601
2624
|
});
|
|
2602
2625
|
if (!flag2(this, "contains")) {
|
|
@@ -2832,7 +2855,7 @@ Assertion.addMethod("members", function(subset, msg) {
|
|
|
2832
2855
|
failMsg = "expected #{this} to have the same " + subject + " as #{exp}";
|
|
2833
2856
|
failNegateMsg = "expected #{this} to not have the same " + subject + " as #{exp}";
|
|
2834
2857
|
}
|
|
2835
|
-
var cmp = flag2(this, "deep") ?
|
|
2858
|
+
var cmp = flag2(this, "deep") ? flag2(this, "eql") : void 0;
|
|
2836
2859
|
this.assert(
|
|
2837
2860
|
isSubsetOf(subset, obj, cmp, contains, ordered),
|
|
2838
2861
|
failMsg,
|
|
@@ -2845,7 +2868,7 @@ Assertion.addMethod("members", function(subset, msg) {
|
|
|
2845
2868
|
function oneOf(list, msg) {
|
|
2846
2869
|
if (msg)
|
|
2847
2870
|
flag2(this, "message", msg);
|
|
2848
|
-
var expected = flag2(this, "object"), flagMsg = flag2(this, "message"), ssfi = flag2(this, "ssfi"), contains = flag2(this, "contains"), isDeep = flag2(this, "deep");
|
|
2871
|
+
var expected = flag2(this, "object"), flagMsg = flag2(this, "message"), ssfi = flag2(this, "ssfi"), contains = flag2(this, "contains"), isDeep = flag2(this, "deep"), eql = flag2(this, "eql");
|
|
2849
2872
|
new Assertion(list, flagMsg, ssfi, true).to.be.an("array");
|
|
2850
2873
|
if (contains) {
|
|
2851
2874
|
this.assert(
|
|
@@ -2861,7 +2884,7 @@ function oneOf(list, msg) {
|
|
|
2861
2884
|
if (isDeep) {
|
|
2862
2885
|
this.assert(
|
|
2863
2886
|
list.some(function(possibility) {
|
|
2864
|
-
return
|
|
2887
|
+
return eql(expected, possibility);
|
|
2865
2888
|
}),
|
|
2866
2889
|
"expected #{this} to deeply equal one of #{exp}",
|
|
2867
2890
|
"expected #{this} to deeply equal one of #{exp}",
|
|
@@ -3227,11 +3250,11 @@ assert.isUndefined = function(val, msg) {
|
|
|
3227
3250
|
assert.isDefined = function(val, msg) {
|
|
3228
3251
|
new Assertion(val, msg, assert.isDefined, true).to.not.equal(void 0);
|
|
3229
3252
|
};
|
|
3230
|
-
assert.
|
|
3231
|
-
new Assertion(val, msg, assert.
|
|
3253
|
+
assert.isCallable = function(val, msg) {
|
|
3254
|
+
new Assertion(val, msg, assert.isCallable, true).is.callable;
|
|
3232
3255
|
};
|
|
3233
|
-
assert.
|
|
3234
|
-
new Assertion(val, msg, assert.
|
|
3256
|
+
assert.isNotCallable = function(val, msg) {
|
|
3257
|
+
new Assertion(val, msg, assert.isNotCallable, true).is.not.callable;
|
|
3235
3258
|
};
|
|
3236
3259
|
assert.isObject = function(val, msg) {
|
|
3237
3260
|
new Assertion(val, msg, assert.isObject, true).to.be.a("object");
|
|
@@ -3672,7 +3695,7 @@ assert.isNotEmpty = function(val, msg) {
|
|
|
3672
3695
|
(/* @__PURE__ */ __name(function alias(name, as) {
|
|
3673
3696
|
assert[as] = assert[name];
|
|
3674
3697
|
return alias;
|
|
3675
|
-
}, "alias"))("isOk", "ok")("isNotOk", "notOk")("throws", "throw")("throws", "Throw")("isExtensible", "extensible")("isNotExtensible", "notExtensible")("isSealed", "sealed")("isNotSealed", "notSealed")("isFrozen", "frozen")("isNotFrozen", "notFrozen")("isEmpty", "empty")("isNotEmpty", "notEmpty");
|
|
3698
|
+
}, "alias"))("isOk", "ok")("isNotOk", "notOk")("throws", "throw")("throws", "Throw")("isExtensible", "extensible")("isNotExtensible", "notExtensible")("isSealed", "sealed")("isNotSealed", "notSealed")("isFrozen", "frozen")("isNotFrozen", "notFrozen")("isEmpty", "empty")("isNotEmpty", "notEmpty")("isCallable", "isFunction")("isNotCallable", "isNotFunction");
|
|
3676
3699
|
|
|
3677
3700
|
// lib/chai.js
|
|
3678
3701
|
var used = [];
|
|
@@ -3774,6 +3797,8 @@ export {
|
|
|
3774
3797
|
* from within another assertion. It's also temporarily set to `true` before
|
|
3775
3798
|
* an overwritten assertion gets called by the overwriting assertion.
|
|
3776
3799
|
*
|
|
3800
|
+
* - `eql`: This flag contains the deepEqual function to be used by the assertion.
|
|
3801
|
+
*
|
|
3777
3802
|
* @param {Mixed} obj target of the assertion
|
|
3778
3803
|
* @param {String} msg (optional) custom error message
|
|
3779
3804
|
* @param {Function} ssfi (optional) starting point for removing stack frames
|
package/lib/chai/assertion.js
CHANGED
|
@@ -54,7 +54,7 @@ export function Assertion (obj, msg, ssfi, lockSsfi) {
|
|
|
54
54
|
util.flag(this, 'lockSsfi', lockSsfi);
|
|
55
55
|
util.flag(this, 'object', obj);
|
|
56
56
|
util.flag(this, 'message', msg);
|
|
57
|
-
util.flag(this, 'eql', config.deepEqual
|
|
57
|
+
util.flag(this, 'eql', config.deepEqual || util.eql);
|
|
58
58
|
|
|
59
59
|
return util.proxify(this);
|
|
60
60
|
}
|
|
@@ -239,6 +239,13 @@ Assertion.addProperty('all', function () {
|
|
|
239
239
|
flag(this, 'any', false);
|
|
240
240
|
});
|
|
241
241
|
|
|
242
|
+
const functionTypes = {
|
|
243
|
+
'function': ['function', 'asyncfunction', 'generatorfunction', 'asyncgeneratorfunction'],
|
|
244
|
+
'asyncfunction': ['asyncfunction', 'asyncgeneratorfunction'],
|
|
245
|
+
'generatorfunction': ['generatorfunction', 'asyncgeneratorfunction'],
|
|
246
|
+
'asyncgeneratorfunction': ['asyncgeneratorfunction']
|
|
247
|
+
}
|
|
248
|
+
|
|
242
249
|
/**
|
|
243
250
|
* ### .a(type[, msg])
|
|
244
251
|
*
|
|
@@ -298,18 +305,27 @@ Assertion.addProperty('all', function () {
|
|
|
298
305
|
* @namespace BDD
|
|
299
306
|
* @api public
|
|
300
307
|
*/
|
|
301
|
-
|
|
302
308
|
function an (type, msg) {
|
|
303
309
|
if (msg) flag(this, 'message', msg);
|
|
304
310
|
type = type.toLowerCase();
|
|
305
311
|
var obj = flag(this, 'object')
|
|
306
312
|
, article = ~[ 'a', 'e', 'i', 'o', 'u' ].indexOf(type.charAt(0)) ? 'an ' : 'a ';
|
|
307
313
|
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
314
|
+
const detectedType = _.type(obj).toLowerCase();
|
|
315
|
+
|
|
316
|
+
if (functionTypes['function'].includes(type)) {
|
|
317
|
+
this.assert(
|
|
318
|
+
functionTypes[type].includes(detectedType)
|
|
319
|
+
, 'expected #{this} to be ' + article + type
|
|
320
|
+
, 'expected #{this} not to be ' + article + type
|
|
321
|
+
);
|
|
322
|
+
} else {
|
|
323
|
+
this.assert(
|
|
324
|
+
type === detectedType
|
|
325
|
+
, 'expected #{this} to be ' + article + type
|
|
326
|
+
, 'expected #{this} not to be ' + article + type
|
|
327
|
+
);
|
|
328
|
+
}
|
|
313
329
|
}
|
|
314
330
|
|
|
315
331
|
Assertion.addChainableMethod('an', an);
|
|
@@ -672,6 +688,43 @@ Assertion.addProperty('true', function () {
|
|
|
672
688
|
);
|
|
673
689
|
});
|
|
674
690
|
|
|
691
|
+
/**
|
|
692
|
+
* ### .callable
|
|
693
|
+
*
|
|
694
|
+
* Asserts that the target a callable function.
|
|
695
|
+
*
|
|
696
|
+
* expect(console.log).to.be.callable;
|
|
697
|
+
*
|
|
698
|
+
* A custom error message can be given as the second argument to `expect`.
|
|
699
|
+
*
|
|
700
|
+
* expect('not a function', 'nooo why fail??').to.be.callable;
|
|
701
|
+
*
|
|
702
|
+
* @name callable
|
|
703
|
+
* @namespace BDD
|
|
704
|
+
* @api public
|
|
705
|
+
*/
|
|
706
|
+
Assertion.addProperty('callable', function () {
|
|
707
|
+
const val = flag(this, 'object')
|
|
708
|
+
const ssfi = flag(this, 'ssfi')
|
|
709
|
+
const message = flag(this, 'message')
|
|
710
|
+
const msg = message ? `${message}: ` : ''
|
|
711
|
+
const negate = flag(this, 'negate');
|
|
712
|
+
|
|
713
|
+
const assertionMessage = negate ?
|
|
714
|
+
`${msg}expected ${_.inspect(val)} not to be a callable function` :
|
|
715
|
+
`${msg}expected ${_.inspect(val)} to be a callable function`;
|
|
716
|
+
|
|
717
|
+
const isCallable = ['Function', 'AsyncFunction', 'GeneratorFunction', 'AsyncGeneratorFunction'].includes(_.type(val));
|
|
718
|
+
|
|
719
|
+
if ((isCallable && negate) || (!isCallable && !negate)) {
|
|
720
|
+
throw new AssertionError(
|
|
721
|
+
assertionMessage,
|
|
722
|
+
undefined,
|
|
723
|
+
ssfi
|
|
724
|
+
);
|
|
725
|
+
}
|
|
726
|
+
});
|
|
727
|
+
|
|
675
728
|
/**
|
|
676
729
|
* ### .false
|
|
677
730
|
*
|
|
@@ -8,6 +8,7 @@ import * as chai from '../../../index.js';
|
|
|
8
8
|
import {Assertion} from '../assertion.js';
|
|
9
9
|
import {flag, inspect} from '../utils/index.js';
|
|
10
10
|
import {AssertionError} from 'assertion-error';
|
|
11
|
+
import {type} from '../utils/type-detect.js';
|
|
11
12
|
|
|
12
13
|
/**
|
|
13
14
|
* ### assert(expression, message)
|
|
@@ -553,41 +554,39 @@ assert.isDefined = function (val, msg) {
|
|
|
553
554
|
};
|
|
554
555
|
|
|
555
556
|
/**
|
|
556
|
-
* ### .
|
|
557
|
+
* ### .isCallable(value, [message])
|
|
557
558
|
*
|
|
558
|
-
* Asserts that `value` is a function.
|
|
559
|
+
* Asserts that `value` is a callable function.
|
|
559
560
|
*
|
|
560
561
|
* function serveTea() { return 'cup of tea'; };
|
|
561
|
-
* assert.
|
|
562
|
+
* assert.isCallable(serveTea, 'great, we can have tea now');
|
|
562
563
|
*
|
|
563
|
-
* @name
|
|
564
|
+
* @name isCallable
|
|
564
565
|
* @param {Mixed} value
|
|
565
566
|
* @param {String} message
|
|
566
567
|
* @namespace Assert
|
|
567
568
|
* @api public
|
|
568
569
|
*/
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
};
|
|
570
|
+
assert.isCallable = function (val, msg) {
|
|
571
|
+
new Assertion(val, msg, assert.isCallable, true).is.callable;
|
|
572
|
+
}
|
|
573
573
|
|
|
574
574
|
/**
|
|
575
|
-
* ### .
|
|
575
|
+
* ### .isNotCallable(value, [message])
|
|
576
576
|
*
|
|
577
|
-
* Asserts that `value` is _not_ a function.
|
|
577
|
+
* Asserts that `value` is _not_ a callable function.
|
|
578
578
|
*
|
|
579
579
|
* var serveTea = [ 'heat', 'pour', 'sip' ];
|
|
580
|
-
* assert.
|
|
580
|
+
* assert.isNotCallable(serveTea, 'great, we have listed the steps');
|
|
581
581
|
*
|
|
582
|
-
* @name
|
|
582
|
+
* @name isNotCallable
|
|
583
583
|
* @param {Mixed} value
|
|
584
584
|
* @param {String} message
|
|
585
585
|
* @namespace Assert
|
|
586
586
|
* @api public
|
|
587
587
|
*/
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
new Assertion(val, msg, assert.isNotFunction, true).to.not.be.a('function');
|
|
588
|
+
assert.isNotCallable = function (val, msg) {
|
|
589
|
+
new Assertion(val, msg, assert.isNotCallable, true).is.not.callable;
|
|
591
590
|
};
|
|
592
591
|
|
|
593
592
|
/**
|
|
@@ -3104,4 +3103,6 @@ assert.isNotEmpty = function(val, msg) {
|
|
|
3104
3103
|
('isFrozen', 'frozen')
|
|
3105
3104
|
('isNotFrozen', 'notFrozen')
|
|
3106
3105
|
('isEmpty', 'empty')
|
|
3107
|
-
('isNotEmpty', 'notEmpty')
|
|
3106
|
+
('isNotEmpty', 'notEmpty')
|
|
3107
|
+
('isCallable', 'isFunction')
|
|
3108
|
+
('isNotCallable', 'isNotFunction')
|
package/package.json
CHANGED
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
"Veselin Todorov <hi@vesln.com>",
|
|
19
19
|
"John Firebaugh <john.firebaugh@gmail.com>"
|
|
20
20
|
],
|
|
21
|
-
"version": "5.0.
|
|
21
|
+
"version": "5.0.3",
|
|
22
22
|
"repository": {
|
|
23
23
|
"type": "git",
|
|
24
24
|
"url": "https://github.com/chaijs/chai"
|
|
@@ -44,16 +44,15 @@
|
|
|
44
44
|
"assertion-error": "^2.0.1",
|
|
45
45
|
"check-error": "^2.0.0",
|
|
46
46
|
"deep-eql": "^5.0.1",
|
|
47
|
-
"loupe": "^3.
|
|
47
|
+
"loupe": "^3.1.0",
|
|
48
48
|
"pathval": "^2.0.0"
|
|
49
49
|
},
|
|
50
50
|
"devDependencies": {
|
|
51
51
|
"@rollup/plugin-commonjs": "^25.0.7",
|
|
52
|
-
"@web/dev-server-rollup": "^0.
|
|
53
|
-
"@web/test-runner": "^0.
|
|
54
|
-
"@web/test-runner-playwright": "^0.
|
|
55
|
-
"
|
|
56
|
-
"
|
|
57
|
-
"mocha": "^8.3.0"
|
|
52
|
+
"@web/dev-server-rollup": "^0.6.1",
|
|
53
|
+
"@web/test-runner": "^0.18.0",
|
|
54
|
+
"@web/test-runner-playwright": "^0.11.0",
|
|
55
|
+
"esbuild": "^0.19.10",
|
|
56
|
+
"mocha": "^10.2.0"
|
|
58
57
|
}
|
|
59
58
|
}
|
package/bower.json
DELETED
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "chai",
|
|
3
|
-
"description": "BDD/TDD assertion library for node.js and the browser. Test framework agnostic.",
|
|
4
|
-
"license": "MIT",
|
|
5
|
-
"keywords": [
|
|
6
|
-
"test",
|
|
7
|
-
"assertion",
|
|
8
|
-
"assert",
|
|
9
|
-
"testing",
|
|
10
|
-
"chai"
|
|
11
|
-
],
|
|
12
|
-
"main": "chai.js",
|
|
13
|
-
"ignore": [
|
|
14
|
-
"build",
|
|
15
|
-
"components",
|
|
16
|
-
"lib",
|
|
17
|
-
"node_modules",
|
|
18
|
-
"support",
|
|
19
|
-
"test",
|
|
20
|
-
"index.js",
|
|
21
|
-
"Makefile",
|
|
22
|
-
".*"
|
|
23
|
-
],
|
|
24
|
-
"dependencies": {},
|
|
25
|
-
"devDependencies": {}
|
|
26
|
-
}
|
package/karma.conf.cjs
DELETED
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
module.exports = function(config) {
|
|
2
|
-
config.set({
|
|
3
|
-
frameworks: [ 'mocha' ]
|
|
4
|
-
, files: [
|
|
5
|
-
{ pattern: 'chai.js', type: 'module', included: false, served: true }
|
|
6
|
-
, { pattern: 'test/bootstrap/index.js', type: 'module'}
|
|
7
|
-
, { pattern: 'test/*.js', type: 'module' }
|
|
8
|
-
, { pattern: 'test/type-detect/*.js', type: 'module' }
|
|
9
|
-
]
|
|
10
|
-
, reporters: [ 'progress' ]
|
|
11
|
-
, colors: true
|
|
12
|
-
, logLevel: config.LOG_INFO
|
|
13
|
-
, autoWatch: false
|
|
14
|
-
, browsers: [ 'HeadlessChrome' ]
|
|
15
|
-
, customLaunchers: {
|
|
16
|
-
HeadlessChrome: {
|
|
17
|
-
base: 'ChromeHeadless'
|
|
18
|
-
, flags: [ '--no-sandbox',]
|
|
19
|
-
, }
|
|
20
|
-
, }
|
|
21
|
-
, browserDisconnectTimeout: 10000
|
|
22
|
-
, browserDisconnectTolerance: 2
|
|
23
|
-
, browserNoActivityTimeout: 20000
|
|
24
|
-
, singleRun: true
|
|
25
|
-
});
|
|
26
|
-
|
|
27
|
-
switch (process.env.CHAI_TEST_ENV) {
|
|
28
|
-
case 'sauce':
|
|
29
|
-
require('./karma.sauce')(config);
|
|
30
|
-
break;
|
|
31
|
-
default:
|
|
32
|
-
// ...
|
|
33
|
-
break;
|
|
34
|
-
};
|
|
35
|
-
};
|
package/karma.sauce.js
DELETED
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
var version = require('./package.json').version;
|
|
2
|
-
var ts = new Date().getTime();
|
|
3
|
-
|
|
4
|
-
module.exports = function(config) {
|
|
5
|
-
var auth;
|
|
6
|
-
|
|
7
|
-
try {
|
|
8
|
-
auth = require('./test/auth/index');
|
|
9
|
-
} catch(ex) {
|
|
10
|
-
auth = {};
|
|
11
|
-
auth.SAUCE_USERNAME = process.env.SAUCE_USERNAME || null;
|
|
12
|
-
auth.SAUCE_ACCESS_KEY = process.env.SAUCE_ACCESS_KEY || null;
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
if (!auth.SAUCE_USERNAME || !auth.SAUCE_ACCESS_KEY) return;
|
|
16
|
-
if (process.env.SKIP_SAUCE) return;
|
|
17
|
-
|
|
18
|
-
var branch = process.env.TRAVIS_BRANCH || 'local'
|
|
19
|
-
var browserConfig = require('./sauce.browsers');
|
|
20
|
-
var browsers = Object.keys(browserConfig);
|
|
21
|
-
var tags = [ 'chaijs_' + version, auth.SAUCE_USERNAME + '@' + branch ];
|
|
22
|
-
var tunnel = process.env.TRAVIS_JOB_NUMBER || ts;
|
|
23
|
-
|
|
24
|
-
if (process.env.TRAVIS_JOB_NUMBER) {
|
|
25
|
-
tags.push('travis@' + process.env.TRAVIS_JOB_NUMBER);
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
config.browsers = config.browsers.concat(browsers);
|
|
29
|
-
Object.assign(config.customLaunchers, browserConfig);
|
|
30
|
-
config.reporters.push('saucelabs');
|
|
31
|
-
config.captureTimeout = 300000;
|
|
32
|
-
|
|
33
|
-
config.sauceLabs = {
|
|
34
|
-
username: auth.SAUCE_USERNAME
|
|
35
|
-
, accessKey: auth.SAUCE_ACCESS_KEY
|
|
36
|
-
, startConnect: ('TRAVIS' in process.env) === false
|
|
37
|
-
, tags: tags
|
|
38
|
-
, testName: 'ChaiJS'
|
|
39
|
-
, tunnelIdentifier: tunnel
|
|
40
|
-
};
|
|
41
|
-
};
|
package/sauce.browsers.js
DELETED
|
@@ -1,106 +0,0 @@
|
|
|
1
|
-
|
|
2
|
-
/*!
|
|
3
|
-
* Chrome
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
exports['SL_Chrome'] = {
|
|
7
|
-
base: 'SauceLabs'
|
|
8
|
-
, browserName: 'chrome'
|
|
9
|
-
};
|
|
10
|
-
|
|
11
|
-
/*!
|
|
12
|
-
* Firefox
|
|
13
|
-
*/
|
|
14
|
-
|
|
15
|
-
exports['SL_Firefox'] = {
|
|
16
|
-
base: 'SauceLabs'
|
|
17
|
-
, browserName: 'firefox'
|
|
18
|
-
};
|
|
19
|
-
|
|
20
|
-
exports['SL_Firefox_ESR'] = {
|
|
21
|
-
base: 'SauceLabs'
|
|
22
|
-
, browserName: 'firefox'
|
|
23
|
-
, version: 38
|
|
24
|
-
};
|
|
25
|
-
|
|
26
|
-
/*!
|
|
27
|
-
* Internet Explorer
|
|
28
|
-
*/
|
|
29
|
-
|
|
30
|
-
exports['SL_IE'] = {
|
|
31
|
-
base: 'SauceLabs'
|
|
32
|
-
, browserName: 'internet explorer'
|
|
33
|
-
};
|
|
34
|
-
|
|
35
|
-
/*!
|
|
36
|
-
* TODO: fails because of Uint8Array support
|
|
37
|
-
*
|
|
38
|
-
exports['SL_IE_Old'] = {
|
|
39
|
-
base: 'SauceLabs'
|
|
40
|
-
, browserName: 'internet explorer'
|
|
41
|
-
, version: 10
|
|
42
|
-
};
|
|
43
|
-
*/
|
|
44
|
-
|
|
45
|
-
exports['SL_Edge'] = {
|
|
46
|
-
base: 'SauceLabs'
|
|
47
|
-
, browserName: 'microsoftedge'
|
|
48
|
-
};
|
|
49
|
-
|
|
50
|
-
/*!
|
|
51
|
-
* Safari
|
|
52
|
-
*/
|
|
53
|
-
|
|
54
|
-
exports['SL_Safari'] = {
|
|
55
|
-
base: 'SauceLabs'
|
|
56
|
-
, browserName: 'safari'
|
|
57
|
-
, platform: 'Mac 10.11'
|
|
58
|
-
};
|
|
59
|
-
|
|
60
|
-
/*!
|
|
61
|
-
* iPhone
|
|
62
|
-
*/
|
|
63
|
-
|
|
64
|
-
/*!
|
|
65
|
-
* TODO: These take forever to boot or shut down. Causes timeout.
|
|
66
|
-
*
|
|
67
|
-
|
|
68
|
-
exports['SL_iPhone_6'] = {
|
|
69
|
-
base: 'SauceLabs'
|
|
70
|
-
, browserName: 'iphone'
|
|
71
|
-
, platform: 'Mac 10.8'
|
|
72
|
-
, version: '6'
|
|
73
|
-
};
|
|
74
|
-
|
|
75
|
-
exports['SL_iPhone_5-1'] = {
|
|
76
|
-
base: 'SauceLabs'
|
|
77
|
-
, browserName: 'iphone'
|
|
78
|
-
, platform: 'Mac 10.8'
|
|
79
|
-
, version: '5.1'
|
|
80
|
-
};
|
|
81
|
-
|
|
82
|
-
exports['SL_iPhone_5'] = {
|
|
83
|
-
base: 'SauceLabs'
|
|
84
|
-
, browserName: 'iphone'
|
|
85
|
-
, platform: 'Mac 10.6'
|
|
86
|
-
, version: '5'
|
|
87
|
-
};
|
|
88
|
-
|
|
89
|
-
*/
|
|
90
|
-
|
|
91
|
-
/*!
|
|
92
|
-
* Android
|
|
93
|
-
*/
|
|
94
|
-
|
|
95
|
-
/*!
|
|
96
|
-
* TODO: fails because of error serialization
|
|
97
|
-
*
|
|
98
|
-
|
|
99
|
-
exports['SL_Android_4'] = {
|
|
100
|
-
base: 'SauceLabs'
|
|
101
|
-
, browserName: 'android'
|
|
102
|
-
, platform: 'Linux'
|
|
103
|
-
, version: '4'
|
|
104
|
-
};
|
|
105
|
-
|
|
106
|
-
*/
|