diff --git a/package-lock.json b/package-lock.json index f575ae788e..4e36f869ae 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1830,6 +1830,51 @@ "dev": true, "optional": true }, + "@sinonjs/commons": { + "version": "1.7.1", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.7.1.tgz", + "integrity": "sha512-Debi3Baff1Qu1Unc3mjJ96MgpbwTn43S1+9yJ0llWygPwDNu2aaWBD6yc9y/Z8XDRNhx7U+u2UDg2OGQXkclUQ==", + "dev": true, + "requires": { + "type-detect": "4.0.8" + } + }, + "@sinonjs/fake-timers": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-6.0.0.tgz", + "integrity": "sha512-atR1J/jRXvQAb47gfzSK8zavXy7BcpnYq21ALon0U99etu99vsir0trzIO3wpeLtW+LLVY6X7EkfVTbjGSH8Ww==", + "dev": true, + "requires": { + "@sinonjs/commons": "^1.7.0" + } + }, + "@sinonjs/formatio": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/@sinonjs/formatio/-/formatio-5.0.1.tgz", + "integrity": "sha512-KaiQ5pBf1MpS09MuA0kp6KBQt2JUOQycqVG1NZXvzeaXe5LGFqAKueIS0bw4w0P9r7KuBSVdUk5QjXsUdu2CxQ==", + "dev": true, + "requires": { + "@sinonjs/commons": "^1", + "@sinonjs/samsam": "^5.0.2" + } + }, + "@sinonjs/samsam": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/@sinonjs/samsam/-/samsam-5.0.3.tgz", + "integrity": "sha512-QucHkc2uMJ0pFGjJUDP3F9dq5dx8QIaqISl9QgwLOh6P9yv877uONPGXh/OH/0zmM3tW1JjuJltAZV2l7zU+uQ==", + "dev": true, + "requires": { + "@sinonjs/commons": "^1.6.0", + "lodash.get": "^4.4.2", + "type-detect": "^4.0.8" + } + }, + "@sinonjs/text-encoding": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/@sinonjs/text-encoding/-/text-encoding-0.7.1.tgz", + "integrity": "sha512-+iTbntw2IZPb/anVDbypzfQa+ay64MW0Zo8aJ8gZPWMMK6/OubMVb6lUPMagqjOPnmtauXnFCACVl3O7ogjeqQ==", + "dev": true + }, "@tannin/compile": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@tannin/compile/-/compile-1.1.0.tgz", @@ -4589,7 +4634,6 @@ "resolved": "https://registry.npmjs.org/p-timeout/-/p-timeout-2.0.1.tgz", "integrity": "sha512-88em58dDVB/KzPEx1X0N3LwFfYZPyDc4B6eF38M1rk9VTZMbxXXgjugz8mmwpS9Ox4BDZ+t6t3QP5+/gazweIA==", "dev": true, - "optional": true, "requires": { "p-finally": "^1.0.0" } @@ -4634,7 +4678,6 @@ "resolved": "http://registry.npmjs.org/bl/-/bl-1.2.2.tgz", "integrity": "sha512-e8tQYnZodmebYDWGH7KMRvtzKXaJHx3BbilrgZCfvyLUYdKpK1t5PSPmpkny/SgiTSCnjfLW7v5rlONXVFkQEA==", "dev": true, - "optional": true, "requires": { "readable-stream": "^2.3.5", "safe-buffer": "^5.1.1" @@ -4927,7 +4970,6 @@ "resolved": "https://registry.npmjs.org/buffer-alloc/-/buffer-alloc-1.2.0.tgz", "integrity": "sha512-CFsHQgjtW1UChdXgbyJGtnm+O/uLQeZdtbDo8mfUgYXCHSM1wgrVxXm6bSyrUuErEb+4sYVGCzASBRot7zyrow==", "dev": true, - "optional": true, "requires": { "buffer-alloc-unsafe": "^1.1.0", "buffer-fill": "^1.0.0" @@ -4937,22 +4979,19 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/buffer-alloc-unsafe/-/buffer-alloc-unsafe-1.1.0.tgz", "integrity": "sha512-TEM2iMIEQdJ2yjPJoSIsldnleVaAk1oW3DBVUykyOLsEsFmEc9kn+SFFPz+gl54KQNxlDnAwCXosOS9Okx2xAg==", - "dev": true, - "optional": true + "dev": true }, "buffer-crc32": { "version": "0.2.13", "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", "integrity": "sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI=", - "dev": true, - "optional": true + "dev": true }, "buffer-fill": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/buffer-fill/-/buffer-fill-1.0.0.tgz", "integrity": "sha1-+PeLdniYiO858gXNY39o5wISKyw=", - "dev": true, - "optional": true + "dev": true }, "buffer-from": { "version": "1.1.1", @@ -5212,7 +5251,6 @@ "resolved": "https://registry.npmjs.org/caw/-/caw-2.0.1.tgz", "integrity": "sha512-Cg8/ZSBEa8ZVY9HspcGUYaK63d/bN7rqS3CYCzEGUxuYv6UlmcjzDUz2fCFFHyTvUW5Pk0I+3hkA3iXlIj6guA==", "dev": true, - "optional": true, "requires": { "get-proxy": "^2.0.0", "isurl": "^1.0.0-alpha5", @@ -5347,9 +5385,9 @@ } }, "minimist": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", - "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", + "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", "dev": true }, "supports-color": { @@ -5787,7 +5825,6 @@ "resolved": "https://registry.npmjs.org/config-chain/-/config-chain-1.1.12.tgz", "integrity": "sha512-a1eOIcu8+7lUInge4Rpf/n4Krkf3Dd9lqhljRzII1/Zno/kRtUWnznPO3jOKBmTEktkt3fkxisUcivoj0ebzoA==", "dev": true, - "optional": true, "requires": { "ini": "^1.3.4", "proto-list": "~1.2.1" @@ -6478,9 +6515,9 @@ } }, "minimist": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", - "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", + "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", "dev": true }, "redent": { @@ -6553,7 +6590,6 @@ "resolved": "https://registry.npmjs.org/decompress/-/decompress-4.2.0.tgz", "integrity": "sha1-eu3YVCflqS2s/lVnSnxQXpbQH50=", "dev": true, - "optional": true, "requires": { "decompress-tar": "^4.0.0", "decompress-tarbz2": "^4.0.0", @@ -6570,7 +6606,6 @@ "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-1.3.0.tgz", "integrity": "sha512-2w31R7SJtieJJnQtGc7RVL2StM2vGYVfqUOvUDxH6bC6aJTxPxTF0GnIgCyu7tjockiUWAYQRbxa7vKn34s5sQ==", "dev": true, - "optional": true, "requires": { "pify": "^3.0.0" }, @@ -6579,8 +6614,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", - "dev": true, - "optional": true + "dev": true } } }, @@ -6588,8 +6622,7 @@ "version": "2.3.0", "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", - "dev": true, - "optional": true + "dev": true } } }, @@ -6598,7 +6631,6 @@ "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-3.3.0.tgz", "integrity": "sha1-gKTdMjdIOEv6JICDYirt7Jgq3/M=", "dev": true, - "optional": true, "requires": { "mimic-response": "^1.0.0" } @@ -6608,7 +6640,6 @@ "resolved": "https://registry.npmjs.org/decompress-tar/-/decompress-tar-4.1.1.tgz", "integrity": "sha512-JdJMaCrGpB5fESVyxwpCx4Jdj2AagLmv3y58Qy4GE6HMVjWz1FeVQk1Ct4Kye7PftcdOo/7U7UKzYBJgqnGeUQ==", "dev": true, - "optional": true, "requires": { "file-type": "^5.2.0", "is-stream": "^1.1.0", @@ -6619,8 +6650,7 @@ "version": "5.2.0", "resolved": "https://registry.npmjs.org/file-type/-/file-type-5.2.0.tgz", "integrity": "sha1-LdvqfHP/42No365J3DOMBYwritY=", - "dev": true, - "optional": true + "dev": true } } }, @@ -6629,7 +6659,6 @@ "resolved": "https://registry.npmjs.org/decompress-tarbz2/-/decompress-tarbz2-4.1.1.tgz", "integrity": "sha512-s88xLzf1r81ICXLAVQVzaN6ZmX4A6U4z2nMbOwobxkLoIIfjVMBg7TeguTUXkKeXni795B6y5rnvDw7rxhAq9A==", "dev": true, - "optional": true, "requires": { "decompress-tar": "^4.1.0", "file-type": "^6.1.0", @@ -6642,8 +6671,7 @@ "version": "6.2.0", "resolved": "https://registry.npmjs.org/file-type/-/file-type-6.2.0.tgz", "integrity": "sha512-YPcTBDV+2Tm0VqjybVd32MHdlEGAtuxS3VAYsumFokDSMG+ROT5wawGlnHDoz7bfMcMDt9hxuXvXwoKUx2fkOg==", - "dev": true, - "optional": true + "dev": true } } }, @@ -6652,7 +6680,6 @@ "resolved": "https://registry.npmjs.org/decompress-targz/-/decompress-targz-4.1.1.tgz", "integrity": "sha512-4z81Znfr6chWnRDNfFNqLwPvm4db3WuZkqV+UgXQzSngG3CEKdBkw5jrv3axjjL96glyiiKjsxJG3X6WBZwX3w==", "dev": true, - "optional": true, "requires": { "decompress-tar": "^4.1.1", "file-type": "^5.2.0", @@ -6663,8 +6690,7 @@ "version": "5.2.0", "resolved": "https://registry.npmjs.org/file-type/-/file-type-5.2.0.tgz", "integrity": "sha1-LdvqfHP/42No365J3DOMBYwritY=", - "dev": true, - "optional": true + "dev": true } } }, @@ -6673,7 +6699,6 @@ "resolved": "https://registry.npmjs.org/decompress-unzip/-/decompress-unzip-4.0.1.tgz", "integrity": "sha1-3qrM39FK6vhVePczroIQ+bSEj2k=", "dev": true, - "optional": true, "requires": { "file-type": "^3.8.0", "get-stream": "^2.2.0", @@ -6686,7 +6711,6 @@ "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz", "integrity": "sha1-JcfInLH5B3+IkbvmHY85Dq4lbx4=", "dev": true, - "optional": true, "requires": { "pend": "~1.2.0" } @@ -6695,15 +6719,13 @@ "version": "3.9.0", "resolved": "https://registry.npmjs.org/file-type/-/file-type-3.9.0.tgz", "integrity": "sha1-JXoHg4TR24CHvESdEH1SpSZyuek=", - "dev": true, - "optional": true + "dev": true }, "get-stream": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-2.3.1.tgz", "integrity": "sha1-Xzj5PzRgCWZu4BUKBUFn+Rvdld4=", "dev": true, - "optional": true, "requires": { "object-assign": "^4.0.1", "pinkie-promise": "^2.0.0" @@ -6713,15 +6735,13 @@ "version": "2.3.0", "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", - "dev": true, - "optional": true + "dev": true }, "yauzl": { "version": "2.10.0", "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz", "integrity": "sha1-x+sXyT4RLLEIb6bY5R+wZnt5pfk=", "dev": true, - "optional": true, "requires": { "buffer-crc32": "~0.2.3", "fd-slicer": "~1.1.0" @@ -6900,9 +6920,9 @@ } }, "kind-of": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", - "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", "dev": true } } @@ -7227,8 +7247,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", - "dev": true, - "optional": true + "dev": true } } }, @@ -7260,8 +7279,7 @@ "version": "0.1.4", "resolved": "https://registry.npmjs.org/duplexer3/-/duplexer3-0.1.4.tgz", "integrity": "sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI=", - "dev": true, - "optional": true + "dev": true }, "duplexify": { "version": "3.7.1", @@ -8252,7 +8270,6 @@ "resolved": "https://registry.npmjs.org/execa/-/execa-0.7.0.tgz", "integrity": "sha1-lEvs00zEHuMqY6n68nrVpl/Fl3c=", "dev": true, - "optional": true, "requires": { "cross-spawn": "^5.0.1", "get-stream": "^3.0.0", @@ -8415,7 +8432,6 @@ "resolved": "https://registry.npmjs.org/ext-list/-/ext-list-2.2.2.tgz", "integrity": "sha512-u+SQgsubraE6zItfVA0tBuCBhfU9ogSRnsvygI7wht9TS510oLkBRXBsqopeUG/GBOIQyKZO9wjTqIu/sf5zFA==", "dev": true, - "optional": true, "requires": { "mime-db": "^1.28.0" } @@ -8425,7 +8441,6 @@ "resolved": "https://registry.npmjs.org/ext-name/-/ext-name-5.0.0.tgz", "integrity": "sha512-yblEwXAbGv1VQDmow7s38W77hzAgJAO50ztBLMcUyUBfxv1HC+LGwtiEN+Co6LtlqT/5uwVOxsD4TNIilWhwdQ==", "dev": true, - "optional": true, "requires": { "ext-list": "^2.0.0", "sort-keys-length": "^1.0.0" @@ -8696,15 +8711,13 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/filename-reserved-regex/-/filename-reserved-regex-2.0.0.tgz", "integrity": "sha1-q/c9+rc10EVECr/qLZHzieu/oik=", - "dev": true, - "optional": true + "dev": true }, "filenamify": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/filenamify/-/filenamify-2.1.0.tgz", "integrity": "sha512-ICw7NTT6RsDp2rnYKVd8Fu4cr6ITzGy3+u4vUujPkabyaz+03F24NWEX7fs5fp+kBonlaqPH8fAO2NM+SXt/JA==", "dev": true, - "optional": true, "requires": { "filename-reserved-regex": "^2.0.0", "strip-outer": "^1.0.0", @@ -9097,8 +9110,7 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==", - "dev": true, - "optional": true + "dev": true }, "fs-exists-sync": { "version": "0.1.0", @@ -9154,8 +9166,7 @@ "ansi-regex": { "version": "2.1.1", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "aproba": { "version": "1.2.0", @@ -9176,14 +9187,12 @@ "balanced-match": { "version": "1.0.0", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "brace-expansion": { "version": "1.1.11", "bundled": true, "dev": true, - "optional": true, "requires": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -9198,20 +9207,17 @@ "code-point-at": { "version": "1.1.0", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "concat-map": { "version": "0.0.1", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "console-control-strings": { "version": "1.1.0", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "core-util-is": { "version": "1.0.2", @@ -9328,8 +9334,7 @@ "inherits": { "version": "2.0.3", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "ini": { "version": "1.3.5", @@ -9341,7 +9346,6 @@ "version": "1.0.0", "bundled": true, "dev": true, - "optional": true, "requires": { "number-is-nan": "^1.0.0" } @@ -9356,7 +9360,6 @@ "version": "3.0.4", "bundled": true, "dev": true, - "optional": true, "requires": { "brace-expansion": "^1.1.7" } @@ -9364,14 +9367,12 @@ "minimist": { "version": "0.0.8", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "minipass": { "version": "2.3.5", "bundled": true, "dev": true, - "optional": true, "requires": { "safe-buffer": "^5.1.2", "yallist": "^3.0.0" @@ -9390,7 +9391,6 @@ "version": "0.5.1", "bundled": true, "dev": true, - "optional": true, "requires": { "minimist": "0.0.8" } @@ -9471,8 +9471,7 @@ "number-is-nan": { "version": "1.0.1", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "object-assign": { "version": "4.1.1", @@ -9484,7 +9483,6 @@ "version": "1.4.0", "bundled": true, "dev": true, - "optional": true, "requires": { "wrappy": "1" } @@ -9570,8 +9568,7 @@ "safe-buffer": { "version": "5.1.2", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "safer-buffer": { "version": "2.1.2", @@ -9607,7 +9604,6 @@ "version": "1.0.2", "bundled": true, "dev": true, - "optional": true, "requires": { "code-point-at": "^1.0.0", "is-fullwidth-code-point": "^1.0.0", @@ -9627,7 +9623,6 @@ "version": "3.0.1", "bundled": true, "dev": true, - "optional": true, "requires": { "ansi-regex": "^2.0.0" } @@ -9671,14 +9666,12 @@ "wrappy": { "version": "1.0.2", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "yallist": { "version": "3.0.3", "bundled": true, - "dev": true, - "optional": true + "dev": true } } }, @@ -9847,7 +9840,6 @@ "resolved": "https://registry.npmjs.org/get-proxy/-/get-proxy-2.1.0.tgz", "integrity": "sha512-zmZIaQTWnNQb4R4fJUEp/FC51eZsc6EkErspy3xtIYStaq8EB/hDIWipxsal+E8rz0qD7f2sL/NA9Xee4RInJw==", "dev": true, - "optional": true, "requires": { "npm-conf": "^1.1.0" } @@ -9870,8 +9862,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz", "integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ=", - "dev": true, - "optional": true + "dev": true }, "get-value": { "version": "2.0.6", @@ -10256,8 +10247,7 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/graceful-readlink/-/graceful-readlink-1.0.1.tgz", "integrity": "sha1-TK+tdrxi8C+gObL5Tpo906ORpyU=", - "dev": true, - "optional": true + "dev": true }, "gradient-parser": { "version": "0.1.5", @@ -11008,8 +10998,7 @@ "version": "1.4.2", "resolved": "https://registry.npmjs.org/has-symbol-support-x/-/has-symbol-support-x-1.4.2.tgz", "integrity": "sha512-3ToOva++HaW+eCpgqZrCfN51IPB+7bJNVT6CUATzueB5Heb8o6Nam0V3HG5dlDvZU1Gn5QLcbahiKw/XVk5JJw==", - "dev": true, - "optional": true + "dev": true }, "has-symbols": { "version": "1.0.0", @@ -11021,7 +11010,6 @@ "resolved": "https://registry.npmjs.org/has-to-string-tag-x/-/has-to-string-tag-x-1.4.1.tgz", "integrity": "sha512-vdbKfmw+3LoOYVr+mtxHaX5a96+0f3DljYd8JOqvOLsf5mw2Otda2qCDT9qRqLAhrjyQ0h7ual5nOiASpsGNFw==", "dev": true, - "optional": true, "requires": { "has-symbol-support-x": "^1.4.1" } @@ -12147,8 +12135,7 @@ "version": "4.0.1", "resolved": "https://registry.npmjs.org/is-natural-number/-/is-natural-number-4.0.1.tgz", "integrity": "sha1-q5124dtM7VHjXeDHLr7PCfc0zeg=", - "dev": true, - "optional": true + "dev": true }, "is-number": { "version": "3.0.0", @@ -12175,8 +12162,7 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/is-object/-/is-object-1.0.1.tgz", "integrity": "sha1-iVJojF7C/9awPsyF52ngKQMINHA=", - "dev": true, - "optional": true + "dev": true }, "is-path-cwd": { "version": "2.2.0", @@ -12253,8 +12239,7 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/is-retry-allowed/-/is-retry-allowed-1.2.0.tgz", "integrity": "sha512-RUbUeKwvm3XG2VYamhJL1xFktgjvPzL0Hq8C+6yrWIswDy3BIXGqCxhxkc30N9jqK311gVU137K8Ei55/zVJRg==", - "dev": true, - "optional": true + "dev": true }, "is-stream": { "version": "1.1.0", @@ -12485,7 +12470,6 @@ "resolved": "https://registry.npmjs.org/isurl/-/isurl-1.0.0.tgz", "integrity": "sha512-1P/yWsxPlDtn7QeRD+ULKQPaIaN6yF368GZ2vDfv0AL0NwpStafjWCDDdn0k8wgFMWpVAqG7oJhxHnlud42i9w==", "dev": true, - "optional": true, "requires": { "has-to-string-tag-x": "^1.2.0", "is-object": "^1.0.1" @@ -13797,6 +13781,12 @@ "resolved": "https://registry.npmjs.org/js-polyfills/-/js-polyfills-0.1.42.tgz", "integrity": "sha1-XUhJArNh489gH9I60PMLr8yT8Ug=" }, + "js-reporters": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/js-reporters/-/js-reporters-1.2.1.tgz", + "integrity": "sha1-+IxgjjJKM3OpW8xFrTBeXJecRZs=", + "dev": true + }, "js-tokens": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", @@ -14101,6 +14091,12 @@ "object.assign": "^4.1.0" } }, + "just-extend": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/just-extend/-/just-extend-4.1.0.tgz", + "integrity": "sha512-ApcjaOdVTJ7y4r08xI5wIqpvwS48Q0PBG4DJROcEkH1f8MdAiNFyFxz3xoL0LWAVwjrwPYZdVHHxhRHcx/uGLA==", + "dev": true + }, "kew": { "version": "0.7.0", "resolved": "https://registry.npmjs.org/kew/-/kew-0.7.0.tgz", @@ -14280,9 +14276,9 @@ } }, "minimist": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", - "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", + "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", "dev": true } } @@ -14325,6 +14321,12 @@ "integrity": "sha1-+wMJF/hqMTTlvJvsDWngAT3f7bI=", "dev": true }, + "lodash.get": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz", + "integrity": "sha1-LRd/ZS+jHpObRDjVNBSZ36OCXpk=", + "dev": true + }, "lodash.isequal": { "version": "4.5.0", "resolved": "https://registry.npmjs.org/lodash.isequal/-/lodash.isequal-4.5.0.tgz", @@ -14476,8 +14478,7 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.1.tgz", "integrity": "sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA==", - "dev": true, - "optional": true + "dev": true }, "lpad-align": { "version": "1.1.2", @@ -14514,15 +14515,13 @@ "version": "4.0.1", "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-4.0.1.tgz", "integrity": "sha1-uWjGsKBDhDJJAui/Gl3zJXmkUP4=", - "dev": true, - "optional": true + "dev": true }, "indent-string": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-2.1.0.tgz", "integrity": "sha1-ji1INIdCEhtKghi3oTfppSBJ3IA=", "dev": true, - "optional": true, "requires": { "repeating": "^2.0.0" } @@ -14531,8 +14530,7 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz", "integrity": "sha1-2TPOuSBdgr3PSIb2dCvcK03qFG0=", - "dev": true, - "optional": true + "dev": true }, "meow": { "version": "3.7.0", @@ -14554,9 +14552,9 @@ } }, "minimist": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", - "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", + "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", "dev": true, "optional": true }, @@ -14995,9 +14993,9 @@ }, "dependencies": { "kind-of": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", - "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", "dev": true } } @@ -15043,8 +15041,7 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz", "integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==", - "dev": true, - "optional": true + "dev": true }, "min-indent": { "version": "1.0.0", @@ -15263,9 +15260,9 @@ }, "dependencies": { "kind-of": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", - "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", "dev": true } } @@ -15318,6 +15315,36 @@ "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", "dev": true }, + "nise": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/nise/-/nise-4.0.3.tgz", + "integrity": "sha512-EGlhjm7/4KvmmE6B/UFsKh7eHykRl9VH+au8dduHLCyWUO/hr7+N+WtTvDUwc9zHuM1IaIJs/0lQ6Ag1jDkQSg==", + "dev": true, + "requires": { + "@sinonjs/commons": "^1.7.0", + "@sinonjs/fake-timers": "^6.0.0", + "@sinonjs/text-encoding": "^0.7.1", + "just-extend": "^4.0.2", + "path-to-regexp": "^1.7.0" + }, + "dependencies": { + "isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", + "dev": true + }, + "path-to-regexp": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.8.0.tgz", + "integrity": "sha512-n43JRhlUKUAlibEJhPeir1ncUID16QnEjNpwzNdO3Lm4ywrBpBZ5oLD0I6br9evr1Y9JTqwRtAh7JLoOzAQdVA==", + "dev": true, + "requires": { + "isarray": "0.0.1" + } + } + } + }, "node-fetch": { "version": "1.7.3", "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-1.7.3.tgz", @@ -15517,9 +15544,9 @@ } }, "minimist": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", - "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", + "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", "dev": true }, "redent": { @@ -15549,6 +15576,12 @@ } } }, + "node-watch": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/node-watch/-/node-watch-0.6.1.tgz", + "integrity": "sha512-gwQiR7weFRV8mAtT0x0kXkZ18dfRLB45xH7q0hCOVQMLfLb2f1ZaSvR57q4/b/Vj6B0RwMNJYbvb69e1yM7qEA==", + "dev": true + }, "nopt": { "version": "3.0.6", "resolved": "https://registry.npmjs.org/nopt/-/nopt-3.0.6.tgz", @@ -15599,7 +15632,6 @@ "resolved": "https://registry.npmjs.org/npm-conf/-/npm-conf-1.1.3.tgz", "integrity": "sha512-Yic4bZHJOt9RCFbRP3GgpqhScOY4HH3V2P8yBj6CeYq118Qr+BLXqT2JvpJ00mryLESpgOxf5XlFv4ZjXxLScw==", "dev": true, - "optional": true, "requires": { "config-chain": "^1.1.11", "pify": "^3.0.0" @@ -15609,8 +15641,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", - "dev": true, - "optional": true + "dev": true } } }, @@ -16346,7 +16377,6 @@ "resolved": "https://registry.npmjs.org/p-timeout/-/p-timeout-1.2.1.tgz", "integrity": "sha1-XrOzU7f86Z8QGhA4iAuwVOu+o4Y=", "dev": true, - "optional": true, "requires": { "p-finally": "^1.0.0" } @@ -17518,8 +17548,7 @@ "version": "1.2.4", "resolved": "https://registry.npmjs.org/proto-list/-/proto-list-1.2.4.tgz", "integrity": "sha1-IS1b/hMYMGpCD2QCuOJv85ZHqEk=", - "dev": true, - "optional": true + "dev": true }, "proxy-addr": { "version": "2.0.5", @@ -17712,6 +17741,36 @@ "integrity": "sha512-ARhCpm70fzdcvNQfPoy49IaanKkTlRWF2JMzqhcJbhSFRZv7nPTvZJdcY7301IPmvW+/p0RgIWnQDLJxifsQ7g==", "dev": true }, + "qunit": { + "version": "2.9.3", + "resolved": "https://registry.npmjs.org/qunit/-/qunit-2.9.3.tgz", + "integrity": "sha512-RH4VYSaVsNRDthMFFboTJAJ8q4kJM5LvOqWponKUYPEAeOcmc/YFV1QsZ7ikknA3TjqliWFJYEV63vvVXaALmQ==", + "dev": true, + "requires": { + "commander": "2.12.2", + "js-reporters": "1.2.1", + "minimatch": "3.0.4", + "node-watch": "0.6.1", + "resolve": "1.9.0" + }, + "dependencies": { + "commander": { + "version": "2.12.2", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.12.2.tgz", + "integrity": "sha512-BFnaq5ZOGcDN7FlrtBT4xxkgIToalIIxwjxLWVJ8bGTpe1LroqMiqQXdA7ygc7CRvaYS+9zfPGFnJqFSayx+AA==", + "dev": true + }, + "resolve": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.9.0.tgz", + "integrity": "sha512-TZNye00tI67lwYvzxCxHGjwTNlUV70io54/Ed4j6PscB8xVfuBJpRenI/o6dVk0cY0PYTY27AgCoGGxRnYuItQ==", + "dev": true, + "requires": { + "path-parse": "^1.0.6" + } + } + } + }, "raf": { "version": "3.4.1", "resolved": "https://registry.npmjs.org/raf/-/raf-3.4.1.tgz", @@ -19004,7 +19063,6 @@ "resolved": "https://registry.npmjs.org/seek-bzip/-/seek-bzip-1.0.5.tgz", "integrity": "sha1-z+kXyz0nS8/6x5J1ivUxc+sfq9w=", "dev": true, - "optional": true, "requires": { "commander": "~2.8.1" }, @@ -19014,7 +19072,6 @@ "resolved": "https://registry.npmjs.org/commander/-/commander-2.8.1.tgz", "integrity": "sha1-Br42f+v9oMMwqh4qBy09yXYkJdQ=", "dev": true, - "optional": true, "requires": { "graceful-readlink": ">= 1.0.0" } @@ -19362,6 +19419,50 @@ } } }, + "sinon": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/sinon/-/sinon-9.0.1.tgz", + "integrity": "sha512-iTTyiQo5T94jrOx7X7QLBZyucUJ2WvL9J13+96HMfm2CGoJYbIPqRfl6wgNcqmzk0DI28jeGx5bUTXizkrqBmg==", + "dev": true, + "requires": { + "@sinonjs/commons": "^1.7.0", + "@sinonjs/fake-timers": "^6.0.0", + "@sinonjs/formatio": "^5.0.1", + "@sinonjs/samsam": "^5.0.3", + "diff": "^4.0.2", + "nise": "^4.0.1", + "supports-color": "^7.1.0" + }, + "dependencies": { + "diff": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", + "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", + "dev": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "supports-color": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz", + "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "sinon-test": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/sinon-test/-/sinon-test-3.0.0.tgz", + "integrity": "sha512-k2V042JwIS6SC3M8Ih3Uo6+6mlL5FKqvvobxoWQobFkACr61WpyAMKsfqXecLL+DrDD3s9T+eYSZdVQzMH1pkA==", + "dev": true + }, "sisteransi": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", @@ -19558,7 +19659,6 @@ "resolved": "https://registry.npmjs.org/sort-keys/-/sort-keys-1.1.2.tgz", "integrity": "sha1-RBttTTRnmPG05J6JIK37oOVD+a0=", "dev": true, - "optional": true, "requires": { "is-plain-obj": "^1.0.0" } @@ -19568,7 +19668,6 @@ "resolved": "https://registry.npmjs.org/sort-keys-length/-/sort-keys-length-1.0.1.tgz", "integrity": "sha1-nLb09OnkgVWmqgZx7dM2/xR5oYg=", "dev": true, - "optional": true, "requires": { "sort-keys": "^1.0.0" } @@ -20194,7 +20293,6 @@ "resolved": "https://registry.npmjs.org/strip-dirs/-/strip-dirs-2.1.0.tgz", "integrity": "sha512-JOCxOeKLm2CAS73y/U4ZeZPTkE+gNVCzKt7Eox84Iej1LT/2pTWYpZKJuxwQpvX1LiZb1xokNR7RLfuBAa7T3g==", "dev": true, - "optional": true, "requires": { "is-natural-number": "^4.0.1" } @@ -20225,7 +20323,6 @@ "resolved": "https://registry.npmjs.org/strip-outer/-/strip-outer-1.0.1.tgz", "integrity": "sha512-k55yxKHwaXnpYGsOzg4Vl8+tDrWylxDEpknGjhTiZB8dFRU5rTo9CAzeycivxV3s+zlTKwrs6WxMxR95n26kwg==", "dev": true, - "optional": true, "requires": { "escape-string-regexp": "^1.0.2" } @@ -20865,7 +20962,6 @@ "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-1.6.2.tgz", "integrity": "sha512-rzS0heiNf8Xn7/mpdSVVSMAWAoy9bfb1WOTYC78Z0UQKeKa/CWS8FOq0lKGNa8DWKAn9gxjCvMLYc5PGXYlK2A==", "dev": true, - "optional": true, "requires": { "bl": "^1.0.0", "buffer-alloc": "^1.2.0", @@ -20880,15 +20976,13 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/temp-dir/-/temp-dir-1.0.0.tgz", "integrity": "sha1-CnwOom06Oa+n4OvqnB/AvE2qAR0=", - "dev": true, - "optional": true + "dev": true }, "tempfile": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/tempfile/-/tempfile-2.0.0.tgz", "integrity": "sha1-awRGhWqbERTRhW/8vlCczLCXcmU=", "dev": true, - "optional": true, "requires": { "temp-dir": "^1.0.0", "uuid": "^3.0.1" @@ -21048,8 +21142,7 @@ "version": "4.0.1", "resolved": "https://registry.npmjs.org/timed-out/-/timed-out-4.0.1.tgz", "integrity": "sha1-8y6srFoXW+ol1/q1Zas+2HQe9W8=", - "dev": true, - "optional": true + "dev": true }, "timers-browserify": { "version": "2.0.10", @@ -21132,8 +21225,7 @@ "version": "1.1.1", "resolved": "https://registry.npmjs.org/to-buffer/-/to-buffer-1.1.1.tgz", "integrity": "sha512-lx9B5iv7msuFYE3dytT+KE5tap+rNYw+K4jVkb9R/asAb+pbBSM17jtunHplhBe6RRJdZx3Pn2Jph24O32mOVg==", - "dev": true, - "optional": true + "dev": true }, "to-fast-properties": { "version": "2.0.0", @@ -21265,7 +21357,6 @@ "resolved": "https://registry.npmjs.org/trim-repeated/-/trim-repeated-1.0.0.tgz", "integrity": "sha1-42RqLqTokTEr9+rObPsFOAvAHCE=", "dev": true, - "optional": true, "requires": { "escape-string-regexp": "^1.0.2" } @@ -21390,6 +21481,12 @@ "prelude-ls": "~1.1.2" } }, + "type-detect": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", + "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", + "dev": true + }, "type-fest": { "version": "0.8.1", "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", @@ -21487,7 +21584,6 @@ "resolved": "https://registry.npmjs.org/unbzip2-stream/-/unbzip2-stream-1.3.3.tgz", "integrity": "sha512-fUlAF7U9Ah1Q6EieQ4x4zLNejrRvDWUYmxXUpN3uziFYCHapjWFaCAnreY9bGgxzaMCFAPPpYNng57CypwJVhg==", "dev": true, - "optional": true, "requires": { "buffer": "^5.2.1", "through": "^2.3.8" @@ -21498,7 +21594,6 @@ "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.4.3.tgz", "integrity": "sha512-zvj65TkFeIt3i6aj5bIvJDzjjQQGs4o/sNoezg1F1kYap9Nu2jcUdpwzRSJTHMMzG0H7bZkn4rNQpImhuxWX2A==", "dev": true, - "optional": true, "requires": { "base64-js": "^1.0.2", "ieee754": "^1.1.4" @@ -21798,8 +21893,7 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/url-to-options/-/url-to-options-1.0.1.tgz", "integrity": "sha1-FQWgOiiaSMvXpDTvuu7FBV9WM6k=", - "dev": true, - "optional": true + "dev": true }, "use": { "version": "3.1.1", @@ -21985,9 +22079,9 @@ "dev": true }, "minimist": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", - "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", + "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", "dev": true } } @@ -22127,9 +22221,9 @@ }, "dependencies": { "acorn": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.3.0.tgz", - "integrity": "sha512-/czfa8BwS88b9gWQVhc8eknunSA2DoJpJyTQkhheIf5E48u1N0R4q/YxxsAeqRrmK9TQ/uYfgLDfZo91UlANIA==", + "version": "6.4.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.4.1.tgz", + "integrity": "sha512-ZVA9k326Nwrj3Cj9jlh3wGFutC2ZornPNARZwsNYqQYgN0EsV2d53w5RN/co65Ohn4sUAUtb1rSUAOD6XN9idA==", "dev": true }, "ajv": { diff --git a/package.json b/package.json index f7156cd3c1..72f4bee8fe 100644 --- a/package.json +++ b/package.json @@ -63,6 +63,9 @@ "jquery-migrate": "1.4.1", "matchdep": "~2.0.0", "node-sass": "~4.13.1", + "qunit": "~2.9.0", + "sinon": "~9.0.0", + "sinon-test": "~3.0.0", "source-map-loader": "^0.2.4", "uglify-js": "^3.6.0", "uglifyjs-webpack-plugin": "2.2.0", diff --git a/tests/qunit/index.html b/tests/qunit/index.html index 3b8ca8fa83..e5ca7ec513 100644 --- a/tests/qunit/index.html +++ b/tests/qunit/index.html @@ -56,11 +56,19 @@ - - - - - + + + + +
diff --git a/tests/qunit/vendor/qunit.css b/tests/qunit/vendor/qunit.css deleted file mode 100644 index f1dcd4e1cc..0000000000 --- a/tests/qunit/vendor/qunit.css +++ /dev/null @@ -1,291 +0,0 @@ -/*! - * QUnit 1.18.0 - * http://qunitjs.com/ - * - * Copyright jQuery Foundation and other contributors - * Released under the MIT license - * http://jquery.org/license - * - * Date: 2015-04-03T10:23Z - */ - -/** Font Family and Sizes */ - -#qunit-tests, #qunit-header, #qunit-banner, #qunit-testrunner-toolbar, #qunit-userAgent, #qunit-testresult { - font-family: "Helvetica Neue Light", "HelveticaNeue-Light", "Helvetica Neue", Calibri, Helvetica, Arial, sans-serif; -} - -#qunit-testrunner-toolbar, #qunit-userAgent, #qunit-testresult, #qunit-tests li { font-size: small; } -#qunit-tests { font-size: smaller; } - - -/** Resets */ - -#qunit-tests, #qunit-header, #qunit-banner, #qunit-userAgent, #qunit-testresult, #qunit-modulefilter { - margin: 0; - padding: 0; -} - - -/** Header */ - -#qunit-header { - padding: 0.5em 0 0.5em 1em; - - color: #8699A4; - background-color: #0D3349; - - font-size: 1.5em; - line-height: 1em; - font-weight: 400; - - border-radius: 5px 5px 0 0; -} - -#qunit-header a { - text-decoration: none; - color: #C2CCD1; -} - -#qunit-header a:hover, -#qunit-header a:focus { - color: #FFF; -} - -#qunit-testrunner-toolbar label { - display: inline-block; - padding: 0 0.5em 0 0.1em; -} - -#qunit-banner { - height: 5px; -} - -#qunit-testrunner-toolbar { - padding: 0.5em 1em 0.5em 1em; - color: #5E740B; - background-color: #EEE; - overflow: hidden; -} - -#qunit-userAgent { - padding: 0.5em 1em 0.5em 1em; - background-color: #2B81AF; - color: #FFF; - text-shadow: rgba(0, 0, 0, 0.5) 2px 2px 1px; -} - -#qunit-modulefilter-container { - float: right; - padding: 0.2em; -} - -.qunit-url-config { - display: inline-block; - padding: 0.1em; -} - -.qunit-filter { - display: block; - float: right; - margin-left: 1em; -} - -/** Tests: Pass/Fail */ - -#qunit-tests { - list-style-position: inside; -} - -#qunit-tests li { - padding: 0.4em 1em 0.4em 1em; - border-bottom: 1px solid #FFF; - list-style-position: inside; -} - -#qunit-tests > li { - display: none; -} - -#qunit-tests li.running, -#qunit-tests li.pass, -#qunit-tests li.fail, -#qunit-tests li.skipped { - display: list-item; -} - -#qunit-tests.hidepass li.running, -#qunit-tests.hidepass li.pass { - visibility: hidden; - position: absolute; - width: 0px; - height: 0px; - padding: 0; - border: 0; - margin: 0; -} - -#qunit-tests li strong { - cursor: pointer; -} - -#qunit-tests li.skipped strong { - cursor: default; -} - -#qunit-tests li a { - padding: 0.5em; - color: #C2CCD1; - text-decoration: none; -} - -#qunit-tests li p a { - padding: 0.25em; - color: #6B6464; -} -#qunit-tests li a:hover, -#qunit-tests li a:focus { - color: #000; -} - -#qunit-tests li .runtime { - float: right; - font-size: smaller; -} - -.qunit-assert-list { - margin-top: 0.5em; - padding: 0.5em; - - background-color: #FFF; - - border-radius: 5px; -} - -.qunit-collapsed { - display: none; -} - -#qunit-tests table { - border-collapse: collapse; - margin-top: 0.2em; -} - -#qunit-tests th { - text-align: right; - vertical-align: top; - padding: 0 0.5em 0 0; -} - -#qunit-tests td { - vertical-align: top; -} - -#qunit-tests pre { - margin: 0; - white-space: pre-wrap; - word-wrap: break-word; -} - -#qunit-tests del { - background-color: #E0F2BE; - color: #374E0C; - text-decoration: none; -} - -#qunit-tests ins { - background-color: #FFCACA; - color: #500; - text-decoration: none; -} - -/*** Test Counts */ - -#qunit-tests b.counts { color: #000; } -#qunit-tests b.passed { color: #5E740B; } -#qunit-tests b.failed { color: #710909; } - -#qunit-tests li li { - padding: 5px; - background-color: #FFF; - border-bottom: none; - list-style-position: inside; -} - -/*** Passing Styles */ - -#qunit-tests li li.pass { - color: #3C510C; - background-color: #FFF; - border-left: 10px solid #C6E746; -} - -#qunit-tests .pass { color: #528CE0; background-color: #D2E0E6; } -#qunit-tests .pass .test-name { color: #366097; } - -#qunit-tests .pass .test-actual, -#qunit-tests .pass .test-expected { color: #999; } - -#qunit-banner.qunit-pass { background-color: #C6E746; } - -/*** Failing Styles */ - -#qunit-tests li li.fail { - color: #710909; - background-color: #FFF; - border-left: 10px solid #EE5757; - white-space: pre; -} - -#qunit-tests > li:last-child { - border-radius: 0 0 5px 5px; -} - -#qunit-tests .fail { color: #000; background-color: #EE5757; } -#qunit-tests .fail .test-name, -#qunit-tests .fail .module-name { color: #000; } - -#qunit-tests .fail .test-actual { color: #EE5757; } -#qunit-tests .fail .test-expected { color: #008000; } - -#qunit-banner.qunit-fail { background-color: #EE5757; } - -/*** Skipped tests */ - -#qunit-tests .skipped { - background-color: #EBECE9; -} - -#qunit-tests .qunit-skipped-label { - background-color: #F4FF77; - display: inline-block; - font-style: normal; - color: #366097; - line-height: 1.8em; - padding: 0 0.5em; - margin: -0.4em 0.4em -0.4em 0; -} - -/** Result */ - -#qunit-testresult { - padding: 0.5em 1em 0.5em 1em; - - color: #2B81AF; - background-color: #D2E0E6; - - border-bottom: 1px solid #FFF; -} -#qunit-testresult .module-name { - font-weight: 700; -} - -/** Fixture */ - -#qunit-fixture { - position: absolute; - top: -10000px; - left: -10000px; - width: 1000px; - height: 1000px; -} diff --git a/tests/qunit/vendor/qunit.js b/tests/qunit/vendor/qunit.js deleted file mode 100644 index f3542ca9d4..0000000000 --- a/tests/qunit/vendor/qunit.js +++ /dev/null @@ -1,3828 +0,0 @@ -/*! - * QUnit 1.18.0 - * http://qunitjs.com/ - * - * Copyright jQuery Foundation and other contributors - * Released under the MIT license - * http://jquery.org/license - * - * Date: 2015-04-03T10:23Z - */ - -(function( window ) { - -var QUnit, - config, - onErrorFnPrev, - loggingCallbacks = {}, - fileName = ( sourceFromStacktrace( 0 ) || "" ).replace( /(:\d+)+\)?/, "" ).replace( /.+\//, "" ), - toString = Object.prototype.toString, - hasOwn = Object.prototype.hasOwnProperty, - // Keep a local reference to Date (GH-283) - Date = window.Date, - now = Date.now || function() { - return new Date().getTime(); - }, - globalStartCalled = false, - runStarted = false, - setTimeout = window.setTimeout, - clearTimeout = window.clearTimeout, - defined = { - document: window.document !== undefined, - setTimeout: window.setTimeout !== undefined, - sessionStorage: (function() { - var x = "qunit-test-string"; - try { - sessionStorage.setItem( x, x ); - sessionStorage.removeItem( x ); - return true; - } catch ( e ) { - return false; - } - }()) - }, - /** - * Provides a normalized error string, correcting an issue - * with IE 7 (and prior) where Error.prototype.toString is - * not properly implemented - * - * Based on http://es5.github.com/#x15.11.4.4 - * - * @param {String|Error} error - * @return {String} error message - */ - errorString = function( error ) { - var name, message, - errorString = error.toString(); - if ( errorString.substring( 0, 7 ) === "[object" ) { - name = error.name ? error.name.toString() : "Error"; - message = error.message ? error.message.toString() : ""; - if ( name && message ) { - return name + ": " + message; - } else if ( name ) { - return name; - } else if ( message ) { - return message; - } else { - return "Error"; - } - } else { - return errorString; - } - }, - /** - * Makes a clone of an object using only Array or Object as base, - * and copies over the own enumerable properties. - * - * @param {Object} obj - * @return {Object} New object with only the own properties (recursively). - */ - objectValues = function( obj ) { - var key, val, - vals = QUnit.is( "array", obj ) ? [] : {}; - for ( key in obj ) { - if ( hasOwn.call( obj, key ) ) { - val = obj[ key ]; - vals[ key ] = val === Object( val ) ? objectValues( val ) : val; - } - } - return vals; - }; - -QUnit = {}; - -/** - * Config object: Maintain internal state - * Later exposed as QUnit.config - * `config` initialized at top of scope - */ -config = { - // The queue of tests to run - queue: [], - - // block until document ready - blocking: true, - - // by default, run previously failed tests first - // very useful in combination with "Hide passed tests" checked - reorder: true, - - // by default, modify document.title when suite is done - altertitle: true, - - // by default, scroll to top of the page when suite is done - scrolltop: true, - - // when enabled, all tests must call expect() - requireExpects: false, - - // depth up-to which object will be dumped - maxDepth: 5, - - // add checkboxes that are persisted in the query-string - // when enabled, the id is set to `true` as a `QUnit.config` property - urlConfig: [ - { - id: "hidepassed", - label: "Hide passed tests", - tooltip: "Only show tests and assertions that fail. Stored as query-strings." - }, - { - id: "noglobals", - label: "Check for Globals", - tooltip: "Enabling this will test if any test introduces new properties on the " + - "`window` object. Stored as query-strings." - }, - { - id: "notrycatch", - label: "No try-catch", - tooltip: "Enabling this will run tests outside of a try-catch block. Makes debugging " + - "exceptions in IE reasonable. Stored as query-strings." - } - ], - - // Set of all modules. - modules: [], - - // The first unnamed module - currentModule: { - name: "", - tests: [] - }, - - callbacks: {} -}; - -// Push a loose unnamed module to the modules collection -config.modules.push( config.currentModule ); - -// Initialize more QUnit.config and QUnit.urlParams -(function() { - var i, current, - location = window.location || { search: "", protocol: "file:" }, - params = location.search.slice( 1 ).split( "&" ), - length = params.length, - urlParams = {}; - - if ( params[ 0 ] ) { - for ( i = 0; i < length; i++ ) { - current = params[ i ].split( "=" ); - current[ 0 ] = decodeURIComponent( current[ 0 ] ); - - // allow just a key to turn on a flag, e.g., test.html?noglobals - current[ 1 ] = current[ 1 ] ? decodeURIComponent( current[ 1 ] ) : true; - if ( urlParams[ current[ 0 ] ] ) { - urlParams[ current[ 0 ] ] = [].concat( urlParams[ current[ 0 ] ], current[ 1 ] ); - } else { - urlParams[ current[ 0 ] ] = current[ 1 ]; - } - } - } - - if ( urlParams.filter === true ) { - delete urlParams.filter; - } - - QUnit.urlParams = urlParams; - - // String search anywhere in moduleName+testName - config.filter = urlParams.filter; - - if ( urlParams.maxDepth ) { - config.maxDepth = parseInt( urlParams.maxDepth, 10 ) === -1 ? - Number.POSITIVE_INFINITY : - urlParams.maxDepth; - } - - config.testId = []; - if ( urlParams.testId ) { - - // Ensure that urlParams.testId is an array - urlParams.testId = decodeURIComponent( urlParams.testId ).split( "," ); - for ( i = 0; i < urlParams.testId.length; i++ ) { - config.testId.push( urlParams.testId[ i ] ); - } - } - - // Figure out if we're running the tests from a server or not - QUnit.isLocal = location.protocol === "file:"; - - // Expose the current QUnit version - QUnit.version = "1.18.0"; -}()); - -// Root QUnit object. -// `QUnit` initialized at top of scope -extend( QUnit, { - - // call on start of module test to prepend name to all tests - module: function( name, testEnvironment ) { - var currentModule = { - name: name, - testEnvironment: testEnvironment, - tests: [] - }; - - // DEPRECATED: handles setup/teardown functions, - // beforeEach and afterEach should be used instead - if ( testEnvironment && testEnvironment.setup ) { - testEnvironment.beforeEach = testEnvironment.setup; - delete testEnvironment.setup; - } - if ( testEnvironment && testEnvironment.teardown ) { - testEnvironment.afterEach = testEnvironment.teardown; - delete testEnvironment.teardown; - } - - config.modules.push( currentModule ); - config.currentModule = currentModule; - }, - - // DEPRECATED: QUnit.asyncTest() will be removed in QUnit 2.0. - asyncTest: function( testName, expected, callback ) { - if ( arguments.length === 2 ) { - callback = expected; - expected = null; - } - - QUnit.test( testName, expected, callback, true ); - }, - - test: function( testName, expected, callback, async ) { - var test; - - if ( arguments.length === 2 ) { - callback = expected; - expected = null; - } - - test = new Test({ - testName: testName, - expected: expected, - async: async, - callback: callback - }); - - test.queue(); - }, - - skip: function( testName ) { - var test = new Test({ - testName: testName, - skip: true - }); - - test.queue(); - }, - - // DEPRECATED: The functionality of QUnit.start() will be altered in QUnit 2.0. - // In QUnit 2.0, invoking it will ONLY affect the `QUnit.config.autostart` blocking behavior. - start: function( count ) { - var globalStartAlreadyCalled = globalStartCalled; - - if ( !config.current ) { - globalStartCalled = true; - - if ( runStarted ) { - throw new Error( "Called start() outside of a test context while already started" ); - } else if ( globalStartAlreadyCalled || count > 1 ) { - throw new Error( "Called start() outside of a test context too many times" ); - } else if ( config.autostart ) { - throw new Error( "Called start() outside of a test context when " + - "QUnit.config.autostart was true" ); - } else if ( !config.pageLoaded ) { - - // The page isn't completely loaded yet, so bail out and let `QUnit.load` handle it - config.autostart = true; - return; - } - } else { - - // If a test is running, adjust its semaphore - config.current.semaphore -= count || 1; - - // Don't start until equal number of stop-calls - if ( config.current.semaphore > 0 ) { - return; - } - - // throw an Error if start is called more often than stop - if ( config.current.semaphore < 0 ) { - config.current.semaphore = 0; - - QUnit.pushFailure( - "Called start() while already started (test's semaphore was 0 already)", - sourceFromStacktrace( 2 ) - ); - return; - } - } - - resumeProcessing(); - }, - - // DEPRECATED: QUnit.stop() will be removed in QUnit 2.0. - stop: function( count ) { - - // If there isn't a test running, don't allow QUnit.stop() to be called - if ( !config.current ) { - throw new Error( "Called stop() outside of a test context" ); - } - - // If a test is running, adjust its semaphore - config.current.semaphore += count || 1; - - pauseProcessing(); - }, - - config: config, - - // Safe object type checking - is: function( type, obj ) { - return QUnit.objectType( obj ) === type; - }, - - objectType: function( obj ) { - if ( typeof obj === "undefined" ) { - return "undefined"; - } - - // Consider: typeof null === object - if ( obj === null ) { - return "null"; - } - - var match = toString.call( obj ).match( /^\[object\s(.*)\]$/ ), - type = match && match[ 1 ] || ""; - - switch ( type ) { - case "Number": - if ( isNaN( obj ) ) { - return "nan"; - } - return "number"; - case "String": - case "Boolean": - case "Array": - case "Date": - case "RegExp": - case "Function": - return type.toLowerCase(); - } - if ( typeof obj === "object" ) { - return "object"; - } - return undefined; - }, - - extend: extend, - - load: function() { - config.pageLoaded = true; - - // Initialize the configuration options - extend( config, { - stats: { all: 0, bad: 0 }, - moduleStats: { all: 0, bad: 0 }, - started: 0, - updateRate: 1000, - autostart: true, - filter: "" - }, true ); - - config.blocking = false; - - if ( config.autostart ) { - resumeProcessing(); - } - } -}); - -// Register logging callbacks -(function() { - var i, l, key, - callbacks = [ "begin", "done", "log", "testStart", "testDone", - "moduleStart", "moduleDone" ]; - - function registerLoggingCallback( key ) { - var loggingCallback = function( callback ) { - if ( QUnit.objectType( callback ) !== "function" ) { - throw new Error( - "QUnit logging methods require a callback function as their first parameters." - ); - } - - config.callbacks[ key ].push( callback ); - }; - - // DEPRECATED: This will be removed on QUnit 2.0.0+ - // Stores the registered functions allowing restoring - // at verifyLoggingCallbacks() if modified - loggingCallbacks[ key ] = loggingCallback; - - return loggingCallback; - } - - for ( i = 0, l = callbacks.length; i < l; i++ ) { - key = callbacks[ i ]; - - // Initialize key collection of logging callback - if ( QUnit.objectType( config.callbacks[ key ] ) === "undefined" ) { - config.callbacks[ key ] = []; - } - - QUnit[ key ] = registerLoggingCallback( key ); - } -})(); - -// `onErrorFnPrev` initialized at top of scope -// Preserve other handlers -onErrorFnPrev = window.onerror; - -// Cover uncaught exceptions -// Returning true will suppress the default browser handler, -// returning false will let it run. -window.onerror = function( error, filePath, linerNr ) { - var ret = false; - if ( onErrorFnPrev ) { - ret = onErrorFnPrev( error, filePath, linerNr ); - } - - // Treat return value as window.onerror itself does, - // Only do our handling if not suppressed. - if ( ret !== true ) { - if ( QUnit.config.current ) { - if ( QUnit.config.current.ignoreGlobalErrors ) { - return true; - } - QUnit.pushFailure( error, filePath + ":" + linerNr ); - } else { - QUnit.test( "global failure", extend(function() { - QUnit.pushFailure( error, filePath + ":" + linerNr ); - }, { validTest: true } ) ); - } - return false; - } - - return ret; -}; - -function done() { - var runtime, passed; - - config.autorun = true; - - // Log the last module results - if ( config.previousModule ) { - runLoggingCallbacks( "moduleDone", { - name: config.previousModule.name, - tests: config.previousModule.tests, - failed: config.moduleStats.bad, - passed: config.moduleStats.all - config.moduleStats.bad, - total: config.moduleStats.all, - runtime: now() - config.moduleStats.started - }); - } - delete config.previousModule; - - runtime = now() - config.started; - passed = config.stats.all - config.stats.bad; - - runLoggingCallbacks( "done", { - failed: config.stats.bad, - passed: passed, - total: config.stats.all, - runtime: runtime - }); -} - -// Doesn't support IE6 to IE9, it will return undefined on these browsers -// See also https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Error/Stack -function extractStacktrace( e, offset ) { - offset = offset === undefined ? 4 : offset; - - var stack, include, i; - - if ( e.stack ) { - stack = e.stack.split( "\n" ); - if ( /^error$/i.test( stack[ 0 ] ) ) { - stack.shift(); - } - if ( fileName ) { - include = []; - for ( i = offset; i < stack.length; i++ ) { - if ( stack[ i ].indexOf( fileName ) !== -1 ) { - break; - } - include.push( stack[ i ] ); - } - if ( include.length ) { - return include.join( "\n" ); - } - } - return stack[ offset ]; - - // Support: Safari <=6 only - } else if ( e.sourceURL ) { - - // exclude useless self-reference for generated Error objects - if ( /qunit.js$/.test( e.sourceURL ) ) { - return; - } - - // for actual exceptions, this is useful - return e.sourceURL + ":" + e.line; - } -} - -function sourceFromStacktrace( offset ) { - var error = new Error(); - - // Support: Safari <=7 only, IE <=10 - 11 only - // Not all browsers generate the `stack` property for `new Error()`, see also #636 - if ( !error.stack ) { - try { - throw error; - } catch ( err ) { - error = err; - } - } - - return extractStacktrace( error, offset ); -} - -function synchronize( callback, last ) { - if ( QUnit.objectType( callback ) === "array" ) { - while ( callback.length ) { - synchronize( callback.shift() ); - } - return; - } - config.queue.push( callback ); - - if ( config.autorun && !config.blocking ) { - process( last ); - } -} - -function process( last ) { - function next() { - process( last ); - } - var start = now(); - config.depth = ( config.depth || 0 ) + 1; - - while ( config.queue.length && !config.blocking ) { - if ( !defined.setTimeout || config.updateRate <= 0 || - ( ( now() - start ) < config.updateRate ) ) { - if ( config.current ) { - - // Reset async tracking for each phase of the Test lifecycle - config.current.usedAsync = false; - } - config.queue.shift()(); - } else { - setTimeout( next, 13 ); - break; - } - } - config.depth--; - if ( last && !config.blocking && !config.queue.length && config.depth === 0 ) { - done(); - } -} - -function begin() { - var i, l, - modulesLog = []; - - // If the test run hasn't officially begun yet - if ( !config.started ) { - - // Record the time of the test run's beginning - config.started = now(); - - verifyLoggingCallbacks(); - - // Delete the loose unnamed module if unused. - if ( config.modules[ 0 ].name === "" && config.modules[ 0 ].tests.length === 0 ) { - config.modules.shift(); - } - - // Avoid unnecessary information by not logging modules' test environments - for ( i = 0, l = config.modules.length; i < l; i++ ) { - modulesLog.push({ - name: config.modules[ i ].name, - tests: config.modules[ i ].tests - }); - } - - // The test run is officially beginning now - runLoggingCallbacks( "begin", { - totalTests: Test.count, - modules: modulesLog - }); - } - - config.blocking = false; - process( true ); -} - -function resumeProcessing() { - runStarted = true; - - // A slight delay to allow this iteration of the event loop to finish (more assertions, etc.) - if ( defined.setTimeout ) { - setTimeout(function() { - if ( config.current && config.current.semaphore > 0 ) { - return; - } - if ( config.timeout ) { - clearTimeout( config.timeout ); - } - - begin(); - }, 13 ); - } else { - begin(); - } -} - -function pauseProcessing() { - config.blocking = true; - - if ( config.testTimeout && defined.setTimeout ) { - clearTimeout( config.timeout ); - config.timeout = setTimeout(function() { - if ( config.current ) { - config.current.semaphore = 0; - QUnit.pushFailure( "Test timed out", sourceFromStacktrace( 2 ) ); - } else { - throw new Error( "Test timed out" ); - } - resumeProcessing(); - }, config.testTimeout ); - } -} - -function saveGlobal() { - config.pollution = []; - - if ( config.noglobals ) { - for ( var key in window ) { - if ( hasOwn.call( window, key ) ) { - // in Opera sometimes DOM element ids show up here, ignore them - if ( /^qunit-test-output/.test( key ) ) { - continue; - } - config.pollution.push( key ); - } - } - } -} - -function checkPollution() { - var newGlobals, - deletedGlobals, - old = config.pollution; - - saveGlobal(); - - newGlobals = diff( config.pollution, old ); - if ( newGlobals.length > 0 ) { - QUnit.pushFailure( "Introduced global variable(s): " + newGlobals.join( ", " ) ); - } - - deletedGlobals = diff( old, config.pollution ); - if ( deletedGlobals.length > 0 ) { - QUnit.pushFailure( "Deleted global variable(s): " + deletedGlobals.join( ", " ) ); - } -} - -// returns a new Array with the elements that are in a but not in b -function diff( a, b ) { - var i, j, - result = a.slice(); - - for ( i = 0; i < result.length; i++ ) { - for ( j = 0; j < b.length; j++ ) { - if ( result[ i ] === b[ j ] ) { - result.splice( i, 1 ); - i--; - break; - } - } - } - return result; -} - -function extend( a, b, undefOnly ) { - for ( var prop in b ) { - if ( hasOwn.call( b, prop ) ) { - - // Avoid "Member not found" error in IE8 caused by messing with window.constructor - if ( !( prop === "constructor" && a === window ) ) { - if ( b[ prop ] === undefined ) { - delete a[ prop ]; - } else if ( !( undefOnly && typeof a[ prop ] !== "undefined" ) ) { - a[ prop ] = b[ prop ]; - } - } - } - } - - return a; -} - -function runLoggingCallbacks( key, args ) { - var i, l, callbacks; - - callbacks = config.callbacks[ key ]; - for ( i = 0, l = callbacks.length; i < l; i++ ) { - callbacks[ i ]( args ); - } -} - -// DEPRECATED: This will be removed on 2.0.0+ -// This function verifies if the loggingCallbacks were modified by the user -// If so, it will restore it, assign the given callback and print a console warning -function verifyLoggingCallbacks() { - var loggingCallback, userCallback; - - for ( loggingCallback in loggingCallbacks ) { - if ( QUnit[ loggingCallback ] !== loggingCallbacks[ loggingCallback ] ) { - - userCallback = QUnit[ loggingCallback ]; - - // Restore the callback function - QUnit[ loggingCallback ] = loggingCallbacks[ loggingCallback ]; - - // Assign the deprecated given callback - QUnit[ loggingCallback ]( userCallback ); - - if ( window.console && window.console.warn ) { - window.console.warn( - "QUnit." + loggingCallback + " was replaced with a new value.\n" + - "Please, check out the documentation on how to apply logging callbacks.\n" + - "Reference: http://api.qunitjs.com/category/callbacks/" - ); - } - } - } -} - -// from jquery.js -function inArray( elem, array ) { - if ( array.indexOf ) { - return array.indexOf( elem ); - } - - for ( var i = 0, length = array.length; i < length; i++ ) { - if ( array[ i ] === elem ) { - return i; - } - } - - return -1; -} - -function Test( settings ) { - var i, l; - - ++Test.count; - - extend( this, settings ); - this.assertions = []; - this.semaphore = 0; - this.usedAsync = false; - this.module = config.currentModule; - this.stack = sourceFromStacktrace( 3 ); - - // Register unique strings - for ( i = 0, l = this.module.tests; i < l.length; i++ ) { - if ( this.module.tests[ i ].name === this.testName ) { - this.testName += " "; - } - } - - this.testId = generateHash( this.module.name, this.testName ); - - this.module.tests.push({ - name: this.testName, - testId: this.testId - }); - - if ( settings.skip ) { - - // Skipped tests will fully ignore any sent callback - this.callback = function() {}; - this.async = false; - this.expected = 0; - } else { - this.assert = new Assert( this ); - } -} - -Test.count = 0; - -Test.prototype = { - before: function() { - if ( - - // Emit moduleStart when we're switching from one module to another - this.module !== config.previousModule || - - // They could be equal (both undefined) but if the previousModule property doesn't - // yet exist it means this is the first test in a suite that isn't wrapped in a - // module, in which case we'll just emit a moduleStart event for 'undefined'. - // Without this, reporters can get testStart before moduleStart which is a problem. - !hasOwn.call( config, "previousModule" ) - ) { - if ( hasOwn.call( config, "previousModule" ) ) { - runLoggingCallbacks( "moduleDone", { - name: config.previousModule.name, - tests: config.previousModule.tests, - failed: config.moduleStats.bad, - passed: config.moduleStats.all - config.moduleStats.bad, - total: config.moduleStats.all, - runtime: now() - config.moduleStats.started - }); - } - config.previousModule = this.module; - config.moduleStats = { all: 0, bad: 0, started: now() }; - runLoggingCallbacks( "moduleStart", { - name: this.module.name, - tests: this.module.tests - }); - } - - config.current = this; - - this.testEnvironment = extend( {}, this.module.testEnvironment ); - delete this.testEnvironment.beforeEach; - delete this.testEnvironment.afterEach; - - this.started = now(); - runLoggingCallbacks( "testStart", { - name: this.testName, - module: this.module.name, - testId: this.testId - }); - - if ( !config.pollution ) { - saveGlobal(); - } - }, - - run: function() { - var promise; - - config.current = this; - - if ( this.async ) { - QUnit.stop(); - } - - this.callbackStarted = now(); - - if ( config.notrycatch ) { - promise = this.callback.call( this.testEnvironment, this.assert ); - this.resolvePromise( promise ); - return; - } - - try { - promise = this.callback.call( this.testEnvironment, this.assert ); - this.resolvePromise( promise ); - } catch ( e ) { - this.pushFailure( "Died on test #" + ( this.assertions.length + 1 ) + " " + - this.stack + ": " + ( e.message || e ), extractStacktrace( e, 0 ) ); - - // else next test will carry the responsibility - saveGlobal(); - - // Restart the tests if they're blocking - if ( config.blocking ) { - QUnit.start(); - } - } - }, - - after: function() { - checkPollution(); - }, - - queueHook: function( hook, hookName ) { - var promise, - test = this; - return function runHook() { - config.current = test; - if ( config.notrycatch ) { - promise = hook.call( test.testEnvironment, test.assert ); - test.resolvePromise( promise, hookName ); - return; - } - try { - promise = hook.call( test.testEnvironment, test.assert ); - test.resolvePromise( promise, hookName ); - } catch ( error ) { - test.pushFailure( hookName + " failed on " + test.testName + ": " + - ( error.message || error ), extractStacktrace( error, 0 ) ); - } - }; - }, - - // Currently only used for module level hooks, can be used to add global level ones - hooks: function( handler ) { - var hooks = []; - - // Hooks are ignored on skipped tests - if ( this.skip ) { - return hooks; - } - - if ( this.module.testEnvironment && - QUnit.objectType( this.module.testEnvironment[ handler ] ) === "function" ) { - hooks.push( this.queueHook( this.module.testEnvironment[ handler ], handler ) ); - } - - return hooks; - }, - - finish: function() { - config.current = this; - if ( config.requireExpects && this.expected === null ) { - this.pushFailure( "Expected number of assertions to be defined, but expect() was " + - "not called.", this.stack ); - } else if ( this.expected !== null && this.expected !== this.assertions.length ) { - this.pushFailure( "Expected " + this.expected + " assertions, but " + - this.assertions.length + " were run", this.stack ); - } else if ( this.expected === null && !this.assertions.length ) { - this.pushFailure( "Expected at least one assertion, but none were run - call " + - "expect(0) to accept zero assertions.", this.stack ); - } - - var i, - bad = 0; - - this.runtime = now() - this.started; - config.stats.all += this.assertions.length; - config.moduleStats.all += this.assertions.length; - - for ( i = 0; i < this.assertions.length; i++ ) { - if ( !this.assertions[ i ].result ) { - bad++; - config.stats.bad++; - config.moduleStats.bad++; - } - } - - runLoggingCallbacks( "testDone", { - name: this.testName, - module: this.module.name, - skipped: !!this.skip, - failed: bad, - passed: this.assertions.length - bad, - total: this.assertions.length, - runtime: this.runtime, - - // HTML Reporter use - assertions: this.assertions, - testId: this.testId, - - // DEPRECATED: this property will be removed in 2.0.0, use runtime instead - duration: this.runtime - }); - - // QUnit.reset() is deprecated and will be replaced for a new - // fixture reset function on QUnit 2.0/2.1. - // It's still called here for backwards compatibility handling - QUnit.reset(); - - config.current = undefined; - }, - - queue: function() { - var bad, - test = this; - - if ( !this.valid() ) { - return; - } - - function run() { - - // each of these can by async - synchronize([ - function() { - test.before(); - }, - - test.hooks( "beforeEach" ), - - function() { - test.run(); - }, - - test.hooks( "afterEach" ).reverse(), - - function() { - test.after(); - }, - function() { - test.finish(); - } - ]); - } - - // `bad` initialized at top of scope - // defer when previous test run passed, if storage is available - bad = QUnit.config.reorder && defined.sessionStorage && - +sessionStorage.getItem( "qunit-test-" + this.module.name + "-" + this.testName ); - - if ( bad ) { - run(); - } else { - synchronize( run, true ); - } - }, - - push: function( result, actual, expected, message ) { - var source, - details = { - module: this.module.name, - name: this.testName, - result: result, - message: message, - actual: actual, - expected: expected, - testId: this.testId, - runtime: now() - this.started - }; - - if ( !result ) { - source = sourceFromStacktrace(); - - if ( source ) { - details.source = source; - } - } - - runLoggingCallbacks( "log", details ); - - this.assertions.push({ - result: !!result, - message: message - }); - }, - - pushFailure: function( message, source, actual ) { - if ( !this instanceof Test ) { - throw new Error( "pushFailure() assertion outside test context, was " + - sourceFromStacktrace( 2 ) ); - } - - var details = { - module: this.module.name, - name: this.testName, - result: false, - message: message || "error", - actual: actual || null, - testId: this.testId, - runtime: now() - this.started - }; - - if ( source ) { - details.source = source; - } - - runLoggingCallbacks( "log", details ); - - this.assertions.push({ - result: false, - message: message - }); - }, - - resolvePromise: function( promise, phase ) { - var then, message, - test = this; - if ( promise != null ) { - then = promise.then; - if ( QUnit.objectType( then ) === "function" ) { - QUnit.stop(); - then.call( - promise, - QUnit.start, - function( error ) { - message = "Promise rejected " + - ( !phase ? "during" : phase.replace( /Each$/, "" ) ) + - " " + test.testName + ": " + ( error.message || error ); - test.pushFailure( message, extractStacktrace( error, 0 ) ); - - // else next test will carry the responsibility - saveGlobal(); - - // Unblock - QUnit.start(); - } - ); - } - } - }, - - valid: function() { - var include, - filter = config.filter && config.filter.toLowerCase(), - module = QUnit.urlParams.module && QUnit.urlParams.module.toLowerCase(), - fullName = ( this.module.name + ": " + this.testName ).toLowerCase(); - - // Internally-generated tests are always valid - if ( this.callback && this.callback.validTest ) { - return true; - } - - if ( config.testId.length > 0 && inArray( this.testId, config.testId ) < 0 ) { - return false; - } - - if ( module && ( !this.module.name || this.module.name.toLowerCase() !== module ) ) { - return false; - } - - if ( !filter ) { - return true; - } - - include = filter.charAt( 0 ) !== "!"; - if ( !include ) { - filter = filter.slice( 1 ); - } - - // If the filter matches, we need to honour include - if ( fullName.indexOf( filter ) !== -1 ) { - return include; - } - - // Otherwise, do the opposite - return !include; - } - -}; - -// Resets the test setup. Useful for tests that modify the DOM. -/* -DEPRECATED: Use multiple tests instead of resetting inside a test. -Use testStart or testDone for custom cleanup. -This method will throw an error in 2.0, and will be removed in 2.1 -*/ -QUnit.reset = function() { - - // Return on non-browser environments - // This is necessary to not break on node tests - if ( typeof window === "undefined" ) { - return; - } - - var fixture = defined.document && document.getElementById && - document.getElementById( "qunit-fixture" ); - - if ( fixture ) { - fixture.innerHTML = config.fixture; - } -}; - -QUnit.pushFailure = function() { - if ( !QUnit.config.current ) { - throw new Error( "pushFailure() assertion outside test context, in " + - sourceFromStacktrace( 2 ) ); - } - - // Gets current test obj - var currentTest = QUnit.config.current; - - return currentTest.pushFailure.apply( currentTest, arguments ); -}; - -// Based on Java's String.hashCode, a simple but not -// rigorously collision resistant hashing function -function generateHash( module, testName ) { - var hex, - i = 0, - hash = 0, - str = module + "\x1C" + testName, - len = str.length; - - for ( ; i < len; i++ ) { - hash = ( ( hash << 5 ) - hash ) + str.charCodeAt( i ); - hash |= 0; - } - - // Convert the possibly negative integer hash code into an 8 character hex string, which isn't - // strictly necessary but increases user understanding that the id is a SHA-like hash - hex = ( 0x100000000 + hash ).toString( 16 ); - if ( hex.length < 8 ) { - hex = "0000000" + hex; - } - - return hex.slice( -8 ); -} - -function Assert( testContext ) { - this.test = testContext; -} - -// Assert helpers -QUnit.assert = Assert.prototype = { - - // Specify the number of expected assertions to guarantee that failed test - // (no assertions are run at all) don't slip through. - expect: function( asserts ) { - if ( arguments.length === 1 ) { - this.test.expected = asserts; - } else { - return this.test.expected; - } - }, - - // Increment this Test's semaphore counter, then return a single-use function that - // decrements that counter a maximum of once. - async: function() { - var test = this.test, - popped = false; - - test.semaphore += 1; - test.usedAsync = true; - pauseProcessing(); - - return function done() { - if ( !popped ) { - test.semaphore -= 1; - popped = true; - resumeProcessing(); - } else { - test.pushFailure( "Called the callback returned from `assert.async` more than once", - sourceFromStacktrace( 2 ) ); - } - }; - }, - - // Exports test.push() to the user API - push: function( /* result, actual, expected, message */ ) { - var assert = this, - currentTest = ( assert instanceof Assert && assert.test ) || QUnit.config.current; - - // Backwards compatibility fix. - // Allows the direct use of global exported assertions and QUnit.assert.* - // Although, it's use is not recommended as it can leak assertions - // to other tests from async tests, because we only get a reference to the current test, - // not exactly the test where assertion were intended to be called. - if ( !currentTest ) { - throw new Error( "assertion outside test context, in " + sourceFromStacktrace( 2 ) ); - } - - if ( currentTest.usedAsync === true && currentTest.semaphore === 0 ) { - currentTest.pushFailure( "Assertion after the final `assert.async` was resolved", - sourceFromStacktrace( 2 ) ); - - // Allow this assertion to continue running anyway... - } - - if ( !( assert instanceof Assert ) ) { - assert = currentTest.assert; - } - return assert.test.push.apply( assert.test, arguments ); - }, - - ok: function( result, message ) { - message = message || ( result ? "okay" : "failed, expected argument to be truthy, was: " + - QUnit.dump.parse( result ) ); - this.push( !!result, result, true, message ); - }, - - notOk: function( result, message ) { - message = message || ( !result ? "okay" : "failed, expected argument to be falsy, was: " + - QUnit.dump.parse( result ) ); - this.push( !result, result, false, message ); - }, - - equal: function( actual, expected, message ) { - /*jshint eqeqeq:false */ - this.push( expected == actual, actual, expected, message ); - }, - - notEqual: function( actual, expected, message ) { - /*jshint eqeqeq:false */ - this.push( expected != actual, actual, expected, message ); - }, - - propEqual: function( actual, expected, message ) { - actual = objectValues( actual ); - expected = objectValues( expected ); - this.push( QUnit.equiv( actual, expected ), actual, expected, message ); - }, - - notPropEqual: function( actual, expected, message ) { - actual = objectValues( actual ); - expected = objectValues( expected ); - this.push( !QUnit.equiv( actual, expected ), actual, expected, message ); - }, - - deepEqual: function( actual, expected, message ) { - this.push( QUnit.equiv( actual, expected ), actual, expected, message ); - }, - - notDeepEqual: function( actual, expected, message ) { - this.push( !QUnit.equiv( actual, expected ), actual, expected, message ); - }, - - strictEqual: function( actual, expected, message ) { - this.push( expected === actual, actual, expected, message ); - }, - - notStrictEqual: function( actual, expected, message ) { - this.push( expected !== actual, actual, expected, message ); - }, - - "throws": function( block, expected, message ) { - var actual, expectedType, - expectedOutput = expected, - ok = false, - currentTest = ( this instanceof Assert && this.test ) || QUnit.config.current; - - // 'expected' is optional unless doing string comparison - if ( message == null && typeof expected === "string" ) { - message = expected; - expected = null; - } - - currentTest.ignoreGlobalErrors = true; - try { - block.call( currentTest.testEnvironment ); - } catch (e) { - actual = e; - } - currentTest.ignoreGlobalErrors = false; - - if ( actual ) { - expectedType = QUnit.objectType( expected ); - - // we don't want to validate thrown error - if ( !expected ) { - ok = true; - expectedOutput = null; - - // expected is a regexp - } else if ( expectedType === "regexp" ) { - ok = expected.test( errorString( actual ) ); - - // expected is a string - } else if ( expectedType === "string" ) { - ok = expected === errorString( actual ); - - // expected is a constructor, maybe an Error constructor - } else if ( expectedType === "function" && actual instanceof expected ) { - ok = true; - - // expected is an Error object - } else if ( expectedType === "object" ) { - ok = actual instanceof expected.constructor && - actual.name === expected.name && - actual.message === expected.message; - - // expected is a validation function which returns true if validation passed - } else if ( expectedType === "function" && expected.call( {}, actual ) === true ) { - expectedOutput = null; - ok = true; - } - } - - currentTest.assert.push( ok, actual, expectedOutput, message ); - } -}; - -// Provide an alternative to assert.throws(), for enviroments that consider throws a reserved word -// Known to us are: Closure Compiler, Narwhal -(function() { - /*jshint sub:true */ - Assert.prototype.raises = Assert.prototype[ "throws" ]; -}()); - -// Test for equality any JavaScript type. -// Author: Philippe Rathé -QUnit.equiv = (function() { - - // Call the o related callback with the given arguments. - function bindCallbacks( o, callbacks, args ) { - var prop = QUnit.objectType( o ); - if ( prop ) { - if ( QUnit.objectType( callbacks[ prop ] ) === "function" ) { - return callbacks[ prop ].apply( callbacks, args ); - } else { - return callbacks[ prop ]; // or undefined - } - } - } - - // the real equiv function - var innerEquiv, - - // stack to decide between skip/abort functions - callers = [], - - // stack to avoiding loops from circular referencing - parents = [], - parentsB = [], - - getProto = Object.getPrototypeOf || function( obj ) { - /* jshint camelcase: false, proto: true */ - return obj.__proto__; - }, - callbacks = (function() { - - // for string, boolean, number and null - function useStrictEquality( b, a ) { - - /*jshint eqeqeq:false */ - if ( b instanceof a.constructor || a instanceof b.constructor ) { - - // to catch short annotation VS 'new' annotation of a - // declaration - // e.g. var i = 1; - // var j = new Number(1); - return a == b; - } else { - return a === b; - } - } - - return { - "string": useStrictEquality, - "boolean": useStrictEquality, - "number": useStrictEquality, - "null": useStrictEquality, - "undefined": useStrictEquality, - - "nan": function( b ) { - return isNaN( b ); - }, - - "date": function( b, a ) { - return QUnit.objectType( b ) === "date" && a.valueOf() === b.valueOf(); - }, - - "regexp": function( b, a ) { - return QUnit.objectType( b ) === "regexp" && - - // the regex itself - a.source === b.source && - - // and its modifiers - a.global === b.global && - - // (gmi) ... - a.ignoreCase === b.ignoreCase && - a.multiline === b.multiline && - a.sticky === b.sticky; - }, - - // - skip when the property is a method of an instance (OOP) - // - abort otherwise, - // initial === would have catch identical references anyway - "function": function() { - var caller = callers[ callers.length - 1 ]; - return caller !== Object && typeof caller !== "undefined"; - }, - - "array": function( b, a ) { - var i, j, len, loop, aCircular, bCircular; - - // b could be an object literal here - if ( QUnit.objectType( b ) !== "array" ) { - return false; - } - - len = a.length; - if ( len !== b.length ) { - // safe and faster - return false; - } - - // track reference to avoid circular references - parents.push( a ); - parentsB.push( b ); - for ( i = 0; i < len; i++ ) { - loop = false; - for ( j = 0; j < parents.length; j++ ) { - aCircular = parents[ j ] === a[ i ]; - bCircular = parentsB[ j ] === b[ i ]; - if ( aCircular || bCircular ) { - if ( a[ i ] === b[ i ] || aCircular && bCircular ) { - loop = true; - } else { - parents.pop(); - parentsB.pop(); - return false; - } - } - } - if ( !loop && !innerEquiv( a[ i ], b[ i ] ) ) { - parents.pop(); - parentsB.pop(); - return false; - } - } - parents.pop(); - parentsB.pop(); - return true; - }, - - "object": function( b, a ) { - - /*jshint forin:false */ - var i, j, loop, aCircular, bCircular, - // Default to true - eq = true, - aProperties = [], - bProperties = []; - - // comparing constructors is more strict than using - // instanceof - if ( a.constructor !== b.constructor ) { - - // Allow objects with no prototype to be equivalent to - // objects with Object as their constructor. - if ( !( ( getProto( a ) === null && getProto( b ) === Object.prototype ) || - ( getProto( b ) === null && getProto( a ) === Object.prototype ) ) ) { - return false; - } - } - - // stack constructor before traversing properties - callers.push( a.constructor ); - - // track reference to avoid circular references - parents.push( a ); - parentsB.push( b ); - - // be strict: don't ensure hasOwnProperty and go deep - for ( i in a ) { - loop = false; - for ( j = 0; j < parents.length; j++ ) { - aCircular = parents[ j ] === a[ i ]; - bCircular = parentsB[ j ] === b[ i ]; - if ( aCircular || bCircular ) { - if ( a[ i ] === b[ i ] || aCircular && bCircular ) { - loop = true; - } else { - eq = false; - break; - } - } - } - aProperties.push( i ); - if ( !loop && !innerEquiv( a[ i ], b[ i ] ) ) { - eq = false; - break; - } - } - - parents.pop(); - parentsB.pop(); - callers.pop(); // unstack, we are done - - for ( i in b ) { - bProperties.push( i ); // collect b's properties - } - - // Ensures identical properties name - return eq && innerEquiv( aProperties.sort(), bProperties.sort() ); - } - }; - }()); - - innerEquiv = function() { // can take multiple arguments - var args = [].slice.apply( arguments ); - if ( args.length < 2 ) { - return true; // end transition - } - - return ( (function( a, b ) { - if ( a === b ) { - return true; // catch the most you can - } else if ( a === null || b === null || typeof a === "undefined" || - typeof b === "undefined" || - QUnit.objectType( a ) !== QUnit.objectType( b ) ) { - - // don't lose time with error prone cases - return false; - } else { - return bindCallbacks( a, callbacks, [ b, a ] ); - } - - // apply transition with (1..n) arguments - }( args[ 0 ], args[ 1 ] ) ) && - innerEquiv.apply( this, args.splice( 1, args.length - 1 ) ) ); - }; - - return innerEquiv; -}()); - -// Based on jsDump by Ariel Flesler -// http://flesler.blogspot.com/2008/05/jsdump-pretty-dump-of-any-javascript.html -QUnit.dump = (function() { - function quote( str ) { - return "\"" + str.toString().replace( /"/g, "\\\"" ) + "\""; - } - function literal( o ) { - return o + ""; - } - function join( pre, arr, post ) { - var s = dump.separator(), - base = dump.indent(), - inner = dump.indent( 1 ); - if ( arr.join ) { - arr = arr.join( "," + s + inner ); - } - if ( !arr ) { - return pre + post; - } - return [ pre, inner + arr, base + post ].join( s ); - } - function array( arr, stack ) { - var i = arr.length, - ret = new Array( i ); - - if ( dump.maxDepth && dump.depth > dump.maxDepth ) { - return "[object Array]"; - } - - this.up(); - while ( i-- ) { - ret[ i ] = this.parse( arr[ i ], undefined, stack ); - } - this.down(); - return join( "[", ret, "]" ); - } - - var reName = /^function (\w+)/, - dump = { - - // objType is used mostly internally, you can fix a (custom) type in advance - parse: function( obj, objType, stack ) { - stack = stack || []; - var res, parser, parserType, - inStack = inArray( obj, stack ); - - if ( inStack !== -1 ) { - return "recursion(" + ( inStack - stack.length ) + ")"; - } - - objType = objType || this.typeOf( obj ); - parser = this.parsers[ objType ]; - parserType = typeof parser; - - if ( parserType === "function" ) { - stack.push( obj ); - res = parser.call( this, obj, stack ); - stack.pop(); - return res; - } - return ( parserType === "string" ) ? parser : this.parsers.error; - }, - typeOf: function( obj ) { - var type; - if ( obj === null ) { - type = "null"; - } else if ( typeof obj === "undefined" ) { - type = "undefined"; - } else if ( QUnit.is( "regexp", obj ) ) { - type = "regexp"; - } else if ( QUnit.is( "date", obj ) ) { - type = "date"; - } else if ( QUnit.is( "function", obj ) ) { - type = "function"; - } else if ( obj.setInterval !== undefined && - obj.document !== undefined && - obj.nodeType === undefined ) { - type = "window"; - } else if ( obj.nodeType === 9 ) { - type = "document"; - } else if ( obj.nodeType ) { - type = "node"; - } else if ( - - // native arrays - toString.call( obj ) === "[object Array]" || - - // NodeList objects - ( typeof obj.length === "number" && obj.item !== undefined && - ( obj.length ? obj.item( 0 ) === obj[ 0 ] : ( obj.item( 0 ) === null && - obj[ 0 ] === undefined ) ) ) - ) { - type = "array"; - } else if ( obj.constructor === Error.prototype.constructor ) { - type = "error"; - } else { - type = typeof obj; - } - return type; - }, - separator: function() { - return this.multiline ? this.HTML ? "
" : "\n" : this.HTML ? " " : " "; - }, - // extra can be a number, shortcut for increasing-calling-decreasing - indent: function( extra ) { - if ( !this.multiline ) { - return ""; - } - var chr = this.indentChar; - if ( this.HTML ) { - chr = chr.replace( /\t/g, " " ).replace( / /g, " " ); - } - return new Array( this.depth + ( extra || 0 ) ).join( chr ); - }, - up: function( a ) { - this.depth += a || 1; - }, - down: function( a ) { - this.depth -= a || 1; - }, - setParser: function( name, parser ) { - this.parsers[ name ] = parser; - }, - // The next 3 are exposed so you can use them - quote: quote, - literal: literal, - join: join, - // - depth: 1, - maxDepth: QUnit.config.maxDepth, - - // This is the list of parsers, to modify them, use dump.setParser - parsers: { - window: "[Window]", - document: "[Document]", - error: function( error ) { - return "Error(\"" + error.message + "\")"; - }, - unknown: "[Unknown]", - "null": "null", - "undefined": "undefined", - "function": function( fn ) { - var ret = "function", - - // functions never have name in IE - name = "name" in fn ? fn.name : ( reName.exec( fn ) || [] )[ 1 ]; - - if ( name ) { - ret += " " + name; - } - ret += "( "; - - ret = [ ret, dump.parse( fn, "functionArgs" ), "){" ].join( "" ); - return join( ret, dump.parse( fn, "functionCode" ), "}" ); - }, - array: array, - nodelist: array, - "arguments": array, - object: function( map, stack ) { - var keys, key, val, i, nonEnumerableProperties, - ret = []; - - if ( dump.maxDepth && dump.depth > dump.maxDepth ) { - return "[object Object]"; - } - - dump.up(); - keys = []; - for ( key in map ) { - keys.push( key ); - } - - // Some properties are not always enumerable on Error objects. - nonEnumerableProperties = [ "message", "name" ]; - for ( i in nonEnumerableProperties ) { - key = nonEnumerableProperties[ i ]; - if ( key in map && inArray( key, keys ) < 0 ) { - keys.push( key ); - } - } - keys.sort(); - for ( i = 0; i < keys.length; i++ ) { - key = keys[ i ]; - val = map[ key ]; - ret.push( dump.parse( key, "key" ) + ": " + - dump.parse( val, undefined, stack ) ); - } - dump.down(); - return join( "{", ret, "}" ); - }, - node: function( node ) { - var len, i, val, - open = dump.HTML ? "<" : "<", - close = dump.HTML ? ">" : ">", - tag = node.nodeName.toLowerCase(), - ret = open + tag, - attrs = node.attributes; - - if ( attrs ) { - for ( i = 0, len = attrs.length; i < len; i++ ) { - val = attrs[ i ].nodeValue; - - // IE6 includes all attributes in .attributes, even ones not explicitly - // set. Those have values like undefined, null, 0, false, "" or - // "inherit". - if ( val && val !== "inherit" ) { - ret += " " + attrs[ i ].nodeName + "=" + - dump.parse( val, "attribute" ); - } - } - } - ret += close; - - // Show content of TextNode or CDATASection - if ( node.nodeType === 3 || node.nodeType === 4 ) { - ret += node.nodeValue; - } - - return ret + open + "/" + tag + close; - }, - - // function calls it internally, it's the arguments part of the function - functionArgs: function( fn ) { - var args, - l = fn.length; - - if ( !l ) { - return ""; - } - - args = new Array( l ); - while ( l-- ) { - - // 97 is 'a' - args[ l ] = String.fromCharCode( 97 + l ); - } - return " " + args.join( ", " ) + " "; - }, - // object calls it internally, the key part of an item in a map - key: quote, - // function calls it internally, it's the content of the function - functionCode: "[code]", - // node calls it internally, it's an html attribute value - attribute: quote, - string: quote, - date: quote, - regexp: literal, - number: literal, - "boolean": literal - }, - // if true, entities are escaped ( <, >, \t, space and \n ) - HTML: false, - // indentation unit - indentChar: " ", - // if true, items in a collection, are separated by a \n, else just a space. - multiline: true - }; - - return dump; -}()); - -// back compat -QUnit.jsDump = QUnit.dump; - -// For browser, export only select globals -if ( typeof window !== "undefined" ) { - - // Deprecated - // Extend assert methods to QUnit and Global scope through Backwards compatibility - (function() { - var i, - assertions = Assert.prototype; - - function applyCurrent( current ) { - return function() { - var assert = new Assert( QUnit.config.current ); - current.apply( assert, arguments ); - }; - } - - for ( i in assertions ) { - QUnit[ i ] = applyCurrent( assertions[ i ] ); - } - })(); - - (function() { - var i, l, - keys = [ - "test", - "module", - "expect", - "asyncTest", - "start", - "stop", - "ok", - "notOk", - "equal", - "notEqual", - "propEqual", - "notPropEqual", - "deepEqual", - "notDeepEqual", - "strictEqual", - "notStrictEqual", - "throws" - ]; - - for ( i = 0, l = keys.length; i < l; i++ ) { - window[ keys[ i ] ] = QUnit[ keys[ i ] ]; - } - })(); - - window.QUnit = QUnit; -} - -// For nodejs -if ( typeof module !== "undefined" && module && module.exports ) { - module.exports = QUnit; - - // For consistency with CommonJS environments' exports - module.exports.QUnit = QUnit; -} - -// For CommonJS with exports, but without module.exports, like Rhino -if ( typeof exports !== "undefined" && exports ) { - exports.QUnit = QUnit; -} - -if ( typeof define === "function" && define.amd ) { - define( function() { - return QUnit; - } ); - QUnit.config.autostart = false; -} - -// Get a reference to the global object, like window in browsers -}( (function() { - return this; -})() )); - -/*istanbul ignore next */ -// jscs:disable maximumLineLength -/* - * This file is a modified version of google-diff-match-patch's JavaScript implementation - * (https://code.google.com/p/google-diff-match-patch/source/browse/trunk/javascript/diff_match_patch_uncompressed.js), - * modifications are licensed as more fully set forth in LICENSE.txt. - * - * The original source of google-diff-match-patch is attributable and licensed as follows: - * - * Copyright 2006 Google Inc. - * http://code.google.com/p/google-diff-match-patch/ - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * More Info: - * https://code.google.com/p/google-diff-match-patch/ - * - * Usage: QUnit.diff(expected, actual) - * - * QUnit.diff( "the quick brown fox jumped over", "the quick fox jumps over" ) === "the quick brown fox jumpsed} Array of diff tuples. - */ - DiffMatchPatch.prototype.DiffMain = function( text1, text2, optChecklines, optDeadline ) { - var deadline, checklines, commonlength, - commonprefix, commonsuffix, diffs; - // Set a deadline by which time the diff must be complete. - if ( typeof optDeadline === "undefined" ) { - if ( this.DiffTimeout <= 0 ) { - optDeadline = Number.MAX_VALUE; - } else { - optDeadline = ( new Date() ).getTime() + this.DiffTimeout * 1000; - } - } - deadline = optDeadline; - - // Check for null inputs. - if ( text1 === null || text2 === null ) { - throw new Error( "Null input. (DiffMain)" ); - } - - // Check for equality (speedup). - if ( text1 === text2 ) { - if ( text1 ) { - return [ - [ DIFF_EQUAL, text1 ] - ]; - } - return []; - } - - if ( typeof optChecklines === "undefined" ) { - optChecklines = true; - } - - checklines = optChecklines; - - // Trim off common prefix (speedup). - commonlength = this.diffCommonPrefix( text1, text2 ); - commonprefix = text1.substring( 0, commonlength ); - text1 = text1.substring( commonlength ); - text2 = text2.substring( commonlength ); - - // Trim off common suffix (speedup). - ///////// - commonlength = this.diffCommonSuffix( text1, text2 ); - commonsuffix = text1.substring( text1.length - commonlength ); - text1 = text1.substring( 0, text1.length - commonlength ); - text2 = text2.substring( 0, text2.length - commonlength ); - - // Compute the diff on the middle block. - diffs = this.diffCompute( text1, text2, checklines, deadline ); - - // Restore the prefix and suffix. - if ( commonprefix ) { - diffs.unshift( [ DIFF_EQUAL, commonprefix ] ); - } - if ( commonsuffix ) { - diffs.push( [ DIFF_EQUAL, commonsuffix ] ); - } - this.diffCleanupMerge( diffs ); - return diffs; - }; - - /** - * Reduce the number of edits by eliminating operationally trivial equalities. - * @param {!Array.} diffs Array of diff tuples. - */ - DiffMatchPatch.prototype.diffCleanupEfficiency = function( diffs ) { - var changes, equalities, equalitiesLength, lastequality, - pointer, preIns, preDel, postIns, postDel; - changes = false; - equalities = []; // Stack of indices where equalities are found. - equalitiesLength = 0; // Keeping our own length var is faster in JS. - /** @type {?string} */ - lastequality = null; - // Always equal to diffs[equalities[equalitiesLength - 1]][1] - pointer = 0; // Index of current position. - // Is there an insertion operation before the last equality. - preIns = false; - // Is there a deletion operation before the last equality. - preDel = false; - // Is there an insertion operation after the last equality. - postIns = false; - // Is there a deletion operation after the last equality. - postDel = false; - while ( pointer < diffs.length ) { - if ( diffs[ pointer ][ 0 ] === DIFF_EQUAL ) { // Equality found. - if ( diffs[ pointer ][ 1 ].length < this.DiffEditCost && ( postIns || postDel ) ) { - // Candidate found. - equalities[ equalitiesLength++ ] = pointer; - preIns = postIns; - preDel = postDel; - lastequality = diffs[ pointer ][ 1 ]; - } else { - // Not a candidate, and can never become one. - equalitiesLength = 0; - lastequality = null; - } - postIns = postDel = false; - } else { // An insertion or deletion. - if ( diffs[ pointer ][ 0 ] === DIFF_DELETE ) { - postDel = true; - } else { - postIns = true; - } - /* - * Five types to be split: - * ABXYCD - * AXCD - * ABXC - * AXCD - * ABXC - */ - if ( lastequality && ( ( preIns && preDel && postIns && postDel ) || - ( ( lastequality.length < this.DiffEditCost / 2 ) && - ( preIns + preDel + postIns + postDel ) === 3 ) ) ) { - // Duplicate record. - diffs.splice( equalities[equalitiesLength - 1], 0, [ DIFF_DELETE, lastequality ] ); - // Change second copy to insert. - diffs[ equalities[ equalitiesLength - 1 ] + 1 ][ 0 ] = DIFF_INSERT; - equalitiesLength--; // Throw away the equality we just deleted; - lastequality = null; - if (preIns && preDel) { - // No changes made which could affect previous entry, keep going. - postIns = postDel = true; - equalitiesLength = 0; - } else { - equalitiesLength--; // Throw away the previous equality. - pointer = equalitiesLength > 0 ? equalities[ equalitiesLength - 1 ] : -1; - postIns = postDel = false; - } - changes = true; - } - } - pointer++; - } - - if ( changes ) { - this.diffCleanupMerge( diffs ); - } - }; - - /** - * Convert a diff array into a pretty HTML report. - * @param {!Array.} diffs Array of diff tuples. - * @param {integer} string to be beautified. - * @return {string} HTML representation. - */ - DiffMatchPatch.prototype.diffPrettyHtml = function( diffs ) { - var op, data, x, html = []; - for ( x = 0; x < diffs.length; x++ ) { - op = diffs[x][0]; // Operation (insert, delete, equal) - data = diffs[x][1]; // Text of change. - switch ( op ) { - case DIFF_INSERT: - html[x] = "" + data + ""; - break; - case DIFF_DELETE: - html[x] = "" + data + ""; - break; - case DIFF_EQUAL: - html[x] = "" + data + ""; - break; - } - } - return html.join(""); - }; - - /** - * Determine the common prefix of two strings. - * @param {string} text1 First string. - * @param {string} text2 Second string. - * @return {number} The number of characters common to the start of each - * string. - */ - DiffMatchPatch.prototype.diffCommonPrefix = function( text1, text2 ) { - var pointermid, pointermax, pointermin, pointerstart; - // Quick check for common null cases. - if ( !text1 || !text2 || text1.charAt(0) !== text2.charAt(0) ) { - return 0; - } - // Binary search. - // Performance analysis: http://neil.fraser.name/news/2007/10/09/ - pointermin = 0; - pointermax = Math.min( text1.length, text2.length ); - pointermid = pointermax; - pointerstart = 0; - while ( pointermin < pointermid ) { - if ( text1.substring( pointerstart, pointermid ) === text2.substring( pointerstart, pointermid ) ) { - pointermin = pointermid; - pointerstart = pointermin; - } else { - pointermax = pointermid; - } - pointermid = Math.floor( ( pointermax - pointermin ) / 2 + pointermin ); - } - return pointermid; - }; - - /** - * Determine the common suffix of two strings. - * @param {string} text1 First string. - * @param {string} text2 Second string. - * @return {number} The number of characters common to the end of each string. - */ - DiffMatchPatch.prototype.diffCommonSuffix = function( text1, text2 ) { - var pointermid, pointermax, pointermin, pointerend; - // Quick check for common null cases. - if (!text1 || !text2 || text1.charAt(text1.length - 1) !== text2.charAt(text2.length - 1)) { - return 0; - } - // Binary search. - // Performance analysis: http://neil.fraser.name/news/2007/10/09/ - pointermin = 0; - pointermax = Math.min(text1.length, text2.length); - pointermid = pointermax; - pointerend = 0; - while ( pointermin < pointermid ) { - if (text1.substring( text1.length - pointermid, text1.length - pointerend ) === - text2.substring( text2.length - pointermid, text2.length - pointerend ) ) { - pointermin = pointermid; - pointerend = pointermin; - } else { - pointermax = pointermid; - } - pointermid = Math.floor( ( pointermax - pointermin ) / 2 + pointermin ); - } - return pointermid; - }; - - /** - * Find the differences between two texts. Assumes that the texts do not - * have any common prefix or suffix. - * @param {string} text1 Old string to be diffed. - * @param {string} text2 New string to be diffed. - * @param {boolean} checklines Speedup flag. If false, then don't run a - * line-level diff first to identify the changed areas. - * If true, then run a faster, slightly less optimal diff. - * @param {number} deadline Time when the diff should be complete by. - * @return {!Array.} Array of diff tuples. - * @private - */ - DiffMatchPatch.prototype.diffCompute = function( text1, text2, checklines, deadline ) { - var diffs, longtext, shorttext, i, hm, - text1A, text2A, text1B, text2B, - midCommon, diffsA, diffsB; - - if ( !text1 ) { - // Just add some text (speedup). - return [ - [ DIFF_INSERT, text2 ] - ]; - } - - if (!text2) { - // Just delete some text (speedup). - return [ - [ DIFF_DELETE, text1 ] - ]; - } - - longtext = text1.length > text2.length ? text1 : text2; - shorttext = text1.length > text2.length ? text2 : text1; - i = longtext.indexOf( shorttext ); - if ( i !== -1 ) { - // Shorter text is inside the longer text (speedup). - diffs = [ - [ DIFF_INSERT, longtext.substring( 0, i ) ], - [ DIFF_EQUAL, shorttext ], - [ DIFF_INSERT, longtext.substring( i + shorttext.length ) ] - ]; - // Swap insertions for deletions if diff is reversed. - if ( text1.length > text2.length ) { - diffs[0][0] = diffs[2][0] = DIFF_DELETE; - } - return diffs; - } - - if ( shorttext.length === 1 ) { - // Single character string. - // After the previous speedup, the character can't be an equality. - return [ - [ DIFF_DELETE, text1 ], - [ DIFF_INSERT, text2 ] - ]; - } - - // Check to see if the problem can be split in two. - hm = this.diffHalfMatch(text1, text2); - if (hm) { - // A half-match was found, sort out the return data. - text1A = hm[0]; - text1B = hm[1]; - text2A = hm[2]; - text2B = hm[3]; - midCommon = hm[4]; - // Send both pairs off for separate processing. - diffsA = this.DiffMain(text1A, text2A, checklines, deadline); - diffsB = this.DiffMain(text1B, text2B, checklines, deadline); - // Merge the results. - return diffsA.concat([ - [ DIFF_EQUAL, midCommon ] - ], diffsB); - } - - if (checklines && text1.length > 100 && text2.length > 100) { - return this.diffLineMode(text1, text2, deadline); - } - - return this.diffBisect(text1, text2, deadline); - }; - - /** - * Do the two texts share a substring which is at least half the length of the - * longer text? - * This speedup can produce non-minimal diffs. - * @param {string} text1 First string. - * @param {string} text2 Second string. - * @return {Array.} Five element Array, containing the prefix of - * text1, the suffix of text1, the prefix of text2, the suffix of - * text2 and the common middle. Or null if there was no match. - * @private - */ - DiffMatchPatch.prototype.diffHalfMatch = function(text1, text2) { - var longtext, shorttext, dmp, - text1A, text2B, text2A, text1B, midCommon, - hm1, hm2, hm; - if (this.DiffTimeout <= 0) { - // Don't risk returning a non-optimal diff if we have unlimited time. - return null; - } - longtext = text1.length > text2.length ? text1 : text2; - shorttext = text1.length > text2.length ? text2 : text1; - if (longtext.length < 4 || shorttext.length * 2 < longtext.length) { - return null; // Pointless. - } - dmp = this; // 'this' becomes 'window' in a closure. - - /** - * Does a substring of shorttext exist within longtext such that the substring - * is at least half the length of longtext? - * Closure, but does not reference any external variables. - * @param {string} longtext Longer string. - * @param {string} shorttext Shorter string. - * @param {number} i Start index of quarter length substring within longtext. - * @return {Array.} Five element Array, containing the prefix of - * longtext, the suffix of longtext, the prefix of shorttext, the suffix - * of shorttext and the common middle. Or null if there was no match. - * @private - */ - function diffHalfMatchI(longtext, shorttext, i) { - var seed, j, bestCommon, prefixLength, suffixLength, - bestLongtextA, bestLongtextB, bestShorttextA, bestShorttextB; - // Start with a 1/4 length substring at position i as a seed. - seed = longtext.substring(i, i + Math.floor(longtext.length / 4)); - j = -1; - bestCommon = ""; - while ((j = shorttext.indexOf(seed, j + 1)) !== -1) { - prefixLength = dmp.diffCommonPrefix(longtext.substring(i), - shorttext.substring(j)); - suffixLength = dmp.diffCommonSuffix(longtext.substring(0, i), - shorttext.substring(0, j)); - if (bestCommon.length < suffixLength + prefixLength) { - bestCommon = shorttext.substring(j - suffixLength, j) + - shorttext.substring(j, j + prefixLength); - bestLongtextA = longtext.substring(0, i - suffixLength); - bestLongtextB = longtext.substring(i + prefixLength); - bestShorttextA = shorttext.substring(0, j - suffixLength); - bestShorttextB = shorttext.substring(j + prefixLength); - } - } - if (bestCommon.length * 2 >= longtext.length) { - return [ bestLongtextA, bestLongtextB, - bestShorttextA, bestShorttextB, bestCommon - ]; - } else { - return null; - } - } - - // First check if the second quarter is the seed for a half-match. - hm1 = diffHalfMatchI(longtext, shorttext, - Math.ceil(longtext.length / 4)); - // Check again based on the third quarter. - hm2 = diffHalfMatchI(longtext, shorttext, - Math.ceil(longtext.length / 2)); - if (!hm1 && !hm2) { - return null; - } else if (!hm2) { - hm = hm1; - } else if (!hm1) { - hm = hm2; - } else { - // Both matched. Select the longest. - hm = hm1[4].length > hm2[4].length ? hm1 : hm2; - } - - // A half-match was found, sort out the return data. - text1A, text1B, text2A, text2B; - if (text1.length > text2.length) { - text1A = hm[0]; - text1B = hm[1]; - text2A = hm[2]; - text2B = hm[3]; - } else { - text2A = hm[0]; - text2B = hm[1]; - text1A = hm[2]; - text1B = hm[3]; - } - midCommon = hm[4]; - return [ text1A, text1B, text2A, text2B, midCommon ]; - }; - - /** - * Do a quick line-level diff on both strings, then rediff the parts for - * greater accuracy. - * This speedup can produce non-minimal diffs. - * @param {string} text1 Old string to be diffed. - * @param {string} text2 New string to be diffed. - * @param {number} deadline Time when the diff should be complete by. - * @return {!Array.} Array of diff tuples. - * @private - */ - DiffMatchPatch.prototype.diffLineMode = function(text1, text2, deadline) { - var a, diffs, linearray, pointer, countInsert, - countDelete, textInsert, textDelete, j; - // Scan the text on a line-by-line basis first. - a = this.diffLinesToChars(text1, text2); - text1 = a.chars1; - text2 = a.chars2; - linearray = a.lineArray; - - diffs = this.DiffMain(text1, text2, false, deadline); - - // Convert the diff back to original text. - this.diffCharsToLines(diffs, linearray); - // Eliminate freak matches (e.g. blank lines) - this.diffCleanupSemantic(diffs); - - // Rediff any replacement blocks, this time character-by-character. - // Add a dummy entry at the end. - diffs.push( [ DIFF_EQUAL, "" ] ); - pointer = 0; - countDelete = 0; - countInsert = 0; - textDelete = ""; - textInsert = ""; - while (pointer < diffs.length) { - switch ( diffs[pointer][0] ) { - case DIFF_INSERT: - countInsert++; - textInsert += diffs[pointer][1]; - break; - case DIFF_DELETE: - countDelete++; - textDelete += diffs[pointer][1]; - break; - case DIFF_EQUAL: - // Upon reaching an equality, check for prior redundancies. - if (countDelete >= 1 && countInsert >= 1) { - // Delete the offending records and add the merged ones. - diffs.splice(pointer - countDelete - countInsert, - countDelete + countInsert); - pointer = pointer - countDelete - countInsert; - a = this.DiffMain(textDelete, textInsert, false, deadline); - for (j = a.length - 1; j >= 0; j--) { - diffs.splice( pointer, 0, a[j] ); - } - pointer = pointer + a.length; - } - countInsert = 0; - countDelete = 0; - textDelete = ""; - textInsert = ""; - break; - } - pointer++; - } - diffs.pop(); // Remove the dummy entry at the end. - - return diffs; - }; - - /** - * Find the 'middle snake' of a diff, split the problem in two - * and return the recursively constructed diff. - * See Myers 1986 paper: An O(ND) Difference Algorithm and Its Variations. - * @param {string} text1 Old string to be diffed. - * @param {string} text2 New string to be diffed. - * @param {number} deadline Time at which to bail if not yet complete. - * @return {!Array.} Array of diff tuples. - * @private - */ - DiffMatchPatch.prototype.diffBisect = function(text1, text2, deadline) { - var text1Length, text2Length, maxD, vOffset, vLength, - v1, v2, x, delta, front, k1start, k1end, k2start, - k2end, k2Offset, k1Offset, x1, x2, y1, y2, d, k1, k2; - // Cache the text lengths to prevent multiple calls. - text1Length = text1.length; - text2Length = text2.length; - maxD = Math.ceil((text1Length + text2Length) / 2); - vOffset = maxD; - vLength = 2 * maxD; - v1 = new Array(vLength); - v2 = new Array(vLength); - // Setting all elements to -1 is faster in Chrome & Firefox than mixing - // integers and undefined. - for (x = 0; x < vLength; x++) { - v1[x] = -1; - v2[x] = -1; - } - v1[vOffset + 1] = 0; - v2[vOffset + 1] = 0; - delta = text1Length - text2Length; - // If the total number of characters is odd, then the front path will collide - // with the reverse path. - front = (delta % 2 !== 0); - // Offsets for start and end of k loop. - // Prevents mapping of space beyond the grid. - k1start = 0; - k1end = 0; - k2start = 0; - k2end = 0; - for (d = 0; d < maxD; d++) { - // Bail out if deadline is reached. - if ((new Date()).getTime() > deadline) { - break; - } - - // Walk the front path one step. - for (k1 = -d + k1start; k1 <= d - k1end; k1 += 2) { - k1Offset = vOffset + k1; - if ( k1 === -d || ( k1 !== d && v1[ k1Offset - 1 ] < v1[ k1Offset + 1 ] ) ) { - x1 = v1[k1Offset + 1]; - } else { - x1 = v1[k1Offset - 1] + 1; - } - y1 = x1 - k1; - while (x1 < text1Length && y1 < text2Length && - text1.charAt(x1) === text2.charAt(y1)) { - x1++; - y1++; - } - v1[k1Offset] = x1; - if (x1 > text1Length) { - // Ran off the right of the graph. - k1end += 2; - } else if (y1 > text2Length) { - // Ran off the bottom of the graph. - k1start += 2; - } else if (front) { - k2Offset = vOffset + delta - k1; - if (k2Offset >= 0 && k2Offset < vLength && v2[k2Offset] !== -1) { - // Mirror x2 onto top-left coordinate system. - x2 = text1Length - v2[k2Offset]; - if (x1 >= x2) { - // Overlap detected. - return this.diffBisectSplit(text1, text2, x1, y1, deadline); - } - } - } - } - - // Walk the reverse path one step. - for (k2 = -d + k2start; k2 <= d - k2end; k2 += 2) { - k2Offset = vOffset + k2; - if ( k2 === -d || (k2 !== d && v2[ k2Offset - 1 ] < v2[ k2Offset + 1 ] ) ) { - x2 = v2[k2Offset + 1]; - } else { - x2 = v2[k2Offset - 1] + 1; - } - y2 = x2 - k2; - while (x2 < text1Length && y2 < text2Length && - text1.charAt(text1Length - x2 - 1) === - text2.charAt(text2Length - y2 - 1)) { - x2++; - y2++; - } - v2[k2Offset] = x2; - if (x2 > text1Length) { - // Ran off the left of the graph. - k2end += 2; - } else if (y2 > text2Length) { - // Ran off the top of the graph. - k2start += 2; - } else if (!front) { - k1Offset = vOffset + delta - k2; - if (k1Offset >= 0 && k1Offset < vLength && v1[k1Offset] !== -1) { - x1 = v1[k1Offset]; - y1 = vOffset + x1 - k1Offset; - // Mirror x2 onto top-left coordinate system. - x2 = text1Length - x2; - if (x1 >= x2) { - // Overlap detected. - return this.diffBisectSplit(text1, text2, x1, y1, deadline); - } - } - } - } - } - // Diff took too long and hit the deadline or - // number of diffs equals number of characters, no commonality at all. - return [ - [ DIFF_DELETE, text1 ], - [ DIFF_INSERT, text2 ] - ]; - }; - - /** - * Given the location of the 'middle snake', split the diff in two parts - * and recurse. - * @param {string} text1 Old string to be diffed. - * @param {string} text2 New string to be diffed. - * @param {number} x Index of split point in text1. - * @param {number} y Index of split point in text2. - * @param {number} deadline Time at which to bail if not yet complete. - * @return {!Array.} Array of diff tuples. - * @private - */ - DiffMatchPatch.prototype.diffBisectSplit = function( text1, text2, x, y, deadline ) { - var text1a, text1b, text2a, text2b, diffs, diffsb; - text1a = text1.substring(0, x); - text2a = text2.substring(0, y); - text1b = text1.substring(x); - text2b = text2.substring(y); - - // Compute both diffs serially. - diffs = this.DiffMain(text1a, text2a, false, deadline); - diffsb = this.DiffMain(text1b, text2b, false, deadline); - - return diffs.concat(diffsb); - }; - - /** - * Reduce the number of edits by eliminating semantically trivial equalities. - * @param {!Array.} diffs Array of diff tuples. - */ - DiffMatchPatch.prototype.diffCleanupSemantic = function(diffs) { - var changes, equalities, equalitiesLength, lastequality, - pointer, lengthInsertions2, lengthDeletions2, lengthInsertions1, - lengthDeletions1, deletion, insertion, overlapLength1, overlapLength2; - changes = false; - equalities = []; // Stack of indices where equalities are found. - equalitiesLength = 0; // Keeping our own length var is faster in JS. - /** @type {?string} */ - lastequality = null; - // Always equal to diffs[equalities[equalitiesLength - 1]][1] - pointer = 0; // Index of current position. - // Number of characters that changed prior to the equality. - lengthInsertions1 = 0; - lengthDeletions1 = 0; - // Number of characters that changed after the equality. - lengthInsertions2 = 0; - lengthDeletions2 = 0; - while (pointer < diffs.length) { - if (diffs[pointer][0] === DIFF_EQUAL) { // Equality found. - equalities[equalitiesLength++] = pointer; - lengthInsertions1 = lengthInsertions2; - lengthDeletions1 = lengthDeletions2; - lengthInsertions2 = 0; - lengthDeletions2 = 0; - lastequality = diffs[pointer][1]; - } else { // An insertion or deletion. - if (diffs[pointer][0] === DIFF_INSERT) { - lengthInsertions2 += diffs[pointer][1].length; - } else { - lengthDeletions2 += diffs[pointer][1].length; - } - // Eliminate an equality that is smaller or equal to the edits on both - // sides of it. - if (lastequality && (lastequality.length <= - Math.max(lengthInsertions1, lengthDeletions1)) && - (lastequality.length <= Math.max(lengthInsertions2, - lengthDeletions2))) { - // Duplicate record. - diffs.splice( equalities[ equalitiesLength - 1 ], 0, [ DIFF_DELETE, lastequality ] ); - // Change second copy to insert. - diffs[equalities[equalitiesLength - 1] + 1][0] = DIFF_INSERT; - // Throw away the equality we just deleted. - equalitiesLength--; - // Throw away the previous equality (it needs to be reevaluated). - equalitiesLength--; - pointer = equalitiesLength > 0 ? equalities[equalitiesLength - 1] : -1; - lengthInsertions1 = 0; // Reset the counters. - lengthDeletions1 = 0; - lengthInsertions2 = 0; - lengthDeletions2 = 0; - lastequality = null; - changes = true; - } - } - pointer++; - } - - // Normalize the diff. - if (changes) { - this.diffCleanupMerge(diffs); - } - - // Find any overlaps between deletions and insertions. - // e.g: abcxxxxxxdef - // -> abcxxxdef - // e.g: xxxabcdefxxx - // -> defxxxabc - // Only extract an overlap if it is as big as the edit ahead or behind it. - pointer = 1; - while (pointer < diffs.length) { - if (diffs[pointer - 1][0] === DIFF_DELETE && - diffs[pointer][0] === DIFF_INSERT) { - deletion = diffs[pointer - 1][1]; - insertion = diffs[pointer][1]; - overlapLength1 = this.diffCommonOverlap(deletion, insertion); - overlapLength2 = this.diffCommonOverlap(insertion, deletion); - if (overlapLength1 >= overlapLength2) { - if (overlapLength1 >= deletion.length / 2 || - overlapLength1 >= insertion.length / 2) { - // Overlap found. Insert an equality and trim the surrounding edits. - diffs.splice( pointer, 0, [ DIFF_EQUAL, insertion.substring( 0, overlapLength1 ) ] ); - diffs[pointer - 1][1] = - deletion.substring(0, deletion.length - overlapLength1); - diffs[pointer + 1][1] = insertion.substring(overlapLength1); - pointer++; - } - } else { - if (overlapLength2 >= deletion.length / 2 || - overlapLength2 >= insertion.length / 2) { - // Reverse overlap found. - // Insert an equality and swap and trim the surrounding edits. - diffs.splice( pointer, 0, [ DIFF_EQUAL, deletion.substring( 0, overlapLength2 ) ] ); - diffs[pointer - 1][0] = DIFF_INSERT; - diffs[pointer - 1][1] = - insertion.substring(0, insertion.length - overlapLength2); - diffs[pointer + 1][0] = DIFF_DELETE; - diffs[pointer + 1][1] = - deletion.substring(overlapLength2); - pointer++; - } - } - pointer++; - } - pointer++; - } - }; - - /** - * Determine if the suffix of one string is the prefix of another. - * @param {string} text1 First string. - * @param {string} text2 Second string. - * @return {number} The number of characters common to the end of the first - * string and the start of the second string. - * @private - */ - DiffMatchPatch.prototype.diffCommonOverlap = function(text1, text2) { - var text1Length, text2Length, textLength, - best, length, pattern, found; - // Cache the text lengths to prevent multiple calls. - text1Length = text1.length; - text2Length = text2.length; - // Eliminate the null case. - if (text1Length === 0 || text2Length === 0) { - return 0; - } - // Truncate the longer string. - if (text1Length > text2Length) { - text1 = text1.substring(text1Length - text2Length); - } else if (text1Length < text2Length) { - text2 = text2.substring(0, text1Length); - } - textLength = Math.min(text1Length, text2Length); - // Quick check for the worst case. - if (text1 === text2) { - return textLength; - } - - // Start by looking for a single character match - // and increase length until no match is found. - // Performance analysis: http://neil.fraser.name/news/2010/11/04/ - best = 0; - length = 1; - while (true) { - pattern = text1.substring(textLength - length); - found = text2.indexOf(pattern); - if (found === -1) { - return best; - } - length += found; - if (found === 0 || text1.substring(textLength - length) === - text2.substring(0, length)) { - best = length; - length++; - } - } - }; - - /** - * Split two texts into an array of strings. Reduce the texts to a string of - * hashes where each Unicode character represents one line. - * @param {string} text1 First string. - * @param {string} text2 Second string. - * @return {{chars1: string, chars2: string, lineArray: !Array.}} - * An object containing the encoded text1, the encoded text2 and - * the array of unique strings. - * The zeroth element of the array of unique strings is intentionally blank. - * @private - */ - DiffMatchPatch.prototype.diffLinesToChars = function(text1, text2) { - var lineArray, lineHash, chars1, chars2; - lineArray = []; // e.g. lineArray[4] === 'Hello\n' - lineHash = {}; // e.g. lineHash['Hello\n'] === 4 - - // '\x00' is a valid character, but various debuggers don't like it. - // So we'll insert a junk entry to avoid generating a null character. - lineArray[0] = ""; - - /** - * Split a text into an array of strings. Reduce the texts to a string of - * hashes where each Unicode character represents one line. - * Modifies linearray and linehash through being a closure. - * @param {string} text String to encode. - * @return {string} Encoded string. - * @private - */ - function diffLinesToCharsMunge(text) { - var chars, lineStart, lineEnd, lineArrayLength, line; - chars = ""; - // Walk the text, pulling out a substring for each line. - // text.split('\n') would would temporarily double our memory footprint. - // Modifying text would create many large strings to garbage collect. - lineStart = 0; - lineEnd = -1; - // Keeping our own length variable is faster than looking it up. - lineArrayLength = lineArray.length; - while (lineEnd < text.length - 1) { - lineEnd = text.indexOf("\n", lineStart); - if (lineEnd === -1) { - lineEnd = text.length - 1; - } - line = text.substring(lineStart, lineEnd + 1); - lineStart = lineEnd + 1; - - if (lineHash.hasOwnProperty ? lineHash.hasOwnProperty(line) : - (lineHash[line] !== undefined)) { - chars += String.fromCharCode( lineHash[ line ] ); - } else { - chars += String.fromCharCode(lineArrayLength); - lineHash[line] = lineArrayLength; - lineArray[lineArrayLength++] = line; - } - } - return chars; - } - - chars1 = diffLinesToCharsMunge(text1); - chars2 = diffLinesToCharsMunge(text2); - return { - chars1: chars1, - chars2: chars2, - lineArray: lineArray - }; - }; - - /** - * Rehydrate the text in a diff from a string of line hashes to real lines of - * text. - * @param {!Array.} diffs Array of diff tuples. - * @param {!Array.} lineArray Array of unique strings. - * @private - */ - DiffMatchPatch.prototype.diffCharsToLines = function( diffs, lineArray ) { - var x, chars, text, y; - for ( x = 0; x < diffs.length; x++ ) { - chars = diffs[x][1]; - text = []; - for ( y = 0; y < chars.length; y++ ) { - text[y] = lineArray[chars.charCodeAt(y)]; - } - diffs[x][1] = text.join(""); - } - }; - - /** - * Reorder and merge like edit sections. Merge equalities. - * Any edit section can move as long as it doesn't cross an equality. - * @param {!Array.} diffs Array of diff tuples. - */ - DiffMatchPatch.prototype.diffCleanupMerge = function(diffs) { - var pointer, countDelete, countInsert, textInsert, textDelete, - commonlength, changes; - diffs.push( [ DIFF_EQUAL, "" ] ); // Add a dummy entry at the end. - pointer = 0; - countDelete = 0; - countInsert = 0; - textDelete = ""; - textInsert = ""; - commonlength; - while (pointer < diffs.length) { - switch ( diffs[ pointer ][ 0 ] ) { - case DIFF_INSERT: - countInsert++; - textInsert += diffs[pointer][1]; - pointer++; - break; - case DIFF_DELETE: - countDelete++; - textDelete += diffs[pointer][1]; - pointer++; - break; - case DIFF_EQUAL: - // Upon reaching an equality, check for prior redundancies. - if (countDelete + countInsert > 1) { - if (countDelete !== 0 && countInsert !== 0) { - // Factor out any common prefixies. - commonlength = this.diffCommonPrefix(textInsert, textDelete); - if (commonlength !== 0) { - if ((pointer - countDelete - countInsert) > 0 && - diffs[pointer - countDelete - countInsert - 1][0] === - DIFF_EQUAL) { - diffs[pointer - countDelete - countInsert - 1][1] += - textInsert.substring(0, commonlength); - } else { - diffs.splice( 0, 0, [ DIFF_EQUAL, - textInsert.substring( 0, commonlength ) - ] ); - pointer++; - } - textInsert = textInsert.substring(commonlength); - textDelete = textDelete.substring(commonlength); - } - // Factor out any common suffixies. - commonlength = this.diffCommonSuffix(textInsert, textDelete); - if (commonlength !== 0) { - diffs[pointer][1] = textInsert.substring(textInsert.length - - commonlength) + diffs[pointer][1]; - textInsert = textInsert.substring(0, textInsert.length - - commonlength); - textDelete = textDelete.substring(0, textDelete.length - - commonlength); - } - } - // Delete the offending records and add the merged ones. - if (countDelete === 0) { - diffs.splice( pointer - countInsert, - countDelete + countInsert, [ DIFF_INSERT, textInsert ] ); - } else if (countInsert === 0) { - diffs.splice( pointer - countDelete, - countDelete + countInsert, [ DIFF_DELETE, textDelete ] ); - } else { - diffs.splice( pointer - countDelete - countInsert, - countDelete + countInsert, [ DIFF_DELETE, textDelete ], [ DIFF_INSERT, textInsert ] ); - } - pointer = pointer - countDelete - countInsert + - (countDelete ? 1 : 0) + (countInsert ? 1 : 0) + 1; - } else if (pointer !== 0 && diffs[pointer - 1][0] === DIFF_EQUAL) { - // Merge this equality with the previous one. - diffs[pointer - 1][1] += diffs[pointer][1]; - diffs.splice(pointer, 1); - } else { - pointer++; - } - countInsert = 0; - countDelete = 0; - textDelete = ""; - textInsert = ""; - break; - } - } - if (diffs[diffs.length - 1][1] === "") { - diffs.pop(); // Remove the dummy entry at the end. - } - - // Second pass: look for single edits surrounded on both sides by equalities - // which can be shifted sideways to eliminate an equality. - // e.g: ABAC -> ABAC - changes = false; - pointer = 1; - // Intentionally ignore the first and last element (don't need checking). - while (pointer < diffs.length - 1) { - if (diffs[pointer - 1][0] === DIFF_EQUAL && - diffs[pointer + 1][0] === DIFF_EQUAL) { - // This is a single edit surrounded by equalities. - if ( diffs[ pointer ][ 1 ].substring( diffs[ pointer ][ 1 ].length - - diffs[ pointer - 1 ][ 1 ].length ) === diffs[ pointer - 1 ][ 1 ] ) { - // Shift the edit over the previous equality. - diffs[pointer][1] = diffs[pointer - 1][1] + - diffs[pointer][1].substring(0, diffs[pointer][1].length - - diffs[pointer - 1][1].length); - diffs[pointer + 1][1] = diffs[pointer - 1][1] + diffs[pointer + 1][1]; - diffs.splice(pointer - 1, 1); - changes = true; - } else if ( diffs[ pointer ][ 1 ].substring( 0, diffs[ pointer + 1 ][ 1 ].length ) === - diffs[ pointer + 1 ][ 1 ] ) { - // Shift the edit over the next equality. - diffs[pointer - 1][1] += diffs[pointer + 1][1]; - diffs[pointer][1] = - diffs[pointer][1].substring(diffs[pointer + 1][1].length) + - diffs[pointer + 1][1]; - diffs.splice(pointer + 1, 1); - changes = true; - } - } - pointer++; - } - // If shifts were made, the diff needs reordering and another shift sweep. - if (changes) { - this.diffCleanupMerge(diffs); - } - }; - - return function(o, n) { - var diff, output, text; - diff = new DiffMatchPatch(); - output = diff.DiffMain(o, n); - //console.log(output); - diff.diffCleanupEfficiency(output); - text = diff.diffPrettyHtml(output); - - return text; - }; -}()); -// jscs:enable - -(function() { - -// Deprecated QUnit.init - Ref #530 -// Re-initialize the configuration options -QUnit.init = function() { - var tests, banner, result, qunit, - config = QUnit.config; - - config.stats = { all: 0, bad: 0 }; - config.moduleStats = { all: 0, bad: 0 }; - config.started = 0; - config.updateRate = 1000; - config.blocking = false; - config.autostart = true; - config.autorun = false; - config.filter = ""; - config.queue = []; - - // Return on non-browser environments - // This is necessary to not break on node tests - if ( typeof window === "undefined" ) { - return; - } - - qunit = id( "qunit" ); - if ( qunit ) { - qunit.innerHTML = - "

" + escapeText( document.title ) + "

" + - "

" + - "
" + - "

" + - "
    "; - } - - tests = id( "qunit-tests" ); - banner = id( "qunit-banner" ); - result = id( "qunit-testresult" ); - - if ( tests ) { - tests.innerHTML = ""; - } - - if ( banner ) { - banner.className = ""; - } - - if ( result ) { - result.parentNode.removeChild( result ); - } - - if ( tests ) { - result = document.createElement( "p" ); - result.id = "qunit-testresult"; - result.className = "result"; - tests.parentNode.insertBefore( result, tests ); - result.innerHTML = "Running...
     "; - } -}; - -// Don't load the HTML Reporter on non-Browser environments -if ( typeof window === "undefined" ) { - return; -} - -var config = QUnit.config, - hasOwn = Object.prototype.hasOwnProperty, - defined = { - document: window.document !== undefined, - sessionStorage: (function() { - var x = "qunit-test-string"; - try { - sessionStorage.setItem( x, x ); - sessionStorage.removeItem( x ); - return true; - } catch ( e ) { - return false; - } - }()) - }, - modulesList = []; - -/** -* Escape text for attribute or text content. -*/ -function escapeText( s ) { - if ( !s ) { - return ""; - } - s = s + ""; - - // Both single quotes and double quotes (for attributes) - return s.replace( /['"<>&]/g, function( s ) { - switch ( s ) { - case "'": - return "'"; - case "\"": - return """; - case "<": - return "<"; - case ">": - return ">"; - case "&": - return "&"; - } - }); -} - -/** - * @param {HTMLElement} elem - * @param {string} type - * @param {Function} fn - */ -function addEvent( elem, type, fn ) { - if ( elem.addEventListener ) { - - // Standards-based browsers - elem.addEventListener( type, fn, false ); - } else if ( elem.attachEvent ) { - - // support: IE <9 - elem.attachEvent( "on" + type, function() { - var event = window.event; - if ( !event.target ) { - event.target = event.srcElement || document; - } - - fn.call( elem, event ); - }); - } -} - -/** - * @param {Array|NodeList} elems - * @param {string} type - * @param {Function} fn - */ -function addEvents( elems, type, fn ) { - var i = elems.length; - while ( i-- ) { - addEvent( elems[ i ], type, fn ); - } -} - -function hasClass( elem, name ) { - return ( " " + elem.className + " " ).indexOf( " " + name + " " ) >= 0; -} - -function addClass( elem, name ) { - if ( !hasClass( elem, name ) ) { - elem.className += ( elem.className ? " " : "" ) + name; - } -} - -function toggleClass( elem, name ) { - if ( hasClass( elem, name ) ) { - removeClass( elem, name ); - } else { - addClass( elem, name ); - } -} - -function removeClass( elem, name ) { - var set = " " + elem.className + " "; - - // Class name may appear multiple times - while ( set.indexOf( " " + name + " " ) >= 0 ) { - set = set.replace( " " + name + " ", " " ); - } - - // trim for prettiness - elem.className = typeof set.trim === "function" ? set.trim() : set.replace( /^\s+|\s+$/g, "" ); -} - -function id( name ) { - return defined.document && document.getElementById && document.getElementById( name ); -} - -function getUrlConfigHtml() { - var i, j, val, - escaped, escapedTooltip, - selection = false, - len = config.urlConfig.length, - urlConfigHtml = ""; - - for ( i = 0; i < len; i++ ) { - val = config.urlConfig[ i ]; - if ( typeof val === "string" ) { - val = { - id: val, - label: val - }; - } - - escaped = escapeText( val.id ); - escapedTooltip = escapeText( val.tooltip ); - - if ( config[ val.id ] === undefined ) { - config[ val.id ] = QUnit.urlParams[ val.id ]; - } - - if ( !val.value || typeof val.value === "string" ) { - urlConfigHtml += ""; - } else { - urlConfigHtml += ""; - } - } - - return urlConfigHtml; -} - -// Handle "click" events on toolbar checkboxes and "change" for select menus. -// Updates the URL with the new state of `config.urlConfig` values. -function toolbarChanged() { - var updatedUrl, value, - field = this, - params = {}; - - // Detect if field is a select menu or a checkbox - if ( "selectedIndex" in field ) { - value = field.options[ field.selectedIndex ].value || undefined; - } else { - value = field.checked ? ( field.defaultValue || true ) : undefined; - } - - params[ field.name ] = value; - updatedUrl = setUrl( params ); - - if ( "hidepassed" === field.name && "replaceState" in window.history ) { - config[ field.name ] = value || false; - if ( value ) { - addClass( id( "qunit-tests" ), "hidepass" ); - } else { - removeClass( id( "qunit-tests" ), "hidepass" ); - } - - // It is not necessary to refresh the whole page - window.history.replaceState( null, "", updatedUrl ); - } else { - window.location = updatedUrl; - } -} - -function setUrl( params ) { - var key, - querystring = "?"; - - params = QUnit.extend( QUnit.extend( {}, QUnit.urlParams ), params ); - - for ( key in params ) { - if ( hasOwn.call( params, key ) ) { - if ( params[ key ] === undefined ) { - continue; - } - querystring += encodeURIComponent( key ); - if ( params[ key ] !== true ) { - querystring += "=" + encodeURIComponent( params[ key ] ); - } - querystring += "&"; - } - } - return location.protocol + "//" + location.host + - location.pathname + querystring.slice( 0, -1 ); -} - -function applyUrlParams() { - var selectedModule, - modulesList = id( "qunit-modulefilter" ), - filter = id( "qunit-filter-input" ).value; - - selectedModule = modulesList ? - decodeURIComponent( modulesList.options[ modulesList.selectedIndex ].value ) : - undefined; - - window.location = setUrl({ - module: ( selectedModule === "" ) ? undefined : selectedModule, - filter: ( filter === "" ) ? undefined : filter, - - // Remove testId filter - testId: undefined - }); -} - -function toolbarUrlConfigContainer() { - var urlConfigContainer = document.createElement( "span" ); - - urlConfigContainer.innerHTML = getUrlConfigHtml(); - addClass( urlConfigContainer, "qunit-url-config" ); - - // For oldIE support: - // * Add handlers to the individual elements instead of the container - // * Use "click" instead of "change" for checkboxes - addEvents( urlConfigContainer.getElementsByTagName( "input" ), "click", toolbarChanged ); - addEvents( urlConfigContainer.getElementsByTagName( "select" ), "change", toolbarChanged ); - - return urlConfigContainer; -} - -function toolbarLooseFilter() { - var filter = document.createElement( "form" ), - label = document.createElement( "label" ), - input = document.createElement( "input" ), - button = document.createElement( "button" ); - - addClass( filter, "qunit-filter" ); - - label.innerHTML = "Filter: "; - - input.type = "text"; - input.value = config.filter || ""; - input.name = "filter"; - input.id = "qunit-filter-input"; - - button.innerHTML = "Go"; - - label.appendChild( input ); - - filter.appendChild( label ); - filter.appendChild( button ); - addEvent( filter, "submit", function( ev ) { - applyUrlParams(); - - if ( ev && ev.preventDefault ) { - ev.preventDefault(); - } - - return false; - }); - - return filter; -} - -function toolbarModuleFilterHtml() { - var i, - moduleFilterHtml = ""; - - if ( !modulesList.length ) { - return false; - } - - modulesList.sort(function( a, b ) { - return a.localeCompare( b ); - }); - - moduleFilterHtml += "" + - ""; - - return moduleFilterHtml; -} - -function toolbarModuleFilter() { - var toolbar = id( "qunit-testrunner-toolbar" ), - moduleFilter = document.createElement( "span" ), - moduleFilterHtml = toolbarModuleFilterHtml(); - - if ( !toolbar || !moduleFilterHtml ) { - return false; - } - - moduleFilter.setAttribute( "id", "qunit-modulefilter-container" ); - moduleFilter.innerHTML = moduleFilterHtml; - - addEvent( moduleFilter.lastChild, "change", applyUrlParams ); - - toolbar.appendChild( moduleFilter ); -} - -function appendToolbar() { - var toolbar = id( "qunit-testrunner-toolbar" ); - - if ( toolbar ) { - toolbar.appendChild( toolbarUrlConfigContainer() ); - toolbar.appendChild( toolbarLooseFilter() ); - } -} - -function appendHeader() { - var header = id( "qunit-header" ); - - if ( header ) { - header.innerHTML = "" + header.innerHTML + " "; - } -} - -function appendBanner() { - var banner = id( "qunit-banner" ); - - if ( banner ) { - banner.className = ""; - } -} - -function appendTestResults() { - var tests = id( "qunit-tests" ), - result = id( "qunit-testresult" ); - - if ( result ) { - result.parentNode.removeChild( result ); - } - - if ( tests ) { - tests.innerHTML = ""; - result = document.createElement( "p" ); - result.id = "qunit-testresult"; - result.className = "result"; - tests.parentNode.insertBefore( result, tests ); - result.innerHTML = "Running...
     "; - } -} - -function storeFixture() { - var fixture = id( "qunit-fixture" ); - if ( fixture ) { - config.fixture = fixture.innerHTML; - } -} - -function appendUserAgent() { - var userAgent = id( "qunit-userAgent" ); - - if ( userAgent ) { - userAgent.innerHTML = ""; - userAgent.appendChild( - document.createTextNode( - "QUnit " + QUnit.version + "; " + navigator.userAgent - ) - ); - } -} - -function appendTestsList( modules ) { - var i, l, x, z, test, moduleObj; - - for ( i = 0, l = modules.length; i < l; i++ ) { - moduleObj = modules[ i ]; - - if ( moduleObj.name ) { - modulesList.push( moduleObj.name ); - } - - for ( x = 0, z = moduleObj.tests.length; x < z; x++ ) { - test = moduleObj.tests[ x ]; - - appendTest( test.name, test.testId, moduleObj.name ); - } - } -} - -function appendTest( name, testId, moduleName ) { - var title, rerunTrigger, testBlock, assertList, - tests = id( "qunit-tests" ); - - if ( !tests ) { - return; - } - - title = document.createElement( "strong" ); - title.innerHTML = getNameHtml( name, moduleName ); - - rerunTrigger = document.createElement( "a" ); - rerunTrigger.innerHTML = "Rerun"; - rerunTrigger.href = setUrl({ testId: testId }); - - testBlock = document.createElement( "li" ); - testBlock.appendChild( title ); - testBlock.appendChild( rerunTrigger ); - testBlock.id = "qunit-test-output-" + testId; - - assertList = document.createElement( "ol" ); - assertList.className = "qunit-assert-list"; - - testBlock.appendChild( assertList ); - - tests.appendChild( testBlock ); -} - -// HTML Reporter initialization and load -QUnit.begin(function( details ) { - var qunit = id( "qunit" ); - - // Fixture is the only one necessary to run without the #qunit element - storeFixture(); - - if ( qunit ) { - qunit.innerHTML = - "

    " + escapeText( document.title ) + "

    " + - "

    " + - "
    " + - "

    " + - "
      "; - } - - appendHeader(); - appendBanner(); - appendTestResults(); - appendUserAgent(); - appendToolbar(); - appendTestsList( details.modules ); - toolbarModuleFilter(); - - if ( qunit && config.hidepassed ) { - addClass( qunit.lastChild, "hidepass" ); - } -}); - -QUnit.done(function( details ) { - var i, key, - banner = id( "qunit-banner" ), - tests = id( "qunit-tests" ), - html = [ - "Tests completed in ", - details.runtime, - " milliseconds.
      ", - "", - details.passed, - " assertions of ", - details.total, - " passed, ", - details.failed, - " failed." - ].join( "" ); - - if ( banner ) { - banner.className = details.failed ? "qunit-fail" : "qunit-pass"; - } - - if ( tests ) { - id( "qunit-testresult" ).innerHTML = html; - } - - if ( config.altertitle && defined.document && document.title ) { - - // show ✖ for good, ✔ for bad suite result in title - // use escape sequences in case file gets loaded with non-utf-8-charset - document.title = [ - ( details.failed ? "\u2716" : "\u2714" ), - document.title.replace( /^[\u2714\u2716] /i, "" ) - ].join( " " ); - } - - // clear own sessionStorage items if all tests passed - if ( config.reorder && defined.sessionStorage && details.failed === 0 ) { - for ( i = 0; i < sessionStorage.length; i++ ) { - key = sessionStorage.key( i++ ); - if ( key.indexOf( "qunit-test-" ) === 0 ) { - sessionStorage.removeItem( key ); - } - } - } - - // scroll back to top to show results - if ( config.scrolltop && window.scrollTo ) { - window.scrollTo( 0, 0 ); - } -}); - -function getNameHtml( name, module ) { - var nameHtml = ""; - - if ( module ) { - nameHtml = "" + escapeText( module ) + ": "; - } - - nameHtml += "" + escapeText( name ) + ""; - - return nameHtml; -} - -QUnit.testStart(function( details ) { - var running, testBlock, bad; - - testBlock = id( "qunit-test-output-" + details.testId ); - if ( testBlock ) { - testBlock.className = "running"; - } else { - - // Report later registered tests - appendTest( details.name, details.testId, details.module ); - } - - running = id( "qunit-testresult" ); - if ( running ) { - bad = QUnit.config.reorder && defined.sessionStorage && - +sessionStorage.getItem( "qunit-test-" + details.module + "-" + details.name ); - - running.innerHTML = ( bad ? - "Rerunning previously failed test:
      " : - "Running:
      " ) + - getNameHtml( details.name, details.module ); - } - -}); - -QUnit.log(function( details ) { - var assertList, assertLi, - message, expected, actual, - testItem = id( "qunit-test-output-" + details.testId ); - - if ( !testItem ) { - return; - } - - message = escapeText( details.message ) || ( details.result ? "okay" : "failed" ); - message = "" + message + ""; - message += "@ " + details.runtime + " ms"; - - // pushFailure doesn't provide details.expected - // when it calls, it's implicit to also not show expected and diff stuff - // Also, we need to check details.expected existence, as it can exist and be undefined - if ( !details.result && hasOwn.call( details, "expected" ) ) { - expected = escapeText( QUnit.dump.parse( details.expected ) ); - actual = escapeText( QUnit.dump.parse( details.actual ) ); - message += ""; - - if ( actual !== expected ) { - message += "" + - ""; - } else { - if ( expected.indexOf( "[object Array]" ) !== -1 || - expected.indexOf( "[object Object]" ) !== -1 ) { - message += ""; - } - } - - if ( details.source ) { - message += ""; - } - - message += "
      Expected:
      " +
      -			expected +
      -			"
      Result:
      " +
      -				actual + "
      Diff:
      " +
      -				QUnit.diff( expected, actual ) + "
      Message: " + - "Diff suppressed as the depth of object is more than current max depth (" + - QUnit.config.maxDepth + ").

      Hint: Use QUnit.dump.maxDepth to " + - " run with a higher max depth or " + - "Rerun without max depth.

      Source:
      " +
      -				escapeText( details.source ) + "
      "; - - // this occours when pushFailure is set and we have an extracted stack trace - } else if ( !details.result && details.source ) { - message += "" + - "" + - "
      Source:
      " +
      -			escapeText( details.source ) + "
      "; - } - - assertList = testItem.getElementsByTagName( "ol" )[ 0 ]; - - assertLi = document.createElement( "li" ); - assertLi.className = details.result ? "pass" : "fail"; - assertLi.innerHTML = message; - assertList.appendChild( assertLi ); -}); - -QUnit.testDone(function( details ) { - var testTitle, time, testItem, assertList, - good, bad, testCounts, skipped, - tests = id( "qunit-tests" ); - - if ( !tests ) { - return; - } - - testItem = id( "qunit-test-output-" + details.testId ); - - assertList = testItem.getElementsByTagName( "ol" )[ 0 ]; - - good = details.passed; - bad = details.failed; - - // store result when possible - if ( config.reorder && defined.sessionStorage ) { - if ( bad ) { - sessionStorage.setItem( "qunit-test-" + details.module + "-" + details.name, bad ); - } else { - sessionStorage.removeItem( "qunit-test-" + details.module + "-" + details.name ); - } - } - - if ( bad === 0 ) { - addClass( assertList, "qunit-collapsed" ); - } - - // testItem.firstChild is the test name - testTitle = testItem.firstChild; - - testCounts = bad ? - "" + bad + ", " + "" + good + ", " : - ""; - - testTitle.innerHTML += " (" + testCounts + - details.assertions.length + ")"; - - if ( details.skipped ) { - testItem.className = "skipped"; - skipped = document.createElement( "em" ); - skipped.className = "qunit-skipped-label"; - skipped.innerHTML = "skipped"; - testItem.insertBefore( skipped, testTitle ); - } else { - addEvent( testTitle, "click", function() { - toggleClass( assertList, "qunit-collapsed" ); - }); - - testItem.className = bad ? "fail" : "pass"; - - time = document.createElement( "span" ); - time.className = "runtime"; - time.innerHTML = details.runtime + " ms"; - testItem.insertBefore( time, assertList ); - } -}); - -if ( defined.document ) { - if ( document.readyState === "complete" ) { - QUnit.load(); - } else { - addEvent( window, "load", QUnit.load ); - } -} else { - config.pageLoaded = true; - config.autorun = true; -} - -})(); diff --git a/tests/qunit/vendor/sinon-qunit.js b/tests/qunit/vendor/sinon-qunit.js deleted file mode 100644 index a9dca782f5..0000000000 --- a/tests/qunit/vendor/sinon-qunit.js +++ /dev/null @@ -1,63 +0,0 @@ -/** - * sinon-qunit 1.0.0, 2010/12/09 - * - * @author Christian Johansen (christian@cjohansen.no) - * - * (The BSD License) - * - * Copyright (c) 2010-2011, Christian Johansen, christian@cjohansen.no - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * * Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * * Neither the name of Christian Johansen nor the names of his contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -/*global sinon, QUnit, test*/ -sinon.assert.fail = function (msg) { - QUnit.ok(false, msg); -}; - -sinon.assert.pass = function (assertion) { - QUnit.ok(true, assertion); -}; - -sinon.config = { - injectIntoThis: true, - injectInto: null, - properties: ["spy", "stub", "mock", "clock", "sandbox"], - useFakeTimers: true, - useFakeServer: false -}; - -(function (global) { - var qTest = QUnit.test; - - QUnit.test = global.test = function (testName, expected, callback, async) { - if (arguments.length === 2) { - callback = expected; - expected = null; - } - - - return qTest(testName, expected, sinon.test(callback), async); - }; -}(this)); diff --git a/tests/qunit/vendor/sinon.js b/tests/qunit/vendor/sinon.js deleted file mode 100644 index 27a7ab4163..0000000000 --- a/tests/qunit/vendor/sinon.js +++ /dev/null @@ -1,4728 +0,0 @@ -/** - * Sinon.JS 1.8.2, 2014/02/11 - * - * @author Christian Johansen (christian@cjohansen.no) - * @author Contributors: https://github.com/cjohansen/Sinon.JS/blob/master/AUTHORS - * - * (The BSD License) - * - * Copyright (c) 2010-2014, Christian Johansen, christian@cjohansen.no - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * * Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * * Neither the name of Christian Johansen nor the names of his contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -this.sinon = (function () { -var samsam, formatio; -function define(mod, deps, fn) { if (mod == "samsam") { samsam = deps(); } else { formatio = fn(samsam); } } -define.amd = true; -((typeof define === "function" && define.amd && function (m) { define("samsam", m); }) || - (typeof module === "object" && - function (m) { module.exports = m(); }) || // Node - function (m) { this.samsam = m(); } // Browser globals -)(function () { - var o = Object.prototype; - var div = typeof document !== "undefined" && document.createElement("div"); - - function isNaN(value) { - // Unlike global isNaN, this avoids type coercion - // typeof check avoids IE host object issues, hat tip to - // lodash - var val = value; // JsLint thinks value !== value is "weird" - return typeof value === "number" && value !== val; - } - - function getClass(value) { - // Returns the internal [[Class]] by calling Object.prototype.toString - // with the provided value as this. Return value is a string, naming the - // internal class, e.g. "Array" - return o.toString.call(value).split(/[ \]]/)[1]; - } - - /** - * @name samsam.isArguments - * @param Object object - * - * Returns ``true`` if ``object`` is an ``arguments`` object, - * ``false`` otherwise. - */ - function isArguments(object) { - if (typeof object !== "object" || typeof object.length !== "number" || - getClass(object) === "Array") { - return false; - } - if (typeof object.callee == "function") { return true; } - try { - object[object.length] = 6; - delete object[object.length]; - } catch (e) { - return true; - } - return false; - } - - /** - * @name samsam.isElement - * @param Object object - * - * Returns ``true`` if ``object`` is a DOM element node. Unlike - * Underscore.js/lodash, this function will return ``false`` if ``object`` - * is an *element-like* object, i.e. a regular object with a ``nodeType`` - * property that holds the value ``1``. - */ - function isElement(object) { - if (!object || object.nodeType !== 1 || !div) { return false; } - try { - object.appendChild(div); - object.removeChild(div); - } catch (e) { - return false; - } - return true; - } - - /** - * @name samsam.keys - * @param Object object - * - * Return an array of own property names. - */ - function keys(object) { - var ks = [], prop; - for (prop in object) { - if (o.hasOwnProperty.call(object, prop)) { ks.push(prop); } - } - return ks; - } - - /** - * @name samsam.isDate - * @param Object value - * - * Returns true if the object is a ``Date``, or *date-like*. Duck typing - * of date objects work by checking that the object has a ``getTime`` - * function whose return value equals the return value from the object's - * ``valueOf``. - */ - function isDate(value) { - return typeof value.getTime == "function" && - value.getTime() == value.valueOf(); - } - - /** - * @name samsam.isNegZero - * @param Object value - * - * Returns ``true`` if ``value`` is ``-0``. - */ - function isNegZero(value) { - return value === 0 && 1 / value === -Infinity; - } - - /** - * @name samsam.equal - * @param Object obj1 - * @param Object obj2 - * - * Returns ``true`` if two objects are strictly equal. Compared to - * ``===`` there are two exceptions: - * - * - NaN is considered equal to NaN - * - -0 and +0 are not considered equal - */ - function identical(obj1, obj2) { - if (obj1 === obj2 || (isNaN(obj1) && isNaN(obj2))) { - return obj1 !== 0 || isNegZero(obj1) === isNegZero(obj2); - } - } - - - /** - * @name samsam.deepEqual - * @param Object obj1 - * @param Object obj2 - * - * Deep equal comparison. Two values are "deep equal" if: - * - * - They are equal, according to samsam.identical - * - They are both date objects representing the same time - * - They are both arrays containing elements that are all deepEqual - * - They are objects with the same set of properties, and each property - * in ``obj1`` is deepEqual to the corresponding property in ``obj2`` - * - * Supports cyclic objects. - */ - function deepEqualCyclic(obj1, obj2) { - - // used for cyclic comparison - // contain already visited objects - var objects1 = [], - objects2 = [], - // contain pathes (position in the object structure) - // of the already visited objects - // indexes same as in objects arrays - paths1 = [], - paths2 = [], - // contains combinations of already compared objects - // in the manner: { "$1['ref']$2['ref']": true } - compared = {}; - - /** - * used to check, if the value of a property is an object - * (cyclic logic is only needed for objects) - * only needed for cyclic logic - */ - function isObject(value) { - - if (typeof value === 'object' && value !== null && - !(value instanceof Boolean) && - !(value instanceof Date) && - !(value instanceof Number) && - !(value instanceof RegExp) && - !(value instanceof String)) { - - return true; - } - - return false; - } - - /** - * returns the index of the given object in the - * given objects array, -1 if not contained - * only needed for cyclic logic - */ - function getIndex(objects, obj) { - - var i; - for (i = 0; i < objects.length; i++) { - if (objects[i] === obj) { - return i; - } - } - - return -1; - } - - // does the recursion for the deep equal check - return (function deepEqual(obj1, obj2, path1, path2) { - var type1 = typeof obj1; - var type2 = typeof obj2; - - // == null also matches undefined - if (obj1 === obj2 || - isNaN(obj1) || isNaN(obj2) || - obj1 == null || obj2 == null || - type1 !== "object" || type2 !== "object") { - - return identical(obj1, obj2); - } - - // Elements are only equal if identical(expected, actual) - if (isElement(obj1) || isElement(obj2)) { return false; } - - var isDate1 = isDate(obj1), isDate2 = isDate(obj2); - if (isDate1 || isDate2) { - if (!isDate1 || !isDate2 || obj1.getTime() !== obj2.getTime()) { - return false; - } - } - - if (obj1 instanceof RegExp && obj2 instanceof RegExp) { - if (obj1.toString() !== obj2.toString()) { return false; } - } - - var class1 = getClass(obj1); - var class2 = getClass(obj2); - var keys1 = keys(obj1); - var keys2 = keys(obj2); - - if (isArguments(obj1) || isArguments(obj2)) { - if (obj1.length !== obj2.length) { return false; } - } else { - if (type1 !== type2 || class1 !== class2 || - keys1.length !== keys2.length) { - return false; - } - } - - var key, i, l, - // following vars are used for the cyclic logic - value1, value2, - isObject1, isObject2, - index1, index2, - newPath1, newPath2; - - for (i = 0, l = keys1.length; i < l; i++) { - key = keys1[i]; - if (!o.hasOwnProperty.call(obj2, key)) { - return false; - } - - // Start of the cyclic logic - - value1 = obj1[key]; - value2 = obj2[key]; - - isObject1 = isObject(value1); - isObject2 = isObject(value2); - - // determine, if the objects were already visited - // (it's faster to check for isObject first, than to - // get -1 from getIndex for non objects) - index1 = isObject1 ? getIndex(objects1, value1) : -1; - index2 = isObject2 ? getIndex(objects2, value2) : -1; - - // determine the new pathes of the objects - // - for non cyclic objects the current path will be extended - // by current property name - // - for cyclic objects the stored path is taken - newPath1 = index1 !== -1 - ? paths1[index1] - : path1 + '[' + JSON.stringify(key) + ']'; - newPath2 = index2 !== -1 - ? paths2[index2] - : path2 + '[' + JSON.stringify(key) + ']'; - - // stop recursion if current objects are already compared - if (compared[newPath1 + newPath2]) { - return true; - } - - // remember the current objects and their pathes - if (index1 === -1 && isObject1) { - objects1.push(value1); - paths1.push(newPath1); - } - if (index2 === -1 && isObject2) { - objects2.push(value2); - paths2.push(newPath2); - } - - // remember that the current objects are already compared - if (isObject1 && isObject2) { - compared[newPath1 + newPath2] = true; - } - - // End of cyclic logic - - // neither value1 nor value2 is a cycle - // continue with next level - if (!deepEqual(value1, value2, newPath1, newPath2)) { - return false; - } - } - - return true; - - }(obj1, obj2, '$1', '$2')); - } - - var match; - - function arrayContains(array, subset) { - if (subset.length === 0) { return true; } - var i, l, j, k; - for (i = 0, l = array.length; i < l; ++i) { - if (match(array[i], subset[0])) { - for (j = 0, k = subset.length; j < k; ++j) { - if (!match(array[i + j], subset[j])) { return false; } - } - return true; - } - } - return false; - } - - /** - * @name samsam.match - * @param Object object - * @param Object matcher - * - * Compare arbitrary value ``object`` with matcher. - */ - match = function match(object, matcher) { - if (matcher && typeof matcher.test === "function") { - return matcher.test(object); - } - - if (typeof matcher === "function") { - return matcher(object) === true; - } - - if (typeof matcher === "string") { - matcher = matcher.toLowerCase(); - var notNull = typeof object === "string" || !!object; - return notNull && - (String(object)).toLowerCase().indexOf(matcher) >= 0; - } - - if (typeof matcher === "number") { - return matcher === object; - } - - if (typeof matcher === "boolean") { - return matcher === object; - } - - if (getClass(object) === "Array" && getClass(matcher) === "Array") { - return arrayContains(object, matcher); - } - - if (matcher && typeof matcher === "object") { - var prop; - for (prop in matcher) { - if (!match(object[prop], matcher[prop])) { - return false; - } - } - return true; - } - - throw new Error("Matcher was not a string, a number, a " + - "function, a boolean or an object"); - }; - - return { - isArguments: isArguments, - isElement: isElement, - isDate: isDate, - isNegZero: isNegZero, - identical: identical, - deepEqual: deepEqualCyclic, - match: match, - keys: keys - }; -}); -((typeof define === "function" && define.amd && function (m) { - define("formatio", ["samsam"], m); -}) || (typeof module === "object" && function (m) { - module.exports = m(require("samsam")); -}) || function (m) { this.formatio = m(this.samsam); } -)(function (samsam) { - - var formatio = { - excludeConstructors: ["Object", /^.$/], - quoteStrings: true - }; - - var hasOwn = Object.prototype.hasOwnProperty; - - var specialObjects = []; - if (typeof global !== "undefined") { - specialObjects.push({ object: global, value: "[object global]" }); - } - if (typeof document !== "undefined") { - specialObjects.push({ - object: document, - value: "[object HTMLDocument]" - }); - } - if (typeof window !== "undefined") { - specialObjects.push({ object: window, value: "[object Window]" }); - } - - function functionName(func) { - if (!func) { return ""; } - if (func.displayName) { return func.displayName; } - if (func.name) { return func.name; } - var matches = func.toString().match(/function\s+([^\(]+)/m); - return (matches && matches[1]) || ""; - } - - function constructorName(f, object) { - var name = functionName(object && object.constructor); - var excludes = f.excludeConstructors || - formatio.excludeConstructors || []; - - var i, l; - for (i = 0, l = excludes.length; i < l; ++i) { - if (typeof excludes[i] === "string" && excludes[i] === name) { - return ""; - } else if (excludes[i].test && excludes[i].test(name)) { - return ""; - } - } - - return name; - } - - function isCircular(object, objects) { - if (typeof object !== "object") { return false; } - var i, l; - for (i = 0, l = objects.length; i < l; ++i) { - if (objects[i] === object) { return true; } - } - return false; - } - - function ascii(f, object, processed, indent) { - if (typeof object === "string") { - var qs = f.quoteStrings; - var quote = typeof qs !== "boolean" || qs; - return processed || quote ? '"' + object + '"' : object; - } - - if (typeof object === "function" && !(object instanceof RegExp)) { - return ascii.func(object); - } - - processed = processed || []; - - if (isCircular(object, processed)) { return "[Circular]"; } - - if (Object.prototype.toString.call(object) === "[object Array]") { - return ascii.array.call(f, object, processed); - } - - if (!object) { return String((1/object) === -Infinity ? "-0" : object); } - if (samsam.isElement(object)) { return ascii.element(object); } - - if (typeof object.toString === "function" && - object.toString !== Object.prototype.toString) { - return object.toString(); - } - - var i, l; - for (i = 0, l = specialObjects.length; i < l; i++) { - if (object === specialObjects[i].object) { - return specialObjects[i].value; - } - } - - return ascii.object.call(f, object, processed, indent); - } - - ascii.func = function (func) { - return "function " + functionName(func) + "() {}"; - }; - - ascii.array = function (array, processed) { - processed = processed || []; - processed.push(array); - var i, l, pieces = []; - for (i = 0, l = array.length; i < l; ++i) { - pieces.push(ascii(this, array[i], processed)); - } - return "[" + pieces.join(", ") + "]"; - }; - - ascii.object = function (object, processed, indent) { - processed = processed || []; - processed.push(object); - indent = indent || 0; - var pieces = [], properties = samsam.keys(object).sort(); - var length = 3; - var prop, str, obj, i, l; - - for (i = 0, l = properties.length; i < l; ++i) { - prop = properties[i]; - obj = object[prop]; - - if (isCircular(obj, processed)) { - str = "[Circular]"; - } else { - str = ascii(this, obj, processed, indent + 2); - } - - str = (/\s/.test(prop) ? '"' + prop + '"' : prop) + ": " + str; - length += str.length; - pieces.push(str); - } - - var cons = constructorName(this, object); - var prefix = cons ? "[" + cons + "] " : ""; - var is = ""; - for (i = 0, l = indent; i < l; ++i) { is += " "; } - - if (length + indent > 80) { - return prefix + "{\n " + is + pieces.join(",\n " + is) + "\n" + - is + "}"; - } - return prefix + "{ " + pieces.join(", ") + " }"; - }; - - ascii.element = function (element) { - var tagName = element.tagName.toLowerCase(); - var attrs = element.attributes, attr, pairs = [], attrName, i, l, val; - - for (i = 0, l = attrs.length; i < l; ++i) { - attr = attrs.item(i); - attrName = attr.nodeName.toLowerCase().replace("html:", ""); - val = attr.nodeValue; - if (attrName !== "contenteditable" || val !== "inherit") { - if (!!val) { pairs.push(attrName + "=\"" + val + "\""); } - } - } - - var formatted = "<" + tagName + (pairs.length > 0 ? " " : ""); - var content = element.innerHTML; - - if (content.length > 20) { - content = content.substr(0, 20) + "[...]"; - } - - var res = formatted + pairs.join(" ") + ">" + content + - ""; - - return res.replace(/ contentEditable="inherit"/, ""); - }; - - function Formatio(options) { - for (var opt in options) { - this[opt] = options[opt]; - } - } - - Formatio.prototype = { - functionName: functionName, - - configure: function (options) { - return new Formatio(options); - }, - - constructorName: function (object) { - return constructorName(this, object); - }, - - ascii: function (object, processed, indent) { - return ascii(this, object, processed, indent); - } - }; - - return Formatio.prototype; -}); -/*jslint eqeqeq: false, onevar: false, forin: true, nomen: false, regexp: false, plusplus: false*/ -/*global module, require, __dirname, document*/ -/** - * Sinon core utilities. For internal use only. - * - * @author Christian Johansen (christian@cjohansen.no) - * @license BSD - * - * Copyright (c) 2010-2013 Christian Johansen - */ - -var sinon = (function (formatio) { - var div = typeof document != "undefined" && document.createElement("div"); - var hasOwn = Object.prototype.hasOwnProperty; - - function isDOMNode(obj) { - var success = false; - - try { - obj.appendChild(div); - success = div.parentNode == obj; - } catch (e) { - return false; - } finally { - try { - obj.removeChild(div); - } catch (e) { - // Remove failed, not much we can do about that - } - } - - return success; - } - - function isElement(obj) { - return div && obj && obj.nodeType === 1 && isDOMNode(obj); - } - - function isFunction(obj) { - return typeof obj === "function" || !!(obj && obj.constructor && obj.call && obj.apply); - } - - function mirrorProperties(target, source) { - for (var prop in source) { - if (!hasOwn.call(target, prop)) { - target[prop] = source[prop]; - } - } - } - - function isRestorable (obj) { - return typeof obj === "function" && typeof obj.restore === "function" && obj.restore.sinon; - } - - var sinon = { - wrapMethod: function wrapMethod(object, property, method) { - if (!object) { - throw new TypeError("Should wrap property of object"); - } - - if (typeof method != "function") { - throw new TypeError("Method wrapper should be function"); - } - - var wrappedMethod = object[property], - error; - - if (!isFunction(wrappedMethod)) { - error = new TypeError("Attempted to wrap " + (typeof wrappedMethod) + " property " + - property + " as function"); - } - - if (wrappedMethod.restore && wrappedMethod.restore.sinon) { - error = new TypeError("Attempted to wrap " + property + " which is already wrapped"); - } - - if (wrappedMethod.calledBefore) { - var verb = !!wrappedMethod.returns ? "stubbed" : "spied on"; - error = new TypeError("Attempted to wrap " + property + " which is already " + verb); - } - - if (error) { - if (wrappedMethod._stack) { - error.stack += '\n--------------\n' + wrappedMethod._stack; - } - throw error; - } - - // IE 8 does not support hasOwnProperty on the window object and Firefox has a problem - // when using hasOwn.call on objects from other frames. - var owned = object.hasOwnProperty ? object.hasOwnProperty(property) : hasOwn.call(object, property); - object[property] = method; - method.displayName = property; - // Set up a stack trace which can be used later to find what line of - // code the original method was created on. - method._stack = (new Error('Stack Trace for original')).stack; - - method.restore = function () { - // For prototype properties try to reset by delete first. - // If this fails (ex: localStorage on mobile safari) then force a reset - // via direct assignment. - if (!owned) { - delete object[property]; - } - if (object[property] === method) { - object[property] = wrappedMethod; - } - }; - - method.restore.sinon = true; - mirrorProperties(method, wrappedMethod); - - return method; - }, - - extend: function extend(target) { - for (var i = 1, l = arguments.length; i < l; i += 1) { - for (var prop in arguments[i]) { - if (arguments[i].hasOwnProperty(prop)) { - target[prop] = arguments[i][prop]; - } - - // DONT ENUM bug, only care about toString - if (arguments[i].hasOwnProperty("toString") && - arguments[i].toString != target.toString) { - target.toString = arguments[i].toString; - } - } - } - - return target; - }, - - create: function create(proto) { - var F = function () {}; - F.prototype = proto; - return new F(); - }, - - deepEqual: function deepEqual(a, b) { - if (sinon.match && sinon.match.isMatcher(a)) { - return a.test(b); - } - if (typeof a != "object" || typeof b != "object") { - return a === b; - } - - if (isElement(a) || isElement(b)) { - return a === b; - } - - if (a === b) { - return true; - } - - if ((a === null && b !== null) || (a !== null && b === null)) { - return false; - } - - var aString = Object.prototype.toString.call(a); - if (aString != Object.prototype.toString.call(b)) { - return false; - } - - if (aString == "[object Date]") { - return a.valueOf() === b.valueOf(); - } - - var prop, aLength = 0, bLength = 0; - - if (aString == "[object Array]" && a.length !== b.length) { - return false; - } - - for (prop in a) { - aLength += 1; - - if (!deepEqual(a[prop], b[prop])) { - return false; - } - } - - for (prop in b) { - bLength += 1; - } - - return aLength == bLength; - }, - - functionName: function functionName(func) { - var name = func.displayName || func.name; - - // Use function decomposition as a last resort to get function - // name. Does not rely on function decomposition to work - if it - // doesn't debugging will be slightly less informative - // (i.e. toString will say 'spy' rather than 'myFunc'). - if (!name) { - var matches = func.toString().match(/function ([^\s\(]+)/); - name = matches && matches[1]; - } - - return name; - }, - - functionToString: function toString() { - if (this.getCall && this.callCount) { - var thisValue, prop, i = this.callCount; - - while (i--) { - thisValue = this.getCall(i).thisValue; - - for (prop in thisValue) { - if (thisValue[prop] === this) { - return prop; - } - } - } - } - - return this.displayName || "sinon fake"; - }, - - getConfig: function (custom) { - var config = {}; - custom = custom || {}; - var defaults = sinon.defaultConfig; - - for (var prop in defaults) { - if (defaults.hasOwnProperty(prop)) { - config[prop] = custom.hasOwnProperty(prop) ? custom[prop] : defaults[prop]; - } - } - - return config; - }, - - format: function (val) { - return "" + val; - }, - - defaultConfig: { - injectIntoThis: true, - injectInto: null, - properties: ["spy", "stub", "mock", "clock", "server", "requests"], - useFakeTimers: true, - useFakeServer: true - }, - - timesInWords: function timesInWords(count) { - return count == 1 && "once" || - count == 2 && "twice" || - count == 3 && "thrice" || - (count || 0) + " times"; - }, - - calledInOrder: function (spies) { - for (var i = 1, l = spies.length; i < l; i++) { - if (!spies[i - 1].calledBefore(spies[i]) || !spies[i].called) { - return false; - } - } - - return true; - }, - - orderByFirstCall: function (spies) { - return spies.sort(function (a, b) { - // uuid, won't ever be equal - var aCall = a.getCall(0); - var bCall = b.getCall(0); - var aId = aCall && aCall.callId || -1; - var bId = bCall && bCall.callId || -1; - - return aId < bId ? -1 : 1; - }); - }, - - log: function () {}, - - logError: function (label, err) { - var msg = label + " threw exception: "; - sinon.log(msg + "[" + err.name + "] " + err.message); - if (err.stack) { sinon.log(err.stack); } - - setTimeout(function () { - err.message = msg + err.message; - throw err; - }, 0); - }, - - typeOf: function (value) { - if (value === null) { - return "null"; - } - else if (value === undefined) { - return "undefined"; - } - var string = Object.prototype.toString.call(value); - return string.substring(8, string.length - 1).toLowerCase(); - }, - - createStubInstance: function (constructor) { - if (typeof constructor !== "function") { - throw new TypeError("The constructor should be a function."); - } - return sinon.stub(sinon.create(constructor.prototype)); - }, - - restore: function (object) { - if (object !== null && typeof object === "object") { - for (var prop in object) { - if (isRestorable(object[prop])) { - object[prop].restore(); - } - } - } - else if (isRestorable(object)) { - object.restore(); - } - } - }; - - var isNode = typeof module !== "undefined" && module.exports; - var isAMD = typeof define === 'function' && typeof define.amd === 'object' && define.amd; - - if (isAMD) { - define(function(){ - return sinon; - }); - } else if (isNode) { - try { - formatio = require("formatio"); - } catch (e) {} - module.exports = sinon; - module.exports.spy = require("./sinon/spy"); - module.exports.spyCall = require("./sinon/call"); - module.exports.behavior = require("./sinon/behavior"); - module.exports.stub = require("./sinon/stub"); - module.exports.mock = require("./sinon/mock"); - module.exports.collection = require("./sinon/collection"); - module.exports.assert = require("./sinon/assert"); - module.exports.sandbox = require("./sinon/sandbox"); - module.exports.test = require("./sinon/test"); - module.exports.testCase = require("./sinon/test_case"); - module.exports.assert = require("./sinon/assert"); - module.exports.match = require("./sinon/match"); - } - - if (formatio) { - var formatter = formatio.configure({ quoteStrings: false }); - sinon.format = function () { - return formatter.ascii.apply(formatter, arguments); - }; - } else if (isNode) { - try { - var util = require("util"); - sinon.format = function (value) { - return typeof value == "object" && value.toString === Object.prototype.toString ? util.inspect(value) : value; - }; - } catch (e) { - /* Node, but no util module - would be very old, but better safe than - sorry */ - } - } - - return sinon; -}(typeof formatio == "object" && formatio)); - -/* @depend ../sinon.js */ -/*jslint eqeqeq: false, onevar: false, plusplus: false*/ -/*global module, require, sinon*/ -/** - * Match functions - * - * @author Maximilian Antoni (mail@maxantoni.de) - * @license BSD - * - * Copyright (c) 2012 Maximilian Antoni - */ - -(function (sinon) { - var commonJSModule = typeof module !== 'undefined' && module.exports; - - if (!sinon && commonJSModule) { - sinon = require("../sinon"); - } - - if (!sinon) { - return; - } - - function assertType(value, type, name) { - var actual = sinon.typeOf(value); - if (actual !== type) { - throw new TypeError("Expected type of " + name + " to be " + - type + ", but was " + actual); - } - } - - var matcher = { - toString: function () { - return this.message; - } - }; - - function isMatcher(object) { - return matcher.isPrototypeOf(object); - } - - function matchObject(expectation, actual) { - if (actual === null || actual === undefined) { - return false; - } - for (var key in expectation) { - if (expectation.hasOwnProperty(key)) { - var exp = expectation[key]; - var act = actual[key]; - if (match.isMatcher(exp)) { - if (!exp.test(act)) { - return false; - } - } else if (sinon.typeOf(exp) === "object") { - if (!matchObject(exp, act)) { - return false; - } - } else if (!sinon.deepEqual(exp, act)) { - return false; - } - } - } - return true; - } - - matcher.or = function (m2) { - if (!isMatcher(m2)) { - throw new TypeError("Matcher expected"); - } - var m1 = this; - var or = sinon.create(matcher); - or.test = function (actual) { - return m1.test(actual) || m2.test(actual); - }; - or.message = m1.message + ".or(" + m2.message + ")"; - return or; - }; - - matcher.and = function (m2) { - if (!isMatcher(m2)) { - throw new TypeError("Matcher expected"); - } - var m1 = this; - var and = sinon.create(matcher); - and.test = function (actual) { - return m1.test(actual) && m2.test(actual); - }; - and.message = m1.message + ".and(" + m2.message + ")"; - return and; - }; - - var match = function (expectation, message) { - var m = sinon.create(matcher); - var type = sinon.typeOf(expectation); - switch (type) { - case "object": - if (typeof expectation.test === "function") { - m.test = function (actual) { - return expectation.test(actual) === true; - }; - m.message = "match(" + sinon.functionName(expectation.test) + ")"; - return m; - } - var str = []; - for (var key in expectation) { - if (expectation.hasOwnProperty(key)) { - str.push(key + ": " + expectation[key]); - } - } - m.test = function (actual) { - return matchObject(expectation, actual); - }; - m.message = "match(" + str.join(", ") + ")"; - break; - case "number": - m.test = function (actual) { - return expectation == actual; - }; - break; - case "string": - m.test = function (actual) { - if (typeof actual !== "string") { - return false; - } - return actual.indexOf(expectation) !== -1; - }; - m.message = "match(\"" + expectation + "\")"; - break; - case "regexp": - m.test = function (actual) { - if (typeof actual !== "string") { - return false; - } - return expectation.test(actual); - }; - break; - case "function": - m.test = expectation; - if (message) { - m.message = message; - } else { - m.message = "match(" + sinon.functionName(expectation) + ")"; - } - break; - default: - m.test = function (actual) { - return sinon.deepEqual(expectation, actual); - }; - } - if (!m.message) { - m.message = "match(" + expectation + ")"; - } - return m; - }; - - match.isMatcher = isMatcher; - - match.any = match(function () { - return true; - }, "any"); - - match.defined = match(function (actual) { - return actual !== null && actual !== undefined; - }, "defined"); - - match.truthy = match(function (actual) { - return !!actual; - }, "truthy"); - - match.falsy = match(function (actual) { - return !actual; - }, "falsy"); - - match.same = function (expectation) { - return match(function (actual) { - return expectation === actual; - }, "same(" + expectation + ")"); - }; - - match.typeOf = function (type) { - assertType(type, "string", "type"); - return match(function (actual) { - return sinon.typeOf(actual) === type; - }, "typeOf(\"" + type + "\")"); - }; - - match.instanceOf = function (type) { - assertType(type, "function", "type"); - return match(function (actual) { - return actual instanceof type; - }, "instanceOf(" + sinon.functionName(type) + ")"); - }; - - function createPropertyMatcher(propertyTest, messagePrefix) { - return function (property, value) { - assertType(property, "string", "property"); - var onlyProperty = arguments.length === 1; - var message = messagePrefix + "(\"" + property + "\""; - if (!onlyProperty) { - message += ", " + value; - } - message += ")"; - return match(function (actual) { - if (actual === undefined || actual === null || - !propertyTest(actual, property)) { - return false; - } - return onlyProperty || sinon.deepEqual(value, actual[property]); - }, message); - }; - } - - match.has = createPropertyMatcher(function (actual, property) { - if (typeof actual === "object") { - return property in actual; - } - return actual[property] !== undefined; - }, "has"); - - match.hasOwn = createPropertyMatcher(function (actual, property) { - return actual.hasOwnProperty(property); - }, "hasOwn"); - - match.bool = match.typeOf("boolean"); - match.number = match.typeOf("number"); - match.string = match.typeOf("string"); - match.object = match.typeOf("object"); - match.func = match.typeOf("function"); - match.array = match.typeOf("array"); - match.regexp = match.typeOf("regexp"); - match.date = match.typeOf("date"); - - if (commonJSModule) { - module.exports = match; - } else { - sinon.match = match; - } -}(typeof sinon == "object" && sinon || null)); - -/** - * @depend ../sinon.js - * @depend match.js - */ -/*jslint eqeqeq: false, onevar: false, plusplus: false*/ -/*global module, require, sinon*/ -/** - * Spy calls - * - * @author Christian Johansen (christian@cjohansen.no) - * @author Maximilian Antoni (mail@maxantoni.de) - * @license BSD - * - * Copyright (c) 2010-2013 Christian Johansen - * Copyright (c) 2013 Maximilian Antoni - */ - -(function (sinon) { - var commonJSModule = typeof module !== 'undefined' && module.exports; - if (!sinon && commonJSModule) { - sinon = require("../sinon"); - } - - if (!sinon) { - return; - } - - function throwYieldError(proxy, text, args) { - var msg = sinon.functionName(proxy) + text; - if (args.length) { - msg += " Received [" + slice.call(args).join(", ") + "]"; - } - throw new Error(msg); - } - - var slice = Array.prototype.slice; - - var callProto = { - calledOn: function calledOn(thisValue) { - if (sinon.match && sinon.match.isMatcher(thisValue)) { - return thisValue.test(this.thisValue); - } - return this.thisValue === thisValue; - }, - - calledWith: function calledWith() { - for (var i = 0, l = arguments.length; i < l; i += 1) { - if (!sinon.deepEqual(arguments[i], this.args[i])) { - return false; - } - } - - return true; - }, - - calledWithMatch: function calledWithMatch() { - for (var i = 0, l = arguments.length; i < l; i += 1) { - var actual = this.args[i]; - var expectation = arguments[i]; - if (!sinon.match || !sinon.match(expectation).test(actual)) { - return false; - } - } - return true; - }, - - calledWithExactly: function calledWithExactly() { - return arguments.length == this.args.length && - this.calledWith.apply(this, arguments); - }, - - notCalledWith: function notCalledWith() { - return !this.calledWith.apply(this, arguments); - }, - - notCalledWithMatch: function notCalledWithMatch() { - return !this.calledWithMatch.apply(this, arguments); - }, - - returned: function returned(value) { - return sinon.deepEqual(value, this.returnValue); - }, - - threw: function threw(error) { - if (typeof error === "undefined" || !this.exception) { - return !!this.exception; - } - - return this.exception === error || this.exception.name === error; - }, - - calledWithNew: function calledWithNew() { - return this.proxy.prototype && this.thisValue instanceof this.proxy; - }, - - calledBefore: function (other) { - return this.callId < other.callId; - }, - - calledAfter: function (other) { - return this.callId > other.callId; - }, - - callArg: function (pos) { - this.args[pos](); - }, - - callArgOn: function (pos, thisValue) { - this.args[pos].apply(thisValue); - }, - - callArgWith: function (pos) { - this.callArgOnWith.apply(this, [pos, null].concat(slice.call(arguments, 1))); - }, - - callArgOnWith: function (pos, thisValue) { - var args = slice.call(arguments, 2); - this.args[pos].apply(thisValue, args); - }, - - "yield": function () { - this.yieldOn.apply(this, [null].concat(slice.call(arguments, 0))); - }, - - yieldOn: function (thisValue) { - var args = this.args; - for (var i = 0, l = args.length; i < l; ++i) { - if (typeof args[i] === "function") { - args[i].apply(thisValue, slice.call(arguments, 1)); - return; - } - } - throwYieldError(this.proxy, " cannot yield since no callback was passed.", args); - }, - - yieldTo: function (prop) { - this.yieldToOn.apply(this, [prop, null].concat(slice.call(arguments, 1))); - }, - - yieldToOn: function (prop, thisValue) { - var args = this.args; - for (var i = 0, l = args.length; i < l; ++i) { - if (args[i] && typeof args[i][prop] === "function") { - args[i][prop].apply(thisValue, slice.call(arguments, 2)); - return; - } - } - throwYieldError(this.proxy, " cannot yield to '" + prop + - "' since no callback was passed.", args); - }, - - toString: function () { - var callStr = this.proxy.toString() + "("; - var args = []; - - for (var i = 0, l = this.args.length; i < l; ++i) { - args.push(sinon.format(this.args[i])); - } - - callStr = callStr + args.join(", ") + ")"; - - if (typeof this.returnValue != "undefined") { - callStr += " => " + sinon.format(this.returnValue); - } - - if (this.exception) { - callStr += " !" + this.exception.name; - - if (this.exception.message) { - callStr += "(" + this.exception.message + ")"; - } - } - - return callStr; - } - }; - - callProto.invokeCallback = callProto.yield; - - function createSpyCall(spy, thisValue, args, returnValue, exception, id) { - if (typeof id !== "number") { - throw new TypeError("Call id is not a number"); - } - var proxyCall = sinon.create(callProto); - proxyCall.proxy = spy; - proxyCall.thisValue = thisValue; - proxyCall.args = args; - proxyCall.returnValue = returnValue; - proxyCall.exception = exception; - proxyCall.callId = id; - - return proxyCall; - } - createSpyCall.toString = callProto.toString; // used by mocks - - if (commonJSModule) { - module.exports = createSpyCall; - } else { - sinon.spyCall = createSpyCall; - } -}(typeof sinon == "object" && sinon || null)); - - -/** - * @depend ../sinon.js - * @depend call.js - */ -/*jslint eqeqeq: false, onevar: false, plusplus: false*/ -/*global module, require, sinon*/ -/** - * Spy functions - * - * @author Christian Johansen (christian@cjohansen.no) - * @license BSD - * - * Copyright (c) 2010-2013 Christian Johansen - */ - -(function (sinon) { - var commonJSModule = typeof module !== 'undefined' && module.exports; - var push = Array.prototype.push; - var slice = Array.prototype.slice; - var callId = 0; - - if (!sinon && commonJSModule) { - sinon = require("../sinon"); - } - - if (!sinon) { - return; - } - - function spy(object, property) { - if (!property && typeof object == "function") { - return spy.create(object); - } - - if (!object && !property) { - return spy.create(function () { }); - } - - var method = object[property]; - return sinon.wrapMethod(object, property, spy.create(method)); - } - - function matchingFake(fakes, args, strict) { - if (!fakes) { - return; - } - - for (var i = 0, l = fakes.length; i < l; i++) { - if (fakes[i].matches(args, strict)) { - return fakes[i]; - } - } - } - - function incrementCallCount() { - this.called = true; - this.callCount += 1; - this.notCalled = false; - this.calledOnce = this.callCount == 1; - this.calledTwice = this.callCount == 2; - this.calledThrice = this.callCount == 3; - } - - function createCallProperties() { - this.firstCall = this.getCall(0); - this.secondCall = this.getCall(1); - this.thirdCall = this.getCall(2); - this.lastCall = this.getCall(this.callCount - 1); - } - - var vars = "a,b,c,d,e,f,g,h,i,j,k,l"; - function createProxy(func) { - // Retain the function length: - var p; - if (func.length) { - eval("p = (function proxy(" + vars.substring(0, func.length * 2 - 1) + - ") { return p.invoke(func, this, slice.call(arguments)); });"); - } - else { - p = function proxy() { - return p.invoke(func, this, slice.call(arguments)); - }; - } - return p; - } - - var uuid = 0; - - // Public API - var spyApi = { - reset: function () { - this.called = false; - this.notCalled = true; - this.calledOnce = false; - this.calledTwice = false; - this.calledThrice = false; - this.callCount = 0; - this.firstCall = null; - this.secondCall = null; - this.thirdCall = null; - this.lastCall = null; - this.args = []; - this.returnValues = []; - this.thisValues = []; - this.exceptions = []; - this.callIds = []; - if (this.fakes) { - for (var i = 0; i < this.fakes.length; i++) { - this.fakes[i].reset(); - } - } - }, - - create: function create(func) { - var name; - - if (typeof func != "function") { - func = function () { }; - } else { - name = sinon.functionName(func); - } - - var proxy = createProxy(func); - - sinon.extend(proxy, spy); - delete proxy.create; - sinon.extend(proxy, func); - - proxy.reset(); - proxy.prototype = func.prototype; - proxy.displayName = name || "spy"; - proxy.toString = sinon.functionToString; - proxy._create = sinon.spy.create; - proxy.id = "spy#" + uuid++; - - return proxy; - }, - - invoke: function invoke(func, thisValue, args) { - var matching = matchingFake(this.fakes, args); - var exception, returnValue; - - incrementCallCount.call(this); - push.call(this.thisValues, thisValue); - push.call(this.args, args); - push.call(this.callIds, callId++); - - try { - if (matching) { - returnValue = matching.invoke(func, thisValue, args); - } else { - returnValue = (this.func || func).apply(thisValue, args); - } - - var thisCall = this.getCall(this.callCount - 1); - if (thisCall.calledWithNew() && typeof returnValue !== 'object') { - returnValue = thisValue; - } - } catch (e) { - exception = e; - } - - push.call(this.exceptions, exception); - push.call(this.returnValues, returnValue); - - createCallProperties.call(this); - - if (exception !== undefined) { - throw exception; - } - - return returnValue; - }, - - getCall: function getCall(i) { - if (i < 0 || i >= this.callCount) { - return null; - } - - return sinon.spyCall(this, this.thisValues[i], this.args[i], - this.returnValues[i], this.exceptions[i], - this.callIds[i]); - }, - - getCalls: function () { - var calls = []; - var i; - - for (i = 0; i < this.callCount; i++) { - calls.push(this.getCall(i)); - } - - return calls; - }, - - calledBefore: function calledBefore(spyFn) { - if (!this.called) { - return false; - } - - if (!spyFn.called) { - return true; - } - - return this.callIds[0] < spyFn.callIds[spyFn.callIds.length - 1]; - }, - - calledAfter: function calledAfter(spyFn) { - if (!this.called || !spyFn.called) { - return false; - } - - return this.callIds[this.callCount - 1] > spyFn.callIds[spyFn.callCount - 1]; - }, - - withArgs: function () { - var args = slice.call(arguments); - - if (this.fakes) { - var match = matchingFake(this.fakes, args, true); - - if (match) { - return match; - } - } else { - this.fakes = []; - } - - var original = this; - var fake = this._create(); - fake.matchingAguments = args; - fake.parent = this; - push.call(this.fakes, fake); - - fake.withArgs = function () { - return original.withArgs.apply(original, arguments); - }; - - for (var i = 0; i < this.args.length; i++) { - if (fake.matches(this.args[i])) { - incrementCallCount.call(fake); - push.call(fake.thisValues, this.thisValues[i]); - push.call(fake.args, this.args[i]); - push.call(fake.returnValues, this.returnValues[i]); - push.call(fake.exceptions, this.exceptions[i]); - push.call(fake.callIds, this.callIds[i]); - } - } - createCallProperties.call(fake); - - return fake; - }, - - matches: function (args, strict) { - var margs = this.matchingAguments; - - if (margs.length <= args.length && - sinon.deepEqual(margs, args.slice(0, margs.length))) { - return !strict || margs.length == args.length; - } - }, - - printf: function (format) { - var spy = this; - var args = slice.call(arguments, 1); - var formatter; - - return (format || "").replace(/%(.)/g, function (match, specifyer) { - formatter = spyApi.formatters[specifyer]; - - if (typeof formatter == "function") { - return formatter.call(null, spy, args); - } else if (!isNaN(parseInt(specifyer, 10))) { - return sinon.format(args[specifyer - 1]); - } - - return "%" + specifyer; - }); - } - }; - - function delegateToCalls(method, matchAny, actual, notCalled) { - spyApi[method] = function () { - if (!this.called) { - if (notCalled) { - return notCalled.apply(this, arguments); - } - return false; - } - - var currentCall; - var matches = 0; - - for (var i = 0, l = this.callCount; i < l; i += 1) { - currentCall = this.getCall(i); - - if (currentCall[actual || method].apply(currentCall, arguments)) { - matches += 1; - - if (matchAny) { - return true; - } - } - } - - return matches === this.callCount; - }; - } - - delegateToCalls("calledOn", true); - delegateToCalls("alwaysCalledOn", false, "calledOn"); - delegateToCalls("calledWith", true); - delegateToCalls("calledWithMatch", true); - delegateToCalls("alwaysCalledWith", false, "calledWith"); - delegateToCalls("alwaysCalledWithMatch", false, "calledWithMatch"); - delegateToCalls("calledWithExactly", true); - delegateToCalls("alwaysCalledWithExactly", false, "calledWithExactly"); - delegateToCalls("neverCalledWith", false, "notCalledWith", - function () { return true; }); - delegateToCalls("neverCalledWithMatch", false, "notCalledWithMatch", - function () { return true; }); - delegateToCalls("threw", true); - delegateToCalls("alwaysThrew", false, "threw"); - delegateToCalls("returned", true); - delegateToCalls("alwaysReturned", false, "returned"); - delegateToCalls("calledWithNew", true); - delegateToCalls("alwaysCalledWithNew", false, "calledWithNew"); - delegateToCalls("callArg", false, "callArgWith", function () { - throw new Error(this.toString() + " cannot call arg since it was not yet invoked."); - }); - spyApi.callArgWith = spyApi.callArg; - delegateToCalls("callArgOn", false, "callArgOnWith", function () { - throw new Error(this.toString() + " cannot call arg since it was not yet invoked."); - }); - spyApi.callArgOnWith = spyApi.callArgOn; - delegateToCalls("yield", false, "yield", function () { - throw new Error(this.toString() + " cannot yield since it was not yet invoked."); - }); - // "invokeCallback" is an alias for "yield" since "yield" is invalid in strict mode. - spyApi.invokeCallback = spyApi.yield; - delegateToCalls("yieldOn", false, "yieldOn", function () { - throw new Error(this.toString() + " cannot yield since it was not yet invoked."); - }); - delegateToCalls("yieldTo", false, "yieldTo", function (property) { - throw new Error(this.toString() + " cannot yield to '" + property + - "' since it was not yet invoked."); - }); - delegateToCalls("yieldToOn", false, "yieldToOn", function (property) { - throw new Error(this.toString() + " cannot yield to '" + property + - "' since it was not yet invoked."); - }); - - spyApi.formatters = { - "c": function (spy) { - return sinon.timesInWords(spy.callCount); - }, - - "n": function (spy) { - return spy.toString(); - }, - - "C": function (spy) { - var calls = []; - - for (var i = 0, l = spy.callCount; i < l; ++i) { - var stringifiedCall = " " + spy.getCall(i).toString(); - if (/\n/.test(calls[i - 1])) { - stringifiedCall = "\n" + stringifiedCall; - } - push.call(calls, stringifiedCall); - } - - return calls.length > 0 ? "\n" + calls.join("\n") : ""; - }, - - "t": function (spy) { - var objects = []; - - for (var i = 0, l = spy.callCount; i < l; ++i) { - push.call(objects, sinon.format(spy.thisValues[i])); - } - - return objects.join(", "); - }, - - "*": function (spy, args) { - var formatted = []; - - for (var i = 0, l = args.length; i < l; ++i) { - push.call(formatted, sinon.format(args[i])); - } - - return formatted.join(", "); - } - }; - - sinon.extend(spy, spyApi); - - spy.spyCall = sinon.spyCall; - - if (commonJSModule) { - module.exports = spy; - } else { - sinon.spy = spy; - } -}(typeof sinon == "object" && sinon || null)); - -/** - * @depend ../sinon.js - */ -/*jslint eqeqeq: false, onevar: false*/ -/*global module, require, sinon, process, setImmediate, setTimeout*/ -/** - * Stub behavior - * - * @author Christian Johansen (christian@cjohansen.no) - * @author Tim Fischbach (mail@timfischbach.de) - * @license BSD - * - * Copyright (c) 2010-2013 Christian Johansen - */ - -(function (sinon) { - var commonJSModule = typeof module !== 'undefined' && module.exports; - - if (!sinon && commonJSModule) { - sinon = require("../sinon"); - } - - if (!sinon) { - return; - } - - var slice = Array.prototype.slice; - var join = Array.prototype.join; - var proto; - - var nextTick = (function () { - if (typeof process === "object" && typeof process.nextTick === "function") { - return process.nextTick; - } else if (typeof setImmediate === "function") { - return setImmediate; - } else { - return function (callback) { - setTimeout(callback, 0); - }; - } - })(); - - function throwsException(error, message) { - if (typeof error == "string") { - this.exception = new Error(message || ""); - this.exception.name = error; - } else if (!error) { - this.exception = new Error("Error"); - } else { - this.exception = error; - } - - return this; - } - - function getCallback(behavior, args) { - var callArgAt = behavior.callArgAt; - - if (callArgAt < 0) { - var callArgProp = behavior.callArgProp; - - for (var i = 0, l = args.length; i < l; ++i) { - if (!callArgProp && typeof args[i] == "function") { - return args[i]; - } - - if (callArgProp && args[i] && - typeof args[i][callArgProp] == "function") { - return args[i][callArgProp]; - } - } - - return null; - } - - return args[callArgAt]; - } - - function getCallbackError(behavior, func, args) { - if (behavior.callArgAt < 0) { - var msg; - - if (behavior.callArgProp) { - msg = sinon.functionName(behavior.stub) + - " expected to yield to '" + behavior.callArgProp + - "', but no object with such a property was passed."; - } else { - msg = sinon.functionName(behavior.stub) + - " expected to yield, but no callback was passed."; - } - - if (args.length > 0) { - msg += " Received [" + join.call(args, ", ") + "]"; - } - - return msg; - } - - return "argument at index " + behavior.callArgAt + " is not a function: " + func; - } - - function callCallback(behavior, args) { - if (typeof behavior.callArgAt == "number") { - var func = getCallback(behavior, args); - - if (typeof func != "function") { - throw new TypeError(getCallbackError(behavior, func, args)); - } - - if (behavior.callbackAsync) { - nextTick(function() { - func.apply(behavior.callbackContext, behavior.callbackArguments); - }); - } else { - func.apply(behavior.callbackContext, behavior.callbackArguments); - } - } - } - - proto = { - create: function(stub) { - var behavior = sinon.extend({}, sinon.behavior); - delete behavior.create; - behavior.stub = stub; - - return behavior; - }, - - isPresent: function() { - return (typeof this.callArgAt == 'number' || - this.exception || - typeof this.returnArgAt == 'number' || - this.returnThis || - this.returnValueDefined); - }, - - invoke: function(context, args) { - callCallback(this, args); - - if (this.exception) { - throw this.exception; - } else if (typeof this.returnArgAt == 'number') { - return args[this.returnArgAt]; - } else if (this.returnThis) { - return context; - } - - return this.returnValue; - }, - - onCall: function(index) { - return this.stub.onCall(index); - }, - - onFirstCall: function() { - return this.stub.onFirstCall(); - }, - - onSecondCall: function() { - return this.stub.onSecondCall(); - }, - - onThirdCall: function() { - return this.stub.onThirdCall(); - }, - - withArgs: function(/* arguments */) { - throw new Error('Defining a stub by invoking "stub.onCall(...).withArgs(...)" is not supported. ' + - 'Use "stub.withArgs(...).onCall(...)" to define sequential behavior for calls with certain arguments.'); - }, - - callsArg: function callsArg(pos) { - if (typeof pos != "number") { - throw new TypeError("argument index is not number"); - } - - this.callArgAt = pos; - this.callbackArguments = []; - this.callbackContext = undefined; - this.callArgProp = undefined; - this.callbackAsync = false; - - return this; - }, - - callsArgOn: function callsArgOn(pos, context) { - if (typeof pos != "number") { - throw new TypeError("argument index is not number"); - } - if (typeof context != "object") { - throw new TypeError("argument context is not an object"); - } - - this.callArgAt = pos; - this.callbackArguments = []; - this.callbackContext = context; - this.callArgProp = undefined; - this.callbackAsync = false; - - return this; - }, - - callsArgWith: function callsArgWith(pos) { - if (typeof pos != "number") { - throw new TypeError("argument index is not number"); - } - - this.callArgAt = pos; - this.callbackArguments = slice.call(arguments, 1); - this.callbackContext = undefined; - this.callArgProp = undefined; - this.callbackAsync = false; - - return this; - }, - - callsArgOnWith: function callsArgWith(pos, context) { - if (typeof pos != "number") { - throw new TypeError("argument index is not number"); - } - if (typeof context != "object") { - throw new TypeError("argument context is not an object"); - } - - this.callArgAt = pos; - this.callbackArguments = slice.call(arguments, 2); - this.callbackContext = context; - this.callArgProp = undefined; - this.callbackAsync = false; - - return this; - }, - - yields: function () { - this.callArgAt = -1; - this.callbackArguments = slice.call(arguments, 0); - this.callbackContext = undefined; - this.callArgProp = undefined; - this.callbackAsync = false; - - return this; - }, - - yieldsOn: function (context) { - if (typeof context != "object") { - throw new TypeError("argument context is not an object"); - } - - this.callArgAt = -1; - this.callbackArguments = slice.call(arguments, 1); - this.callbackContext = context; - this.callArgProp = undefined; - this.callbackAsync = false; - - return this; - }, - - yieldsTo: function (prop) { - this.callArgAt = -1; - this.callbackArguments = slice.call(arguments, 1); - this.callbackContext = undefined; - this.callArgProp = prop; - this.callbackAsync = false; - - return this; - }, - - yieldsToOn: function (prop, context) { - if (typeof context != "object") { - throw new TypeError("argument context is not an object"); - } - - this.callArgAt = -1; - this.callbackArguments = slice.call(arguments, 2); - this.callbackContext = context; - this.callArgProp = prop; - this.callbackAsync = false; - - return this; - }, - - - "throws": throwsException, - throwsException: throwsException, - - returns: function returns(value) { - this.returnValue = value; - this.returnValueDefined = true; - - return this; - }, - - returnsArg: function returnsArg(pos) { - if (typeof pos != "number") { - throw new TypeError("argument index is not number"); - } - - this.returnArgAt = pos; - - return this; - }, - - returnsThis: function returnsThis() { - this.returnThis = true; - - return this; - } - }; - - // create asynchronous versions of callsArg* and yields* methods - for (var method in proto) { - // need to avoid creating anotherasync versions of the newly added async methods - if (proto.hasOwnProperty(method) && - method.match(/^(callsArg|yields)/) && - !method.match(/Async/)) { - proto[method + 'Async'] = (function (syncFnName) { - return function () { - var result = this[syncFnName].apply(this, arguments); - this.callbackAsync = true; - return result; - }; - })(method); - } - } - - if (commonJSModule) { - module.exports = proto; - } else { - sinon.behavior = proto; - } -}(typeof sinon == "object" && sinon || null)); -/** - * @depend ../sinon.js - * @depend spy.js - * @depend behavior.js - */ -/*jslint eqeqeq: false, onevar: false*/ -/*global module, require, sinon*/ -/** - * Stub functions - * - * @author Christian Johansen (christian@cjohansen.no) - * @license BSD - * - * Copyright (c) 2010-2013 Christian Johansen - */ - -(function (sinon) { - var commonJSModule = typeof module !== 'undefined' && module.exports; - - if (!sinon && commonJSModule) { - sinon = require("../sinon"); - } - - if (!sinon) { - return; - } - - function stub(object, property, func) { - if (!!func && typeof func != "function") { - throw new TypeError("Custom stub should be function"); - } - - var wrapper; - - if (func) { - wrapper = sinon.spy && sinon.spy.create ? sinon.spy.create(func) : func; - } else { - wrapper = stub.create(); - } - - if (!object && typeof property === "undefined") { - return sinon.stub.create(); - } - - if (typeof property === "undefined" && typeof object == "object") { - for (var prop in object) { - if (typeof object[prop] === "function") { - stub(object, prop); - } - } - - return object; - } - - return sinon.wrapMethod(object, property, wrapper); - } - - function getDefaultBehavior(stub) { - return stub.defaultBehavior || getParentBehaviour(stub) || sinon.behavior.create(stub); - } - - function getParentBehaviour(stub) { - return (stub.parent && getCurrentBehavior(stub.parent)); - } - - function getCurrentBehavior(stub) { - var behavior = stub.behaviors[stub.callCount - 1]; - return behavior && behavior.isPresent() ? behavior : getDefaultBehavior(stub); - } - - var uuid = 0; - - sinon.extend(stub, (function () { - var proto = { - create: function create() { - var functionStub = function () { - return getCurrentBehavior(functionStub).invoke(this, arguments); - }; - - functionStub.id = "stub#" + uuid++; - var orig = functionStub; - functionStub = sinon.spy.create(functionStub); - functionStub.func = orig; - - sinon.extend(functionStub, stub); - functionStub._create = sinon.stub.create; - functionStub.displayName = "stub"; - functionStub.toString = sinon.functionToString; - - functionStub.defaultBehavior = null; - functionStub.behaviors = []; - - return functionStub; - }, - - resetBehavior: function () { - var i; - - this.defaultBehavior = null; - this.behaviors = []; - - delete this.returnValue; - delete this.returnArgAt; - this.returnThis = false; - - if (this.fakes) { - for (i = 0; i < this.fakes.length; i++) { - this.fakes[i].resetBehavior(); - } - } - }, - - onCall: function(index) { - if (!this.behaviors[index]) { - this.behaviors[index] = sinon.behavior.create(this); - } - - return this.behaviors[index]; - }, - - onFirstCall: function() { - return this.onCall(0); - }, - - onSecondCall: function() { - return this.onCall(1); - }, - - onThirdCall: function() { - return this.onCall(2); - } - }; - - for (var method in sinon.behavior) { - if (sinon.behavior.hasOwnProperty(method) && - !proto.hasOwnProperty(method) && - method != 'create' && - method != 'withArgs' && - method != 'invoke') { - proto[method] = (function(behaviorMethod) { - return function() { - this.defaultBehavior = this.defaultBehavior || sinon.behavior.create(this); - this.defaultBehavior[behaviorMethod].apply(this.defaultBehavior, arguments); - return this; - }; - }(method)); - } - } - - return proto; - }())); - - if (commonJSModule) { - module.exports = stub; - } else { - sinon.stub = stub; - } -}(typeof sinon == "object" && sinon || null)); - -/** - * @depend ../sinon.js - * @depend stub.js - */ -/*jslint eqeqeq: false, onevar: false, nomen: false*/ -/*global module, require, sinon*/ -/** - * Mock functions. - * - * @author Christian Johansen (christian@cjohansen.no) - * @license BSD - * - * Copyright (c) 2010-2013 Christian Johansen - */ - -(function (sinon) { - var commonJSModule = typeof module !== 'undefined' && module.exports; - var push = [].push; - var match; - - if (!sinon && commonJSModule) { - sinon = require("../sinon"); - } - - if (!sinon) { - return; - } - - match = sinon.match; - - if (!match && commonJSModule) { - match = require("./match"); - } - - function mock(object) { - if (!object) { - return sinon.expectation.create("Anonymous mock"); - } - - return mock.create(object); - } - - sinon.mock = mock; - - sinon.extend(mock, (function () { - function each(collection, callback) { - if (!collection) { - return; - } - - for (var i = 0, l = collection.length; i < l; i += 1) { - callback(collection[i]); - } - } - - return { - create: function create(object) { - if (!object) { - throw new TypeError("object is null"); - } - - var mockObject = sinon.extend({}, mock); - mockObject.object = object; - delete mockObject.create; - - return mockObject; - }, - - expects: function expects(method) { - if (!method) { - throw new TypeError("method is falsy"); - } - - if (!this.expectations) { - this.expectations = {}; - this.proxies = []; - } - - if (!this.expectations[method]) { - this.expectations[method] = []; - var mockObject = this; - - sinon.wrapMethod(this.object, method, function () { - return mockObject.invokeMethod(method, this, arguments); - }); - - push.call(this.proxies, method); - } - - var expectation = sinon.expectation.create(method); - push.call(this.expectations[method], expectation); - - return expectation; - }, - - restore: function restore() { - var object = this.object; - - each(this.proxies, function (proxy) { - if (typeof object[proxy].restore == "function") { - object[proxy].restore(); - } - }); - }, - - verify: function verify() { - var expectations = this.expectations || {}; - var messages = [], met = []; - - each(this.proxies, function (proxy) { - each(expectations[proxy], function (expectation) { - if (!expectation.met()) { - push.call(messages, expectation.toString()); - } else { - push.call(met, expectation.toString()); - } - }); - }); - - this.restore(); - - if (messages.length > 0) { - sinon.expectation.fail(messages.concat(met).join("\n")); - } else { - sinon.expectation.pass(messages.concat(met).join("\n")); - } - - return true; - }, - - invokeMethod: function invokeMethod(method, thisValue, args) { - var expectations = this.expectations && this.expectations[method]; - var length = expectations && expectations.length || 0, i; - - for (i = 0; i < length; i += 1) { - if (!expectations[i].met() && - expectations[i].allowsCall(thisValue, args)) { - return expectations[i].apply(thisValue, args); - } - } - - var messages = [], available, exhausted = 0; - - for (i = 0; i < length; i += 1) { - if (expectations[i].allowsCall(thisValue, args)) { - available = available || expectations[i]; - } else { - exhausted += 1; - } - push.call(messages, " " + expectations[i].toString()); - } - - if (exhausted === 0) { - return available.apply(thisValue, args); - } - - messages.unshift("Unexpected call: " + sinon.spyCall.toString.call({ - proxy: method, - args: args - })); - - sinon.expectation.fail(messages.join("\n")); - } - }; - }())); - - var times = sinon.timesInWords; - - sinon.expectation = (function () { - var slice = Array.prototype.slice; - var _invoke = sinon.spy.invoke; - - function callCountInWords(callCount) { - if (callCount == 0) { - return "never called"; - } else { - return "called " + times(callCount); - } - } - - function expectedCallCountInWords(expectation) { - var min = expectation.minCalls; - var max = expectation.maxCalls; - - if (typeof min == "number" && typeof max == "number") { - var str = times(min); - - if (min != max) { - str = "at least " + str + " and at most " + times(max); - } - - return str; - } - - if (typeof min == "number") { - return "at least " + times(min); - } - - return "at most " + times(max); - } - - function receivedMinCalls(expectation) { - var hasMinLimit = typeof expectation.minCalls == "number"; - return !hasMinLimit || expectation.callCount >= expectation.minCalls; - } - - function receivedMaxCalls(expectation) { - if (typeof expectation.maxCalls != "number") { - return false; - } - - return expectation.callCount == expectation.maxCalls; - } - - function verifyMatcher(possibleMatcher, arg){ - if (match && match.isMatcher(possibleMatcher)) { - return possibleMatcher.test(arg); - } else { - return true; - } - } - - return { - minCalls: 1, - maxCalls: 1, - - create: function create(methodName) { - var expectation = sinon.extend(sinon.stub.create(), sinon.expectation); - delete expectation.create; - expectation.method = methodName; - - return expectation; - }, - - invoke: function invoke(func, thisValue, args) { - this.verifyCallAllowed(thisValue, args); - - return _invoke.apply(this, arguments); - }, - - atLeast: function atLeast(num) { - if (typeof num != "number") { - throw new TypeError("'" + num + "' is not number"); - } - - if (!this.limitsSet) { - this.maxCalls = null; - this.limitsSet = true; - } - - this.minCalls = num; - - return this; - }, - - atMost: function atMost(num) { - if (typeof num != "number") { - throw new TypeError("'" + num + "' is not number"); - } - - if (!this.limitsSet) { - this.minCalls = null; - this.limitsSet = true; - } - - this.maxCalls = num; - - return this; - }, - - never: function never() { - return this.exactly(0); - }, - - once: function once() { - return this.exactly(1); - }, - - twice: function twice() { - return this.exactly(2); - }, - - thrice: function thrice() { - return this.exactly(3); - }, - - exactly: function exactly(num) { - if (typeof num != "number") { - throw new TypeError("'" + num + "' is not a number"); - } - - this.atLeast(num); - return this.atMost(num); - }, - - met: function met() { - return !this.failed && receivedMinCalls(this); - }, - - verifyCallAllowed: function verifyCallAllowed(thisValue, args) { - if (receivedMaxCalls(this)) { - this.failed = true; - sinon.expectation.fail(this.method + " already called " + times(this.maxCalls)); - } - - if ("expectedThis" in this && this.expectedThis !== thisValue) { - sinon.expectation.fail(this.method + " called with " + thisValue + " as thisValue, expected " + - this.expectedThis); - } - - if (!("expectedArguments" in this)) { - return; - } - - if (!args) { - sinon.expectation.fail(this.method + " received no arguments, expected " + - sinon.format(this.expectedArguments)); - } - - if (args.length < this.expectedArguments.length) { - sinon.expectation.fail(this.method + " received too few arguments (" + sinon.format(args) + - "), expected " + sinon.format(this.expectedArguments)); - } - - if (this.expectsExactArgCount && - args.length != this.expectedArguments.length) { - sinon.expectation.fail(this.method + " received too many arguments (" + sinon.format(args) + - "), expected " + sinon.format(this.expectedArguments)); - } - - for (var i = 0, l = this.expectedArguments.length; i < l; i += 1) { - - if (!verifyMatcher(this.expectedArguments[i],args[i])) { - sinon.expectation.fail(this.method + " received wrong arguments " + sinon.format(args) + - ", didn't match " + this.expectedArguments.toString()); - } - - if (!sinon.deepEqual(this.expectedArguments[i], args[i])) { - sinon.expectation.fail(this.method + " received wrong arguments " + sinon.format(args) + - ", expected " + sinon.format(this.expectedArguments)); - } - } - }, - - allowsCall: function allowsCall(thisValue, args) { - if (this.met() && receivedMaxCalls(this)) { - return false; - } - - if ("expectedThis" in this && this.expectedThis !== thisValue) { - return false; - } - - if (!("expectedArguments" in this)) { - return true; - } - - args = args || []; - - if (args.length < this.expectedArguments.length) { - return false; - } - - if (this.expectsExactArgCount && - args.length != this.expectedArguments.length) { - return false; - } - - for (var i = 0, l = this.expectedArguments.length; i < l; i += 1) { - if (!verifyMatcher(this.expectedArguments[i],args[i])) { - return false; - } - - if (!sinon.deepEqual(this.expectedArguments[i], args[i])) { - return false; - } - } - - return true; - }, - - withArgs: function withArgs() { - this.expectedArguments = slice.call(arguments); - return this; - }, - - withExactArgs: function withExactArgs() { - this.withArgs.apply(this, arguments); - this.expectsExactArgCount = true; - return this; - }, - - on: function on(thisValue) { - this.expectedThis = thisValue; - return this; - }, - - toString: function () { - var args = (this.expectedArguments || []).slice(); - - if (!this.expectsExactArgCount) { - push.call(args, "[...]"); - } - - var callStr = sinon.spyCall.toString.call({ - proxy: this.method || "anonymous mock expectation", - args: args - }); - - var message = callStr.replace(", [...", "[, ...") + " " + - expectedCallCountInWords(this); - - if (this.met()) { - return "Expectation met: " + message; - } - - return "Expected " + message + " (" + - callCountInWords(this.callCount) + ")"; - }, - - verify: function verify() { - if (!this.met()) { - sinon.expectation.fail(this.toString()); - } else { - sinon.expectation.pass(this.toString()); - } - - return true; - }, - - pass: function(message) { - sinon.assert.pass(message); - }, - fail: function (message) { - var exception = new Error(message); - exception.name = "ExpectationError"; - - throw exception; - } - }; - }()); - - if (commonJSModule) { - module.exports = mock; - } else { - sinon.mock = mock; - } -}(typeof sinon == "object" && sinon || null)); - -/** - * @depend ../sinon.js - * @depend stub.js - * @depend mock.js - */ -/*jslint eqeqeq: false, onevar: false, forin: true*/ -/*global module, require, sinon*/ -/** - * Collections of stubs, spies and mocks. - * - * @author Christian Johansen (christian@cjohansen.no) - * @license BSD - * - * Copyright (c) 2010-2013 Christian Johansen - */ - -(function (sinon) { - var commonJSModule = typeof module !== 'undefined' && module.exports; - var push = [].push; - var hasOwnProperty = Object.prototype.hasOwnProperty; - - if (!sinon && commonJSModule) { - sinon = require("../sinon"); - } - - if (!sinon) { - return; - } - - function getFakes(fakeCollection) { - if (!fakeCollection.fakes) { - fakeCollection.fakes = []; - } - - return fakeCollection.fakes; - } - - function each(fakeCollection, method) { - var fakes = getFakes(fakeCollection); - - for (var i = 0, l = fakes.length; i < l; i += 1) { - if (typeof fakes[i][method] == "function") { - fakes[i][method](); - } - } - } - - function compact(fakeCollection) { - var fakes = getFakes(fakeCollection); - var i = 0; - while (i < fakes.length) { - fakes.splice(i, 1); - } - } - - var collection = { - verify: function resolve() { - each(this, "verify"); - }, - - restore: function restore() { - each(this, "restore"); - compact(this); - }, - - verifyAndRestore: function verifyAndRestore() { - var exception; - - try { - this.verify(); - } catch (e) { - exception = e; - } - - this.restore(); - - if (exception) { - throw exception; - } - }, - - add: function add(fake) { - push.call(getFakes(this), fake); - return fake; - }, - - spy: function spy() { - return this.add(sinon.spy.apply(sinon, arguments)); - }, - - stub: function stub(object, property, value) { - if (property) { - var original = object[property]; - - if (typeof original != "function") { - if (!hasOwnProperty.call(object, property)) { - throw new TypeError("Cannot stub non-existent own property " + property); - } - - object[property] = value; - - return this.add({ - restore: function () { - object[property] = original; - } - }); - } - } - if (!property && !!object && typeof object == "object") { - var stubbedObj = sinon.stub.apply(sinon, arguments); - - for (var prop in stubbedObj) { - if (typeof stubbedObj[prop] === "function") { - this.add(stubbedObj[prop]); - } - } - - return stubbedObj; - } - - return this.add(sinon.stub.apply(sinon, arguments)); - }, - - mock: function mock() { - return this.add(sinon.mock.apply(sinon, arguments)); - }, - - inject: function inject(obj) { - var col = this; - - obj.spy = function () { - return col.spy.apply(col, arguments); - }; - - obj.stub = function () { - return col.stub.apply(col, arguments); - }; - - obj.mock = function () { - return col.mock.apply(col, arguments); - }; - - return obj; - } - }; - - if (commonJSModule) { - module.exports = collection; - } else { - sinon.collection = collection; - } -}(typeof sinon == "object" && sinon || null)); - -/*jslint eqeqeq: false, plusplus: false, evil: true, onevar: false, browser: true, forin: false*/ -/*global module, require, window*/ -/** - * Fake timer API - * setTimeout - * setInterval - * clearTimeout - * clearInterval - * tick - * reset - * Date - * - * Inspired by jsUnitMockTimeOut from JsUnit - * - * @author Christian Johansen (christian@cjohansen.no) - * @license BSD - * - * Copyright (c) 2010-2013 Christian Johansen - */ - -if (typeof sinon == "undefined") { - var sinon = {}; -} - -(function (global) { - var id = 1; - - function addTimer(args, recurring) { - if (args.length === 0) { - throw new Error("Function requires at least 1 parameter"); - } - - if (typeof args[0] === "undefined") { - throw new Error("Callback must be provided to timer calls"); - } - - var toId = id++; - var delay = args[1] || 0; - - if (!this.timeouts) { - this.timeouts = {}; - } - - this.timeouts[toId] = { - id: toId, - func: args[0], - callAt: this.now + delay, - invokeArgs: Array.prototype.slice.call(args, 2) - }; - - if (recurring === true) { - this.timeouts[toId].interval = delay; - } - - return toId; - } - - function parseTime(str) { - if (!str) { - return 0; - } - - var strings = str.split(":"); - var l = strings.length, i = l; - var ms = 0, parsed; - - if (l > 3 || !/^(\d\d:){0,2}\d\d?$/.test(str)) { - throw new Error("tick only understands numbers and 'h:m:s'"); - } - - while (i--) { - parsed = parseInt(strings[i], 10); - - if (parsed >= 60) { - throw new Error("Invalid time " + str); - } - - ms += parsed * Math.pow(60, (l - i - 1)); - } - - return ms * 1000; - } - - function createObject(object) { - var newObject; - - if (Object.create) { - newObject = Object.create(object); - } else { - var F = function () {}; - F.prototype = object; - newObject = new F(); - } - - newObject.Date.clock = newObject; - return newObject; - } - - sinon.clock = { - now: 0, - - create: function create(now) { - var clock = createObject(this); - - if (typeof now == "number") { - clock.now = now; - } - - if (!!now && typeof now == "object") { - throw new TypeError("now should be milliseconds since UNIX epoch"); - } - - return clock; - }, - - setTimeout: function setTimeout(callback, timeout) { - return addTimer.call(this, arguments, false); - }, - - clearTimeout: function clearTimeout(timerId) { - if (!this.timeouts) { - this.timeouts = []; - } - - if (timerId in this.timeouts) { - delete this.timeouts[timerId]; - } - }, - - setInterval: function setInterval(callback, timeout) { - return addTimer.call(this, arguments, true); - }, - - clearInterval: function clearInterval(timerId) { - this.clearTimeout(timerId); - }, - - setImmediate: function setImmediate(callback) { - var passThruArgs = Array.prototype.slice.call(arguments, 1); - - return addTimer.call(this, [callback, 0].concat(passThruArgs), false); - }, - - clearImmediate: function clearImmediate(timerId) { - this.clearTimeout(timerId); - }, - - tick: function tick(ms) { - ms = typeof ms == "number" ? ms : parseTime(ms); - var tickFrom = this.now, tickTo = this.now + ms, previous = this.now; - var timer = this.firstTimerInRange(tickFrom, tickTo); - - var firstException; - while (timer && tickFrom <= tickTo) { - if (this.timeouts[timer.id]) { - tickFrom = this.now = timer.callAt; - try { - this.callTimer(timer); - } catch (e) { - firstException = firstException || e; - } - } - - timer = this.firstTimerInRange(previous, tickTo); - previous = tickFrom; - } - - this.now = tickTo; - - if (firstException) { - throw firstException; - } - - return this.now; - }, - - firstTimerInRange: function (from, to) { - var timer, smallest = null, originalTimer; - - for (var id in this.timeouts) { - if (this.timeouts.hasOwnProperty(id)) { - if (this.timeouts[id].callAt < from || this.timeouts[id].callAt > to) { - continue; - } - - if (smallest === null || this.timeouts[id].callAt < smallest) { - originalTimer = this.timeouts[id]; - smallest = this.timeouts[id].callAt; - - timer = { - func: this.timeouts[id].func, - callAt: this.timeouts[id].callAt, - interval: this.timeouts[id].interval, - id: this.timeouts[id].id, - invokeArgs: this.timeouts[id].invokeArgs - }; - } - } - } - - return timer || null; - }, - - callTimer: function (timer) { - if (typeof timer.interval == "number") { - this.timeouts[timer.id].callAt += timer.interval; - } else { - delete this.timeouts[timer.id]; - } - - try { - if (typeof timer.func == "function") { - timer.func.apply(null, timer.invokeArgs); - } else { - eval(timer.func); - } - } catch (e) { - var exception = e; - } - - if (!this.timeouts[timer.id]) { - if (exception) { - throw exception; - } - return; - } - - if (exception) { - throw exception; - } - }, - - reset: function reset() { - this.timeouts = {}; - }, - - Date: (function () { - var NativeDate = Date; - - function ClockDate(year, month, date, hour, minute, second, ms) { - // Defensive and verbose to avoid potential harm in passing - // explicit undefined when user does not pass argument - switch (arguments.length) { - case 0: - return new NativeDate(ClockDate.clock.now); - case 1: - return new NativeDate(year); - case 2: - return new NativeDate(year, month); - case 3: - return new NativeDate(year, month, date); - case 4: - return new NativeDate(year, month, date, hour); - case 5: - return new NativeDate(year, month, date, hour, minute); - case 6: - return new NativeDate(year, month, date, hour, minute, second); - default: - return new NativeDate(year, month, date, hour, minute, second, ms); - } - } - - return mirrorDateProperties(ClockDate, NativeDate); - }()) - }; - - function mirrorDateProperties(target, source) { - if (source.now) { - target.now = function now() { - return target.clock.now; - }; - } else { - delete target.now; - } - - if (source.toSource) { - target.toSource = function toSource() { - return source.toSource(); - }; - } else { - delete target.toSource; - } - - target.toString = function toString() { - return source.toString(); - }; - - target.prototype = source.prototype; - target.parse = source.parse; - target.UTC = source.UTC; - target.prototype.toUTCString = source.prototype.toUTCString; - - for (var prop in source) { - if (source.hasOwnProperty(prop)) { - target[prop] = source[prop]; - } - } - - return target; - } - - var methods = ["Date", "setTimeout", "setInterval", - "clearTimeout", "clearInterval"]; - - if (typeof global.setImmediate !== "undefined") { - methods.push("setImmediate"); - } - - if (typeof global.clearImmediate !== "undefined") { - methods.push("clearImmediate"); - } - - function restore() { - var method; - - for (var i = 0, l = this.methods.length; i < l; i++) { - method = this.methods[i]; - - if (global[method].hadOwnProperty) { - global[method] = this["_" + method]; - } else { - try { - delete global[method]; - } catch (e) {} - } - } - - // Prevent multiple executions which will completely remove these props - this.methods = []; - } - - function stubGlobal(method, clock) { - clock[method].hadOwnProperty = Object.prototype.hasOwnProperty.call(global, method); - clock["_" + method] = global[method]; - - if (method == "Date") { - var date = mirrorDateProperties(clock[method], global[method]); - global[method] = date; - } else { - global[method] = function () { - return clock[method].apply(clock, arguments); - }; - - for (var prop in clock[method]) { - if (clock[method].hasOwnProperty(prop)) { - global[method][prop] = clock[method][prop]; - } - } - } - - global[method].clock = clock; - } - - sinon.useFakeTimers = function useFakeTimers(now) { - var clock = sinon.clock.create(now); - clock.restore = restore; - clock.methods = Array.prototype.slice.call(arguments, - typeof now == "number" ? 1 : 0); - - if (clock.methods.length === 0) { - clock.methods = methods; - } - - for (var i = 0, l = clock.methods.length; i < l; i++) { - stubGlobal(clock.methods[i], clock); - } - - return clock; - }; -}(typeof global != "undefined" && typeof global !== "function" ? global : this)); - -sinon.timers = { - setTimeout: setTimeout, - clearTimeout: clearTimeout, - setImmediate: (typeof setImmediate !== "undefined" ? setImmediate : undefined), - clearImmediate: (typeof clearImmediate !== "undefined" ? clearImmediate: undefined), - setInterval: setInterval, - clearInterval: clearInterval, - Date: Date -}; - -if (typeof module !== 'undefined' && module.exports) { - module.exports = sinon; -} - -/*jslint eqeqeq: false, onevar: false*/ -/*global sinon, module, require, ActiveXObject, XMLHttpRequest, DOMParser*/ -/** - * Minimal Event interface implementation - * - * Original implementation by Sven Fuchs: https://gist.github.com/995028 - * Modifications and tests by Christian Johansen. - * - * @author Sven Fuchs (svenfuchs@artweb-design.de) - * @author Christian Johansen (christian@cjohansen.no) - * @license BSD - * - * Copyright (c) 2011 Sven Fuchs, Christian Johansen - */ - -if (typeof sinon == "undefined") { - this.sinon = {}; -} - -(function () { - var push = [].push; - - sinon.Event = function Event(type, bubbles, cancelable, target) { - this.initEvent(type, bubbles, cancelable, target); - }; - - sinon.Event.prototype = { - initEvent: function(type, bubbles, cancelable, target) { - this.type = type; - this.bubbles = bubbles; - this.cancelable = cancelable; - this.target = target; - }, - - stopPropagation: function () {}, - - preventDefault: function () { - this.defaultPrevented = true; - } - }; - - sinon.EventTarget = { - addEventListener: function addEventListener(event, listener) { - this.eventListeners = this.eventListeners || {}; - this.eventListeners[event] = this.eventListeners[event] || []; - push.call(this.eventListeners[event], listener); - }, - - removeEventListener: function removeEventListener(event, listener) { - var listeners = this.eventListeners && this.eventListeners[event] || []; - - for (var i = 0, l = listeners.length; i < l; ++i) { - if (listeners[i] == listener) { - return listeners.splice(i, 1); - } - } - }, - - dispatchEvent: function dispatchEvent(event) { - var type = event.type; - var listeners = this.eventListeners && this.eventListeners[type] || []; - - for (var i = 0; i < listeners.length; i++) { - if (typeof listeners[i] == "function") { - listeners[i].call(this, event); - } else { - listeners[i].handleEvent(event); - } - } - - return !!event.defaultPrevented; - } - }; -}()); - -/** - * @depend ../../sinon.js - * @depend event.js - */ -/*jslint eqeqeq: false, onevar: false*/ -/*global sinon, module, require, ActiveXObject, XMLHttpRequest, DOMParser*/ -/** - * Fake XMLHttpRequest object - * - * @author Christian Johansen (christian@cjohansen.no) - * @license BSD - * - * Copyright (c) 2010-2013 Christian Johansen - */ - -// wrapper for global -(function(global) { - if (typeof sinon === "undefined") { - global.sinon = {}; - } - - var supportsProgress = typeof ProgressEvent !== "undefined"; - var supportsCustomEvent = typeof CustomEvent !== "undefined"; - sinon.xhr = { XMLHttpRequest: global.XMLHttpRequest }; - var xhr = sinon.xhr; - xhr.GlobalXMLHttpRequest = global.XMLHttpRequest; - xhr.GlobalActiveXObject = global.ActiveXObject; - xhr.supportsActiveX = typeof xhr.GlobalActiveXObject != "undefined"; - xhr.supportsXHR = typeof xhr.GlobalXMLHttpRequest != "undefined"; - xhr.workingXHR = xhr.supportsXHR ? xhr.GlobalXMLHttpRequest : xhr.supportsActiveX - ? function() { return new xhr.GlobalActiveXObject("MSXML2.XMLHTTP.3.0") } : false; - xhr.supportsCORS = 'withCredentials' in (new sinon.xhr.GlobalXMLHttpRequest()); - - /*jsl:ignore*/ - var unsafeHeaders = { - "Accept-Charset": true, - "Accept-Encoding": true, - "Connection": true, - "Content-Length": true, - "Cookie": true, - "Cookie2": true, - "Content-Transfer-Encoding": true, - "Date": true, - "Expect": true, - "Host": true, - "Keep-Alive": true, - "Referer": true, - "TE": true, - "Trailer": true, - "Transfer-Encoding": true, - "Upgrade": true, - "User-Agent": true, - "Via": true - }; - /*jsl:end*/ - - function FakeXMLHttpRequest() { - this.readyState = FakeXMLHttpRequest.UNSENT; - this.requestHeaders = {}; - this.requestBody = null; - this.status = 0; - this.statusText = ""; - this.upload = new UploadProgress(); - if (sinon.xhr.supportsCORS) { - this.withCredentials = false; - } - - - var xhr = this; - var events = ["loadstart", "load", "abort", "loadend"]; - - function addEventListener(eventName) { - xhr.addEventListener(eventName, function (event) { - var listener = xhr["on" + eventName]; - - if (listener && typeof listener == "function") { - listener(event); - } - }); - } - - for (var i = events.length - 1; i >= 0; i--) { - addEventListener(events[i]); - } - - if (typeof FakeXMLHttpRequest.onCreate == "function") { - FakeXMLHttpRequest.onCreate(this); - } - } - - // An upload object is created for each - // FakeXMLHttpRequest and allows upload - // events to be simulated using uploadProgress - // and uploadError. - function UploadProgress() { - this.eventListeners = { - "progress": [], - "load": [], - "abort": [], - "error": [] - } - } - - UploadProgress.prototype.addEventListener = function(event, listener) { - this.eventListeners[event].push(listener); - }; - - UploadProgress.prototype.removeEventListener = function(event, listener) { - var listeners = this.eventListeners[event] || []; - - for (var i = 0, l = listeners.length; i < l; ++i) { - if (listeners[i] == listener) { - return listeners.splice(i, 1); - } - } - }; - - UploadProgress.prototype.dispatchEvent = function(event) { - var listeners = this.eventListeners[event.type] || []; - - for (var i = 0, listener; (listener = listeners[i]) != null; i++) { - listener(event); - } - }; - - function verifyState(xhr) { - if (xhr.readyState !== FakeXMLHttpRequest.OPENED) { - throw new Error("INVALID_STATE_ERR"); - } - - if (xhr.sendFlag) { - throw new Error("INVALID_STATE_ERR"); - } - } - - // filtering to enable a white-list version of Sinon FakeXhr, - // where whitelisted requests are passed through to real XHR - function each(collection, callback) { - if (!collection) return; - for (var i = 0, l = collection.length; i < l; i += 1) { - callback(collection[i]); - } - } - function some(collection, callback) { - for (var index = 0; index < collection.length; index++) { - if(callback(collection[index]) === true) return true; - } - return false; - } - // largest arity in XHR is 5 - XHR#open - var apply = function(obj,method,args) { - switch(args.length) { - case 0: return obj[method](); - case 1: return obj[method](args[0]); - case 2: return obj[method](args[0],args[1]); - case 3: return obj[method](args[0],args[1],args[2]); - case 4: return obj[method](args[0],args[1],args[2],args[3]); - case 5: return obj[method](args[0],args[1],args[2],args[3],args[4]); - } - }; - - FakeXMLHttpRequest.filters = []; - FakeXMLHttpRequest.addFilter = function(fn) { - this.filters.push(fn) - }; - var IE6Re = /MSIE 6/; - FakeXMLHttpRequest.defake = function(fakeXhr,xhrArgs) { - var xhr = new sinon.xhr.workingXHR(); - each(["open","setRequestHeader","send","abort","getResponseHeader", - "getAllResponseHeaders","addEventListener","overrideMimeType","removeEventListener"], - function(method) { - fakeXhr[method] = function() { - return apply(xhr,method,arguments); - }; - }); - - var copyAttrs = function(args) { - each(args, function(attr) { - try { - fakeXhr[attr] = xhr[attr] - } catch(e) { - if(!IE6Re.test(navigator.userAgent)) throw e; - } - }); - }; - - var stateChange = function() { - fakeXhr.readyState = xhr.readyState; - if(xhr.readyState >= FakeXMLHttpRequest.HEADERS_RECEIVED) { - copyAttrs(["status","statusText"]); - } - if(xhr.readyState >= FakeXMLHttpRequest.LOADING) { - copyAttrs(["responseText"]); - } - if(xhr.readyState === FakeXMLHttpRequest.DONE) { - copyAttrs(["responseXML"]); - } - if(fakeXhr.onreadystatechange) fakeXhr.onreadystatechange.call(fakeXhr, { target: fakeXhr }); - }; - if(xhr.addEventListener) { - for(var event in fakeXhr.eventListeners) { - if(fakeXhr.eventListeners.hasOwnProperty(event)) { - each(fakeXhr.eventListeners[event],function(handler) { - xhr.addEventListener(event, handler); - }); - } - } - xhr.addEventListener("readystatechange",stateChange); - } else { - xhr.onreadystatechange = stateChange; - } - apply(xhr,"open",xhrArgs); - }; - FakeXMLHttpRequest.useFilters = false; - - function verifyRequestSent(xhr) { - if (xhr.readyState == FakeXMLHttpRequest.DONE) { - throw new Error("Request done"); - } - } - - function verifyHeadersReceived(xhr) { - if (xhr.async && xhr.readyState != FakeXMLHttpRequest.HEADERS_RECEIVED) { - throw new Error("No headers received"); - } - } - - function verifyResponseBodyType(body) { - if (typeof body != "string") { - var error = new Error("Attempted to respond to fake XMLHttpRequest with " + - body + ", which is not a string."); - error.name = "InvalidBodyException"; - throw error; - } - } - - sinon.extend(FakeXMLHttpRequest.prototype, sinon.EventTarget, { - async: true, - - open: function open(method, url, async, username, password) { - this.method = method; - this.url = url; - this.async = typeof async == "boolean" ? async : true; - this.username = username; - this.password = password; - this.responseText = null; - this.responseXML = null; - this.requestHeaders = {}; - this.sendFlag = false; - if(sinon.FakeXMLHttpRequest.useFilters === true) { - var xhrArgs = arguments; - var defake = some(FakeXMLHttpRequest.filters,function(filter) { - return filter.apply(this,xhrArgs) - }); - if (defake) { - return sinon.FakeXMLHttpRequest.defake(this,arguments); - } - } - this.readyStateChange(FakeXMLHttpRequest.OPENED); - }, - - readyStateChange: function readyStateChange(state) { - this.readyState = state; - - if (typeof this.onreadystatechange == "function") { - try { - this.onreadystatechange(); - } catch (e) { - sinon.logError("Fake XHR onreadystatechange handler", e); - } - } - - this.dispatchEvent(new sinon.Event("readystatechange")); - - switch (this.readyState) { - case FakeXMLHttpRequest.DONE: - this.dispatchEvent(new sinon.Event("load", false, false, this)); - this.dispatchEvent(new sinon.Event("loadend", false, false, this)); - this.upload.dispatchEvent(new sinon.Event("load", false, false, this)); - if (supportsProgress) { - this.upload.dispatchEvent(new ProgressEvent("progress", {loaded: 100, total: 100})); - } - break; - } - }, - - setRequestHeader: function setRequestHeader(header, value) { - verifyState(this); - - if (unsafeHeaders[header] || /^(Sec-|Proxy-)/.test(header)) { - throw new Error("Refused to set unsafe header \"" + header + "\""); - } - - if (this.requestHeaders[header]) { - this.requestHeaders[header] += "," + value; - } else { - this.requestHeaders[header] = value; - } - }, - - // Helps testing - setResponseHeaders: function setResponseHeaders(headers) { - this.responseHeaders = {}; - - for (var header in headers) { - if (headers.hasOwnProperty(header)) { - this.responseHeaders[header] = headers[header]; - } - } - - if (this.async) { - this.readyStateChange(FakeXMLHttpRequest.HEADERS_RECEIVED); - } else { - this.readyState = FakeXMLHttpRequest.HEADERS_RECEIVED; - } - }, - - // Currently treats ALL data as a DOMString (i.e. no Document) - send: function send(data) { - verifyState(this); - - if (!/^(get|head)$/i.test(this.method)) { - if (this.requestHeaders["Content-Type"]) { - var value = this.requestHeaders["Content-Type"].split(";"); - this.requestHeaders["Content-Type"] = value[0] + ";charset=utf-8"; - } else { - this.requestHeaders["Content-Type"] = "text/plain;charset=utf-8"; - } - - this.requestBody = data; - } - - this.errorFlag = false; - this.sendFlag = this.async; - this.readyStateChange(FakeXMLHttpRequest.OPENED); - - if (typeof this.onSend == "function") { - this.onSend(this); - } - - this.dispatchEvent(new sinon.Event("loadstart", false, false, this)); - }, - - abort: function abort() { - this.aborted = true; - this.responseText = null; - this.errorFlag = true; - this.requestHeaders = {}; - - if (this.readyState > sinon.FakeXMLHttpRequest.UNSENT && this.sendFlag) { - this.readyStateChange(sinon.FakeXMLHttpRequest.DONE); - this.sendFlag = false; - } - - this.readyState = sinon.FakeXMLHttpRequest.UNSENT; - - this.dispatchEvent(new sinon.Event("abort", false, false, this)); - - this.upload.dispatchEvent(new sinon.Event("abort", false, false, this)); - - if (typeof this.onerror === "function") { - this.onerror(); - } - }, - - getResponseHeader: function getResponseHeader(header) { - if (this.readyState < FakeXMLHttpRequest.HEADERS_RECEIVED) { - return null; - } - - if (/^Set-Cookie2?$/i.test(header)) { - return null; - } - - header = header.toLowerCase(); - - for (var h in this.responseHeaders) { - if (h.toLowerCase() == header) { - return this.responseHeaders[h]; - } - } - - return null; - }, - - getAllResponseHeaders: function getAllResponseHeaders() { - if (this.readyState < FakeXMLHttpRequest.HEADERS_RECEIVED) { - return ""; - } - - var headers = ""; - - for (var header in this.responseHeaders) { - if (this.responseHeaders.hasOwnProperty(header) && - !/^Set-Cookie2?$/i.test(header)) { - headers += header + ": " + this.responseHeaders[header] + "\r\n"; - } - } - - return headers; - }, - - setResponseBody: function setResponseBody(body) { - verifyRequestSent(this); - verifyHeadersReceived(this); - verifyResponseBodyType(body); - - var chunkSize = this.chunkSize || 10; - var index = 0; - this.responseText = ""; - - do { - if (this.async) { - this.readyStateChange(FakeXMLHttpRequest.LOADING); - } - - this.responseText += body.substring(index, index + chunkSize); - index += chunkSize; - } while (index < body.length); - - var type = this.getResponseHeader("Content-Type"); - - if (this.responseText && - (!type || /(text\/xml)|(application\/xml)|(\+xml)/.test(type))) { - try { - this.responseXML = FakeXMLHttpRequest.parseXML(this.responseText); - } catch (e) { - // Unable to parse XML - no biggie - } - } - - if (this.async) { - this.readyStateChange(FakeXMLHttpRequest.DONE); - } else { - this.readyState = FakeXMLHttpRequest.DONE; - } - }, - - respond: function respond(status, headers, body) { - this.status = typeof status == "number" ? status : 200; - this.statusText = FakeXMLHttpRequest.statusCodes[this.status]; - this.setResponseHeaders(headers || {}); - this.setResponseBody(body || ""); - }, - - uploadProgress: function uploadProgress(progressEventRaw) { - if (supportsProgress) { - this.upload.dispatchEvent(new ProgressEvent("progress", progressEventRaw)); - } - }, - - uploadError: function uploadError(error) { - if (supportsCustomEvent) { - this.upload.dispatchEvent(new CustomEvent("error", {"detail": error})); - } - } - }); - - sinon.extend(FakeXMLHttpRequest, { - UNSENT: 0, - OPENED: 1, - HEADERS_RECEIVED: 2, - LOADING: 3, - DONE: 4 - }); - - // Borrowed from JSpec - FakeXMLHttpRequest.parseXML = function parseXML(text) { - var xmlDoc; - - if (typeof DOMParser != "undefined") { - var parser = new DOMParser(); - xmlDoc = parser.parseFromString(text, "text/xml"); - } else { - xmlDoc = new ActiveXObject("Microsoft.XMLDOM"); - xmlDoc.async = "false"; - xmlDoc.loadXML(text); - } - - return xmlDoc; - }; - - FakeXMLHttpRequest.statusCodes = { - 100: "Continue", - 101: "Switching Protocols", - 200: "OK", - 201: "Created", - 202: "Accepted", - 203: "Non-Authoritative Information", - 204: "No Content", - 205: "Reset Content", - 206: "Partial Content", - 300: "Multiple Choice", - 301: "Moved Permanently", - 302: "Found", - 303: "See Other", - 304: "Not Modified", - 305: "Use Proxy", - 307: "Temporary Redirect", - 400: "Bad Request", - 401: "Unauthorized", - 402: "Payment Required", - 403: "Forbidden", - 404: "Not Found", - 405: "Method Not Allowed", - 406: "Not Acceptable", - 407: "Proxy Authentication Required", - 408: "Request Timeout", - 409: "Conflict", - 410: "Gone", - 411: "Length Required", - 412: "Precondition Failed", - 413: "Request Entity Too Large", - 414: "Request-URI Too Long", - 415: "Unsupported Media Type", - 416: "Requested Range Not Satisfiable", - 417: "Expectation Failed", - 422: "Unprocessable Entity", - 500: "Internal Server Error", - 501: "Not Implemented", - 502: "Bad Gateway", - 503: "Service Unavailable", - 504: "Gateway Timeout", - 505: "HTTP Version Not Supported" - }; - - sinon.useFakeXMLHttpRequest = function () { - sinon.FakeXMLHttpRequest.restore = function restore(keepOnCreate) { - if (xhr.supportsXHR) { - global.XMLHttpRequest = xhr.GlobalXMLHttpRequest; - } - - if (xhr.supportsActiveX) { - global.ActiveXObject = xhr.GlobalActiveXObject; - } - - delete sinon.FakeXMLHttpRequest.restore; - - if (keepOnCreate !== true) { - delete sinon.FakeXMLHttpRequest.onCreate; - } - }; - if (xhr.supportsXHR) { - global.XMLHttpRequest = sinon.FakeXMLHttpRequest; - } - - if (xhr.supportsActiveX) { - global.ActiveXObject = function ActiveXObject(objId) { - if (objId == "Microsoft.XMLHTTP" || /^Msxml2\.XMLHTTP/i.test(objId)) { - - return new sinon.FakeXMLHttpRequest(); - } - - return new xhr.GlobalActiveXObject(objId); - }; - } - - return sinon.FakeXMLHttpRequest; - }; - - sinon.FakeXMLHttpRequest = FakeXMLHttpRequest; - -})(typeof global === "object" ? global : this); - -if (typeof module !== 'undefined' && module.exports) { - module.exports = sinon; -} - -/** - * @depend fake_xml_http_request.js - */ -/*jslint eqeqeq: false, onevar: false, regexp: false, plusplus: false*/ -/*global module, require, window*/ -/** - * The Sinon "server" mimics a web server that receives requests from - * sinon.FakeXMLHttpRequest and provides an API to respond to those requests, - * both synchronously and asynchronously. To respond synchronuously, canned - * answers have to be provided upfront. - * - * @author Christian Johansen (christian@cjohansen.no) - * @license BSD - * - * Copyright (c) 2010-2013 Christian Johansen - */ - -if (typeof sinon == "undefined") { - var sinon = {}; -} - -sinon.fakeServer = (function () { - var push = [].push; - function F() {} - - function create(proto) { - F.prototype = proto; - return new F(); - } - - function responseArray(handler) { - var response = handler; - - if (Object.prototype.toString.call(handler) != "[object Array]") { - response = [200, {}, handler]; - } - - if (typeof response[2] != "string") { - throw new TypeError("Fake server response body should be string, but was " + - typeof response[2]); - } - - return response; - } - - var wloc = typeof window !== "undefined" ? window.location : {}; - var rCurrLoc = new RegExp("^" + wloc.protocol + "//" + wloc.host); - - function matchOne(response, reqMethod, reqUrl) { - var rmeth = response.method; - var matchMethod = !rmeth || rmeth.toLowerCase() == reqMethod.toLowerCase(); - var url = response.url; - var matchUrl = !url || url == reqUrl || (typeof url.test == "function" && url.test(reqUrl)); - - return matchMethod && matchUrl; - } - - function match(response, request) { - var requestUrl = request.url; - - if (!/^https?:\/\//.test(requestUrl) || rCurrLoc.test(requestUrl)) { - requestUrl = requestUrl.replace(rCurrLoc, ""); - } - - if (matchOne(response, this.getHTTPMethod(request), requestUrl)) { - if (typeof response.response == "function") { - var ru = response.url; - var args = [request].concat(ru && typeof ru.exec == "function" ? ru.exec(requestUrl).slice(1) : []); - return response.response.apply(response, args); - } - - return true; - } - - return false; - } - - function log(response, request) { - var str; - - str = "Request:\n" + sinon.format(request) + "\n\n"; - str += "Response:\n" + sinon.format(response) + "\n\n"; - - sinon.log(str); - } - - return { - create: function () { - var server = create(this); - this.xhr = sinon.useFakeXMLHttpRequest(); - server.requests = []; - - this.xhr.onCreate = function (xhrObj) { - server.addRequest(xhrObj); - }; - - return server; - }, - - addRequest: function addRequest(xhrObj) { - var server = this; - push.call(this.requests, xhrObj); - - xhrObj.onSend = function () { - server.handleRequest(this); - - if (server.autoRespond && !server.responding) { - setTimeout(function () { - server.responding = false; - server.respond(); - }, server.autoRespondAfter || 10); - - server.responding = true; - } - }; - }, - - getHTTPMethod: function getHTTPMethod(request) { - if (this.fakeHTTPMethods && /post/i.test(request.method)) { - var matches = (request.requestBody || "").match(/_method=([^\b;]+)/); - return !!matches ? matches[1] : request.method; - } - - return request.method; - }, - - handleRequest: function handleRequest(xhr) { - if (xhr.async) { - if (!this.queue) { - this.queue = []; - } - - push.call(this.queue, xhr); - } else { - this.processRequest(xhr); - } - }, - - respondWith: function respondWith(method, url, body) { - if (arguments.length == 1 && typeof method != "function") { - this.response = responseArray(method); - return; - } - - if (!this.responses) { this.responses = []; } - - if (arguments.length == 1) { - body = method; - url = method = null; - } - - if (arguments.length == 2) { - body = url; - url = method; - method = null; - } - - push.call(this.responses, { - method: method, - url: url, - response: typeof body == "function" ? body : responseArray(body) - }); - }, - - respond: function respond() { - if (arguments.length > 0) this.respondWith.apply(this, arguments); - var queue = this.queue || []; - var requests = queue.splice(0); - var request; - - while(request = requests.shift()) { - this.processRequest(request); - } - }, - - processRequest: function processRequest(request) { - try { - if (request.aborted) { - return; - } - - var response = this.response || [404, {}, ""]; - - if (this.responses) { - for (var l = this.responses.length, i = l - 1; i >= 0; i--) { - if (match.call(this, this.responses[i], request)) { - response = this.responses[i].response; - break; - } - } - } - - if (request.readyState != 4) { - log(response, request); - - request.respond(response[0], response[1], response[2]); - } - } catch (e) { - sinon.logError("Fake server request processing", e); - } - }, - - restore: function restore() { - return this.xhr.restore && this.xhr.restore.apply(this.xhr, arguments); - } - }; -}()); - -if (typeof module !== 'undefined' && module.exports) { - module.exports = sinon; -} - -/** - * @depend fake_server.js - * @depend fake_timers.js - */ -/*jslint browser: true, eqeqeq: false, onevar: false*/ -/*global sinon*/ -/** - * Add-on for sinon.fakeServer that automatically handles a fake timer along with - * the FakeXMLHttpRequest. The direct inspiration for this add-on is jQuery - * 1.3.x, which does not use xhr object's onreadystatehandler at all - instead, - * it polls the object for completion with setInterval. Dispite the direct - * motivation, there is nothing jQuery-specific in this file, so it can be used - * in any environment where the ajax implementation depends on setInterval or - * setTimeout. - * - * @author Christian Johansen (christian@cjohansen.no) - * @license BSD - * - * Copyright (c) 2010-2013 Christian Johansen - */ - -(function () { - function Server() {} - Server.prototype = sinon.fakeServer; - - sinon.fakeServerWithClock = new Server(); - - sinon.fakeServerWithClock.addRequest = function addRequest(xhr) { - if (xhr.async) { - if (typeof setTimeout.clock == "object") { - this.clock = setTimeout.clock; - } else { - this.clock = sinon.useFakeTimers(); - this.resetClock = true; - } - - if (!this.longestTimeout) { - var clockSetTimeout = this.clock.setTimeout; - var clockSetInterval = this.clock.setInterval; - var server = this; - - this.clock.setTimeout = function (fn, timeout) { - server.longestTimeout = Math.max(timeout, server.longestTimeout || 0); - - return clockSetTimeout.apply(this, arguments); - }; - - this.clock.setInterval = function (fn, timeout) { - server.longestTimeout = Math.max(timeout, server.longestTimeout || 0); - - return clockSetInterval.apply(this, arguments); - }; - } - } - - return sinon.fakeServer.addRequest.call(this, xhr); - }; - - sinon.fakeServerWithClock.respond = function respond() { - var returnVal = sinon.fakeServer.respond.apply(this, arguments); - - if (this.clock) { - this.clock.tick(this.longestTimeout || 0); - this.longestTimeout = 0; - - if (this.resetClock) { - this.clock.restore(); - this.resetClock = false; - } - } - - return returnVal; - }; - - sinon.fakeServerWithClock.restore = function restore() { - if (this.clock) { - this.clock.restore(); - } - - return sinon.fakeServer.restore.apply(this, arguments); - }; -}()); - -/** - * @depend ../sinon.js - * @depend collection.js - * @depend util/fake_timers.js - * @depend util/fake_server_with_clock.js - */ -/*jslint eqeqeq: false, onevar: false, plusplus: false*/ -/*global require, module*/ -/** - * Manages fake collections as well as fake utilities such as Sinon's - * timers and fake XHR implementation in one convenient object. - * - * @author Christian Johansen (christian@cjohansen.no) - * @license BSD - * - * Copyright (c) 2010-2013 Christian Johansen - */ - -if (typeof module !== 'undefined' && module.exports) { - var sinon = require("../sinon"); - sinon.extend(sinon, require("./util/fake_timers")); -} - -(function () { - var push = [].push; - - function exposeValue(sandbox, config, key, value) { - if (!value) { - return; - } - - if (config.injectInto && !(key in config.injectInto) ) { - config.injectInto[key] = value; - } else { - push.call(sandbox.args, value); - } - } - - function prepareSandboxFromConfig(config) { - var sandbox = sinon.create(sinon.sandbox); - - if (config.useFakeServer) { - if (typeof config.useFakeServer == "object") { - sandbox.serverPrototype = config.useFakeServer; - } - - sandbox.useFakeServer(); - } - - if (config.useFakeTimers) { - if (typeof config.useFakeTimers == "object") { - sandbox.useFakeTimers.apply(sandbox, config.useFakeTimers); - } else { - sandbox.useFakeTimers(); - } - } - - return sandbox; - } - - sinon.sandbox = sinon.extend(sinon.create(sinon.collection), { - useFakeTimers: function useFakeTimers() { - this.clock = sinon.useFakeTimers.apply(sinon, arguments); - - return this.add(this.clock); - }, - - serverPrototype: sinon.fakeServer, - - useFakeServer: function useFakeServer() { - var proto = this.serverPrototype || sinon.fakeServer; - - if (!proto || !proto.create) { - return null; - } - - this.server = proto.create(); - return this.add(this.server); - }, - - inject: function (obj) { - sinon.collection.inject.call(this, obj); - - if (this.clock) { - obj.clock = this.clock; - } - - if (this.server) { - obj.server = this.server; - obj.requests = this.server.requests; - } - - return obj; - }, - - create: function (config) { - if (!config) { - return sinon.create(sinon.sandbox); - } - - var sandbox = prepareSandboxFromConfig(config); - sandbox.args = sandbox.args || []; - var prop, value, exposed = sandbox.inject({}); - - if (config.properties) { - for (var i = 0, l = config.properties.length; i < l; i++) { - prop = config.properties[i]; - value = exposed[prop] || prop == "sandbox" && sandbox; - exposeValue(sandbox, config, prop, value); - } - } else { - exposeValue(sandbox, config, "sandbox", value); - } - - return sandbox; - } - }); - - sinon.sandbox.useFakeXMLHttpRequest = sinon.sandbox.useFakeServer; - - if (typeof module !== 'undefined' && module.exports) { - module.exports = sinon.sandbox; - } -}()); - -/** - * @depend ../sinon.js - * @depend stub.js - * @depend mock.js - * @depend sandbox.js - */ -/*jslint eqeqeq: false, onevar: false, forin: true, plusplus: false*/ -/*global module, require, sinon*/ -/** - * Test function, sandboxes fakes - * - * @author Christian Johansen (christian@cjohansen.no) - * @license BSD - * - * Copyright (c) 2010-2013 Christian Johansen - */ - -(function (sinon) { - var commonJSModule = typeof module !== 'undefined' && module.exports; - - if (!sinon && commonJSModule) { - sinon = require("../sinon"); - } - - if (!sinon) { - return; - } - - function test(callback) { - var type = typeof callback; - - if (type != "function") { - throw new TypeError("sinon.test needs to wrap a test function, got " + type); - } - - return function () { - var config = sinon.getConfig(sinon.config); - config.injectInto = config.injectIntoThis && this || config.injectInto; - var sandbox = sinon.sandbox.create(config); - var exception, result; - var args = Array.prototype.slice.call(arguments).concat(sandbox.args); - - try { - result = callback.apply(this, args); - } catch (e) { - exception = e; - } - - if (typeof exception !== "undefined") { - sandbox.restore(); - throw exception; - } - else { - sandbox.verifyAndRestore(); - } - - return result; - }; - } - - test.config = { - injectIntoThis: true, - injectInto: null, - properties: ["spy", "stub", "mock", "clock", "server", "requests"], - useFakeTimers: true, - useFakeServer: true - }; - - if (commonJSModule) { - module.exports = test; - } else { - sinon.test = test; - } -}(typeof sinon == "object" && sinon || null)); - -/** - * @depend ../sinon.js - * @depend test.js - */ -/*jslint eqeqeq: false, onevar: false, eqeqeq: false*/ -/*global module, require, sinon*/ -/** - * Test case, sandboxes all test functions - * - * @author Christian Johansen (christian@cjohansen.no) - * @license BSD - * - * Copyright (c) 2010-2013 Christian Johansen - */ - -(function (sinon) { - var commonJSModule = typeof module !== 'undefined' && module.exports; - - if (!sinon && commonJSModule) { - sinon = require("../sinon"); - } - - if (!sinon || !Object.prototype.hasOwnProperty) { - return; - } - - function createTest(property, setUp, tearDown) { - return function () { - if (setUp) { - setUp.apply(this, arguments); - } - - var exception, result; - - try { - result = property.apply(this, arguments); - } catch (e) { - exception = e; - } - - if (tearDown) { - tearDown.apply(this, arguments); - } - - if (exception) { - throw exception; - } - - return result; - }; - } - - function testCase(tests, prefix) { - /*jsl:ignore*/ - if (!tests || typeof tests != "object") { - throw new TypeError("sinon.testCase needs an object with test functions"); - } - /*jsl:end*/ - - prefix = prefix || "test"; - var rPrefix = new RegExp("^" + prefix); - var methods = {}, testName, property, method; - var setUp = tests.setUp; - var tearDown = tests.tearDown; - - for (testName in tests) { - if (tests.hasOwnProperty(testName)) { - property = tests[testName]; - - if (/^(setUp|tearDown)$/.test(testName)) { - continue; - } - - if (typeof property == "function" && rPrefix.test(testName)) { - method = property; - - if (setUp || tearDown) { - method = createTest(property, setUp, tearDown); - } - - methods[testName] = sinon.test(method); - } else { - methods[testName] = tests[testName]; - } - } - } - - return methods; - } - - if (commonJSModule) { - module.exports = testCase; - } else { - sinon.testCase = testCase; - } -}(typeof sinon == "object" && sinon || null)); - -/** - * @depend ../sinon.js - * @depend stub.js - */ -/*jslint eqeqeq: false, onevar: false, nomen: false, plusplus: false*/ -/*global module, require, sinon*/ -/** - * Assertions matching the test spy retrieval interface. - * - * @author Christian Johansen (christian@cjohansen.no) - * @license BSD - * - * Copyright (c) 2010-2013 Christian Johansen - */ - -(function (sinon, global) { - var commonJSModule = typeof module !== "undefined" && module.exports; - var slice = Array.prototype.slice; - var assert; - - if (!sinon && commonJSModule) { - sinon = require("../sinon"); - } - - if (!sinon) { - return; - } - - function verifyIsStub() { - var method; - - for (var i = 0, l = arguments.length; i < l; ++i) { - method = arguments[i]; - - if (!method) { - assert.fail("fake is not a spy"); - } - - if (typeof method != "function") { - assert.fail(method + " is not a function"); - } - - if (typeof method.getCall != "function") { - assert.fail(method + " is not stubbed"); - } - } - } - - function failAssertion(object, msg) { - object = object || global; - var failMethod = object.fail || assert.fail; - failMethod.call(object, msg); - } - - function mirrorPropAsAssertion(name, method, message) { - if (arguments.length == 2) { - message = method; - method = name; - } - - assert[name] = function (fake) { - verifyIsStub(fake); - - var args = slice.call(arguments, 1); - var failed = false; - - if (typeof method == "function") { - failed = !method(fake); - } else { - failed = typeof fake[method] == "function" ? - !fake[method].apply(fake, args) : !fake[method]; - } - - if (failed) { - failAssertion(this, fake.printf.apply(fake, [message].concat(args))); - } else { - assert.pass(name); - } - }; - } - - function exposedName(prefix, prop) { - return !prefix || /^fail/.test(prop) ? prop : - prefix + prop.slice(0, 1).toUpperCase() + prop.slice(1); - } - - assert = { - failException: "AssertError", - - fail: function fail(message) { - var error = new Error(message); - error.name = this.failException || assert.failException; - - throw error; - }, - - pass: function pass(assertion) {}, - - callOrder: function assertCallOrder() { - verifyIsStub.apply(null, arguments); - var expected = "", actual = ""; - - if (!sinon.calledInOrder(arguments)) { - try { - expected = [].join.call(arguments, ", "); - var calls = slice.call(arguments); - var i = calls.length; - while (i) { - if (!calls[--i].called) { - calls.splice(i, 1); - } - } - actual = sinon.orderByFirstCall(calls).join(", "); - } catch (e) { - // If this fails, we'll just fall back to the blank string - } - - failAssertion(this, "expected " + expected + " to be " + - "called in order but were called as " + actual); - } else { - assert.pass("callOrder"); - } - }, - - callCount: function assertCallCount(method, count) { - verifyIsStub(method); - - if (method.callCount != count) { - var msg = "expected %n to be called " + sinon.timesInWords(count) + - " but was called %c%C"; - failAssertion(this, method.printf(msg)); - } else { - assert.pass("callCount"); - } - }, - - expose: function expose(target, options) { - if (!target) { - throw new TypeError("target is null or undefined"); - } - - var o = options || {}; - var prefix = typeof o.prefix == "undefined" && "assert" || o.prefix; - var includeFail = typeof o.includeFail == "undefined" || !!o.includeFail; - - for (var method in this) { - if (method != "export" && (includeFail || !/^(fail)/.test(method))) { - target[exposedName(prefix, method)] = this[method]; - } - } - - return target; - } - }; - - mirrorPropAsAssertion("called", "expected %n to have been called at least once but was never called"); - mirrorPropAsAssertion("notCalled", function (spy) { return !spy.called; }, - "expected %n to not have been called but was called %c%C"); - mirrorPropAsAssertion("calledOnce", "expected %n to be called once but was called %c%C"); - mirrorPropAsAssertion("calledTwice", "expected %n to be called twice but was called %c%C"); - mirrorPropAsAssertion("calledThrice", "expected %n to be called thrice but was called %c%C"); - mirrorPropAsAssertion("calledOn", "expected %n to be called with %1 as this but was called with %t"); - mirrorPropAsAssertion("alwaysCalledOn", "expected %n to always be called with %1 as this but was called with %t"); - mirrorPropAsAssertion("calledWithNew", "expected %n to be called with new"); - mirrorPropAsAssertion("alwaysCalledWithNew", "expected %n to always be called with new"); - mirrorPropAsAssertion("calledWith", "expected %n to be called with arguments %*%C"); - mirrorPropAsAssertion("calledWithMatch", "expected %n to be called with match %*%C"); - mirrorPropAsAssertion("alwaysCalledWith", "expected %n to always be called with arguments %*%C"); - mirrorPropAsAssertion("alwaysCalledWithMatch", "expected %n to always be called with match %*%C"); - mirrorPropAsAssertion("calledWithExactly", "expected %n to be called with exact arguments %*%C"); - mirrorPropAsAssertion("alwaysCalledWithExactly", "expected %n to always be called with exact arguments %*%C"); - mirrorPropAsAssertion("neverCalledWith", "expected %n to never be called with arguments %*%C"); - mirrorPropAsAssertion("neverCalledWithMatch", "expected %n to never be called with match %*%C"); - mirrorPropAsAssertion("threw", "%n did not throw exception%C"); - mirrorPropAsAssertion("alwaysThrew", "%n did not always throw exception%C"); - - if (commonJSModule) { - module.exports = assert; - } else { - sinon.assert = assert; - } -}(typeof sinon == "object" && sinon || null, typeof window != "undefined" ? window : (typeof self != "undefined") ? self : global)); - -return sinon;}.call(typeof window != 'undefined' && window || {})); diff --git a/tests/qunit/wp-admin/js/customize-base.js b/tests/qunit/wp-admin/js/customize-base.js index 2db95db23e..bd3535b3bc 100644 --- a/tests/qunit/wp-admin/js/customize-base.js +++ b/tests/qunit/wp-admin/js/customize-base.js @@ -1,14 +1,14 @@ -/* global wp, test, ok, equal, module */ +/* global wp */ jQuery( function( $ ) { var FooSuperClass, BarSubClass, foo, bar, ConstructorTestClass, newConstructor, constructorTest, $mockElement, mockString, firstInitialValue, firstValueInstance, valuesInstance, wasCallbackFired, mockValueCallback; - module( 'Customize Base: Class' ); + QUnit.module( 'Customize Base: Class' ); FooSuperClass = wp.customize.Class.extend( { - initialize: function ( instanceProps ) { + initialize: function( instanceProps ) { $.extend( this, instanceProps || {} ); }, protoProp: 'protoPropValue' @@ -17,40 +17,40 @@ jQuery( function( $ ) { staticProp: 'staticPropValue' } ); - test( 'FooSuperClass is a function ', function () { - equal( typeof FooSuperClass, 'function' ); + QUnit.test( 'FooSuperClass is a function', function( assert ) { + assert.equal( typeof FooSuperClass, 'function' ); }); - test( 'FooSuperClass prototype has protoProp', function () { - equal( FooSuperClass.prototype.protoProp, 'protoPropValue' ); + QUnit.test( 'FooSuperClass prototype has protoProp', function( assert ) { + assert.equal( FooSuperClass.prototype.protoProp, 'protoPropValue' ); }); - test( 'FooSuperClass does not have protoProp', function () { - equal( typeof FooSuperClass.protoProp, 'undefined' ); + QUnit.test( 'FooSuperClass does not have protoProp', function( assert ) { + assert.equal( typeof FooSuperClass.protoProp, 'undefined' ); }); - test( 'FooSuperClass has staticProp', function () { - equal( FooSuperClass.staticProp, 'staticPropValue' ); + QUnit.test( 'FooSuperClass has staticProp', function( assert ) { + assert.equal( FooSuperClass.staticProp, 'staticPropValue' ); }); - test( 'FooSuperClass prototype does not have staticProp', function () { - equal( typeof FooSuperClass.prototype.staticProp, 'undefined' ); + QUnit.test( 'FooSuperClass prototype does not have staticProp', function( assert ) { + assert.equal( typeof FooSuperClass.prototype.staticProp, 'undefined' ); }); foo = new FooSuperClass( { instanceProp: 'instancePropValue' } ); - test( 'FooSuperClass instance foo extended Class', function () { - equal( foo.extended( wp.customize.Class ), true ); + QUnit.test( 'FooSuperClass instance foo extended Class', function( assert ) { + assert.equal( foo.extended( wp.customize.Class ), true ); }); - test( 'foo instance has protoProp', function () { - equal( foo.protoProp, 'protoPropValue' ); + QUnit.test( 'foo instance has protoProp', function( assert ) { + assert.equal( foo.protoProp, 'protoPropValue' ); }); - test( 'foo instance does not have staticProp', function () { - equal( typeof foo.staticProp, 'undefined' ); + QUnit.test( 'foo instance does not have staticProp', function( assert ) { + assert.equal( typeof foo.staticProp, 'undefined' ); }); - test( 'FooSuperClass instance foo ran initialize() and has supplied instanceProp', function () { - equal( foo.instanceProp, 'instancePropValue' ); + QUnit.test( 'FooSuperClass instance foo ran initialize() and has supplied instanceProp', function( assert ) { + assert.equal( foo.instanceProp, 'instancePropValue' ); }); // @todo Test Class.applicator? // @todo Do we test object.instance? - module( 'Customize Base: Subclass' ); + QUnit.module( 'Customize Base: Subclass' ); BarSubClass = FooSuperClass.extend( { @@ -64,26 +64,26 @@ jQuery( function( $ ) { subStaticProp: 'subStaticPropValue' } ); - test( 'BarSubClass prototype has subProtoProp', function () { - equal( BarSubClass.prototype.subProtoProp, 'subProtoPropValue' ); + QUnit.test( 'BarSubClass prototype has subProtoProp', function( assert ) { + assert.equal( BarSubClass.prototype.subProtoProp, 'subProtoPropValue' ); }); - test( 'BarSubClass prototype has parent FooSuperClass protoProp', function () { - equal( BarSubClass.prototype.protoProp, 'protoPropValue' ); + QUnit.test( 'BarSubClass prototype has parent FooSuperClass protoProp', function( assert ) { + assert.equal( BarSubClass.prototype.protoProp, 'protoPropValue' ); }); bar = new BarSubClass( { instanceProp: 'instancePropValue' } ); - test( 'BarSubClass instance bar its initialize() and parent initialize() run', function () { - equal( bar.instanceProp, 'instancePropValue' ); - equal( bar.subInstanceProp, 'subInstancePropValue' ); + QUnit.test( 'BarSubClass instance bar its initialize() and parent initialize() run', function( assert ) { + assert.equal( bar.instanceProp, 'instancePropValue' ); + assert.equal( bar.subInstanceProp, 'subInstancePropValue' ); }); - test( 'BarSubClass instance bar extended FooSuperClass', function () { - equal( bar.extended( FooSuperClass ), true ); + QUnit.test( 'BarSubClass instance bar extended FooSuperClass', function( assert ) { + assert.equal( bar.extended( FooSuperClass ), true ); }); // Implements todo: Test Class.constructor() manipulation. - module( 'Customize Base: Constructor Manipulation' ); + QUnit.module( 'Customize Base: Constructor Manipulation' ); newConstructor = function ( instanceProps ) { $.extend( this , instanceProps || {} ); @@ -99,71 +99,71 @@ jQuery( function( $ ) { } ); - test( 'New constructor added to class' , function () { - equal( ConstructorTestClass.prototype.constructor , newConstructor ); + QUnit.test( 'New constructor added to class', function( assert ) { + assert.equal( ConstructorTestClass.prototype.constructor , newConstructor ); }); - test( 'Class with new constructor has protoPropValue' , function () { - equal( ConstructorTestClass.prototype.protoProp , 'protoPropValue' ); + QUnit.test( 'Class with new constructor has protoPropValue', function( assert ) { + assert.equal( ConstructorTestClass.prototype.protoProp , 'protoPropValue' ); }); constructorTest = new ConstructorTestClass( { instanceProp: 'instancePropValue' } ); - test( 'ConstructorTestClass instance constructorTest has the new constructor', function () { - equal( constructorTest.constructor, newConstructor ); + QUnit.test( 'ConstructorTestClass instance constructorTest has the new constructor', function( assert ) { + assert.equal( constructorTest.constructor, newConstructor ); }); - test( 'ConstructorTestClass instance constructorTest extended Class', function () { - equal( constructorTest.extended( wp.customize.Class ), true ); + QUnit.test( 'ConstructorTestClass instance constructorTest extended Class', function( assert ) { + assert.equal( constructorTest.extended( wp.customize.Class ), true ); }); - test( 'ConstructorTestClass instance constructorTest has the added instance property', function () { - equal( constructorTest.instanceProp , 'instancePropValue' ); + QUnit.test( 'ConstructorTestClass instance constructorTest has the added instance property', function( assert ) { + assert.equal( constructorTest.instanceProp , 'instancePropValue' ); }); - module( 'Customize Base: wp.customizer.ensure' ); + QUnit.module( 'Customize Base: wp.customizer.ensure' ); $mockElement = $( '
      ' ); - test( 'Handles jQuery argument' , function() { - equal( wp.customize.ensure( $mockElement ) , $mockElement ); + QUnit.test( 'Handles jQuery argument', function( assert ) { + assert.equal( wp.customize.ensure( $mockElement ) , $mockElement ); }); mockString = '
      '; - test( 'Handles string argument' , function() { - ok( wp.customize.ensure( mockString ) instanceof jQuery ); + QUnit.test( 'Handles string argument', function( assert ) { + assert.ok( wp.customize.ensure( mockString ) instanceof jQuery ); }); - module( 'Customize Base: Value Class' ); + QUnit.module( 'Customize Base: Value Class' ); firstInitialValue = true; firstValueInstance = new wp.customize.Value( firstInitialValue ); - test( 'Initialized with the right value' , function() { - equal( firstValueInstance.get() , firstInitialValue ); + QUnit.test( 'Initialized with the right value', function( assert ) { + assert.equal( firstValueInstance.get() , firstInitialValue ); }); - test( '.set() works' , function() { + QUnit.test( '.set() works', function( assert ) { firstValueInstance.set( false ); - equal( firstValueInstance.get() , false ); + assert.equal( firstValueInstance.get() , false ); }); - test( '.bind() adds new callback that fires on set()' , function() { + QUnit.test( '.bind() adds new callback that fires on set()', function( assert ) { wasCallbackFired = false; mockValueCallback = function() { wasCallbackFired = true; }; firstValueInstance.bind( mockValueCallback ); firstValueInstance.set( 'newValue' ); - ok( wasCallbackFired ); + assert.ok( wasCallbackFired ); }); - module( 'Customize Base: Values Class' ); + QUnit.module( 'Customize Base: Values Class' ); valuesInstance = new wp.customize.Values(); - test( 'Correct events are triggered when adding to or removing from Values collection', function() { + QUnit.test( 'Correct events are triggered when adding to or removing from Values collection', function( assert ) { var hasFooOnAdd = false, hasFooOnRemove = false, hasFooOnRemoved = true, @@ -179,8 +179,8 @@ jQuery( function( $ ) { valuePassedToAdd = value; } ); valuesInstance.add( 'foo', fooValue ); - ok( hasFooOnAdd ); - equal( valuePassedToAdd.get(), fooValue.get() ); + assert.ok( hasFooOnAdd ); + assert.equal( valuePassedToAdd.get(), fooValue.get() ); // Test events when removing the value. valuesInstance.bind( 'remove', function( value ) { @@ -194,19 +194,19 @@ jQuery( function( $ ) { wasEventFiredOnRemoval = true; } ); valuesInstance.remove( 'foo' ); - ok( hasFooOnRemove ); - equal( valuePassedToRemove.get(), fooValue.get() ); - ok( ! hasFooOnRemoved ); - equal( valuePassedToRemoved.get(), fooValue.get() ); + assert.ok( hasFooOnRemove ); + assert.equal( valuePassedToRemove.get(), fooValue.get() ); + assert.ok( ! hasFooOnRemoved ); + assert.equal( valuePassedToRemoved.get(), fooValue.get() ); // Confirm no events are fired when nonexistent value is removed. wasEventFiredOnRemoval = false; valuesInstance.remove( 'bar' ); - ok( ! wasEventFiredOnRemoval ); + assert.ok( ! wasEventFiredOnRemoval ); }); - module( 'Customize Base: Notification' ); - test( 'Notification object exists and has expected properties', function ( assert ) { + QUnit.module( 'Customize Base: Notification' ); + QUnit.test( 'Notification object exists and has expected properties', function ( assert ) { var notification = new wp.customize.Notification( 'mycode', { 'message': 'Hello World', 'type': 'update', @@ -231,8 +231,8 @@ jQuery( function( $ ) { assert.equal( null, notification.data ); } ); - module( 'Customize Base: utils.parseQueryString' ); - test( 'wp.customize.utils.parseQueryString works', function( assert ) { + QUnit.module( 'Customize Base: utils.parseQueryString' ); + QUnit.test( 'wp.customize.utils.parseQueryString works', function( assert ) { var queryParams; queryParams = wp.customize.utils.parseQueryString( 'a=1&b=2' ); assert.ok( _.isEqual( queryParams, { a: '1', b: '2' } ) ); diff --git a/tests/qunit/wp-admin/js/customize-controls-utils.js b/tests/qunit/wp-admin/js/customize-controls-utils.js index 5216ad1026..aa816ddaf2 100644 --- a/tests/qunit/wp-admin/js/customize-controls-utils.js +++ b/tests/qunit/wp-admin/js/customize-controls-utils.js @@ -4,7 +4,7 @@ jQuery( function( $ ) { var trueMockEvent, falseMockEvent, mockElementLists, $firstMockElement, $secondMockElement, $thirdMockElement, BubbleTester, BubbleTesterTwoValues, bubbleTesterParent, firstBubbleTester, secondBubbleTester; - module( 'Customizer Model Utility functions' ); + QUnit.module( 'Customizer Model Utility functions' ); trueMockEvent = { type : 'keydown', @@ -16,12 +16,12 @@ jQuery( function( $ ) { which : 13 }; - test( 'isKeydownButNotEnterEvent returns true' , function () { - ok( wp.customize.utils.isKeydownButNotEnterEvent( trueMockEvent ) ); + QUnit.test( 'isKeydownButNotEnterEvent returns true', function( assert ) { + assert.ok( wp.customize.utils.isKeydownButNotEnterEvent( trueMockEvent ) ); }); - test( 'isKeydownButNotEnterEvent returns false' , function () { - equal( wp.customize.utils.isKeydownButNotEnterEvent( falseMockEvent ) , false ); + QUnit.test( 'isKeydownButNotEnterEvent returns false', function( assert ) { + assert.equal( wp.customize.utils.isKeydownButNotEnterEvent( falseMockEvent ) , false ); }); $firstMockElement = $( '
      ' ); @@ -36,20 +36,20 @@ jQuery( function( $ ) { thirdButLonger : [ $firstMockElement, $secondMockElement, $thirdMockElement ] }; - test( 'areElementListsEqual returns true' , function () { - ok( wp.customize.utils.areElementListsEqual( mockElementLists.first , mockElementLists.first ) ); + QUnit.test( 'areElementListsEqual returns true', function( assert ) { + assert.ok( wp.customize.utils.areElementListsEqual( mockElementLists.first , mockElementLists.first ) ); }); - test( 'areElementListsEqual returns false' , function () { - equal( wp.customize.utils.areElementListsEqual( mockElementLists.first , mockElementLists.second ) , false ); + QUnit.test( 'areElementListsEqual returns false', function( assert ) { + assert.equal( wp.customize.utils.areElementListsEqual( mockElementLists.first , mockElementLists.second ) , false ); }); - test( 'areElementListsEqual: lists have same values, but in reverse order' , function () { - equal( wp.customize.utils.areElementListsEqual( mockElementLists.first , mockElementLists.firstInReverseOrder ) , false ); + QUnit.test( 'areElementListsEqual: lists have same values, but in reverse order', function( assert ) { + assert.equal( wp.customize.utils.areElementListsEqual( mockElementLists.first , mockElementLists.firstInReverseOrder ) , false ); }); - test( 'areElementListsEqual: lists have same values, but one is longer' , function () { - equal( wp.customize.utils.areElementListsEqual( mockElementLists.third , mockElementLists.thirdButLonger ) , false ); + QUnit.test( 'areElementListsEqual: lists have same values, but one is longer', function( assert ) { + assert.equal( wp.customize.utils.areElementListsEqual( mockElementLists.third , mockElementLists.thirdButLonger ) , false ); }); @@ -72,15 +72,15 @@ jQuery( function( $ ) { } ); - test( 'bubbleChildValueChanges notifies parent of change' , function() { + QUnit.test( 'bubbleChildValueChanges notifies parent of change', function( assert ) { firstBubbleTester = new BubbleTester(); wp.customize.utils.bubbleChildValueChanges( firstBubbleTester , [ 'fooValue' ] ); firstBubbleTester.fooValue.set( 'new value' ); - ok( firstBubbleTester.parent.wasChangeTriggered ); + assert.ok( firstBubbleTester.parent.wasChangeTriggered ); }); - test( 'bubbleChildValueChanges passes a reference to its instance' , function() { - ok( firstBubbleTester.parent.instancePassedInTrigger instanceof BubbleTester ); + QUnit.test( 'bubbleChildValueChanges passes a reference to its instance', function( assert ) { + assert.ok( firstBubbleTester.parent.instancePassedInTrigger instanceof BubbleTester ); }); BubbleTesterTwoValues = wp.customize.Class.extend( @@ -98,11 +98,11 @@ jQuery( function( $ ) { wp.customize.utils.bubbleChildValueChanges( secondBubbleTester , [ 'exampleValue' , 'barValue' ] ); secondBubbleTester.barValue.set( 'new value' ); - test( 'bubbleChildValueChanges notifies parent of change when two values are bound' , function() { - ok( secondBubbleTester.parent.wasChangeTriggered ); + QUnit.test( 'bubbleChildValueChanges notifies parent of change when two values are bound', function( assert ) { + assert.ok( secondBubbleTester.parent.wasChangeTriggered ); }); - test( 'bubbleChildValueChanges passes a reference to its instance when two values are bound' , function() { - ok( secondBubbleTester.parent.instancePassedInTrigger instanceof BubbleTesterTwoValues ); + QUnit.test( 'bubbleChildValueChanges passes a reference to its instance when two values are bound', function( assert ) { + assert.ok( secondBubbleTester.parent.instancePassedInTrigger instanceof BubbleTesterTwoValues ); }); }); diff --git a/tests/qunit/wp-admin/js/customize-controls.js b/tests/qunit/wp-admin/js/customize-controls.js index 85d043f78f..6bf694c5ae 100644 --- a/tests/qunit/wp-admin/js/customize-controls.js +++ b/tests/qunit/wp-admin/js/customize-controls.js @@ -1,4 +1,4 @@ -/* global JSON, wp, test, ok, equal, module */ +/* global JSON, wp */ wp.customize.settingConstructor.abbreviation = wp.customize.Setting.extend({ validate: function( value ) { @@ -6,7 +6,7 @@ wp.customize.settingConstructor.abbreviation = wp.customize.Setting.extend({ } }); -jQuery( window ).load( function (){ +jQuery( window ).load( function() { 'use strict'; var controlId, controlLabel, controlType, controlContent, controlDescription, controlData, mockControl, @@ -19,76 +19,76 @@ jQuery( window ).load( function (){ throw new Error( 'Must pass value type in expectedValues.' ); } var type = expectedValues.type; - test( 'Model extends proper type', function () { - ok( model.extended( wp.customize[ type ] ) ); + QUnit.test( 'Model extends proper type', function( assert ) { + assert.ok( model.extended( wp.customize[ type ] ) ); } ); if ( expectedValues.hasOwnProperty( 'id' ) ) { - test( type + ' instance has the right id', function () { - equal( model.id, expectedValues.id ); + QUnit.test( type + ' instance has the right id', function( assert ) { + assert.equal( model.id, expectedValues.id ); }); } if ( expectedValues.hasOwnProperty( 'title') ) { - test( type + ' instance has the right title.', function () { - equal( model.params.title, expectedValues.title ); + QUnit.test( type + ' instance has the right title.', function( assert ) { + assert.equal( model.params.title, expectedValues.title ); }); } if ( expectedValues.hasOwnProperty( 'description' ) ) { - test( type + ' instance has the right description.', function () { - equal( model.params.description, expectedValues.description ); + QUnit.test( type + ' instance has the right description.', function( assert ) { + assert.equal( model.params.description, expectedValues.description ); }); } if ( expectedValues.hasOwnProperty( 'content' ) ) { - test( type + ' instance has the right content.', function () { - equal( model.params.content, expectedValues.content ); + QUnit.test( type + ' instance has the right content.', function( assert ) { + assert.equal( model.params.content, expectedValues.content ); }); } if ( expectedValues.hasOwnProperty( 'priority' ) ) { - test( type + ' instance has the right priority.', function () { - equal( model.priority(), expectedValues.priority ); + QUnit.test( type + ' instance has the right priority.', function( assert ) { + assert.equal( model.priority(), expectedValues.priority ); }); } if ( expectedValues.hasOwnProperty( 'active' ) ) { - test( type + ' instance has the right active state.', function () { - equal( model.active(), expectedValues.active ); + QUnit.test( type + ' instance has the right active state.', function( assert ) { + assert.equal( model.active(), expectedValues.active ); }); } - test( type + ' can be deactivated', function () { + QUnit.test( type + ' can be deactivated', function( assert ) { model.activate(); model.deactivate(); - equal( model.active(), false ); + assert.equal( model.active(), false ); model.activate(); - equal( model.active(), true ); - ok(true); + assert.equal( model.active(), true ); + assert.ok(true); }); if ( type === 'Panel' || type === 'Section' ) { if ( expectedValues.hasOwnProperty( 'expanded' ) ) { - test( type + ' instance has the right expanded state.', function () { - equal( model.expanded(), expectedValues.expanded ); + QUnit.test( type + ' instance has the right expanded state.', function( assert ) { + assert.equal( model.expanded(), expectedValues.expanded ); } ); } - test( type + ' instance is collapsed after calling .collapse()', function () { + QUnit.test( type + ' instance is collapsed after calling .collapse()', function( assert ) { model.collapse(); - ok( ! model.expanded() ); + assert.ok( ! model.expanded() ); }); - test( type + ' instance is expanded after calling .expand()', function () { + QUnit.test( type + ' instance is expanded after calling .expand()', function( assert ) { model.expand(); - ok( model.expanded() ); + assert.ok( model.expanded() ); }); } }; - module( 'Customizer notifications collection' ); - test( 'Notifications collection exists', function() { - ok( wp.customize.notifications ); - equal( wp.customize.notifications.defaultConstructor, wp.customize.Notification ); + QUnit.module( 'Customizer notifications collection' ); + QUnit.test( 'Notifications collection exists', function( assert ) { + assert.ok( wp.customize.notifications ); + assert.equal( wp.customize.notifications.defaultConstructor, wp.customize.Notification ); } ); - test( 'Notification objects are rendered as part of notifications collection', function() { + QUnit.test( 'Notification objects are rendered as part of notifications collection', function( assert ) { var container = jQuery( '#customize-notifications-test' ), items, collection; collection = new wp.customize.Notifications({ @@ -97,8 +97,8 @@ jQuery( window ).load( function (){ collection.add( 'mycode-1', new wp.customize.Notification( 'mycode-1', { message: 'My message 1' } ) ); collection.render(); items = collection.container.find( 'li' ); - equal( items.length, 1 ); - equal( items.first().data( 'code' ), 'mycode-1' ); + assert.equal( items.length, 1 ); + assert.equal( items.first().data( 'code' ), 'mycode-1' ); collection.add( 'mycode-2', new wp.customize.Notification( 'mycode-2', { message: 'My message 2', @@ -106,69 +106,69 @@ jQuery( window ).load( function (){ } ) ); collection.render(); items = collection.container.find( 'li' ); - equal( items.length, 2 ); - equal( items.first().data( 'code' ), 'mycode-2' ); - equal( items.last().data( 'code' ), 'mycode-1' ); + assert.equal( items.length, 2 ); + assert.equal( items.first().data( 'code' ), 'mycode-2' ); + assert.equal( items.last().data( 'code' ), 'mycode-1' ); - equal( items.first().find( '.notice-dismiss' ).length, 1 ); - equal( items.last().find( '.notice-dismiss' ).length, 0 ); + assert.equal( items.first().find( '.notice-dismiss' ).length, 1 ); + assert.equal( items.last().find( '.notice-dismiss' ).length, 0 ); collection.remove( 'mycode-2' ); collection.render(); items = collection.container.find( 'li' ); - equal( items.length, 1 ); - equal( items.first().data( 'code' ), 'mycode-1' ); + assert.equal( items.length, 1 ); + assert.equal( items.first().data( 'code' ), 'mycode-1' ); collection.remove( 'mycode-1' ); collection.render(); - ok( collection.container.is( ':hidden' ), 'Notifications area is hidden.' ); + assert.ok( collection.container.is( ':hidden' ), 'Notifications area is hidden.' ); } ); - module( 'Customizer Previewed Device' ); - test( 'Previewed device defaults to desktop.', function () { - equal( wp.customize.previewedDevice.get(), 'desktop' ); + QUnit.module( 'Customizer Previewed Device' ); + QUnit.test( 'Previewed device defaults to desktop.', function( assert ) { + assert.equal( wp.customize.previewedDevice.get(), 'desktop' ); } ); - module( 'Customizer Setting in Fixture' ); - test( 'Setting has fixture value', function () { - equal( wp.customize( 'fixture-setting' )(), 'Lorem Ipsum' ); + QUnit.module( 'Customizer Setting in Fixture' ); + QUnit.test( 'Setting has fixture value', function( assert ) { + assert.equal( wp.customize( 'fixture-setting' )(), 'Lorem Ipsum' ); } ); - test( 'Setting has notifications', function () { + QUnit.test( 'Setting has notifications', function( assert ) { var setting = wp.customize( 'fixture-setting' ); - ok( setting.notifications.extended( wp.customize.Values ) ); - equal( wp.customize.Notification, setting.notifications.prototype.constructor.defaultConstructor ); + assert.ok( setting.notifications.extended( wp.customize.Values ) ); + assert.equal( wp.customize.Notification, setting.notifications.prototype.constructor.defaultConstructor ); } ); - test( 'Setting has findControls method', function() { + QUnit.test( 'Setting has findControls method', function( assert ) { var controls, setting = wp.customize( 'fixture-setting' ); - equal( 'function', typeof setting.findControls ); + assert.equal( 'function', typeof setting.findControls ); controls = setting.findControls(); - equal( 1, controls.length ); - equal( 'fixture-control', controls[0].id ); + assert.equal( 1, controls.length ); + assert.equal( 'fixture-control', controls[0].id ); } ); - test( 'Setting constructor object exists', function( assert ) { + QUnit.test( 'Setting constructor object exists', function( assert ) { assert.ok( _.isObject( wp.customize.settingConstructor ) ); } ); - test( 'Custom setting constructor is used', function( assert ) { + QUnit.test( 'Custom setting constructor is used', function( assert ) { var setting = wp.customize( 'fixture-setting-abbr' ); assert.ok( setting.extended( wp.customize.settingConstructor.abbreviation ) ); setting.set( 'usa' ); assert.equal( 'USA', setting.get() ); } ); - module( 'Customizer Control in Fixture' ); - test( 'Control exists', function () { - ok( wp.customize.control.has( 'fixture-control' ) ); + QUnit.module( 'Customizer Control in Fixture' ); + QUnit.test( 'Control exists', function( assert ) { + assert.ok( wp.customize.control.has( 'fixture-control' ) ); } ); - test( 'Control has the fixture setting', function () { + QUnit.test( 'Control has the fixture setting', function( assert ) { var control = wp.customize.control( 'fixture-control' ); - equal( control.setting(), 'Lorem Ipsum' ); - equal( control.setting.id, 'fixture-setting' ); + assert.equal( control.setting(), 'Lorem Ipsum' ); + assert.equal( control.setting.id, 'fixture-setting' ); } ); - test( 'Control has the section fixture section ID', function () { + QUnit.test( 'Control has the section fixture section ID', function( assert ) { var control = wp.customize.control( 'fixture-control' ); - equal( control.section(), 'fixture-section' ); + assert.equal( control.section(), 'fixture-section' ); } ); - test( 'Control has notifications', function ( assert ) { + QUnit.test( 'Control has notifications', function ( assert ) { var control = wp.customize.control( 'fixture-control' ), settingNotification, controlOnlyNotification, doneEmbedded; assert.ok( control.notifications.extended( wp.customize.Values ) ); assert.equal( wp.customize.Notification, control.notifications.prototype.constructor.defaultConstructor ); @@ -215,8 +215,8 @@ jQuery( window ).load( function (){ } ); } ); - module( 'Customizer control without associated settings' ); - test( 'Control can be created without settings', function() { + QUnit.module( 'Customizer control without associated settings' ); + QUnit.test( 'Control can be created without settings', function( assert ) { var control = new wp.customize.Control( 'settingless', { params: { content: jQuery( '
    1. Hello World
    2. ' ), @@ -224,79 +224,79 @@ jQuery( window ).load( function (){ } } ); wp.customize.control.add( control.id, control ); - equal( control.deferred.embedded.state(), 'resolved' ); - ok( null === control.setting ); - ok( jQuery.isEmptyObject( control.settings ) ); + assert.equal( control.deferred.embedded.state(), 'resolved' ); + assert.ok( null === control.setting ); + assert.ok( jQuery.isEmptyObject( control.settings ) ); } ); // Begin sections. - module( 'Customizer Section in Fixture' ); - test( 'Fixture section exists', function () { - ok( wp.customize.section.has( 'fixture-section' ) ); + QUnit.module( 'Customizer Section in Fixture' ); + QUnit.test( 'Fixture section exists', function( assert ) { + assert.ok( wp.customize.section.has( 'fixture-section' ) ); } ); - test( 'Fixture section has control among controls()', function () { + QUnit.test( 'Fixture section has control among controls()', function( assert ) { var section = wp.customize.section( 'fixture-section' ); - ok( -1 !== _.pluck( section.controls(), 'id' ).indexOf( 'fixture-control' ) ); + assert.ok( -1 !== _.pluck( section.controls(), 'id' ).indexOf( 'fixture-control' ) ); } ); - test( 'Fixture section has has expected panel', function () { + QUnit.test( 'Fixture section has has expected panel', function( assert ) { var section = wp.customize.section( 'fixture-section' ); - equal( section.panel(), 'fixture-panel' ); + assert.equal( section.panel(), 'fixture-panel' ); } ); - module( 'Customizer Default Section with Template in Fixture' ); - test( 'Fixture section exists', function () { - ok( wp.customize.section.has( 'fixture-section-default-templated' ) ); + QUnit.module( 'Customizer Default Section with Template in Fixture' ); + QUnit.test( 'Fixture section exists', function( assert ) { + assert.ok( wp.customize.section.has( 'fixture-section-default-templated' ) ); } ); - test( 'Fixture section has expected content', function () { + QUnit.test( 'Fixture section has expected content', function( assert ) { var id = 'fixture-section-default-templated', section; section = wp.customize.section( id ); - ok( ! section.params.content ); - ok( !! section.container ); - ok( !! section.headContainer ); - ok( !! section.contentContainer ); - ok( section.container.has( section.headContainer ) ); - ok( section.container.has( section.contentContainer ) ); - ok( section.headContainer.is( '.control-section.control-section-default' ) ); - ok( 1 === section.headContainer.find( '> .accordion-section-title' ).length ); - ok( section.contentContainer.is( '.accordion-section-content' ) ); - equal( section.headContainer.attr( 'aria-owns' ), section.contentContainer.attr( 'id' ) ); + assert.ok( ! section.params.content ); + assert.ok( !! section.container ); + assert.ok( !! section.headContainer ); + assert.ok( !! section.contentContainer ); + assert.ok( section.container.has( section.headContainer ) ); + assert.ok( section.container.has( section.contentContainer ) ); + assert.ok( section.headContainer.is( '.control-section.control-section-default' ) ); + assert.ok( 1 === section.headContainer.find( '> .accordion-section-title' ).length ); + assert.ok( section.contentContainer.is( '.accordion-section-content' ) ); + assert.equal( section.headContainer.attr( 'aria-owns' ), section.contentContainer.attr( 'id' ) ); } ); - module( 'Customizer Custom Type (titleless) Section with Template in Fixture' ); - test( 'Fixture section exists', function () { - ok( wp.customize.section.has( 'fixture-section-titleless-templated' ) ); + QUnit.module( 'Customizer Custom Type (titleless) Section with Template in Fixture' ); + QUnit.test( 'Fixture section exists', function( assert ) { + assert.ok( wp.customize.section.has( 'fixture-section-titleless-templated' ) ); } ); - test( 'Fixture section has expected content', function () { + QUnit.test( 'Fixture section has expected content', function( assert ) { var id = 'fixture-section-titleless-templated', section; section = wp.customize.section( id ); - ok( ! section.params.content ); - ok( !! section.container ); - ok( !! section.headContainer ); - ok( !! section.contentContainer ); - ok( section.container.has( section.headContainer ) ); - ok( section.container.has( section.contentContainer ) ); - ok( section.container.is( '.control-section.control-section-titleless' ) ); - ok( 0 === section.headContainer.find( '> .accordion-section-title' ).length ); - ok( section.contentContainer.is( '.accordion-section-content' ) ); - equal( section.headContainer.attr( 'aria-owns' ), section.contentContainer.attr( 'id' ) ); + assert.ok( ! section.params.content ); + assert.ok( !! section.container ); + assert.ok( !! section.headContainer ); + assert.ok( !! section.contentContainer ); + assert.ok( section.container.has( section.headContainer ) ); + assert.ok( section.container.has( section.contentContainer ) ); + assert.ok( section.container.is( '.control-section.control-section-titleless' ) ); + assert.ok( 0 === section.headContainer.find( '> .accordion-section-title' ).length ); + assert.ok( section.contentContainer.is( '.accordion-section-content' ) ); + assert.equal( section.headContainer.attr( 'aria-owns' ), section.contentContainer.attr( 'id' ) ); } ); - module( 'Customizer Custom Type Section Lacking Specific Template' ); - test( 'Fixture section has expected content', function () { + QUnit.module( 'Customizer Custom Type Section Lacking Specific Template' ); + QUnit.test( 'Fixture section has expected content', function( assert ) { var id = 'fixture-section-reusing-default-template', section; section = wp.customize.section( id ); - ok( ! section.params.content ); - ok( !! section.container ); - ok( !! section.headContainer ); - ok( !! section.contentContainer ); - ok( section.container.has( section.headContainer ) ); - ok( section.container.has( section.contentContainer ) ); - ok( section.headContainer.is( '.control-section.control-section-' + section.params.type ) ); - ok( 1 === section.headContainer.find( '> .accordion-section-title' ).length ); - ok( section.contentContainer.is( '.accordion-section-content' ) ); - equal( section.headContainer.attr( 'aria-owns' ), section.contentContainer.attr( 'id' ) ); + assert.ok( ! section.params.content ); + assert.ok( !! section.container ); + assert.ok( !! section.headContainer ); + assert.ok( !! section.contentContainer ); + assert.ok( section.container.has( section.headContainer ) ); + assert.ok( section.container.has( section.contentContainer ) ); + assert.ok( section.headContainer.is( '.control-section.control-section-' + section.params.type ) ); + assert.ok( 1 === section.headContainer.find( '> .accordion-section-title' ).length ); + assert.ok( section.contentContainer.is( '.accordion-section-content' ) ); + assert.equal( section.headContainer.attr( 'aria-owns' ), section.contentContainer.attr( 'id' ) ); } ); - module( 'Customizer Section lacking any params' ); - test( 'Fixture section has default params supplied', function () { + QUnit.module( 'Customizer Section lacking any params' ); + QUnit.test( 'Fixture section has default params supplied', function( assert ) { var id = 'fixture-section-without-params', section, defaultParams; section = wp.customize.section( id ); defaultParams = { @@ -310,106 +310,106 @@ jQuery( window ).load( function (){ customizeAction: '' }; jQuery.each( defaultParams, function ( key, value ) { - ok( 'undefined' !== typeof section.params[ key ] ); - equal( value, section.params[ key ] ); + assert.ok( 'undefined' !== typeof section.params[ key ] ); + assert.equal( value, section.params[ key ] ); } ); - ok( _.isNumber( section.params.instanceNumber ) ); + assert.ok( _.isNumber( section.params.instanceNumber ) ); } ); // Begin panels. - module( 'Customizer Panel in Fixture' ); - test( 'Fixture panel exists', function () { - ok( wp.customize.panel.has( 'fixture-panel' ) ); + QUnit.module( 'Customizer Panel in Fixture' ); + QUnit.test( 'Fixture panel exists', function( assert ) { + assert.ok( wp.customize.panel.has( 'fixture-panel' ) ); } ); - test( 'Fixture panel has content', function () { + QUnit.test( 'Fixture panel has content', function( assert ) { var panel = wp.customize.panel( 'fixture-panel' ); - ok( !! panel.params.content ); - ok( !! panel.container ); - ok( !! panel.headContainer ); - ok( !! panel.contentContainer ); - ok( panel.container.has( panel.headContainer ) ); - ok( panel.container.has( panel.contentContainer ) ); + assert.ok( !! panel.params.content ); + assert.ok( !! panel.container ); + assert.ok( !! panel.headContainer ); + assert.ok( !! panel.contentContainer ); + assert.ok( panel.container.has( panel.headContainer ) ); + assert.ok( panel.container.has( panel.contentContainer ) ); } ); - test( 'Fixture panel has section among its sections()', function () { + QUnit.test( 'Fixture panel has section among its sections()', function( assert ) { var panel = wp.customize.panel( 'fixture-panel' ); - ok( -1 !== _.pluck( panel.sections(), 'id' ).indexOf( 'fixture-section' ) ); + assert.ok( -1 !== _.pluck( panel.sections(), 'id' ).indexOf( 'fixture-section' ) ); } ); - test( 'Panel is not expanded by default', function () { + QUnit.test( 'Panel is not expanded by default', function( assert ) { var panel = wp.customize.panel( 'fixture-panel' ); - ok( ! panel.expanded() ); + assert.ok( ! panel.expanded() ); } ); - test( 'Panel is not expanded by default', function () { + QUnit.test( 'Panel is not expanded by default', function( assert ) { var panel = wp.customize.panel( 'fixture-panel' ); - ok( ! panel.expanded() ); + assert.ok( ! panel.expanded() ); } ); - test( 'Focusing on a control will expand the panel and section', function () { + QUnit.test( 'Focusing on a control will expand the panel and section', function( assert ) { var panel, section, control; panel = wp.customize.panel( 'fixture-panel' ); section = wp.customize.section( 'fixture-section' ); control = wp.customize.control( 'fixture-control' ); - ok( ! panel.expanded() ); - ok( ! section.expanded() ); + assert.ok( ! panel.expanded() ); + assert.ok( ! section.expanded() ); control.focus(); - ok( section.expanded() ); - ok( panel.expanded() ); + assert.ok( section.expanded() ); + assert.ok( panel.expanded() ); } ); - module( 'Customizer Default Panel with Template in Fixture' ); - test( 'Fixture section exists', function () { - ok( wp.customize.panel.has( 'fixture-panel-default-templated' ) ); + QUnit.module( 'Customizer Default Panel with Template in Fixture' ); + QUnit.test( 'Fixture section exists', function( assert ) { + assert.ok( wp.customize.panel.has( 'fixture-panel-default-templated' ) ); } ); - test( 'Fixture panel has expected content', function () { + QUnit.test( 'Fixture panel has expected content', function( assert ) { var id = 'fixture-panel-default-templated', panel; panel = wp.customize.panel( id ); - ok( ! panel.params.content ); - ok( !! panel.container ); - ok( !! panel.headContainer ); - ok( !! panel.contentContainer ); - ok( panel.container.has( panel.headContainer ) ); - ok( panel.container.has( panel.contentContainer ) ); - ok( panel.headContainer.is( '.control-panel.control-panel-default' ) ); - ok( 1 === panel.headContainer.find( '> .accordion-section-title' ).length ); - ok( panel.contentContainer.is( '.control-panel-content' ) ); - equal( panel.headContainer.attr( 'aria-owns' ), panel.contentContainer.attr( 'id' ) ); + assert.ok( ! panel.params.content ); + assert.ok( !! panel.container ); + assert.ok( !! panel.headContainer ); + assert.ok( !! panel.contentContainer ); + assert.ok( panel.container.has( panel.headContainer ) ); + assert.ok( panel.container.has( panel.contentContainer ) ); + assert.ok( panel.headContainer.is( '.control-panel.control-panel-default' ) ); + assert.ok( 1 === panel.headContainer.find( '> .accordion-section-title' ).length ); + assert.ok( panel.contentContainer.is( '.control-panel-content' ) ); + assert.equal( panel.headContainer.attr( 'aria-owns' ), panel.contentContainer.attr( 'id' ) ); } ); - module( 'Customizer Custom Type Panel (titleless) with Template in Fixture' ); - test( 'Fixture panel exists', function () { - ok( wp.customize.panel.has( 'fixture-panel-titleless-templated' ) ); + QUnit.module( 'Customizer Custom Type Panel (titleless) with Template in Fixture' ); + QUnit.test( 'Fixture panel exists', function( assert ) { + assert.ok( wp.customize.panel.has( 'fixture-panel-titleless-templated' ) ); } ); - test( 'Fixture panel has expected content', function () { + QUnit.test( 'Fixture panel has expected content', function( assert ) { var id = 'fixture-panel-titleless-templated', panel; panel = wp.customize.panel( id ); - ok( ! panel.params.content ); - ok( !! panel.container ); - ok( !! panel.headContainer ); - ok( !! panel.contentContainer ); - ok( panel.container.has( panel.headContainer ) ); - ok( panel.container.has( panel.contentContainer ) ); - ok( panel.headContainer.is( '.control-panel.control-panel-titleless' ) ); - ok( 0 === panel.headContainer.find( '> .accordion-section-title' ).length ); - ok( panel.contentContainer.is( '.control-panel-content' ) ); - equal( panel.headContainer.attr( 'aria-owns' ), panel.contentContainer.attr( 'id' ) ); + assert.ok( ! panel.params.content ); + assert.ok( !! panel.container ); + assert.ok( !! panel.headContainer ); + assert.ok( !! panel.contentContainer ); + assert.ok( panel.container.has( panel.headContainer ) ); + assert.ok( panel.container.has( panel.contentContainer ) ); + assert.ok( panel.headContainer.is( '.control-panel.control-panel-titleless' ) ); + assert.ok( 0 === panel.headContainer.find( '> .accordion-section-title' ).length ); + assert.ok( panel.contentContainer.is( '.control-panel-content' ) ); + assert.equal( panel.headContainer.attr( 'aria-owns' ), panel.contentContainer.attr( 'id' ) ); } ); - module( 'Customizer Custom Type Panel Lacking Specific Template' ); - test( 'Fixture panel has expected content', function () { + QUnit.module( 'Customizer Custom Type Panel Lacking Specific Template' ); + QUnit.test( 'Fixture panel has expected content', function( assert ) { var id = 'fixture-panel-reusing-default-template', panel; panel = wp.customize.panel( id ); - ok( ! panel.params.content ); - ok( !! panel.container ); - ok( !! panel.headContainer ); - ok( !! panel.contentContainer ); - ok( panel.container.has( panel.headContainer ) ); - ok( panel.container.has( panel.contentContainer ) ); - ok( panel.headContainer.is( '.control-panel.control-panel-' + panel.params.type ) ); - ok( 1 === panel.headContainer.find( '> .accordion-section-title' ).length ); - ok( panel.contentContainer.is( '.control-panel-content' ) ); - equal( panel.headContainer.attr( 'aria-owns' ), panel.contentContainer.attr( 'id' ) ); + assert.ok( ! panel.params.content ); + assert.ok( !! panel.container ); + assert.ok( !! panel.headContainer ); + assert.ok( !! panel.contentContainer ); + assert.ok( panel.container.has( panel.headContainer ) ); + assert.ok( panel.container.has( panel.contentContainer ) ); + assert.ok( panel.headContainer.is( '.control-panel.control-panel-' + panel.params.type ) ); + assert.ok( 1 === panel.headContainer.find( '> .accordion-section-title' ).length ); + assert.ok( panel.contentContainer.is( '.control-panel-content' ) ); + assert.equal( panel.headContainer.attr( 'aria-owns' ), panel.contentContainer.attr( 'id' ) ); } ); - module( 'Customizer Panel lacking any params' ); - test( 'Fixture panel has default params supplied', function () { + QUnit.module( 'Customizer Panel lacking any params' ); + QUnit.test( 'Fixture panel has default params supplied', function( assert ) { var id = 'fixture-panel-without-params', panel, defaultParams; panel = wp.customize.panel( id ); defaultParams = { @@ -421,17 +421,17 @@ jQuery( window ).load( function (){ active: true }; jQuery.each( defaultParams, function ( key, value ) { - ok( 'undefined' !== typeof panel.params[ key ] ); - equal( value, panel.params[ key ] ); + assert.ok( 'undefined' !== typeof panel.params[ key ] ); + assert.equal( value, panel.params[ key ] ); } ); - ok( _.isNumber( panel.params.instanceNumber ) ); + assert.ok( _.isNumber( panel.params.instanceNumber ) ); } ); - module( 'Dynamically-created Customizer Setting Model' ); + QUnit.module( 'Dynamically-created Customizer Setting Model' ); settingId = 'new_blogname'; settingValue = 'Hello World'; - test( 'Create a new setting', function () { + QUnit.test( 'Create a new setting', function( assert ) { mockSetting = wp.customize.create( settingId, settingId, @@ -441,11 +441,11 @@ jQuery( window ).load( function (){ previewer: wp.customize.previewer } ); - equal( mockSetting(), settingValue ); - equal( mockSetting.id, settingId ); + assert.equal( mockSetting(), settingValue ); + assert.equal( mockSetting.id, settingId ); } ); - module( 'Dynamically-created Customizer Section Model' ); + QUnit.module( 'Dynamically-created Customizer Section Model' ); sectionId = 'mock_title_tagline'; sectionContent = '
    3. Section Fixture Press return or enter to open

      • Customizing ▸ Fixture Panel Section Fixture

    4. '; @@ -467,27 +467,27 @@ jQuery( window ).load( function (){ testCustomizerModel( mockSection, sectionExpectedValues ); - test( 'Section has been embedded', function () { - equal( mockSection.deferred.embedded.state(), 'resolved' ); + QUnit.test( 'Section has been embedded', function( assert ) { + assert.equal( mockSection.deferred.embedded.state(), 'resolved' ); } ); wp.customize.section.add( sectionId, mockSection ); - test( 'Section instance added to the wp.customize.section object', function () { - ok( wp.customize.section.has( sectionId ) ); + QUnit.test( 'Section instance added to the wp.customize.section object', function( assert ) { + assert.ok( wp.customize.section.has( sectionId ) ); }); sectionInstance = wp.customize.section( sectionId ); - test( 'Section instance has right content when accessed from wp.customize.section()', function () { - equal( sectionInstance.params.content, sectionContent ); + QUnit.test( 'Section instance has right content when accessed from wp.customize.section()', function( assert ) { + assert.equal( sectionInstance.params.content, sectionContent ); }); - test( 'Section instance has no children yet', function () { - equal( sectionInstance.controls().length, 0 ); + QUnit.test( 'Section instance has no children yet', function( assert ) { + assert.equal( sectionInstance.controls().length, 0 ); }); - module( 'Dynamically-created Customizer Control Model' ); + QUnit.module( 'Dynamically-created Customizer Control Model' ); controlId = 'new_blogname'; controlLabel = 'Site Title'; @@ -520,43 +520,43 @@ jQuery( window ).load( function (){ testCustomizerModel( mockControl, controlExpectedValues ); - test( 'Control instance does not yet belong to a section.', function () { - equal( mockControl.section(), undefined ); + QUnit.test( 'Control instance does not yet belong to a section.', function( assert ) { + assert.equal( mockControl.section(), undefined ); }); - test( 'Control has not been embedded yet', function () { - equal( mockControl.deferred.embedded.state(), 'pending' ); + QUnit.test( 'Control has not been embedded yet', function( assert ) { + assert.equal( mockControl.deferred.embedded.state(), 'pending' ); } ); - test( 'Control instance has the right selector.', function () { - equal( mockControl.selector, '#customize-control-new_blogname' ); + QUnit.test( 'Control instance has the right selector.', function( assert ) { + assert.equal( mockControl.selector, '#customize-control-new_blogname' ); }); wp.customize.control.add( controlId, mockControl ); - test( 'Control instance was added to the control class.', function () { - ok( wp.customize.control.has( controlId ) ); + QUnit.test( 'Control instance was added to the control class.', function( assert ) { + assert.ok( wp.customize.control.has( controlId ) ); }); mockControlInstance = wp.customize.control( controlId ); - test( 'Control instance has the right id when accessed from api.control().', function () { - equal( mockControlInstance.id, controlId ); + QUnit.test( 'Control instance has the right id when accessed from api.control().', function( assert ) { + assert.equal( mockControlInstance.id, controlId ); }); - test( 'Control section can be set as expected', function () { + QUnit.test( 'Control section can be set as expected', function( assert ) { mockControl.section( mockSection.id ); - equal( mockControl.section(), mockSection.id ); + assert.equal( mockControl.section(), mockSection.id ); }); - test( 'Associating a control with a section allows it to be embedded', function () { - equal( mockControl.deferred.embedded.state(), 'resolved' ); + QUnit.test( 'Associating a control with a section allows it to be embedded', function( assert ) { + assert.equal( mockControl.deferred.embedded.state(), 'resolved' ); }); - test( 'Control is now available on section.controls()', function () { - equal( sectionInstance.controls().length, 1 ); - equal( sectionInstance.controls()[0], mockControl ); + QUnit.test( 'Control is now available on section.controls()', function( assert ) { + assert.equal( sectionInstance.controls().length, 1 ); + assert.equal( sectionInstance.controls()[0], mockControl ); }); - module( 'Dynamically-created Customizer Panel Model' ); + QUnit.module( 'Dynamically-created Customizer Panel Model' ); panelId = 'mockPanelId'; panelTitle = 'Mock Panel Title'; @@ -584,49 +584,49 @@ jQuery( window ).load( function (){ testCustomizerModel( mockPanel, panelExpectedValues ); - test( 'Panel instance is not contextuallyActive', function () { - equal( mockPanel.isContextuallyActive(), false ); + QUnit.test( 'Panel instance is not contextuallyActive', function( assert ) { + assert.equal( mockPanel.isContextuallyActive(), false ); }); - module( 'Test wp.customize.findControlsForSettings' ); - test( 'findControlsForSettings(blogname)', function() { + QUnit.module( 'Test wp.customize.findControlsForSettings' ); + QUnit.test( 'findControlsForSettings(blogname)', function( assert ) { var controlsForSettings, settingId = 'fixture-setting', controlId = 'fixture-control'; - ok( wp.customize.control.has( controlId ) ); - ok( wp.customize.has( settingId ) ); + assert.ok( wp.customize.control.has( controlId ) ); + assert.ok( wp.customize.has( settingId ) ); controlsForSettings = wp.customize.findControlsForSettings( [ settingId ] ); - ok( _.isObject( controlsForSettings ), 'Response is object' ); - ok( _.isArray( controlsForSettings['fixture-setting'] ), 'Response has a fixture-setting array' ); - equal( 1, controlsForSettings['fixture-setting'].length ); - equal( wp.customize.control( controlId ), controlsForSettings['fixture-setting'][0] ); + assert.ok( _.isObject( controlsForSettings ), 'Response is object' ); + assert.ok( _.isArray( controlsForSettings['fixture-setting'] ), 'Response has a fixture-setting array' ); + assert.equal( 1, controlsForSettings['fixture-setting'].length ); + assert.equal( wp.customize.control( controlId ), controlsForSettings['fixture-setting'][0] ); } ); - module( 'Customize Controls wp.customize.dirtyValues' ); - test( 'dirtyValues() returns expected values', function() { + QUnit.module( 'Customize Controls wp.customize.dirtyValues' ); + QUnit.test( 'dirtyValues() returns expected values', function( assert ) { wp.customize.state( 'changesetStatus' ).set( 'auto-draft' ); wp.customize.each( function( setting ) { setting._dirty = false; } ); - ok( _.isEmpty( wp.customize.dirtyValues() ) ); - ok( _.isEmpty( wp.customize.dirtyValues( { unsaved: false } ) ) ); + assert.ok( _.isEmpty( wp.customize.dirtyValues() ) ); + assert.ok( _.isEmpty( wp.customize.dirtyValues( { unsaved: false } ) ) ); wp.customize( 'fixture-setting' )._dirty = true; - ok( ! _.isEmpty( wp.customize.dirtyValues() ) ); - ok( _.isEmpty( wp.customize.dirtyValues( { unsaved: true } ) ) ); + assert.ok( ! _.isEmpty( wp.customize.dirtyValues() ) ); + assert.ok( _.isEmpty( wp.customize.dirtyValues( { unsaved: true } ) ) ); wp.customize( 'fixture-setting' ).set( 'Modified' ); - ok( ! _.isEmpty( wp.customize.dirtyValues() ) ); - ok( ! _.isEmpty( wp.customize.dirtyValues( { unsaved: true } ) ) ); - equal( 'Modified', wp.customize.dirtyValues()['fixture-setting'] ); + assert.ok( ! _.isEmpty( wp.customize.dirtyValues() ) ); + assert.ok( ! _.isEmpty( wp.customize.dirtyValues( { unsaved: true } ) ) ); + assert.equal( 'Modified', wp.customize.dirtyValues()['fixture-setting'] ); // When the changeset does not exist, all dirty settings are necessarily unsaved. wp.customize.state( 'changesetStatus' ).set( '' ); wp.customize( 'fixture-setting' )._dirty = true; - ok( ! _.isEmpty( wp.customize.dirtyValues() ) ); - ok( ! _.isEmpty( wp.customize.dirtyValues( { unsaved: true } ) ) ); + assert.ok( ! _.isEmpty( wp.customize.dirtyValues() ) ); + assert.ok( ! _.isEmpty( wp.customize.dirtyValues( { unsaved: true } ) ) ); } ); - module( 'Customize Controls: wp.customize.requestChangesetUpdate()' ); - test( 'requestChangesetUpdate makes request and returns promise', function( assert ) { + QUnit.module( 'Customize Controls: wp.customize.requestChangesetUpdate()' ); + QUnit.test( 'requestChangesetUpdate makes request and returns promise', function( assert ) { var request, originalBeforeSetup = jQuery.ajaxSettings.beforeSend; jQuery.ajaxSetup( { @@ -677,8 +677,8 @@ jQuery( window ).load( function (){ } ); } ); - module( 'Customize Utils: wp.customize.utils.getRemainingTime()' ); - test( 'utils.getRemainingTime calculates time correctly', function( assert ) { + QUnit.module( 'Customize Utils: wp.customize.utils.getRemainingTime()' ); + QUnit.test( 'utils.getRemainingTime calculates time correctly', function( assert ) { var datetime = '2599-08-06 12:12:13', timeRemaining, timeRemainingWithDateInstance, timeRemaingingWithTimestamp; timeRemaining = wp.customize.utils.getRemainingTime( datetime ); @@ -692,15 +692,15 @@ jQuery( window ).load( function (){ assert.deepEqual( timeRemaining, timeRemaingingWithTimestamp ); }); - module( 'Customize Utils: wp.customize.utils.getCurrentTimestamp()' ); - test( 'utils.getCurrentTimestamp returns timestamp', function( assert ) { + QUnit.module( 'Customize Utils: wp.customize.utils.getCurrentTimestamp()' ); + QUnit.test( 'utils.getCurrentTimestamp returns timestamp', function( assert ) { var currentTimeStamp; currentTimeStamp = wp.customize.utils.getCurrentTimestamp(); assert.equal( typeof currentTimeStamp, 'number' ); }); - module( 'Customize Controls: wp.customize.DateTimeControl' ); - test( 'Test DateTimeControl creation and its methods', function( assert ) { + QUnit.module( 'Customize Controls: wp.customize.DateTimeControl' ); + QUnit.test( 'Test DateTimeControl creation and its methods', function( assert ) { var control, controlId = 'date_time', section, sectionId = 'fixture-section', datetime = '2599-08-06 18:12:13', dateTimeArray, dateTimeArrayInampm, timeString, day, year, month, minute, meridian, hour; @@ -864,8 +864,8 @@ jQuery( window ).load( function (){ wp.customize.control.remove( controlId ); }); - module( 'Customize Sections: wp.customize.OuterSection' ); - test( 'Test OuterSection', function( assert ) { + QUnit.module( 'Customize Sections: wp.customize.OuterSection' ); + QUnit.test( 'Test OuterSection', function( assert ) { var section, sectionId = 'test_outer_section', body = jQuery( 'body' ), defaultSection, defaultSectionId = 'fixture-section'; @@ -899,8 +899,8 @@ jQuery( window ).load( function (){ wp.customize.section.remove( sectionId ); }); - module( 'Customize Controls: PreviewLinkControl' ); - test( 'Test PreviewLinkControl creation and its methods', function( assert ) { + QUnit.module( 'Customize Controls: PreviewLinkControl' ); + QUnit.test( 'Test PreviewLinkControl creation and its methods', function( assert ) { var section, sectionId = 'publish_settings', newLink; section = wp.customize.section( sectionId ); diff --git a/tests/qunit/wp-admin/js/customize-header.js b/tests/qunit/wp-admin/js/customize-header.js index d5f01100f8..eb05e839aa 100644 --- a/tests/qunit/wp-admin/js/customize-header.js +++ b/tests/qunit/wp-admin/js/customize-header.js @@ -1,48 +1,48 @@ /* global wp, sinon */ jQuery( function() { - module('Custom Header: ChoiceList', { - setup: function() { + QUnit.module('Custom Header: ChoiceList', { + beforeEach: function() { wp.customize.HeaderTool.currentHeader = new wp.customize.HeaderTool.ImageModel(); this.apiStub = sinon.stub(wp.customize, 'get').returns('foo'); this.choiceList = new wp.customize.HeaderTool.ChoiceList(); }, - teardown: function() { + afterEach: function() { this.apiStub.restore(); } }); - test('should parse _wpCustomizeHeader.uploads into itself', function() { - equal(this.choiceList.length, 4); + QUnit.test('should parse _wpCustomizeHeader.uploads into itself', function( assert ) { + assert.equal(this.choiceList.length, 4); }); - test('should sort by newest first', function() { - equal(this.choiceList.at(2).get('header').attachment_id, 1); - equal(this.choiceList.first().get('header').attachment_id, 3); + QUnit.test('should sort by newest first', function( assert ) { + assert.equal(this.choiceList.at(2).get('header').attachment_id, 1); + assert.equal(this.choiceList.first().get('header').attachment_id, 3); }); - module('Custom Header: DefaultsList', { - setup: function() { + QUnit.module('Custom Header: DefaultsList', { + beforeEach: function() { wp.customize.HeaderTool.currentHeader = new wp.customize.HeaderTool.ImageModel(); this.apiStub = sinon.stub(wp.customize, 'get').returns('foo'); this.choiceList = new wp.customize.HeaderTool.DefaultsList(); }, - teardown: function() { + afterEach: function() { this.apiStub.restore(); } }); - test('it should parse _wpCustomizeHeader.defaults into itself', function() { - equal(this.choiceList.length, 4); + QUnit.test('it should parse _wpCustomizeHeader.defaults into itself', function( assert ) { + assert.equal(this.choiceList.length, 4); }); - test('it parses the default image names', function() { - equal(this.choiceList.first().get('header').defaultName, 'circle'); - equal(this.choiceList.at(2).get('header').defaultName, 'star'); + QUnit.test('it parses the default image names', function( assert ) { + assert.equal(this.choiceList.first().get('header').defaultName, 'circle'); + assert.equal(this.choiceList.at(2).get('header').defaultName, 'star'); }); - module('Custom Header: HeaderImage shouldBeCropped()', { - setup: function() { + QUnit.module('Custom Header: HeaderImage shouldBeCropped()', { + beforeEach: function() { wp.customize.HeaderTool.currentHeader = new wp.customize.HeaderTool.ImageModel(); this.model = new wp.customize.HeaderTool.ImageModel(); this.model.set({ @@ -52,7 +52,7 @@ jQuery( function() { } }); - test('should not be cropped when the theme does not support flex width or height and the image has the same dimensions of the theme image', function() { + QUnit.test('should not be cropped when the theme does not support flex width or height and the image has the same dimensions of the theme image', function( assert ) { this.model.set({ themeFlexWidth: false, themeFlexHeight: false, @@ -60,10 +60,10 @@ jQuery( function() { imageHeight: 200 }); - equal(this.model.shouldBeCropped(), false); + assert.equal(this.model.shouldBeCropped(), false); }); - test('should be cropped when the image has the same dimensions of the theme image', function() { + QUnit.test('should be cropped when the image has the same dimensions of the theme image', function( assert ) { this.model.set({ themeFlexWidth: false, themeFlexHeight: false, @@ -71,10 +71,10 @@ jQuery( function() { imageHeight: 400 }); - equal(this.model.shouldBeCropped(), true); + assert.equal(this.model.shouldBeCropped(), true); }); - test('should not be cropped when the theme only supports flex width and the image has the same height as the theme image', function() { + QUnit.test('should not be cropped when the theme only supports flex width and the image has the same height as the theme image', function( assert ) { this.model.set({ themeFlexWidth: true, themeFlexHeight: false, @@ -82,10 +82,10 @@ jQuery( function() { imageHeight: 200 }); - equal(this.model.shouldBeCropped(), false); + assert.equal(this.model.shouldBeCropped(), false); }); - test('should not be cropped when the theme only supports flex height and the image has the same width as the theme image', function() { + QUnit.test('should not be cropped when the theme only supports flex height and the image has the same width as the theme image', function( assert ) { this.model.set({ themeFlexWidth: false, themeFlexHeight: true, @@ -93,10 +93,10 @@ jQuery( function() { imageHeight: 600 }); - equal(this.model.shouldBeCropped(), false); + assert.equal(this.model.shouldBeCropped(), false); }); - test('should not be cropped when the theme supports flex height AND width', function() { + QUnit.test('should not be cropped when the theme supports flex height AND width', function( assert ) { this.model.set({ themeFlexWidth: true, themeFlexHeight: true, @@ -104,10 +104,10 @@ jQuery( function() { imageHeight: 8600 }); - equal(this.model.shouldBeCropped(), false); + assert.equal(this.model.shouldBeCropped(), false); }); - test('should not be cropped when the image width is smaller than or equal to theme width', function() { + QUnit.test('should not be cropped when the image width is smaller than or equal to theme width', function( assert ) { this.model.set({ themeFlexWidth: false, themeFlexHeight: false, @@ -115,10 +115,10 @@ jQuery( function() { imageHeight: 100 }); - equal(this.model.shouldBeCropped(), false); + assert.equal(this.model.shouldBeCropped(), false); }); - test('should not be cropped when the image width is smaller than or equal to theme width, theme supports flex height and width', function() { + QUnit.test('should not be cropped when the image width is smaller than or equal to theme width, theme supports flex height and width', function( assert ) { this.model.set({ themeFlexWidth: true, themeFlexHeight: true, @@ -126,6 +126,6 @@ jQuery( function() { imageHeight: 100 }); - equal(this.model.shouldBeCropped(), false); + assert.equal(this.model.shouldBeCropped(), false); }); }); diff --git a/tests/qunit/wp-admin/js/customize-nav-menus.js b/tests/qunit/wp-admin/js/customize-nav-menus.js index 524c9ab6f5..b3b8fef9e5 100644 --- a/tests/qunit/wp-admin/js/customize-nav-menus.js +++ b/tests/qunit/wp-admin/js/customize-nav-menus.js @@ -1,109 +1,109 @@ /* global wp */ -jQuery( window ).load( function (){ +jQuery( window ).load( function() { var api = wp.customize, primaryMenuId = 3, socialMenuId = 2; - module( 'Customize Nav Menus' ); + QUnit.module( 'Customize Nav Menus' ); /** * Generate 20 IDs and verify they are all unique. */ - test( 'generatePlaceholderAutoIncrementId generates unique IDs', function() { + QUnit.test( 'generatePlaceholderAutoIncrementId generates unique IDs', function( assert ) { var testIterations = 20, ids = [ api.Menus.generatePlaceholderAutoIncrementId() ]; while ( testIterations ) { var placeholderID = api.Menus.generatePlaceholderAutoIncrementId(); - ok( -1 === ids.indexOf( placeholderID ) ); + assert.ok( -1 === ids.indexOf( placeholderID ) ); ids.push( placeholderID ); testIterations -= 1; } } ); - test( 'it should parse _wpCustomizeMenusSettings.defaults into itself', function() { - deepEqual( window._wpCustomizeNavMenusSettings, api.Menus.data ); + QUnit.test( 'it should parse _wpCustomizeMenusSettings.defaults into itself', function( assert ) { + assert.deepEqual( window._wpCustomizeNavMenusSettings, api.Menus.data ); } ); - test( 'empty menus should have no Menu Item Controls', function() { - ok( 0 === wp.customize.Menus.getMenuControl( socialMenuId ).getMenuItemControls().length, 'empty menus' ); + QUnit.test( 'empty menus should have no Menu Item Controls', function( assert ) { + assert.ok( 0 === wp.customize.Menus.getMenuControl( socialMenuId ).getMenuItemControls().length, 'empty menus' ); } ); - test( 'populated menus should have no Menu Item Controls', function() { - ok( 0 !== wp.customize.Menus.getMenuControl( primaryMenuId ).getMenuItemControls().length, 'non-empty menus' ); + QUnit.test( 'populated menus should have no Menu Item Controls', function( assert ) { + assert.ok( 0 !== wp.customize.Menus.getMenuControl( primaryMenuId ).getMenuItemControls().length, 'non-empty menus' ); } ); // @todo Add tests for api.Menus.AvailableMenuItemsPanelView // (and api.Menus.AvailableItemCollection, api.Menus.AvailableItemModel). - test( 'there is a properly configured MenusPanel', function() { + QUnit.test( 'there is a properly configured MenusPanel', function( assert ) { var panel, sections; panel = api.panel( 'nav_menus' ); - ok( panel ); - ok( panel.extended( api.Menus.MenusPanel ) ); + assert.ok( panel ); + assert.ok( panel.extended( api.Menus.MenusPanel ) ); sections = panel.sections(); - ok( 'menu_locations' === sections[0].id, 'first section is menu_locations' ); - ok( sections[1].extended( api.Menus.MenuSection ), 'second section is MenuSection' ); - ok( sections[ sections.length - 1 ].extended( api.Menus.NewMenuSection ), 'last section is NewMenuSection' ); + assert.ok( 'menu_locations' === sections[0].id, 'first section is menu_locations' ); + assert.ok( sections[1].extended( api.Menus.MenuSection ), 'second section is MenuSection' ); + assert.ok( sections[ sections.length - 1 ].extended( api.Menus.NewMenuSection ), 'last section is NewMenuSection' ); } ); // @todo Add more tests for api.Menus.MenusPanel behaviors. - test( 'there an expected MenuSection for the primary menu', function() { + QUnit.test( 'there an expected MenuSection for the primary menu', function( assert ) { var section, controls, lastControl; section = api.section( 'nav_menu[' + primaryMenuId + ']' ); - ok( section, 'section exists' ); - ok( section.extended( api.Menus.MenuSection ), 'section is a api.Menus.MenuSection' ); - ok( section.deferred.initSortables, 'has section.deferred.initSortables' ); - ok( section.active(), 'section active() is true' ); - ok( section.active.set( false ).get(), 'section active() cannot be set false' ); + assert.ok( section, 'section exists' ); + assert.ok( section.extended( api.Menus.MenuSection ), 'section is a api.Menus.MenuSection' ); + assert.ok( section.deferred.initSortables, 'has section.deferred.initSortables' ); + assert.ok( section.active(), 'section active() is true' ); + assert.ok( section.active.set( false ).get(), 'section active() cannot be set false' ); controls = section.controls(); - ok( controls[0].extended( api.Menus.MenuNameControl ), 'first control in menu section is MenuNameControl' ); - ok( controls[1].extended( api.Menus.MenuItemControl ), 'second control in menu section is MenuItemControl' ); + assert.ok( controls[0].extended( api.Menus.MenuNameControl ), 'first control in menu section is MenuNameControl' ); + assert.ok( controls[1].extended( api.Menus.MenuItemControl ), 'second control in menu section is MenuItemControl' ); lastControl = controls[ controls.length - 1 ]; - ok( lastControl.extended( api.Control ), 'last control in menu section is a base Control' ); - ok( lastControl.params.templateId === 'nav-menu-delete-button', 'last control in menu section has a delete-button template' ); + assert.ok( lastControl.extended( api.Control ), 'last control in menu section is a base Control' ); + assert.ok( lastControl.params.templateId === 'nav-menu-delete-button', 'last control in menu section has a delete-button template' ); } ); // @todo Add more tests for api.Menus.MenuSection behaviors. - test( 'changing a MenuNameControl change the corresponding menu value', function() { + QUnit.test( 'changing a MenuNameControl change the corresponding menu value', function( assert ) { var section, control; section = api.section( 'nav_menu[' + primaryMenuId + ']' ); control = section.controls()[0]; - ok( control.extended( api.Menus.MenuNameControl ), 'control is a MenuNameControl' ); - equal( control.setting().name, 'Primary menu' ); - ok( ! control.setting._dirty ); + assert.ok( control.extended( api.Menus.MenuNameControl ), 'control is a MenuNameControl' ); + assert.equal( control.setting().name, 'Primary menu' ); + assert.ok( ! control.setting._dirty ); control.container.find( 'input[type=text]:first' ).val( 'Main menu' ).trigger( 'change' ); - equal( control.setting().name, 'Main menu' ); - ok( control.setting._dirty ); + assert.equal( control.setting().name, 'Main menu' ); + assert.ok( control.setting._dirty ); } ); // @todo Add more tests for api.Menus.MenuNameControl - test( 'manipulating a MenuItemControl works', function() { + QUnit.test( 'manipulating a MenuItemControl works', function( assert ) { var section, control, value; section = api.section( 'nav_menu[' + primaryMenuId + ']' ); - ok( section ); + assert.ok( section ); control = section.controls()[1]; - ok( control.extended( api.Menus.MenuItemControl ), 'control is a MenuItemControl' ); + assert.ok( control.extended( api.Menus.MenuItemControl ), 'control is a MenuItemControl' ); control.actuallyEmbed(); control.container.find( '.edit-menu-item-title' ).val( 'Hello World' ).trigger( 'change' ); - equal( control.setting().title, 'Hello World' ); + assert.equal( control.setting().title, 'Hello World' ); value = _.clone( control.setting() ); value.title = 'Hola Mundo'; - equal( control.container.find( '.edit-menu-item-title' ).val(), 'Hello World' ); - equal( value.position, 1 ); - equal( control.priority(), 1 ); + assert.equal( control.container.find( '.edit-menu-item-title' ).val(), 'Hello World' ); + assert.equal( value.position, 1 ); + assert.equal( control.priority(), 1 ); // @todo Test control.moveDown(). } ); @@ -118,16 +118,16 @@ jQuery( window ).load( function (){ // @todo Add tests for api.Menus.focusMenuItemControl. // @todo Add tests for api.Menus.createNavMenu. - test( 'api.Menus.getMenuControl() should return the expected control', function() { + QUnit.test( 'api.Menus.getMenuControl() should return the expected control', function( assert ) { var control = api.Menus.getMenuControl( primaryMenuId ); - ok( !! control, 'control is returned' ); - ok( control.extended( api.Menus.MenuControl ), 'control is a MenuControl' ); + assert.ok( !! control, 'control is returned' ); + assert.ok( control.extended( api.Menus.MenuControl ), 'control is a MenuControl' ); } ); - test( 'api.Menus.getMenuItemControl() should return the expected control', function() { + QUnit.test( 'api.Menus.getMenuItemControl() should return the expected control', function( assert ) { var control = api.Menus.getMenuItemControl( 2000 ); - ok( !! control, 'control is returned' ); - ok( control.extended( api.Menus.MenuItemControl ), 'control is a MenuItemControl' ); + assert.ok( !! control, 'control is returned' ); + assert.ok( control.extended( api.Menus.MenuItemControl ), 'control is a MenuItemControl' ); } ); } ); diff --git a/tests/qunit/wp-admin/js/customize-widgets.js b/tests/qunit/wp-admin/js/customize-widgets.js index 5f754a497a..22a6166c66 100644 --- a/tests/qunit/wp-admin/js/customize-widgets.js +++ b/tests/qunit/wp-admin/js/customize-widgets.js @@ -3,25 +3,25 @@ jQuery( window ).load( function() { var api = wp.customize, $ = jQuery; - module( 'Customize Widgets' ); + QUnit.module( 'Customize Widgets' ); - test( 'fixtures should be present', function() { + QUnit.test( 'fixtures should be present', function( assert ) { var widgetControl; - ok( api.panel( 'widgets' ) ); - ok( api.section( 'sidebar-widgets-sidebar-1' ) ); + assert.ok( api.panel( 'widgets' ) ); + assert.ok( api.section( 'sidebar-widgets-sidebar-1' ) ); widgetControl = api.control( 'widget_search[2]' ); - ok( widgetControl ); - ok( api.control( 'sidebars_widgets[sidebar-1]' ) ); - ok( api( 'widget_search[2]' ) ); - ok( api( 'sidebars_widgets[sidebar-1]' ) ); - ok( widgetControl.params.content ); - ok( widgetControl.params.widget_control ); - ok( widgetControl.params.widget_content ); - ok( widgetControl.params.widget_id ); - ok( widgetControl.params.widget_id_base ); + assert.ok( widgetControl ); + assert.ok( api.control( 'sidebars_widgets[sidebar-1]' ) ); + assert.ok( api( 'widget_search[2]' ) ); + assert.ok( api( 'sidebars_widgets[sidebar-1]' ) ); + assert.ok( widgetControl.params.content ); + assert.ok( widgetControl.params.widget_control ); + assert.ok( widgetControl.params.widget_content ); + assert.ok( widgetControl.params.widget_id ); + assert.ok( widgetControl.params.widget_id_base ); }); - test( 'widget contents should embed (with widget-added event) when section and control expand', function() { + QUnit.test( 'widget contents should embed (with widget-added event) when section and control expand', function( assert ) { var control, section, widgetAddedEvent = null, widgetControlRootElement = null; control = api.control( 'widget_search[2]' ); section = api.section( 'sidebar-widgets-sidebar-1' ); @@ -31,8 +31,8 @@ jQuery( window ).load( function() { widgetControlRootElement = widgetElement; }); - ok( ! section.expanded() ); - ok( 0 === control.container.find( '> .widget' ).length ); + assert.ok( ! section.expanded() ); + assert.ok( 0 === control.container.find( '> .widget' ).length ); // Preview sets the active state. section.active.set( true ); @@ -40,32 +40,32 @@ jQuery( window ).load( function() { api.control( 'sidebars_widgets[sidebar-1]' ).active.set( true ); section.expand(); - ok( ! widgetAddedEvent, 'expected widget added event not fired' ); - ok( 1 === control.container.find( '> .widget' ).length, 'expected there to be one .widget element in the container' ); - ok( 0 === control.container.find( '.widget-content' ).children().length ); + assert.ok( ! widgetAddedEvent, 'expected widget added event not fired' ); + assert.ok( 1 === control.container.find( '> .widget' ).length, 'expected there to be one .widget element in the container' ); + assert.ok( 0 === control.container.find( '.widget-content' ).children().length ); control.expand(); - ok( 1 === control.container.find( '.widget-content' ).children().length ); - ok( widgetAddedEvent ); - ok( widgetControlRootElement.is( control.container.find( '> .widget' ) ) ); - ok( 1 === control.container.find( '.widget-content #widget-search-2-title' ).length ); + assert.ok( 1 === control.container.find( '.widget-content' ).children().length ); + assert.ok( widgetAddedEvent ); + assert.ok( widgetControlRootElement.is( control.container.find( '> .widget' ) ) ); + assert.ok( 1 === control.container.find( '.widget-content #widget-search-2-title' ).length ); $( document ).off( 'widget-added' ); }); - test( 'widgets panel should have notice', function() { + QUnit.test( 'widgets panel should have notice', function( assert ) { var panel = api.panel( 'widgets' ); - ok( panel.extended( api.Widgets.WidgetsPanel ) ); + assert.ok( panel.extended( api.Widgets.WidgetsPanel ) ); panel.deferred.embedded.done( function() { - ok( 1 === panel.contentContainer.find( '.no-widget-areas-rendered-notice' ).length ); - ok( panel.contentContainer.find( '.no-widget-areas-rendered-notice' ).is( ':visible' ) ); + assert.ok( 1 === panel.contentContainer.find( '.no-widget-areas-rendered-notice' ).length ); + assert.ok( panel.contentContainer.find( '.no-widget-areas-rendered-notice' ).is( ':visible' ) ); api.section( 'sidebar-widgets-sidebar-1' ).active( true ); api.control( 'sidebars_widgets[sidebar-1]' ).active( true ); api.trigger( 'pane-contents-reflowed' ); - ok( ! panel.contentContainer.find( '.no-widget-areas-rendered-notice' ).is( ':visible' ) ); + assert.ok( ! panel.contentContainer.find( '.no-widget-areas-rendered-notice' ).is( ':visible' ) ); } ); - expect( 4 ); + assert.expect( 4 ); }); }); diff --git a/tests/qunit/wp-admin/js/nav-menu.js b/tests/qunit/wp-admin/js/nav-menu.js index de99e3d6f7..98a3448a34 100644 --- a/tests/qunit/wp-admin/js/nav-menu.js +++ b/tests/qunit/wp-admin/js/nav-menu.js @@ -6,7 +6,7 @@ eventsFired = 0; // Fail if we don't see the expected number of events triggered in 3 seconds. - setTimeout( function() { + setTimeout( function( assert ) { // QUnit may load this file without running it, in which case `assert` // will never be set to `assertPassed` below. assert && assert.equal( diff --git a/tests/qunit/wp-admin/js/password-strength-meter.js b/tests/qunit/wp-admin/js/password-strength-meter.js index 3df7cc9379..78f4c4e02a 100644 --- a/tests/qunit/wp-admin/js/password-strength-meter.js +++ b/tests/qunit/wp-admin/js/password-strength-meter.js @@ -1,16 +1,16 @@ /* global passwordStrength, wp, jQuery */ jQuery( function() { - module( 'password-strength-meter' ); + QUnit.module( 'password-strength-meter' ); - test( 'mismatched passwords should return 5', function() { - equal( passwordStrength( 'password1', 'username', 'password2' ), 5, 'mismatched passwords return 5' ); + QUnit.test( 'mismatched passwords should return 5', function( assert ) { + assert.equal( passwordStrength( 'password1', 'username', 'password2' ), 5, 'mismatched passwords return 5' ); }); - test( 'passwords shorter than 4 characters should return 0', function() { - equal( passwordStrength( 'abc', 'username', 'abc' ), 0, 'short passwords return 0' ); + QUnit.test( 'passwords shorter than 4 characters should return 0', function( assert ) { + assert.equal( passwordStrength( 'abc', 'username', 'abc' ), 0, 'short passwords return 0' ); }); - test( 'long complicated passwords should return 4', function() { + QUnit.test( 'long complicated passwords should return 4', function( assert ) { var password = function( length ) { var i, n, retVal = '', possibility = 'abcdefghijklnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'; @@ -21,21 +21,21 @@ jQuery( function() { }, twofifty = password( 250 ); - equal( passwordStrength( twofifty, 'username', twofifty ), 4, '250 character complicated password returns 4' ); + assert.equal( passwordStrength( twofifty, 'username', twofifty ), 4, '250 character complicated password returns 4' ); }); - test( 'short uncomplicated passwords should return 0', function() { + QUnit.test( 'short uncomplicated passwords should return 0', function( assert ) { var letters = 'aaaa', numbers = '1111', password = 'password', uppercase = 'AAAA'; - equal( passwordStrength( letters, 'username', letters ), 0, 'password of `' + letters + '` returns 0' ); - equal( passwordStrength( numbers, 'username', numbers ), 0, 'password of `' + numbers + '` returns 0' ); - equal( passwordStrength( uppercase, 'username', uppercase ), 0, 'password of `' + uppercase + '` returns 0' ); - equal( passwordStrength( password, 'username', password ), 0, 'password of `' + password + '` returns 0' ); + assert.equal( passwordStrength( letters, 'username', letters ), 0, 'password of `' + letters + '` returns 0' ); + assert.equal( passwordStrength( numbers, 'username', numbers ), 0, 'password of `' + numbers + '` returns 0' ); + assert.equal( passwordStrength( uppercase, 'username', uppercase ), 0, 'password of `' + uppercase + '` returns 0' ); + assert.equal( passwordStrength( password, 'username', password ), 0, 'password of `' + password + '` returns 0' ); }); - test( 'zxcvbn password tests should return the score we expect', function() { + QUnit.test( 'zxcvbn password tests should return the score we expect', function( assert ) { var passwords, i; passwords = [ { pw: 'zxcvbn', score: 0 }, @@ -76,11 +76,11 @@ jQuery( function() { ]; for ( i = 0; i < passwords.length; i++ ) { - equal( passwordStrength( passwords[i].pw, 'username', passwords[i].pw ), passwords[i].score, 'password of `' + passwords[i].pw + '` returns ' + passwords[i].score ); + assert.equal( passwordStrength( passwords[i].pw, 'username', passwords[i].pw ), passwords[i].score, 'password of `' + passwords[i].pw + '` returns ' + passwords[i].score ); } }); - test( 'blacklisted words in password should be penalized', function() { + QUnit.test( 'blacklisted words in password should be penalized', function( assert ) { var allowedPasswordScore, penalizedPasswordScore, allowedPassword = 'a[janedoefoe]4', penalizedPassword = 'a[johndoefoe]4', @@ -89,14 +89,14 @@ jQuery( function() { allowedPasswordScore = passwordStrength( allowedPassword, blacklist, allowedPassword ); penalizedPasswordScore = passwordStrength( penalizedPassword, blacklist, penalizedPassword ); - ok( penalizedPasswordScore < allowedPasswordScore, 'Penalized password scored ' + penalizedPasswordScore + '; allowed password scored: ' + allowedPasswordScore ); + assert.ok( penalizedPasswordScore < allowedPasswordScore, 'Penalized password scored ' + penalizedPasswordScore + '; allowed password scored: ' + allowedPasswordScore ); }); - test( 'user input blacklist array should contain expected words', function() { + QUnit.test( 'user input blacklist array should contain expected words', function( assert ) { var blacklist = wp.passwordStrength.userInputBlacklist(); - ok( jQuery.isArray( blacklist ), 'blacklist is an array' ); - ok( jQuery.inArray( 'WordPress', blacklist ) > -1, 'blacklist contains "WordPress" from page title' ); - ok( jQuery.inArray( 'tests', blacklist ) > -1, 'blacklist contains "tests" from site URL' ); + assert.ok( jQuery.isArray( blacklist ), 'blacklist is an array' ); + assert.ok( jQuery.inArray( 'WordPress', blacklist ) > -1, 'blacklist contains "WordPress" from page title' ); + assert.ok( jQuery.inArray( 'tests', blacklist ) > -1, 'blacklist contains "tests" from site URL' ); }); }); diff --git a/tests/qunit/wp-admin/js/widgets/test-media-gallery-widget.js b/tests/qunit/wp-admin/js/widgets/test-media-gallery-widget.js index c07dae52d8..17fa81f567 100644 --- a/tests/qunit/wp-admin/js/widgets/test-media-gallery-widget.js +++ b/tests/qunit/wp-admin/js/widgets/test-media-gallery-widget.js @@ -6,24 +6,24 @@ ( function() { 'use strict'; - module( 'Gallery Media Widget' ); + QUnit.module( 'Gallery Media Widget' ); - test( 'gallery widget control', function() { + QUnit.test( 'gallery widget control', function( assert ) { var GalleryWidgetControl; - equal( typeof wp.mediaWidgets.controlConstructors.media_gallery, 'function', 'wp.mediaWidgets.controlConstructors.media_gallery is a function' ); + assert.equal( typeof wp.mediaWidgets.controlConstructors.media_gallery, 'function', 'wp.mediaWidgets.controlConstructors.media_gallery is a function' ); GalleryWidgetControl = wp.mediaWidgets.controlConstructors.media_gallery; - ok( GalleryWidgetControl.prototype instanceof wp.mediaWidgets.MediaWidgetControl, 'wp.mediaWidgets.controlConstructors.media_gallery subclasses wp.mediaWidgets.MediaWidgetControl' ); + assert.ok( GalleryWidgetControl.prototype instanceof wp.mediaWidgets.MediaWidgetControl, 'wp.mediaWidgets.controlConstructors.media_gallery subclasses wp.mediaWidgets.MediaWidgetControl' ); }); - test( 'gallery media model', function() { + QUnit.test( 'gallery media model', function( assert ) { var GalleryWidgetModel, galleryWidgetModelInstance; - equal( typeof wp.mediaWidgets.modelConstructors.media_gallery, 'function', 'wp.mediaWidgets.modelConstructors.media_gallery is a function' ); + assert.equal( typeof wp.mediaWidgets.modelConstructors.media_gallery, 'function', 'wp.mediaWidgets.modelConstructors.media_gallery is a function' ); GalleryWidgetModel = wp.mediaWidgets.modelConstructors.media_gallery; - ok( GalleryWidgetModel.prototype instanceof wp.mediaWidgets.MediaWidgetModel, 'wp.mediaWidgets.modelConstructors.media_gallery subclasses wp.mediaWidgets.MediaWidgetModel' ); + assert.ok( GalleryWidgetModel.prototype instanceof wp.mediaWidgets.MediaWidgetModel, 'wp.mediaWidgets.modelConstructors.media_gallery subclasses wp.mediaWidgets.MediaWidgetModel' ); galleryWidgetModelInstance = new GalleryWidgetModel(); _.each( galleryWidgetModelInstance.attributes, function( value, key ) { - equal( value, GalleryWidgetModel.prototype.schema[ key ][ 'default' ], 'Should properly set default for ' + key ); + assert.equal( value, GalleryWidgetModel.prototype.schema[ key ][ 'default' ], 'Should properly set default for ' + key ); }); }); diff --git a/tests/qunit/wp-admin/js/widgets/test-media-image-widget.js b/tests/qunit/wp-admin/js/widgets/test-media-image-widget.js index 62d4262749..b474fc19e9 100644 --- a/tests/qunit/wp-admin/js/widgets/test-media-image-widget.js +++ b/tests/qunit/wp-admin/js/widgets/test-media-image-widget.js @@ -6,14 +6,14 @@ ( function() { 'use strict'; - module( 'Image Media Widget' ); + QUnit.module( 'Image Media Widget' ); - test( 'image widget control', function() { + QUnit.test( 'image widget control', function( assert ) { var ImageWidgetControl, imageWidgetControlInstance, imageWidgetModelInstance, mappedProps, testImageUrl, templateProps; testImageUrl = 'http://s.w.org/style/images/wp-header-logo.png'; - equal( typeof wp.mediaWidgets.controlConstructors.media_image, 'function', 'wp.mediaWidgets.controlConstructors.media_image is a function' ); + assert.equal( typeof wp.mediaWidgets.controlConstructors.media_image, 'function', 'wp.mediaWidgets.controlConstructors.media_image is a function' ); ImageWidgetControl = wp.mediaWidgets.controlConstructors.media_image; - ok( ImageWidgetControl.prototype instanceof wp.mediaWidgets.MediaWidgetControl, 'wp.mediaWidgets.controlConstructors.media_image subclasses wp.mediaWidgets.MediaWidgetControl' ); + assert.ok( ImageWidgetControl.prototype instanceof wp.mediaWidgets.MediaWidgetControl, 'wp.mediaWidgets.controlConstructors.media_image subclasses wp.mediaWidgets.MediaWidgetControl' ); imageWidgetModelInstance = new wp.mediaWidgets.modelConstructors.media_image(); imageWidgetControlInstance = new ImageWidgetControl({ @@ -24,35 +24,35 @@ // Test mapModelToPreviewTemplateProps() when no data is set. templateProps = imageWidgetControlInstance.mapModelToPreviewTemplateProps(); - equal( templateProps.caption, undefined, 'mapModelToPreviewTemplateProps should not return attributes that are should_preview_update false' ); - equal( templateProps.attachment_id, 0, 'mapModelToPreviewTemplateProps should return default values' ); - equal( templateProps.currentFilename, '', 'mapModelToPreviewTemplateProps should return a currentFilename' ); + assert.equal( templateProps.caption, undefined, 'mapModelToPreviewTemplateProps should not return attributes that are should_preview_update false' ); + assert.equal( templateProps.attachment_id, 0, 'mapModelToPreviewTemplateProps should return default values' ); + assert.equal( templateProps.currentFilename, '', 'mapModelToPreviewTemplateProps should return a currentFilename' ); // Test mapModelToPreviewTemplateProps() when data is set on model. imageWidgetControlInstance.model.set( { url: testImageUrl, alt: 'some alt text', link_type: 'none' } ); templateProps = imageWidgetControlInstance.mapModelToPreviewTemplateProps(); - equal( templateProps.currentFilename, 'wp-header-logo.png', 'mapModelToPreviewTemplateProps should set currentFilename based off of url' ); - equal( templateProps.url, testImageUrl, 'mapModelToPreviewTemplateProps should return the proper url' ); - equal( templateProps.alt, 'some alt text', 'mapModelToPreviewTemplateProps should return the proper alt text' ); - equal( templateProps.link_type, undefined, 'mapModelToPreviewTemplateProps should ignore attributes that are not needed in the preview' ); - equal( templateProps.error, false, 'mapModelToPreviewTemplateProps should return error state' ); + assert.equal( templateProps.currentFilename, 'wp-header-logo.png', 'mapModelToPreviewTemplateProps should set currentFilename based off of url' ); + assert.equal( templateProps.url, testImageUrl, 'mapModelToPreviewTemplateProps should return the proper url' ); + assert.equal( templateProps.alt, 'some alt text', 'mapModelToPreviewTemplateProps should return the proper alt text' ); + assert.equal( templateProps.link_type, undefined, 'mapModelToPreviewTemplateProps should ignore attributes that are not needed in the preview' ); + assert.equal( templateProps.error, false, 'mapModelToPreviewTemplateProps should return error state' ); // Test mapModelToPreviewTemplateProps() when error is set on model. imageWidgetControlInstance.model.set( 'error', 'missing_attachment' ); templateProps = imageWidgetControlInstance.mapModelToPreviewTemplateProps(); - equal( templateProps.error, 'missing_attachment', 'mapModelToPreviewTemplateProps should return error string' ); + assert.equal( templateProps.error, 'missing_attachment', 'mapModelToPreviewTemplateProps should return error string' ); // Reset model. imageWidgetControlInstance.model.set({ error: false, attachment_id: 0, url: null }); // Test isSelected(). - equal( imageWidgetControlInstance.isSelected(), false, 'media_image.isSelected() should return false when no media is selected' ); + assert.equal( imageWidgetControlInstance.isSelected(), false, 'media_image.isSelected() should return false when no media is selected' ); imageWidgetControlInstance.model.set({ error: 'missing_attachment', attachment_id: 777 }); - equal( imageWidgetControlInstance.isSelected(), false, 'media_image.isSelected() should return false when media is selected and error is set' ); + assert.equal( imageWidgetControlInstance.isSelected(), false, 'media_image.isSelected() should return false when media is selected and error is set' ); imageWidgetControlInstance.model.set({ error: false, attachment_id: 777 }); - equal( imageWidgetControlInstance.isSelected(), true, 'media_image.isSelected() should return true when media is selected and no error exists' ); + assert.equal( imageWidgetControlInstance.isSelected(), true, 'media_image.isSelected() should return true when media is selected and no error exists' ); imageWidgetControlInstance.model.set({ error: false, attachment_id: 0, url: testImageUrl }); - equal( imageWidgetControlInstance.isSelected(), true, 'media_image.isSelected() should return true when url is set and no error exists' ); + assert.equal( imageWidgetControlInstance.isSelected(), true, 'media_image.isSelected() should return true when url is set and no error exists' ); // Reset model. imageWidgetControlInstance.model.set({ error: false, attachment_id: 0, url: null }); @@ -60,27 +60,27 @@ // Test editing of widget title. imageWidgetControlInstance.render(); imageWidgetControlInstance.$el.find( '.title' ).val( 'Chicken and Ribs' ).trigger( 'input' ); - equal( imageWidgetModelInstance.get( 'title' ), 'Chicken and Ribs', 'Changing title should update model title attribute' ); + assert.equal( imageWidgetModelInstance.get( 'title' ), 'Chicken and Ribs', 'Changing title should update model title attribute' ); // Test mapMediaToModelProps. mappedProps = imageWidgetControlInstance.mapMediaToModelProps( { link: 'file', url: testImageUrl } ); - equal( mappedProps.link_url, testImageUrl, 'mapMediaToModelProps should set file link_url according to mediaFrameProps.link' ); + assert.equal( mappedProps.link_url, testImageUrl, 'mapMediaToModelProps should set file link_url according to mediaFrameProps.link' ); mappedProps = imageWidgetControlInstance.mapMediaToModelProps( { link: 'post', postUrl: 'https://wordpress.org/image-2/' } ); - equal( mappedProps.link_url, 'https://wordpress.org/image-2/', 'mapMediaToModelProps should set file link_url according to mediaFrameProps.link' ); + assert.equal( mappedProps.link_url, 'https://wordpress.org/image-2/', 'mapMediaToModelProps should set file link_url according to mediaFrameProps.link' ); mappedProps = imageWidgetControlInstance.mapMediaToModelProps( { link: 'custom', linkUrl: 'https://wordpress.org' } ); - equal( mappedProps.link_url, 'https://wordpress.org', 'mapMediaToModelProps should set custom link_url according to mediaFrameProps.linkUrl' ); + assert.equal( mappedProps.link_url, 'https://wordpress.org', 'mapMediaToModelProps should set custom link_url according to mediaFrameProps.linkUrl' ); // Test mapModelToMediaFrameProps(). imageWidgetControlInstance.model.set({ error: false, url: testImageUrl, 'link_type': 'custom', 'link_url': 'https://wordpress.org', 'size': 'custom', 'width': 100, 'height': 150, 'title': 'widget title', 'image_title': 'title of image' }); mappedProps = imageWidgetControlInstance.mapModelToMediaFrameProps( imageWidgetControlInstance.model.toJSON() ); - equal( mappedProps.linkUrl, 'https://wordpress.org', 'mapModelToMediaFrameProps should set linkUrl from model.link_url' ); - equal( mappedProps.link, 'custom', 'mapModelToMediaFrameProps should set link from model.link_type' ); - equal( mappedProps.width, 100, 'mapModelToMediaFrameProps should set width when model.size is custom' ); - equal( mappedProps.height, 150, 'mapModelToMediaFrameProps should set height when model.size is custom' ); - equal( mappedProps.title, 'title of image', 'mapModelToMediaFrameProps should set title from model.image_title' ); + assert.equal( mappedProps.linkUrl, 'https://wordpress.org', 'mapModelToMediaFrameProps should set linkUrl from model.link_url' ); + assert.equal( mappedProps.link, 'custom', 'mapModelToMediaFrameProps should set link from model.link_type' ); + assert.equal( mappedProps.width, 100, 'mapModelToMediaFrameProps should set width when model.size is custom' ); + assert.equal( mappedProps.height, 150, 'mapModelToMediaFrameProps should set height when model.size is custom' ); + assert.equal( mappedProps.title, 'title of image', 'mapModelToMediaFrameProps should set title from model.image_title' ); }); - test( 'image widget control renderPreview', function( assert ) { + QUnit.test( 'image widget control renderPreview', function( assert ) { var imageWidgetControlInstance, imageWidgetModelInstance, done; done = assert.async(); @@ -90,27 +90,27 @@ syncContainer: jQuery( '
      ' ), model: imageWidgetModelInstance }); - equal( imageWidgetControlInstance.$el.find( 'img' ).length, 0, 'No images should be rendered' ); + assert.equal( imageWidgetControlInstance.$el.find( 'img' ).length, 0, 'No images should be rendered' ); imageWidgetControlInstance.model.set({ error: false, url: 'http://s.w.org/style/images/wp-header-logo.png' }); // Due to renderPreview being deferred. setTimeout( function() { - equal( imageWidgetControlInstance.$el.find( 'img[src="http://s.w.org/style/images/wp-header-logo.png"]' ).length, 1, 'One image should be rendered' ); + assert.equal( imageWidgetControlInstance.$el.find( 'img[src="http://s.w.org/style/images/wp-header-logo.png"]' ).length, 1, 'One image should be rendered' ); done(); }, 50 ); - start(); + done(); }); - test( 'image media model', function() { + QUnit.test( 'image media model', function( assert ) { var ImageWidgetModel, imageWidgetModelInstance; - equal( typeof wp.mediaWidgets.modelConstructors.media_image, 'function', 'wp.mediaWidgets.modelConstructors.media_image is a function' ); + assert.equal( typeof wp.mediaWidgets.modelConstructors.media_image, 'function', 'wp.mediaWidgets.modelConstructors.media_image is a function' ); ImageWidgetModel = wp.mediaWidgets.modelConstructors.media_image; - ok( ImageWidgetModel.prototype instanceof wp.mediaWidgets.MediaWidgetModel, 'wp.mediaWidgets.modelConstructors.media_image subclasses wp.mediaWidgets.MediaWidgetModel' ); + assert.ok( ImageWidgetModel.prototype instanceof wp.mediaWidgets.MediaWidgetModel, 'wp.mediaWidgets.modelConstructors.media_image subclasses wp.mediaWidgets.MediaWidgetModel' ); imageWidgetModelInstance = new ImageWidgetModel(); _.each( imageWidgetModelInstance.attributes, function( value, key ) { - equal( value, ImageWidgetModel.prototype.schema[ key ][ 'default' ], 'Should properly set default for ' + key ); + assert.equal( value, ImageWidgetModel.prototype.schema[ key ][ 'default' ], 'Should properly set default for ' + key ); }); }); diff --git a/tests/qunit/wp-admin/js/widgets/test-media-video-widget.js b/tests/qunit/wp-admin/js/widgets/test-media-video-widget.js index 776ea5f952..f1574f095c 100644 --- a/tests/qunit/wp-admin/js/widgets/test-media-video-widget.js +++ b/tests/qunit/wp-admin/js/widgets/test-media-video-widget.js @@ -6,14 +6,14 @@ ( function() { 'use strict'; - module( 'Video Media Widget' ); + QUnit.module( 'Video Media Widget' ); - test( 'video widget control', function() { + QUnit.test( 'video widget control', function( assert ) { var VideoWidgetControl, videoWidgetControlInstance, videoWidgetModelInstance, mappedProps, testVideoUrl; testVideoUrl = 'https://videos.files.wordpress.com/AHz0Ca46/wp4-7-vaughan-r8-mastered_hd.mp4'; - equal( typeof wp.mediaWidgets.controlConstructors.media_video, 'function', 'wp.mediaWidgets.controlConstructors.media_video is a function' ); + assert.equal( typeof wp.mediaWidgets.controlConstructors.media_video, 'function', 'wp.mediaWidgets.controlConstructors.media_video is a function' ); VideoWidgetControl = wp.mediaWidgets.controlConstructors.media_video; - ok( VideoWidgetControl.prototype instanceof wp.mediaWidgets.MediaWidgetControl, 'wp.mediaWidgets.controlConstructors.media_video subclasses wp.mediaWidgets.MediaWidgetControl' ); + assert.ok( VideoWidgetControl.prototype instanceof wp.mediaWidgets.MediaWidgetControl, 'wp.mediaWidgets.controlConstructors.media_video subclasses wp.mediaWidgets.MediaWidgetControl' ); videoWidgetModelInstance = new wp.mediaWidgets.modelConstructors.media_video(); videoWidgetControlInstance = new VideoWidgetControl({ @@ -25,18 +25,18 @@ // Test mapModelToMediaFrameProps(). videoWidgetControlInstance.model.set({ error: false, url: testVideoUrl, loop: false, preload: 'meta' }); mappedProps = videoWidgetControlInstance.mapModelToMediaFrameProps( videoWidgetControlInstance.model.toJSON() ); - equal( mappedProps.url, testVideoUrl, 'mapModelToMediaFrameProps should set url' ); - equal( mappedProps.loop, false, 'mapModelToMediaFrameProps should set loop' ); - equal( mappedProps.preload, 'meta', 'mapModelToMediaFrameProps should set preload' ); + assert.equal( mappedProps.url, testVideoUrl, 'mapModelToMediaFrameProps should set url' ); + assert.equal( mappedProps.loop, false, 'mapModelToMediaFrameProps should set loop' ); + assert.equal( mappedProps.preload, 'meta', 'mapModelToMediaFrameProps should set preload' ); // Test mapMediaToModelProps(). mappedProps = videoWidgetControlInstance.mapMediaToModelProps( { loop: false, preload: 'meta', url: testVideoUrl, title: 'random movie file title' } ); - equal( mappedProps.title, undefined, 'mapMediaToModelProps should ignore title inputs' ); - equal( mappedProps.loop, false, 'mapMediaToModelProps should set loop' ); - equal( mappedProps.preload, 'meta', 'mapMediaToModelProps should set preload' ); + assert.equal( mappedProps.title, undefined, 'mapMediaToModelProps should ignore title inputs' ); + assert.equal( mappedProps.loop, false, 'mapMediaToModelProps should set loop' ); + assert.equal( mappedProps.preload, 'meta', 'mapMediaToModelProps should set preload' ); }); - test( 'video widget control renderPreview', function( assert ) { + QUnit.test( 'video widget control renderPreview', function( assert ) { var videoWidgetControlInstance, videoWidgetModelInstance, done; done = assert.async(); @@ -46,26 +46,27 @@ syncContainer: jQuery( '
      ' ), model: videoWidgetModelInstance }); - equal( videoWidgetControlInstance.$el.find( 'a' ).length, 0, 'No video links should be rendered' ); + assert.equal( videoWidgetControlInstance.$el.find( 'a' ).length, 0, 'No video links should be rendered' ); videoWidgetControlInstance.model.set({ error: false, url: 'https://videos.files.wordpress.com/AHz0Ca46/wp4-7-vaughan-r8-mastered_hd.mp4' }); // Due to renderPreview being deferred. setTimeout( function() { - equal( videoWidgetControlInstance.$el.find( 'a[href="https://videos.files.wordpress.com/AHz0Ca46/wp4-7-vaughan-r8-mastered_hd.mp4"]' ).length, 1, 'One video link should be rendered' ); + assert.equal( videoWidgetControlInstance.$el.find( 'a[href="https://videos.files.wordpress.com/AHz0Ca46/wp4-7-vaughan-r8-mastered_hd.mp4"]' ).length, 1, 'One video link should be rendered' ); done(); }, 50 ); - start(); + + done(); }); - test( 'video media model', function() { + QUnit.test( 'video media model', function( assert ) { var VideoWidgetModel, videoWidgetModelInstance; - equal( typeof wp.mediaWidgets.modelConstructors.media_video, 'function', 'wp.mediaWidgets.modelConstructors.media_video is a function' ); + assert.equal( typeof wp.mediaWidgets.modelConstructors.media_video, 'function', 'wp.mediaWidgets.modelConstructors.media_video is a function' ); VideoWidgetModel = wp.mediaWidgets.modelConstructors.media_video; - ok( VideoWidgetModel.prototype instanceof wp.mediaWidgets.MediaWidgetModel, 'wp.mediaWidgets.modelConstructors.media_video subclasses wp.mediaWidgets.MediaWidgetModel' ); + assert.ok( VideoWidgetModel.prototype instanceof wp.mediaWidgets.MediaWidgetModel, 'wp.mediaWidgets.modelConstructors.media_video subclasses wp.mediaWidgets.MediaWidgetModel' ); videoWidgetModelInstance = new VideoWidgetModel(); _.each( videoWidgetModelInstance.attributes, function( value, key ) { - equal( value, VideoWidgetModel.prototype.schema[ key ][ 'default' ], 'Should properly set default for ' + key ); + assert.equal( value, VideoWidgetModel.prototype.schema[ key ][ 'default' ], 'Should properly set default for ' + key ); }); }); diff --git a/tests/qunit/wp-admin/js/widgets/test-media-widgets.js b/tests/qunit/wp-admin/js/widgets/test-media-widgets.js index 5fd8b346d4..4340f53ab7 100644 --- a/tests/qunit/wp-admin/js/widgets/test-media-widgets.js +++ b/tests/qunit/wp-admin/js/widgets/test-media-widgets.js @@ -2,44 +2,44 @@ /* jshint qunit: true */ /* eslint-env qunit */ -(function() { +( function() { 'use strict'; - module( 'Media Widgets' ); + QUnit.module( 'Media Widgets' ); - test( 'namespace', function() { - equal( typeof wp.mediaWidgets, 'object', 'wp.mediaWidgets is an object' ); - equal( typeof wp.mediaWidgets.controlConstructors, 'object', 'wp.mediaWidgets.controlConstructors is an object' ); - equal( typeof wp.mediaWidgets.modelConstructors, 'object', 'wp.mediaWidgets.modelConstructors is an object' ); - equal( typeof wp.mediaWidgets.widgetControls, 'object', 'wp.mediaWidgets.widgetControls is an object' ); - equal( typeof wp.mediaWidgets.handleWidgetAdded, 'function', 'wp.mediaWidgets.handleWidgetAdded is an function' ); - equal( typeof wp.mediaWidgets.handleWidgetUpdated, 'function', 'wp.mediaWidgets.handleWidgetUpdated is an function' ); - equal( typeof wp.mediaWidgets.init, 'function', 'wp.mediaWidgets.init is an function' ); + QUnit.test( 'namespace', function( assert ) { + assert.equal( typeof wp.mediaWidgets, 'object', 'wp.mediaWidgets is an object' ); + assert.equal( typeof wp.mediaWidgets.controlConstructors, 'object', 'wp.mediaWidgets.controlConstructors is an object' ); + assert.equal( typeof wp.mediaWidgets.modelConstructors, 'object', 'wp.mediaWidgets.modelConstructors is an object' ); + assert.equal( typeof wp.mediaWidgets.widgetControls, 'object', 'wp.mediaWidgets.widgetControls is an object' ); + assert.equal( typeof wp.mediaWidgets.handleWidgetAdded, 'function', 'wp.mediaWidgets.handleWidgetAdded is an function' ); + assert.equal( typeof wp.mediaWidgets.handleWidgetUpdated, 'function', 'wp.mediaWidgets.handleWidgetUpdated is an function' ); + assert.equal( typeof wp.mediaWidgets.init, 'function', 'wp.mediaWidgets.init is an function' ); }); - test( 'media widget control', function() { - equal( typeof wp.mediaWidgets.MediaWidgetControl, 'function', 'wp.mediaWidgets.MediaWidgetControl' ); - ok( wp.mediaWidgets.MediaWidgetControl.prototype instanceof Backbone.View, 'wp.mediaWidgets.MediaWidgetControl subclasses Backbone.View' ); + QUnit.test( 'media widget control', function( assert ) { + assert.equal( typeof wp.mediaWidgets.MediaWidgetControl, 'function', 'wp.mediaWidgets.MediaWidgetControl' ); + assert.ok( wp.mediaWidgets.MediaWidgetControl.prototype instanceof Backbone.View, 'wp.mediaWidgets.MediaWidgetControl subclasses Backbone.View' ); }); - test( 'media widget model', function() { + QUnit.test( 'media widget model', function( assert ) { var widgetModelInstance; - equal( typeof wp.mediaWidgets.MediaWidgetModel, 'function', 'wp.mediaWidgets.MediaWidgetModel is a function' ); - ok( wp.mediaWidgets.MediaWidgetModel.prototype instanceof Backbone.Model, 'wp.mediaWidgets.MediaWidgetModel subclasses Backbone.Model' ); + assert.equal( typeof wp.mediaWidgets.MediaWidgetModel, 'function', 'wp.mediaWidgets.MediaWidgetModel is a function' ); + assert.ok( wp.mediaWidgets.MediaWidgetModel.prototype instanceof Backbone.Model, 'wp.mediaWidgets.MediaWidgetModel subclasses Backbone.Model' ); widgetModelInstance = new wp.mediaWidgets.MediaWidgetModel(); - equal( widgetModelInstance.get( 'title' ), '', 'wp.mediaWidgets.MediaWidgetModel defaults title to empty string' ); - equal( widgetModelInstance.get( 'attachment_id' ), 0, 'wp.mediaWidgets.MediaWidgetModel defaults attachment_id to 0' ); - equal( widgetModelInstance.get( 'url' ), 0, 'wp.mediaWidgets.MediaWidgetModel defaults url to empty string' ); + assert.equal( widgetModelInstance.get( 'title' ), '', 'wp.mediaWidgets.MediaWidgetModel defaults title to empty string' ); + assert.equal( widgetModelInstance.get( 'attachment_id' ), 0, 'wp.mediaWidgets.MediaWidgetModel defaults attachment_id to 0' ); + assert.equal( widgetModelInstance.get( 'url' ), 0, 'wp.mediaWidgets.MediaWidgetModel defaults url to empty string' ); widgetModelInstance.set({ title: 'chicken and ribs', attachment_id: '1', url: 'https://wordpress.org' }); - equal( widgetModelInstance.get( 'title' ), 'chicken and ribs', 'wp.mediaWidgets.MediaWidgetModel properly sets the title attribute' ); - equal( widgetModelInstance.get( 'url' ), 'https://wordpress.org', 'wp.mediaWidgets.MediaWidgetModel properly sets the url attribute' ); - equal( widgetModelInstance.get( 'attachment_id' ), 1, 'wp.mediaWidgets.MediaWidgetModel properly sets and casts the attachment_id attribute' ); + assert.equal( widgetModelInstance.get( 'title' ), 'chicken and ribs', 'wp.mediaWidgets.MediaWidgetModel properly sets the title attribute' ); + assert.equal( widgetModelInstance.get( 'url' ), 'https://wordpress.org', 'wp.mediaWidgets.MediaWidgetModel properly sets the url attribute' ); + assert.equal( widgetModelInstance.get( 'attachment_id' ), 1, 'wp.mediaWidgets.MediaWidgetModel properly sets and casts the attachment_id attribute' ); }); })(); diff --git a/tests/qunit/wp-includes/js/shortcode.js b/tests/qunit/wp-includes/js/shortcode.js index 405b53546d..af1b25847c 100644 --- a/tests/qunit/wp-includes/js/shortcode.js +++ b/tests/qunit/wp-includes/js/shortcode.js @@ -1,167 +1,167 @@ /* global wp, jQuery */ jQuery( function() { - module( 'shortcode' ); + QUnit.module( 'shortcode' ); - test( 'next() should find the shortcode', function() { + QUnit.test( 'next() should find the shortcode', function( assert ) { var result; // Basic. result = wp.shortcode.next( 'foo', 'this has the [foo] shortcode' ); - equal( result.index, 13, 'foo shortcode found at index 13' ); + assert.equal( result.index, 13, 'foo shortcode found at index 13' ); result = wp.shortcode.next( 'foo', 'this has the [foo param="foo"] shortcode' ); - equal( result.index, 13, 'foo shortcode with params found at index 13' ); + assert.equal( result.index, 13, 'foo shortcode with params found at index 13' ); }); - test( 'next() should not find shortcodes that are not there', function() { + QUnit.test( 'next() should not find shortcodes that are not there', function( assert ) { var result; // Not found. result = wp.shortcode.next( 'bar', 'this has the [foo] shortcode' ); - equal( result, undefined, 'bar shortcode not found' ); + assert.equal( result, undefined, 'bar shortcode not found' ); result = wp.shortcode.next( 'bar', 'this has the [foo param="bar"] shortcode' ); - equal( result, undefined, 'bar shortcode not found with params' ); + assert.equal( result, undefined, 'bar shortcode not found with params' ); }); - test( 'next() should find the shortcode when told to start looking beyond the start of the string', function() { + QUnit.test( 'next() should find the shortcode when told to start looking beyond the start of the string', function( assert ) { var result; // Starting at indices. result = wp.shortcode.next( 'foo', 'this has the [foo] shortcode', 12 ); - equal( result.index, 13, 'foo shortcode found before index 13' ); + assert.equal( result.index, 13, 'foo shortcode found before index 13' ); result = wp.shortcode.next( 'foo', 'this has the [foo] shortcode', 13 ); - equal( result.index, 13, 'foo shortcode found at index 13' ); + assert.equal( result.index, 13, 'foo shortcode found at index 13' ); result = wp.shortcode.next( 'foo', 'this has the [foo] shortcode', 14 ); - equal( result, undefined, 'foo shortcode not found after index 13' ); + assert.equal( result, undefined, 'foo shortcode not found after index 13' ); }); - test( 'next() should find the second instances of the shortcode when the starting indice is after the start of the first one', function() { + QUnit.test( 'next() should find the second instances of the shortcode when the starting indice is after the start of the first one', function( assert ) { var result; result = wp.shortcode.next( 'foo', 'this has the [foo] shortcode [foo] twice', 14 ); - equal( result.index, 29, 'foo shortcode found the second foo at index 29' ); + assert.equal( result.index, 29, 'foo shortcode found the second foo at index 29' ); }); - test( 'next() should not find escaped shortcodes', function() { + QUnit.test( 'next() should not find escaped shortcodes', function( assert ) { var result; // Escaped. result = wp.shortcode.next( 'foo', 'this has the [[foo]] shortcode' ); - equal( result, undefined, 'foo shortcode not found when escaped' ); + assert.equal( result, undefined, 'foo shortcode not found when escaped' ); result = wp.shortcode.next( 'foo', 'this has the [[foo param="foo"]] shortcode' ); - equal( result, undefined, 'foo shortcode not found when escaped with params' ); + assert.equal( result, undefined, 'foo shortcode not found when escaped with params' ); }); - test( 'next() should find shortcodes that are incorrectly escaped by newlines', function() { + QUnit.test( 'next() should find shortcodes that are incorrectly escaped by newlines', function( assert ) { var result; result = wp.shortcode.next( 'foo', 'this has the [\n[foo]] shortcode' ); - equal( result.index, 15, 'shortcode found when incorrectly escaping the start of it' ); + assert.equal( result.index, 15, 'shortcode found when incorrectly escaping the start of it' ); result = wp.shortcode.next( 'foo', 'this has the [[foo]\n] shortcode' ); - equal( result.index, 14, 'shortcode found when incorrectly escaping the end of it' ); + assert.equal( result.index, 14, 'shortcode found when incorrectly escaping the end of it' ); }); - test( 'next() should still work when there are not equal ammounts of square brackets', function() { + QUnit.test( 'next() should still work when there are not equal ammounts of square brackets', function( assert ) { var result; result = wp.shortcode.next( 'foo', 'this has the [[foo] shortcode' ); - equal( result.index, 14, 'shortcode found when there are offset square brackets' ); + assert.equal( result.index, 14, 'shortcode found when there are offset square brackets' ); result = wp.shortcode.next( 'foo', 'this has the [foo]] shortcode' ); - equal( result.index, 13, 'shortcode found when there are offset square brackets' ); + assert.equal( result.index, 13, 'shortcode found when there are offset square brackets' ); }); - test( 'next() should find the second instances of the shortcode when the first one is escaped', function() { + QUnit.test( 'next() should find the second instances of the shortcode when the first one is escaped', function( assert ) { var result; result = wp.shortcode.next( 'foo', 'this has the [[foo]] shortcode [foo] twice' ); - equal( result.index, 31, 'foo shortcode found the non-escaped foo at index 31' ); + assert.equal( result.index, 31, 'foo shortcode found the non-escaped foo at index 31' ); }); - test( 'next() should not find shortcodes that are not full matches', function() { + QUnit.test( 'next() should not find shortcodes that are not full matches', function( assert ) { var result; // Stubs. result = wp.shortcode.next( 'foo', 'this has the [foobar] shortcode' ); - equal( result, undefined, 'stub does not trigger match' ); + assert.equal( result, undefined, 'stub does not trigger match' ); result = wp.shortcode.next( 'foobar', 'this has the [foo] shortcode' ); - equal( result, undefined, 'stub does not trigger match' ); + assert.equal( result, undefined, 'stub does not trigger match' ); }); - test( 'replace() should replace the shortcode', function() { + QUnit.test( 'replace() should replace the shortcode', function( assert ) { var result; // Basic. result = wp.shortcode.replace( 'foo', 'this has the [foo] shortcode', shortcodeReplaceCallback ); - equal( result, 'this has the bar shortcode', 'foo replaced with bar' ); + assert.equal( result, 'this has the bar shortcode', 'foo replaced with bar' ); result = wp.shortcode.replace( 'foo', 'this has the [foo param="foo"] shortcode', shortcodeReplaceCallback ); - equal( result, 'this has the bar shortcode', 'foo and params replaced with bar' ); + assert.equal( result, 'this has the bar shortcode', 'foo and params replaced with bar' ); }); - test( 'replace() should not replace the shortcode when it does not match', function() { + QUnit.test( 'replace() should not replace the shortcode when it does not match', function( assert ) { var result; // Not found. result = wp.shortcode.replace( 'bar', 'this has the [foo] shortcode', shortcodeReplaceCallback ); - equal( result, 'this has the [foo] shortcode', 'bar not found' ); + assert.equal( result, 'this has the [foo] shortcode', 'bar not found' ); result = wp.shortcode.replace( 'bar', 'this has the [foo param="bar"] shortcode', shortcodeReplaceCallback ); - equal( result, 'this has the [foo param="bar"] shortcode', 'bar not found with params' ); + assert.equal( result, 'this has the [foo param="bar"] shortcode', 'bar not found with params' ); }); - test( 'replace() should replace the shortcode in all instances of its use', function() { + QUnit.test( 'replace() should replace the shortcode in all instances of its use', function( assert ) { var result; // Multiple instances. result = wp.shortcode.replace( 'foo', 'this has the [foo] shortcode [foo] twice', shortcodeReplaceCallback ); - equal( result, 'this has the bar shortcode bar twice', 'foo replaced with bar twice' ); + assert.equal( result, 'this has the bar shortcode bar twice', 'foo replaced with bar twice' ); result = wp.shortcode.replace( 'foo', 'this has the [foo param="foo"] shortcode [foo] twice', shortcodeReplaceCallback ); - equal( result, 'this has the bar shortcode bar twice', 'foo and params replaced with bar twice' ); + assert.equal( result, 'this has the bar shortcode bar twice', 'foo and params replaced with bar twice' ); }); - test( 'replace() should not replace the escaped shortcodes', function() { + QUnit.test( 'replace() should not replace the escaped shortcodes', function( assert ) { var result; // Escaped. result = wp.shortcode.replace( 'foo', 'this has the [[foo]] shortcode', shortcodeReplaceCallback ); - equal( result, 'this has the [[foo]] shortcode', 'escaped foo not replaced' ); + assert.equal( result, 'this has the [[foo]] shortcode', 'escaped foo not replaced' ); result = wp.shortcode.replace( 'foo', 'this has the [[foo param="bar"]] shortcode', shortcodeReplaceCallback ); - equal( result, 'this has the [[foo param="bar"]] shortcode', 'escaped foo with params not replaced' ); + assert.equal( result, 'this has the [[foo param="bar"]] shortcode', 'escaped foo with params not replaced' ); result = wp.shortcode.replace( 'foo', 'this [foo] has the [[foo param="bar"]] shortcode escaped', shortcodeReplaceCallback ); - equal( result, 'this bar has the [[foo param="bar"]] shortcode escaped', 'escaped foo with params not replaced but unescaped foo replaced' ); + assert.equal( result, 'this bar has the [[foo param="bar"]] shortcode escaped', 'escaped foo with params not replaced but unescaped foo replaced' ); }); - test( 'replace() should replace improperly escaped shortcodes that include newlines', function() { + QUnit.test( 'replace() should replace improperly escaped shortcodes that include newlines', function( assert ) { var result; result = wp.shortcode.replace( 'foo', 'this [foo] has the [[foo param="bar"]\n] shortcode ', shortcodeReplaceCallback ); - equal( result, 'this bar has the [bar\n] shortcode ', 'escaping with newlines should not actually escape the content' ); + assert.equal( result, 'this bar has the [bar\n] shortcode ', 'escaping with newlines should not actually escape the content' ); result = wp.shortcode.replace( 'foo', 'this [foo] has the [\n[foo param="bar"]] shortcode ', shortcodeReplaceCallback ); - equal( result, 'this bar has the [\nbar] shortcode ', 'escaping with newlines should not actually escape the content' ); + assert.equal( result, 'this bar has the [\nbar] shortcode ', 'escaping with newlines should not actually escape the content' ); }); - test( 'replace() should not replace the shortcode when it is an incomplete match', function() { + QUnit.test( 'replace() should not replace the shortcode when it is an incomplete match', function( assert ) { var result; // Stubs. result = wp.shortcode.replace( 'foo', 'this has the [foobar] shortcode', shortcodeReplaceCallback ); - equal( result, 'this has the [foobar] shortcode', 'stub not replaced' ); + assert.equal( result, 'this has the [foobar] shortcode', 'stub not replaced' ); result = wp.shortcode.replace( 'foobar', 'this has the [foo] shortcode', shortcodeReplaceCallback ); - equal( result, 'this has the [foo] shortcode', 'stub not replaced' ); + assert.equal( result, 'this has the [foo] shortcode', 'stub not replaced' ); }); /** @@ -171,7 +171,7 @@ jQuery( function() { return 'bar'; } - test( 'attrs() should return named attributes created with single, double, and no quotes', function() { + QUnit.test( 'attrs() should return named attributes created with single, double, and no quotes', function( assert ) { var expected = { 'named': { 'param': 'foo', @@ -180,42 +180,42 @@ jQuery( function() { }, 'numeric' : [] }; - deepEqual( wp.shortcode.attrs('param="foo" another=\'bar\' andagain=baz'), expected, 'attr parsed all three named types'); + assert.deepEqual( wp.shortcode.attrs('param="foo" another=\'bar\' andagain=baz'), expected, 'attr parsed all three named types'); }); - test( 'attrs() should return numeric attributes in the order they are used', function() { + QUnit.test( 'attrs() should return numeric attributes in the order they are used', function( assert ) { var expected = { 'named': {}, 'numeric' : ['foo', 'bar', 'baz'] }; - deepEqual( wp.shortcode.attrs('foo bar baz'), expected, 'attr parsed numeric attributes'); + assert.deepEqual( wp.shortcode.attrs('foo bar baz'), expected, 'attr parsed numeric attributes'); }); - test( 'attrs() should return numeric attributes in the order they are used when they have named attributes in between', function() { + QUnit.test( 'attrs() should return numeric attributes in the order they are used when they have named attributes in between', function( assert ) { var expected = { 'named': { 'not': 'a blocker' }, 'numeric' : ['foo', 'bar', 'baz'] }; - deepEqual( wp.shortcode.attrs('foo not="a blocker" bar baz'), expected, 'attr parsed numeric attributes'); + assert.deepEqual( wp.shortcode.attrs('foo not="a blocker" bar baz'), expected, 'attr parsed numeric attributes'); }); - test( 'attrs() should return numeric attributes created with single, double, and no quotes', function() { + QUnit.test( 'attrs() should return numeric attributes created with single, double, and no quotes', function( assert ) { var expected = { 'named': {}, 'numeric' : ['foo', 'bar', 'baz'] }; - deepEqual( wp.shortcode.attrs('foo "bar" \'baz\''), expected, 'attr parsed numeric attributes'); + assert.deepEqual( wp.shortcode.attrs('foo "bar" \'baz\''), expected, 'attr parsed numeric attributes'); }); - test( 'attrs() should return mixed attributes created with single, double, and no quotes', function() { + QUnit.test( 'attrs() should return mixed attributes created with single, double, and no quotes', function( assert ) { var expected = { 'named': { a: 'foo', b: 'bar', c: 'baz' }, 'numeric' : ['foo', 'bar', 'baz'] }; - deepEqual( wp.shortcode.attrs('a="foo" b=\'bar\' c=baz foo "bar" \'baz\''), expected, 'attr parsed numeric attributes'); + assert.deepEqual( wp.shortcode.attrs('a="foo" b=\'bar\' c=baz foo "bar" \'baz\''), expected, 'attr parsed numeric attributes'); }); - test( 'string() should accept attrs in any order', function() { + QUnit.test( 'string() should accept attrs in any order', function( assert ) { var expected = '[short abc123 foo="bar"]'; var result; @@ -227,7 +227,7 @@ jQuery( function() { numeric : [ 'abc123' ] } }); - deepEqual( result, expected, 'attributes are accepted in any order' ); + assert.deepEqual( result, expected, 'attributes are accepted in any order' ); result = wp.shortcode.string({ tag : 'short', @@ -237,6 +237,6 @@ jQuery( function() { named : { foo : 'bar' } } }); - deepEqual( result, expected, 'attributes are accepted in any order' ); + assert.deepEqual( result, expected, 'attributes are accepted in any order' ); }); }); diff --git a/tests/qunit/wp-includes/js/tinymce/tinymce-obsolete.js b/tests/qunit/wp-includes/js/tinymce/tinymce-obsolete.js index 9db1f9ac9d..e4dd00227f 100644 --- a/tests/qunit/wp-includes/js/tinymce/tinymce-obsolete.js +++ b/tests/qunit/wp-includes/js/tinymce/tinymce-obsolete.js @@ -81,7 +81,7 @@ // Ref: http://www.w3.org/TR/html5/obsolete.html, http://developers.whatwg.org/obsolete.html - QUnit.test('HTML elements non-conforming to HTML 5.0', function() { + QUnit.test('HTML elements non-conforming to HTML 5.0', function( assert ) { var testString; /* @@ -109,97 +109,97 @@ The rest are still supported in TinyMCE but "...must not be used by authors". */ - expect(6); + assert.expect(6); text = 'acronym'; testString = '

      WWW

      '; editor.setContent( testString ); - equal( editor.getContent(), testString, text ); + assert.equal( editor.getContent(), testString, text ); text = 'strike, converted to span'; editor.setContent( 'test' ); - equal( editor.getContent(), '

      test

      ', text ); + assert.equal( editor.getContent(), '

      test

      ', text ); text = 'big'; testString = '

      test

      '; editor.setContent( testString ); - equal( editor.getContent(), testString, text ); + assert.equal( editor.getContent(), testString, text ); text = 'center'; testString = '
      test
      '; editor.setContent( testString ); - equal( editor.getContent(), testString, text ); + assert.equal( editor.getContent(), testString, text ); text = 'font, converted to span'; editor.setContent( '

      test

      ' ); - equal( editor.getContent(), '

      test

      ', text ); + assert.equal( editor.getContent(), '

      test

      ', text ); text = 'tt'; testString = '

      test

      '; editor.setContent( testString ); - equal( editor.getContent(), testString, text ); + assert.equal( editor.getContent(), testString, text ); }); - QUnit.test('Obsolete (but still conforming) HTML attributes', function() { + QUnit.test('Obsolete (but still conforming) HTML attributes', function( assert ) { var testString; - expect(3); + assert.expect(3); text = 'border on '; testString = '

      '; editor.setContent( testString ); - equal( editor.getContent(), testString, text ); + assert.equal( editor.getContent(), testString, text ); text = 'Old style anchors'; testString = '

      '; editor.setContent( testString ); - equal( editor.getContent(), testString, text ); + assert.equal( editor.getContent(), testString, text ); text = 'maxlength, size on input type="number"'; testString = '

      '; editor.setContent( testString ); - ok( hasAttr( editor.getContent(), { input: 'maxlength size' } ), text ); + assert.ok( hasAttr( editor.getContent(), { input: 'maxlength size' } ), text ); }); - QUnit.test('Obsolete attributes in HTML 5.0', function() { + QUnit.test('Obsolete attributes in HTML 5.0', function( assert ) { var testString, text; - expect(22); + assert.expect(22); text = 'charset, rev, shape, coords on elements'; testString = '

      test

      '; editor.setContent( testString ); - ok( hasAttr( editor.getContent(), { a: 'charset rev shape coords' } ), text ); + assert.ok( hasAttr( editor.getContent(), { a: 'charset rev shape coords' } ), text ); text = 'name, align, hspace, vspace on img elements'; testString = '

      '; editor.setContent( testString ); - ok( hasAttr( editor.getContent(), { img: 'name align hspace vspace' } ), text ); + assert.ok( hasAttr( editor.getContent(), { img: 'name align hspace vspace' } ), text ); text = 'name, align, hspace, vspace, on embed elements'; testString = '

      '; editor.setContent( testString ); - ok( hasAttr( editor.getContent(), { embed: 'name align hspace vspace' } ), text ); + assert.ok( hasAttr( editor.getContent(), { embed: 'name align hspace vspace' } ), text ); text = 'archive, classid, code, codebase, codetype, declare, standby on object elements'; testString = '

      '; editor.setContent( testString ); - ok( hasAttr( editor.getContent(), { object: 'archive classid code codebase codetype declare standby' } ), text ); + assert.ok( hasAttr( editor.getContent(), { object: 'archive classid code codebase codetype declare standby' } ), text ); text = 'type, valuetype on param elements'; testString = '

      '; editor.setContent( testString ); - ok( hasAttr( editor.getContent(), { param: 'type valuetype' } ), text ); + assert.ok( hasAttr( editor.getContent(), { param: 'type valuetype' } ), text ); text = 'align, bgcolor, border, cellpadding, cellspacing, frame, rules, summary, width on table elements'; testString = '
      test
      '; editor.setContent( testString ); - ok( hasAttr( editor.getContent(), { table: 'align bgcolor border cellpadding cellspacing frame rules summary width' } ), text ); + assert.ok( hasAttr( editor.getContent(), { table: 'align bgcolor border cellpadding cellspacing frame rules summary width' } ), text ); text = 'align, char, charoff, valign on tbody, thead, and tfoot elements'; testString = '
      testtest
      '; editor.setContent( testString ); - ok( hasAttr( editor.getContent(), { + assert.ok( hasAttr( editor.getContent(), { thead: 'align char charoff valign', tfoot: 'align char charoff valign', tbody: 'align char charoff valign' @@ -208,7 +208,7 @@ text = 'axis, align, bgcolor, char, charoff, height, nowrap, valign, width on td and th elements, scope on td elements'; testString = '
      testtest
      '; editor.setContent( testString ); - ok( hasAttr( editor.getContent(), { + assert.ok( hasAttr( editor.getContent(), { th: 'axis align bgcolor char charoff height nowrap valign width', td: 'axis align bgcolor char charoff height nowrap valign width scope' } ), text ); @@ -216,72 +216,72 @@ text = 'align, bgcolor, char, charoff, valign on tr elements'; testString = '
      test
      '; editor.setContent( testString ); - ok( hasAttr( editor.getContent(), { tr: 'align bgcolor char charoff valign' } ), text ); + assert.ok( hasAttr( editor.getContent(), { tr: 'align bgcolor char charoff valign' } ), text ); text = 'clear on br elements'; testString = '

      test
      test

      '; editor.setContent( testString ); - equal( editor.getContent(), testString, text ); + assert.equal( editor.getContent(), testString, text ); text = 'align on caption elements'; testString = '
      test
      test
      '; editor.setContent( testString ); - equal( editor.getContent(), testString, text ); + assert.equal( editor.getContent(), testString, text ); text = 'align, char, charoff, valign, width on col elements'; testString = '
      testtest
      '; editor.setContent( testString ); - ok( hasAttr( editor.getContent(), { col: 'align char charoff valign width' } ), text ); + assert.ok( hasAttr( editor.getContent(), { col: 'align char charoff valign width' } ), text ); text = 'align on div, h1—h6, input, legend, p elements'; testString = '
      1

      1

      1

      test
      '; editor.setContent( testString ); - equal( editor.getContent(), testString, text ); + assert.equal( editor.getContent(), testString, text ); text = 'compact on dl elements'; testString = '
      1
      '; editor.setContent( testString ); - equal( editor.getContent(), testString, text ); + assert.equal( editor.getContent(), testString, text ); text = 'align, hspace, vspace on embed elements'; testString = '

      '; editor.setContent( testString ); - ok( hasAttr( editor.getContent(), { embed: 'align hspace vspace' } ), text ); + assert.ok( hasAttr( editor.getContent(), { embed: 'align hspace vspace' } ), text ); text = 'align, noshade, size, width on hr elements'; testString = '
      '; editor.setContent( testString ); - ok( hasAttr( editor.getContent(), { hr: 'align noshade size width' } ), text ); + assert.ok( hasAttr( editor.getContent(), { hr: 'align noshade size width' } ), text ); text = 'align, frameborder, marginheight, marginwidth, scrolling on iframe elements'; testString = '

      '; editor.setContent( testString ); - ok( hasAttr( editor.getContent(), { iframe: 'align frameborder marginheight marginwidth scrolling' } ), text ); + assert.ok( hasAttr( editor.getContent(), { iframe: 'align frameborder marginheight marginwidth scrolling' } ), text ); text = 'type on li elements'; testString = '
      • test
      '; editor.setContent( testString ); - equal( editor.getContent(), testString, text ); + assert.equal( editor.getContent(), testString, text ); text = 'align, border, hspace, vspace on object elements'; testString = '

      '; editor.setContent( testString ); - ok( hasAttr( editor.getContent(), { object: 'align border hspace vspace' } ), text ); + assert.ok( hasAttr( editor.getContent(), { object: 'align border hspace vspace' } ), text ); text = 'compact on ol elements'; testString = '
      1. test
      '; editor.setContent( testString ); - equal( editor.getContent(), testString, text ); + assert.equal( editor.getContent(), testString, text ); text = 'compact, type on ul elements'; testString = '
      • test
      '; editor.setContent( testString ); - ok( hasAttr( editor.getContent(), { ul: 'compact type' } ), text ); + assert.ok( hasAttr( editor.getContent(), { ul: 'compact type' } ), text ); text = 'width on pre elements'; testString = '
      1
      '; editor.setContent( testString ); - equal( editor.getContent(), testString, text ); + assert.equal( editor.getContent(), testString, text ); }); } )( window.jQuery, window.QUnit, window.tinymce ); diff --git a/tests/qunit/wp-includes/js/wp-api.js b/tests/qunit/wp-includes/js/wp-api.js index 4a9d0b492b..be0249462d 100644 --- a/tests/qunit/wp-includes/js/wp-api.js +++ b/tests/qunit/wp-includes/js/wp-api.js @@ -1,6 +1,6 @@ /* global wp, JSON */ ( function( QUnit ) { - module( 'wpapi' ); + QUnit.module( 'wpapi' ); QUnit.test( 'API Loaded correctly', function( assert ) { var done = assert.async(); @@ -122,7 +122,7 @@ _.each( modelsWithIdsClassNames, function( className ) { - QUnit.test( 'Checking ' + className + ' model.' , function( assert ) { + QUnit.test( 'Checking ' + className + ' model.', function( assert ) { var done = assert.async(); assert.expect( 2 ); @@ -160,7 +160,7 @@ _.each( modelsWithIndexes, function( className ) { - QUnit.test( 'Testing ' + className + ' model.' , function( assert ) { + QUnit.test( 'Testing ' + className + ' model.', function( assert ) { var done = assert.async(); assert.expect( 2 ); @@ -296,7 +296,7 @@ // Check that we have and can get each model type. _.each( customClasses, function( className ) { - QUnit.test( 'Checking ' + className + ' class name.' , function( assert ) { + QUnit.test( 'Checking ' + className + ' class name.', function( assert ) { var done = assert.async(); assert.expect( 2 ); @@ -316,7 +316,7 @@ // Check connecting to a second URL. wp.api.loadPromise.done( function() { - QUnit.test( 'Checking connecting to a remote url.' , function( assert ) { + QUnit.test( 'Checking connecting to a remote url.', function( assert ) { var done = assert.async(); wp.api.init({