Publish tests.

This commit is contained in:
Lars Jung 2015-04-22 17:12:45 +02:00
parent 5a8ecd593d
commit c396800dfa
40 changed files with 21478 additions and 1 deletions

1
.gitignore vendored
View File

@ -1,4 +1,3 @@
build
local
node_modules
test

35
test/.jshintrc Normal file
View File

@ -0,0 +1,35 @@
{
"bitwise": true,
"curly": true,
"eqeqeq": true,
"forin": true,
"freeze": true,
"futurehostile": true,
"latedef": true,
"maxdepth": 3,
"noarg": true,
"nocomma": true,
"nonbsp": true,
"nonew": true,
"plusplus": true,
"strict": false,
"supernew": true,
"trailing": true,
"undef": true,
"unused": true,
"browser": true,
"mocha": true,
"globals": {
"$": false,
"_": false,
"assert": false,
"chai": false,
"jQuery": false,
"mocha": false,
"modulejs": false,
"sinon": false,
"util": false
}
}

17
test/index.html.jade Normal file
View File

@ -0,0 +1,17 @@
doctype html
html
head
meta( charset="utf-8" )
meta( http-equiv="x-ua-compatible", content="ie=edge" )
title h5ai #{pkg.version} test suite
meta( name="viewport", content="width=device-width, initial-scale=1" )
link( rel="stylesheet", href="h5ai-styles.css" )
link( rel="stylesheet", href="styles.css" )
script( src="h5ai-scripts.js" )
script( src="scripts.js" )
body
div#mocha-overlay
div#report
a( href='index.html' ) h5ai #{pkg.version} test suite
div#mocha

5332
test/lib/chai.js Normal file

File diff suppressed because it is too large Load Diff

4
test/lib/jquery.js vendored Normal file

File diff suppressed because one or more lines are too long

93
test/lib/lodash.js Normal file
View File

@ -0,0 +1,93 @@
/**
* @license
* lodash 3.6.0 (Custom Build) lodash.com/license | Underscore.js 1.8.2 underscorejs.org/LICENSE
* Build: `lodash compat -o ./lodash.js`
*/
;(function(){function n(n,t){if(n!==t){var r=n===n,e=t===t;if(n>t||!r||typeof n=="undefined"&&e)return 1;if(n<t||!e||typeof t=="undefined"&&r)return-1}return 0}function t(n,t,r){for(var e=n.length,u=r?e:-1;r?u--:++u<e;)if(t(n[u],u,n))return u;return-1}function r(n,t,r){if(t!==t)return p(n,r);r-=1;for(var e=n.length;++r<e;)if(n[r]===t)return r;return-1}function e(n){return typeof n=="function"||false}function u(n){return typeof n=="string"?n:null==n?"":n+""}function o(n){return n.charCodeAt(0)}function i(n,t){for(var r=-1,e=n.length;++r<e&&-1<t.indexOf(n.charAt(r)););return r
}function f(n,t){for(var r=n.length;r--&&-1<t.indexOf(n.charAt(r)););return r}function a(t,r){return n(t.a,r.a)||t.b-r.b}function c(n){return Ut[n]}function l(n){return Ft[n]}function s(n){return"\\"+Lt[n]}function p(n,t,r){var e=n.length;for(t+=r?0:-1;r?t--:++t<e;){var u=n[t];if(u!==u)return t}return-1}function h(n){return!!n&&typeof n=="object"}function _(n){return 160>=n&&9<=n&&13>=n||32==n||160==n||5760==n||6158==n||8192<=n&&(8202>=n||8232==n||8233==n||8239==n||8287==n||12288==n||65279==n)}function g(n,t){for(var r=-1,e=n.length,u=-1,o=[];++r<e;)n[r]===t&&(n[r]=P,o[++u]=r);
return o}function v(n){for(var t=-1,r=n.length;++t<r&&_(n.charCodeAt(t)););return t}function y(n){for(var t=n.length;t--&&_(n.charCodeAt(t)););return t}function d(n){return Wt[n]}function m(_){function Ut(n){if(h(n)&&!(yi(n)||n instanceof Nt)){if(n instanceof Wt)return n;if(Pu.call(n,"__chain__")&&Pu.call(n,"__wrapped__"))return ke(n)}return new Wt(n)}function Ft(){}function Wt(n,t,r){this.__wrapped__=n,this.__actions__=r||[],this.__chain__=!!t}function Nt(n){this.__wrapped__=n,this.__actions__=null,this.__dir__=1,this.__filtered__=false,this.__iteratees__=null,this.__takeCount__=go,this.__views__=null
}function Lt(){this.__data__={}}function $t(n){var t=n?n.length:0;for(this.data={hash:oo(null),set:new Hu};t--;)this.push(n[t])}function Pt(n,t){var r=n.data;return(typeof t=="string"||nu(t)?r.set.has(t):r.hash[t])?0:-1}function Bt(n,t){var r=-1,e=n.length;for(t||(t=xu(e));++r<e;)t[r]=n[r];return t}function zt(n,t){for(var r=-1,e=n.length;++r<e&&false!==t(n[r],r,n););return n}function Kt(n,t){for(var r=-1,e=n.length;++r<e;)if(!t(n[r],r,n))return false;return true}function Vt(n,t){for(var r=-1,e=n.length,u=-1,o=[];++r<e;){var i=n[r];
t(i,r,n)&&(o[++u]=i)}return o}function Yt(n,t){for(var r=-1,e=n.length,u=xu(e);++r<e;)u[r]=t(n[r],r,n);return u}function Zt(n){for(var t=-1,r=n.length,e=_o;++t<r;){var u=n[t];u>e&&(e=u)}return e}function Gt(n,t){for(var r=-1,e=n.length;++r<e;)if(t(n[r],r,n))return true;return false}function Jt(n,t){return typeof n=="undefined"?t:n}function Xt(n,t,r,e){return typeof n!="undefined"&&Pu.call(e,r)?n:t}function Ht(n,t,r){var e=Ri(t);if(!r)return nr(t,n,e);for(var u=-1,o=e.length;++u<o;){var i=e[u],f=n[i],a=r(f,t[i],i,n,t);
(a===a?a===f:f!==f)&&(typeof f!="undefined"||i in n)||(n[i]=a)}return n}function Qt(n,t){for(var r=-1,e=n.length,u=we(e),o=t.length,i=xu(o);++r<o;){var f=t[r];u?(f=parseFloat(f),i[r]=ye(f,e)?n[f]:w):i[r]=n[f]}return i}function nr(n,t,r){r||(r=t,t={});for(var e=-1,u=r.length;++e<u;){var o=r[e];t[o]=n[o]}return t}function tr(n,t,r){var e=typeof n;return"function"==e?typeof t=="undefined"?n:Fr(n,t,r):null==n?du:"object"==e?yr(n):typeof t=="undefined"?wr(n+""):dr(n+"",t)}function rr(n,t,r,e,u,o,i){var f;
if(r&&(f=u?r(n,e,u):r(n)),typeof f!="undefined")return f;if(!nu(n))return n;if(e=yi(n)){if(f=_e(n),!t)return Bt(n,f)}else{var a=zu.call(n),c=a==K;if(a!=Y&&a!=B&&(!c||u))return Ct[a]?ve(n,a,t):u?n:{};if(Dt(n))return u?n:{};if(f=ge(c?{}:n),!t)return nr(n,f,Ri(n))}for(o||(o=[]),i||(i=[]),u=o.length;u--;)if(o[u]==n)return i[u];return o.push(n),i.push(f),(e?zt:lr)(n,function(e,u){f[u]=rr(e,t,r,u,n,o,i)}),f}function er(n,t,r){if(typeof n!="function")throw new Cu($);return Qu(function(){n.apply(w,r)},t)
}function ur(n,t){var e=n?n.length:0,u=[];if(!e)return u;var o=-1,i=he(),f=i==r,a=f&&200<=t.length?Uo(t):null,c=t.length;a&&(i=Pt,f=false,t=a);n:for(;++o<e;)if(a=n[o],f&&a===a){for(var l=c;l--;)if(t[l]===a)continue n;u.push(a)}else 0>i(t,a,0)&&u.push(a);return u}function or(n,t){var r=true;return ko(n,function(n,e,u){return r=!!t(n,e,u)}),r}function ir(n,t){var r=[];return ko(n,function(n,e,u){t(n,e,u)&&r.push(n)}),r}function fr(n,t,r,e){var u;return r(n,function(n,r,o){return t(n,r,o)?(u=e?r:n,false):void 0
}),u}function ar(n,t,r){for(var e=-1,u=n.length,o=-1,i=[];++e<u;){var f=n[e];if(h(f)&&we(f.length)&&(yi(f)||Xe(f))){t&&(f=ar(f,t,r));var a=-1,c=f.length;for(i.length+=c;++a<c;)i[++o]=f[a]}else r||(i[++o]=f)}return i}function cr(n,t){So(n,t,au)}function lr(n,t){return So(n,t,Ri)}function sr(n,t){return Co(n,t,Ri)}function pr(n,t){for(var r=-1,e=t.length,u=-1,o=[];++r<e;){var i=t[r];mi(n[i])&&(o[++u]=i)}return o}function hr(n,t,r,e,u,o){if(n===t)return 0!==n||1/n==1/t;var i=typeof n,f=typeof t;return"function"!=i&&"object"!=i&&"function"!=f&&"object"!=f||null==n||null==t?n!==n&&t!==t:_r(n,t,hr,r,e,u,o)
}function _r(n,t,r,e,u,o,i){var f=yi(n),a=yi(t),c=z,l=z;f||(c=zu.call(n),c==B?c=Y:c!=Y&&(f=ou(n))),a||(l=zu.call(t),l==B?l=Y:l!=Y&&ou(t));var s=(c==Y||u&&c==K)&&!Dt(n),a=(l==Y||u&&l==K)&&!Dt(t);if((l=c==l)&&!f&&!s)return ce(n,t,c);if(u){if(!(l||s&&a))return false}else{if(c=s&&Pu.call(n,"__wrapped__"),a=a&&Pu.call(t,"__wrapped__"),c||a)return r(c?n.value():n,a?t.value():t,e,u,o,i);if(!l)return false}for(o||(o=[]),i||(i=[]),c=o.length;c--;)if(o[c]==n)return i[c]==t;return o.push(n),i.push(t),n=(f?ae:le)(n,t,r,e,u,o,i),o.pop(),i.pop(),n
}function gr(n,t,r,e,u){for(var o=-1,i=t.length,f=!u;++o<i;)if(f&&e[o]?r[o]!==n[t[o]]:!(t[o]in n))return false;for(o=-1;++o<i;){var a=t[o],c=n[a],l=r[o];if(f&&e[o]?a=typeof c!="undefined"||a in n:(a=u?u(c,l,a):w,typeof a=="undefined"&&(a=hr(l,c,u,true))),!a)return false}return true}function vr(n,t){var r=[];return ko(n,function(n,e,u){r.push(t(n,e,u))}),r}function yr(n){var t=Ri(n),r=t.length;if(!r)return yu(true);if(1==r){var e=t[0],u=n[e];if(be(u))return function(n){return null!=n&&n[e]===u&&(typeof u!="undefined"||e in Ie(n))
}}for(var o=xu(r),i=xu(r);r--;)u=n[t[r]],o[r]=u,i[r]=be(u);return function(n){return null!=n&&gr(Ie(n),t,o,i)}}function dr(n,t){return be(t)?function(r){return null!=r&&r[n]===t&&(typeof t!="undefined"||n in Ie(r))}:function(r){return null!=r&&hr(t,r[n],null,true)}}function mr(n,t,r,e,u){if(!nu(n))return n;var o=we(t.length)&&(yi(t)||ou(t));return(o?zt:lr)(t,function(t,i,f){if(h(t)){e||(e=[]),u||(u=[]);n:{t=e;for(var a=u,c=t.length,l=f[i];c--;)if(t[c]==l){n[i]=a[c],i=void 0;break n}c=n[i],f=r?r(c,l,i,n,f):w;
var s=typeof f=="undefined";s&&(f=l,we(l.length)&&(yi(l)||ou(l))?f=yi(c)?c:c&&c.length?Bt(c):[]:wi(l)||Xe(l)?f=Xe(c)?iu(c):wi(c)?c:{}:s=false),t.push(l),a.push(f),s?n[i]=mr(f,l,r,t,a):(f===f?f!==c:c===c)&&(n[i]=f),i=void 0}return i}a=n[i],f=r?r(a,t,i,n,f):w,(l=typeof f=="undefined")&&(f=t),!o&&typeof f=="undefined"||!l&&(f===f?f===a:a!==a)||(n[i]=f)}),n}function wr(n){return function(t){return null==t?w:t[n]}}function br(n,t){return n+Zu(ho()*(t-n+1))}function xr(n,t,r,e,u){return u(n,function(n,u,o){r=e?(e=false,n):t(r,n,u,o)
}),r}function Ar(n,t,r){var e=-1,u=n.length;for(t=null==t?0:+t||0,0>t&&(t=-t>u?0:u+t),r=typeof r=="undefined"||r>u?u:+r||0,0>r&&(r+=u),u=t>r?0:r-t>>>0,t>>>=0,r=xu(u);++e<u;)r[e]=n[e+t];return r}function jr(n,t){var r;return ko(n,function(n,e,u){return r=t(n,e,u),!r}),!!r}function Or(n,t){var r=n.length;for(n.sort(t);r--;)n[r]=n[r].c;return n}function Er(t,r,e){var u=-1,o=t.length,i=we(o)?xu(o):[];return ko(t,function(n){for(var t=r.length,e=xu(t);t--;)e[t]=null==n?w:n[r[t]];i[++u]={a:e,b:u,c:n}}),Or(i,function(t,r){var u;
n:{u=-1;for(var o=t.a,i=r.a,f=o.length,a=e.length;++u<f;){var c=n(o[u],i[u]);if(c){u=u<a?c*(e[u]?1:-1):c;break n}}u=t.b-r.b}return u})}function Ir(n,t){var r=0;return ko(n,function(n,e,u){r+=+t(n,e,u)||0}),r}function kr(n,t){var e=-1,u=he(),o=n.length,i=u==r,f=i&&200<=o,a=f?Uo():null,c=[];a?(u=Pt,i=false):(f=false,a=t?[]:c);n:for(;++e<o;){var l=n[e],s=t?t(l,e,n):l;if(i&&l===l){for(var p=a.length;p--;)if(a[p]===s)continue n;t&&a.push(s),c.push(l)}else 0>u(a,s,0)&&((t||f)&&a.push(s),c.push(l))}return c}function Rr(n,t){for(var r=-1,e=t.length,u=xu(e);++r<e;)u[r]=n[t[r]];
return u}function Sr(n,t,r,e){for(var u=n.length,o=e?u:-1;(e?o--:++o<u)&&t(n[o],o,n););return r?Ar(n,e?0:o,e?o+1:u):Ar(n,e?o+1:0,e?u:o)}function Cr(n,t){var r=n;r instanceof Nt&&(r=r.value());for(var e=-1,u=t.length;++e<u;){var r=[r],o=t[e];Ju.apply(r,o.args),r=o.func.apply(o.thisArg,r)}return r}function Tr(n,t,r){var e=0,u=n?n.length:e;if(typeof t=="number"&&t===t&&u<=mo){for(;e<u;){var o=e+u>>>1,i=n[o];(r?i<=t:i<t)?e=o+1:u=o}return u}return Ur(n,t,du,r)}function Ur(n,t,r,e){t=r(t);for(var u=0,o=n?n.length:0,i=t!==t,f=typeof t=="undefined";u<o;){var a=Zu((u+o)/2),c=r(n[a]),l=c===c;
(i?l||e:f?l&&(e||typeof c!="undefined"):e?c<=t:c<t)?u=a+1:o=a}return co(o,yo)}function Fr(n,t,r){if(typeof n!="function")return du;if(typeof t=="undefined")return n;switch(r){case 1:return function(r){return n.call(t,r)};case 3:return function(r,e,u){return n.call(t,r,e,u)};case 4:return function(r,e,u,o){return n.call(t,r,e,u,o)};case 5:return function(r,e,u,o,i){return n.call(t,r,e,u,o,i)}}return function(){return n.apply(t,arguments)}}function Wr(n){return Ku.call(n,0)}function Nr(n,t,r){for(var e=r.length,u=-1,o=ao(n.length-e,0),i=-1,f=t.length,a=xu(o+f);++i<f;)a[i]=t[i];
for(;++u<e;)a[r[u]]=n[u];for(;o--;)a[i++]=n[u++];return a}function Lr(n,t,r){for(var e=-1,u=r.length,o=-1,i=ao(n.length-u,0),f=-1,a=t.length,c=xu(i+a);++o<i;)c[o]=n[o];for(i=o;++f<a;)c[i+f]=t[f];for(;++e<u;)c[i+r[e]]=n[o++];return c}function $r(n,t){return function(r,e,u){var o=t?t():{};if(e=pe(e,u,3),yi(r)){u=-1;for(var i=r.length;++u<i;){var f=r[u];n(o,f,e(f,u,r),r)}}else ko(r,function(t,r,u){n(o,t,e(t,r,u),u)});return o}}function Pr(n){return function(){var t=arguments,r=t.length,e=t[0];if(2>r||null==e)return e;
var u=t[r-2],o=t[r-1],i=t[3];for(3<r&&typeof u=="function"?(u=Fr(u,o,5),r-=2):(u=2<r&&typeof o=="function"?o:null,r-=u?1:0),i&&de(t[1],t[2],i)&&(u=3==r?null:u,r=2),o=0;++o<r;)(i=t[o])&&n(e,i,u);return e}}function Br(n,t){return function(r,e){var u=r?r.length:0;if(!we(u))return n(r,e);for(var o=t?u:-1,i=Ie(r);(t?o--:++o<u)&&false!==e(i[o],o,i););return r}}function zr(n){return function(t,r,e){var u=Ie(t);e=e(t);for(var o=e.length,i=n?o:-1;n?i--:++i<o;){var f=e[i];if(false===r(u[f],f,u))break}return t}}function Mr(n,t){function r(){return(this&&this!==Mt&&this instanceof r?e:n).apply(t,arguments)
}var e=qr(n);return r}function Dr(n){return function(t){var r=-1;t=gu(lu(t));for(var e=t.length,u="";++r<e;)u=n(u,t[r],r);return u}}function qr(n){return function(){var t=Io(n.prototype),r=n.apply(t,arguments);return nu(r)?r:t}}function Kr(n){function t(r,e,u){return u&&de(r,e,u)&&(e=null),r=fe(r,n,null,null,null,null,null,e),r.placeholder=t.placeholder,r}return t}function Vr(n,t){return function(r,e,u){u&&de(r,e,u)&&(e=null);var i=pe(),f=null==e;if(i===tr&&f||(f=false,e=i(e,u,3)),f){if(e=yi(r),e||!uu(r))return n(e?r:Ee(r));
e=o}return se(r,e,t)}}function Yr(n,r){return function(e,u,o){return u=pe(u,o,3),yi(e)?(u=t(e,u,r),-1<u?e[u]:w):fr(e,u,n)}}function Zr(n){return function(r,e,u){return r&&r.length?(e=pe(e,u,3),t(r,e,n)):-1}}function Gr(n){return function(t,r,e){return r=pe(r,e,3),fr(t,r,n,true)}}function Jr(n){return function(){var t=arguments.length;if(!t)return function(){return arguments[0]};for(var r,e=n?t:-1,u=0,o=xu(t);n?e--:++e<t;){var i=o[u++]=arguments[e];if(typeof i!="function")throw new Cu($);var f=r?"":Wo(i);
r="wrapper"==f?new Wt([]):r}for(e=r?-1:t;++e<t;)i=o[e],f=Wo(i),r=(u="wrapper"==f?Fo(i):null)&&me(u[0])?r[Wo(u[0])].apply(r,u[3]):1==i.length&&me(i)?r[f]():r.thru(i);return function(){var n=arguments;if(r&&1==n.length&&yi(n[0]))return r.plant(n[0]).value();for(var e=0,n=o[e].apply(this,n);++e<t;)n=o[e].call(this,n);return n}}}function Xr(n,t){return function(r,e,u){return typeof e=="function"&&typeof u=="undefined"&&yi(r)?n(r,e):t(r,Fr(e,u,3))}}function Hr(n){return function(t,r,e){return(typeof r!="function"||typeof e!="undefined")&&(r=Fr(r,e,3)),n(t,r,au)
}}function Qr(n){return function(t,r,e){return(typeof r!="function"||typeof e!="undefined")&&(r=Fr(r,e,3)),n(t,r)}}function ne(n){return function(t,r,e){return(t=u(t))&&(n?t:"")+ue(t,r,e)+(n?"":t)}}function te(n){var t=Je(function(r,e){var u=g(e,t.placeholder);return fe(r,n,null,e,u)});return t}function re(n,t){return function(r,e,u,o){var i=3>arguments.length;return typeof e=="function"&&typeof o=="undefined"&&yi(r)?n(r,e,u,i):xr(r,pe(e,o,4),u,i,t)}}function ee(n,t,r,e,u,o,i,f,a,c){function l(){for(var b=arguments.length,j=b,O=xu(b);j--;)O[j]=arguments[j];
if(e&&(O=Nr(O,e,u)),o&&(O=Lr(O,o,i)),_||y){var j=l.placeholder,E=g(O,j),b=b-E.length;if(b<c){var R=f?Bt(f):null,b=ao(c-b,0),S=_?E:null,E=_?null:E,C=_?O:null,O=_?null:O;return t|=_?I:k,t&=~(_?k:I),v||(t&=~(x|A)),O=[n,t,r,C,S,O,E,R,a,b],R=ee.apply(w,O),me(n)&&No(R,O),R.placeholder=j,R}}if(j=p?r:this,h&&(n=j[m]),f)for(R=O.length,b=co(f.length,R),S=Bt(O);b--;)E=f[b],O[b]=ye(E,R)?S[E]:w;return s&&a<O.length&&(O.length=a),(this&&this!==Mt&&this instanceof l?d||qr(n):n).apply(j,O)}var s=t&R,p=t&x,h=t&A,_=t&O,v=t&j,y=t&E,d=!h&&qr(n),m=n;
return l}function ue(n,t,r){return n=n.length,t=+t,n<t&&io(t)?(t-=n,r=null==r?" ":r+"",hu(r,Vu(t/r.length)).slice(0,t)):""}function oe(n,t,r,e){function u(){for(var t=-1,f=arguments.length,a=-1,c=e.length,l=xu(f+c);++a<c;)l[a]=e[a];for(;f--;)l[a++]=arguments[++t];return(this&&this!==Mt&&this instanceof u?i:n).apply(o?r:this,l)}var o=t&x,i=qr(n);return u}function ie(n){return function(t,r,e,u){var o=pe(e);return o===tr&&null==e?Tr(t,r,n):Ur(t,r,o(e,u,1),n)}}function fe(n,t,r,e,u,o,i,f){var a=t&A;if(!a&&typeof n!="function")throw new Cu($);
var c=e?e.length:0;if(c||(t&=~(I|k),e=u=null),c-=u?u.length:0,t&k){var l=e,s=u;e=u=null}var p=a?null:Fo(n);return r=[n,t,r,e,u,l,s,o,i,f],p&&(e=r[1],t=p[1],f=e|t,u=t==R&&e==O||t==R&&e==S&&r[7].length<=p[8]||t==(R|S)&&e==O,(f<R||u)&&(t&x&&(r[2]=p[2],f|=e&x?0:j),(e=p[3])&&(u=r[3],r[3]=u?Nr(u,e,p[4]):Bt(e),r[4]=u?g(r[3],P):Bt(p[4])),(e=p[5])&&(u=r[5],r[5]=u?Lr(u,e,p[6]):Bt(e),r[6]=u?g(r[5],P):Bt(p[6])),(e=p[7])&&(r[7]=Bt(e)),t&R&&(r[8]=null==r[8]?p[8]:co(r[8],p[8])),null==r[9]&&(r[9]=p[9]),r[0]=p[0],r[1]=f),t=r[1],f=r[9]),r[9]=null==f?a?0:n.length:ao(f-c,0)||0,(p?To:No)(t==x?Mr(r[0],r[2]):t!=I&&t!=(x|I)||r[4].length?ee.apply(w,r):oe.apply(w,r),r)
}function ae(n,t,r,e,u,o,i){var f=-1,a=n.length,c=t.length,l=true;if(a!=c&&(!u||c<=a))return false;for(;l&&++f<a;){var s=n[f],p=t[f],l=w;if(e&&(l=u?e(p,s,f):e(s,p,f)),typeof l=="undefined")if(u)for(var h=c;h--&&(p=t[h],!(l=s&&s===p||r(s,p,e,u,o,i))););else l=s&&s===p||r(s,p,e,u,o,i)}return!!l}function ce(n,t,r){switch(r){case M:case D:return+n==+t;case q:return n.name==t.name&&n.message==t.message;case V:return n!=+n?t!=+t:0==n?1/n==1/t:n==+t;case Z:case G:return n==t+""}return false}function le(n,t,r,e,u,o,i){var f=Ri(n),a=f.length,c=Ri(t).length;
if(a!=c&&!u)return false;for(var c=u,l=-1;++l<a;){var s=f[l],p=u?s in t:Pu.call(t,s);if(p){var h=n[s],_=t[s],p=w;e&&(p=u?e(_,h,s):e(h,_,s)),typeof p=="undefined"&&(p=h&&h===_||r(h,_,e,u,o,i))}if(!p)return false;c||(c="constructor"==s)}return c||(r=n.constructor,e=t.constructor,!(r!=e&&"constructor"in n&&"constructor"in t)||typeof r=="function"&&r instanceof r&&typeof e=="function"&&e instanceof e)?true:false}function se(n,t,r){var e=r?go:_o,u=e,o=u;return ko(n,function(n,i,f){i=t(n,i,f),((r?i<u:i>u)||i===e&&i===o)&&(u=i,o=n)
}),o}function pe(n,t,r){var e=Ut.callback||vu,e=e===vu?tr:e;return r?e(n,t,r):e}function he(n,t,e){var u=Ut.indexOf||Te,u=u===Te?r:u;return n?u(n,t,e):u}function _e(n){var t=n.length,r=new n.constructor(t);return t&&"string"==typeof n[0]&&Pu.call(n,"index")&&(r.index=n.index,r.input=n.input),r}function ge(n){return n=n.constructor,typeof n=="function"&&n instanceof n||(n=ku),new n}function ve(n,t,r){var e=n.constructor;switch(t){case J:return Wr(n);case M:case D:return new e(+n);case X:case H:case Q:case nt:case tt:case rt:case et:case ut:case ot:return e instanceof e&&(e=jo[t]),t=n.buffer,new e(r?Wr(t):t,n.byteOffset,n.length);
case V:case G:return new e(n);case Z:var u=new e(n.source,dt.exec(n));u.lastIndex=n.lastIndex}return u}function ye(n,t){return n=+n,t=null==t?bo:t,-1<n&&0==n%1&&n<t}function de(n,t,r){if(!nu(r))return false;var e=typeof t;return"number"==e?(e=r.length,e=we(e)&&ye(t,e)):e="string"==e&&t in r,e?(t=r[t],n===n?n===t:t!==t):false}function me(n){var t=Wo(n);return!!t&&n===Ut[t]&&t in Nt.prototype}function we(n){return typeof n=="number"&&-1<n&&0==n%1&&n<=bo}function be(n){return n===n&&(0===n?0<1/n:!nu(n))}function xe(n,t){n=Ie(n);
for(var r=-1,e=t.length,u={};++r<e;){var o=t[r];o in n&&(u[o]=n[o])}return u}function Ae(n,t){var r={};return cr(n,function(n,e,u){t(n,e,u)&&(r[e]=n)}),r}function je(n){var t,r=Ut.support;if(!h(n)||zu.call(n)!=Y||Dt(n)||!(Pu.call(n,"constructor")||(t=n.constructor,typeof t!="function"||t instanceof t))||!r.argsTag&&Xe(n))return false;var e;return r.ownLast?(cr(n,function(n,t,r){return e=Pu.call(r,t),false}),false!==e):(cr(n,function(n,t){e=t}),typeof e=="undefined"||Pu.call(n,e))}function Oe(n){for(var t=au(n),r=t.length,e=r&&n.length,u=Ut.support,u=e&&we(e)&&(yi(n)||u.nonEnumStrings&&uu(n)||u.nonEnumArgs&&Xe(n)),o=-1,i=[];++o<r;){var f=t[o];
(u&&ye(f,e)||Pu.call(n,f))&&i.push(f)}return i}function Ee(n){return null==n?[]:we(n.length)?Ut.support.unindexedChars&&uu(n)?n.split(""):nu(n)?n:ku(n):cu(n)}function Ie(n){if(Ut.support.unindexedChars&&uu(n)){for(var t=-1,r=n.length,e=ku(n);++t<r;)e[t]=n.charAt(t);return e}return nu(n)?n:ku(n)}function ke(n){return n instanceof Nt?n.clone():new Wt(n.__wrapped__,n.__chain__,Bt(n.__actions__))}function Re(n,t,r){return n&&n.length?((r?de(n,t,r):null==t)&&(t=1),Ar(n,0>t?0:t)):[]}function Se(n,t,r){var e=n?n.length:0;
return e?((r?de(n,t,r):null==t)&&(t=1),t=e-(+t||0),Ar(n,0,0>t?0:t)):[]}function Ce(n){return n?n[0]:w}function Te(n,t,e){var u=n?n.length:0;if(!u)return-1;if(typeof e=="number")e=0>e?ao(u+e,0):e;else if(e)return e=Tr(n,t),n=n[e],(t===t?t===n:n!==n)?e:-1;return r(n,t,e||0)}function Ue(n){var t=n?n.length:0;return t?n[t-1]:w}function Fe(n){return Re(n,1)}function We(n,t,e,u){if(!n||!n.length)return[];null!=t&&typeof t!="boolean"&&(u=e,e=de(n,t,u)?null:t,t=false);var o=pe();if((o!==tr||null!=e)&&(e=o(e,u,3)),t&&he()==r){t=e;
var i;e=-1,u=n.length;for(var o=-1,f=[];++e<u;){var a=n[e],c=t?t(a,e,n):a;e&&i===c||(i=c,f[++o]=a)}n=f}else n=kr(n,e);return n}function Ne(n){for(var t=-1,r=(n&&n.length&&Zt(Yt(n,$u)))>>>0,e=xu(r);++t<r;)e[t]=Yt(n,wr(t));return e}function Le(n,t){var r=-1,e=n?n.length:0,u={};for(!e||t||yi(n[0])||(t=[]);++r<e;){var o=n[r];t?u[o]=t[r]:o&&(u[o[0]]=o[1])}return u}function $e(n){return n=Ut(n),n.__chain__=true,n}function Pe(n,t,r){return t.call(r,n)}function Be(n,t,r){var e=yi(n)?Kt:or;return r&&de(n,t,r)&&(t=null),(typeof t!="function"||typeof r!="undefined")&&(t=pe(t,r,3)),e(n,t)
}function ze(n,t,r){var e=yi(n)?Vt:ir;return t=pe(t,r,3),e(n,t)}function Me(n,t,r,e){var u=n?n.length:0;return we(u)||(n=cu(n),u=n.length),u?(r=typeof r!="number"||e&&de(t,r,e)?0:0>r?ao(u+r,0):r||0,typeof n=="string"||!yi(n)&&uu(n)?r<u&&-1<n.indexOf(t,r):-1<he(n,t,r)):false}function De(n,t,r){var e=yi(n)?Yt:vr;return t=pe(t,r,3),e(n,t)}function qe(n,t,r){return(r?de(n,t,r):null==t)?(n=Ee(n),t=n.length,0<t?n[br(0,t-1)]:w):(n=Ke(n),n.length=co(0>t?0:+t||0,n.length),n)}function Ke(n){n=Ee(n);for(var t=-1,r=n.length,e=xu(r);++t<r;){var u=br(0,t);
t!=u&&(e[t]=e[u]),e[u]=n[t]}return e}function Ve(n,t,r){var e=yi(n)?Gt:jr;return r&&de(n,t,r)&&(t=null),(typeof t!="function"||typeof r!="undefined")&&(t=pe(t,r,3)),e(n,t)}function Ye(n,t){var r;if(typeof t!="function"){if(typeof n!="function")throw new Cu($);var e=n;n=t,t=e}return function(){return 0<--n?r=t.apply(this,arguments):t=null,r}}function Ze(n,t,r){function e(){var r=t-(ui()-c);0>=r||r>t?(f&&Yu(f),r=p,f=s=p=w,r&&(h=ui(),a=n.apply(l,i),s||f||(i=l=null))):s=Qu(e,r)}function u(){s&&Yu(s),f=s=p=w,(g||_!==t)&&(h=ui(),a=n.apply(l,i),s||f||(i=l=null))
}function o(){if(i=arguments,c=ui(),l=this,p=g&&(s||!v),false===_)var r=v&&!s;else{f||v||(h=c);var o=_-(c-h),y=0>=o||o>_;y?(f&&(f=Yu(f)),h=c,a=n.apply(l,i)):f||(f=Qu(u,o))}return y&&s?s=Yu(s):s||t===_||(s=Qu(e,t)),r&&(y=true,a=n.apply(l,i)),!y||s||f||(i=l=null),a}var i,f,a,c,l,s,p,h=0,_=false,g=true;if(typeof n!="function")throw new Cu($);if(t=0>t?0:+t||0,true===r)var v=true,g=false;else nu(r)&&(v=r.leading,_="maxWait"in r&&ao(+r.maxWait||0,t),g="trailing"in r?r.trailing:g);return o.cancel=function(){s&&Yu(s),f&&Yu(f),f=s=p=w
},o}function Ge(n,t){function r(){var e=arguments,u=r.cache,o=t?t.apply(this,e):e[0];return u.has(o)?u.get(o):(e=n.apply(this,e),u.set(o,e),e)}if(typeof n!="function"||t&&typeof t!="function")throw new Cu($);return r.cache=new Ge.Cache,r}function Je(n,t){if(typeof n!="function")throw new Cu($);return t=ao(typeof t=="undefined"?n.length-1:+t||0,0),function(){for(var r=arguments,e=-1,u=ao(r.length-t,0),o=xu(u);++e<u;)o[e]=r[t+e];switch(t){case 0:return n.call(this,o);case 1:return n.call(this,r[0],o);
case 2:return n.call(this,r[0],r[1],o)}for(u=xu(t+1),e=-1;++e<t;)u[e]=r[e];return u[t]=o,n.apply(this,u)}}function Xe(n){return we(h(n)?n.length:w)&&zu.call(n)==B}function He(n){return!!n&&1===n.nodeType&&h(n)&&(Ut.support.nodeTag?-1<zu.call(n).indexOf("Element"):Dt(n))}function Qe(n){return h(n)&&typeof n.message=="string"&&zu.call(n)==q}function nu(n){var t=typeof n;return"function"==t||!!n&&"object"==t}function tu(n){return null==n?false:zu.call(n)==K?Du.test(Lu.call(n)):h(n)&&(Dt(n)?Du:wt).test(n)
}function ru(n){return typeof n=="number"||h(n)&&zu.call(n)==V}function eu(n){return nu(n)&&zu.call(n)==Z}function uu(n){return typeof n=="string"||h(n)&&zu.call(n)==G}function ou(n){return h(n)&&we(n.length)&&!!St[zu.call(n)]}function iu(n){return nr(n,au(n))}function fu(n){return pr(n,au(n))}function au(n){if(null==n)return[];nu(n)||(n=ku(n));for(var t=n.length,r=Ut.support,t=t&&we(t)&&(yi(n)||r.nonEnumStrings&&uu(n)||r.nonEnumArgs&&Xe(n))&&t||0,e=n.constructor,u=-1,e=mi(e)&&e.prototype||Fu,o=e===n,i=xu(t),f=0<t,a=r.enumErrorProps&&(n===Uu||n instanceof ju),c=r.enumPrototypes&&mi(n);++u<t;)i[u]=u+"";
for(var l in n)c&&"prototype"==l||a&&("message"==l||"name"==l)||f&&ye(l,t)||"constructor"==l&&(o||!Pu.call(n,l))||i.push(l);if(r.nonEnumShadows&&n!==Fu)for(t=n===Wu?G:n===Uu?q:zu.call(n),r=Oo[t]||Oo[Y],t==Y&&(e=Fu),t=Rt.length;t--;)l=Rt[t],u=r[l],o&&u||(u?!Pu.call(n,l):n[l]===e[l])||i.push(l);return i}function cu(n){return Rr(n,Ri(n))}function lu(n){return(n=u(n))&&n.replace(bt,c).replace(vt,"")}function su(n){return(n=u(n))&&jt.test(n)?n.replace(At,"\\$&"):n}function pu(n,t,r){return r&&de(n,t,r)&&(t=0),po(n,t)
}function hu(n,t){var r="";if(n=u(n),t=+t,1>t||!n||!io(t))return r;do t%2&&(r+=n),t=Zu(t/2),n+=n;while(t);return r}function _u(n,t,r){var e=n;return(n=u(n))?(r?de(e,t,r):null==t)?n.slice(v(n),y(n)+1):(t+="",n.slice(i(n,t),f(n,t)+1)):n}function gu(n,t,r){return r&&de(n,t,r)&&(t=null),n=u(n),n.match(t||Et)||[]}function vu(n,t,r){return r&&de(n,t,r)&&(t=null),h(n)?mu(n):tr(n,t)}function yu(n){return function(){return n}}function du(n){return n}function mu(n){return yr(rr(n,true))}function wu(n,t,r){if(null==r){var e=nu(t),u=e&&Ri(t);
((u=u&&u.length&&pr(t,u))?u.length:e)||(u=false,r=t,t=n,n=this)}u||(u=pr(t,Ri(t)));var o=true,e=-1,i=mi(n),f=u.length;false===r?o=false:nu(r)&&"chain"in r&&(o=r.chain);for(;++e<f;){r=u[e];var a=t[r];n[r]=a,i&&(n.prototype[r]=function(t){return function(){var r=this.__chain__;if(o||r){var e=n(this.__wrapped__);return(e.__actions__=Bt(this.__actions__)).push({func:t,args:arguments,thisArg:n}),e.__chain__=r,e}return r=[this.value()],Ju.apply(r,arguments),t.apply(n,r)}}(a))}return n}function bu(){}_=_?qt.defaults(Mt.Object(),_,qt.pick(Mt,kt)):Mt;
var xu=_.Array,Au=_.Date,ju=_.Error,Ou=_.Function,Eu=_.Math,Iu=_.Number,ku=_.Object,Ru=_.RegExp,Su=_.String,Cu=_.TypeError,Tu=xu.prototype,Uu=ju.prototype,Fu=ku.prototype,Wu=Su.prototype,Nu=(Nu=_.window)&&Nu.document,Lu=Ou.prototype.toString,$u=wr("length"),Pu=Fu.hasOwnProperty,Bu=0,zu=Fu.toString,Mu=_._,Du=Ru("^"+su(zu).replace(/toString|(function).*?(?=\\\()| for .+?(?=\\\])/g,"$1.*?")+"$"),qu=tu(qu=_.ArrayBuffer)&&qu,Ku=tu(Ku=qu&&new qu(0).slice)&&Ku,Vu=Eu.ceil,Yu=_.clearTimeout,Zu=Eu.floor,Gu=tu(Gu=ku.getPrototypeOf)&&Gu,Ju=Tu.push,Xu=Fu.propertyIsEnumerable,Hu=tu(Hu=_.Set)&&Hu,Qu=_.setTimeout,no=Tu.splice,to=tu(to=_.Uint8Array)&&to,ro=tu(ro=_.WeakMap)&&ro,eo=function(){try{var n=tu(n=_.Float64Array)&&n,t=new n(new qu(10),0,1)&&n
}catch(r){}return t}(),uo=tu(uo=xu.isArray)&&uo,oo=tu(oo=ku.create)&&oo,io=_.isFinite,fo=tu(fo=ku.keys)&&fo,ao=Eu.max,co=Eu.min,lo=tu(lo=Au.now)&&lo,so=tu(so=Iu.isFinite)&&so,po=_.parseInt,ho=Eu.random,_o=Iu.NEGATIVE_INFINITY,go=Iu.POSITIVE_INFINITY,vo=Eu.pow(2,32)-1,yo=vo-1,mo=vo>>>1,wo=eo?eo.BYTES_PER_ELEMENT:0,bo=Eu.pow(2,53)-1,xo=ro&&new ro,Ao={},jo={};jo[X]=_.Float32Array,jo[H]=_.Float64Array,jo[Q]=_.Int8Array,jo[nt]=_.Int16Array,jo[tt]=_.Int32Array,jo[rt]=_.Uint8Array,jo[et]=_.Uint8ClampedArray,jo[ut]=_.Uint16Array,jo[ot]=_.Uint32Array;
var Oo={};Oo[z]=Oo[D]=Oo[V]={constructor:true,toLocaleString:true,toString:true,valueOf:true},Oo[M]=Oo[G]={constructor:true,toString:true,valueOf:true},Oo[q]=Oo[K]=Oo[Z]={constructor:true,toString:true},Oo[Y]={constructor:true},zt(Rt,function(n){for(var t in Oo)if(Pu.call(Oo,t)){var r=Oo[t];r[n]=Pu.call(r,n)}});var Eo=Ut.support={};!function(n){function t(){this.x=1}var r={0:1,length:1},e=[];t.prototype={valueOf:1,y:1};for(var u in new t)e.push(u);Eo.argsTag=zu.call(arguments)==B,Eo.enumErrorProps=Xu.call(Uu,"message")||Xu.call(Uu,"name"),Eo.enumPrototypes=Xu.call(t,"prototype"),Eo.funcDecomp=/\bthis\b/.test(function(){return this
}),Eo.funcNames=typeof Ou.name=="string",Eo.nodeTag=zu.call(Nu)!=Y,Eo.nonEnumStrings=!Xu.call("x",0),Eo.nonEnumShadows=!/valueOf/.test(e),Eo.ownLast="x"!=e[0],Eo.spliceObjects=(no.call(r,0,1),!r[0]),Eo.unindexedChars="xx"!="x"[0]+ku("x")[0];try{Eo.dom=11===Nu.createDocumentFragment().nodeType}catch(o){Eo.dom=false}try{Eo.nonEnumArgs=!Xu.call(arguments,1)}catch(i){Eo.nonEnumArgs=true}}(0,0),Ut.templateSettings={escape:ht,evaluate:_t,interpolate:gt,variable:"",imports:{_:Ut}};var Io=function(){function n(){}return function(t){if(nu(t)){n.prototype=t;
var r=new n;n.prototype=null}return r||_.Object()}}(),ko=Br(lr),Ro=Br(sr,true),So=zr(),Co=zr(true),To=xo?function(n,t){return xo.set(n,t),n}:du;Ku||(Wr=qu&&to?function(n){var t=n.byteLength,r=eo?Zu(t/wo):0,e=r*wo,u=new qu(t);if(r){var o=new eo(u,0,r);o.set(new eo(n,0,r))}return t!=e&&(o=new to(u,e),o.set(new to(n,e))),u}:yu(null));var Uo=oo&&Hu?function(n){return new $t(n)}:yu(null),Fo=xo?function(n){return xo.get(n)}:bu,Wo=function(){return Eo.funcNames?"constant"==yu.name?wr("name"):function(n){for(var t=n.name,r=Ao[t],e=r?r.length:0;e--;){var u=r[e],o=u.func;
if(null==o||o==n)return u.name}return t}:yu("")}(),No=function(){var n=0,t=0;return function(r,e){var u=ui(),o=F-(u-t);if(t=u,0<o){if(++n>=U)return r}else n=0;return To(r,e)}}(),Lo=Je(function(n,t){return yi(n)||Xe(n)?ur(n,ar(t,false,true)):[]}),$o=Zr(),Po=Zr(true),Bo=Je(function(t,r){t||(t=[]),r=ar(r);var e=r.length,u=Qt(t,r);for(r.sort(n);e--;){var o=parseFloat(r[e]);if(o!=i&&ye(o)){var i=o;no.call(t,o,1)}}return u}),zo=ie(),Mo=ie(true),Do=Je(function(n){return kr(ar(n,false,true))}),qo=Je(function(n,t){return yi(n)||Xe(n)?ur(n,t):[]
}),Ko=Je(Ne),Vo=Je(function(n,t){return we(n?n.length:0)&&(n=Ee(n)),Qt(n,ar(t))}),Yo=$r(function(n,t,r){Pu.call(n,r)?++n[r]:n[r]=1}),Zo=Yr(ko),Go=Yr(Ro,true),Jo=Xr(zt,ko),Xo=Xr(function(n,t){for(var r=n.length;r--&&false!==t(n[r],r,n););return n},Ro),Ho=$r(function(n,t,r){Pu.call(n,r)?n[r].push(t):n[r]=[t]}),Qo=$r(function(n,t,r){n[r]=t}),ni=Je(function(n,t,r){var e=-1,u=typeof t=="function",o=n?n.length:0,i=we(o)?xu(o):[];return ko(n,function(n){var o=u?t:null!=n&&n[t];i[++e]=o?o.apply(n,r):w}),i}),ti=$r(function(n,t,r){n[r?0:1].push(t)
},function(){return[[],[]]}),ri=re(function(n,t,r,e){var u=-1,o=n.length;for(e&&o&&(r=n[++u]);++u<o;)r=t(r,n[u],u,n);return r},ko),ei=re(function(n,t,r,e){var u=n.length;for(e&&u&&(r=n[--u]);u--;)r=t(r,n[u],u,n);return r},Ro),ui=lo||function(){return(new Au).getTime()},oi=Je(function(n,t,r){var e=x;if(r.length)var u=g(r,oi.placeholder),e=e|I;return fe(n,e,t,r,u)}),ii=Je(function(n,t){t=t.length?ar(t):fu(n);for(var r=-1,e=t.length;++r<e;){var u=t[r];n[u]=fe(n[u],x,n)}return n}),fi=Je(function(n,t,r){var e=x|A;
if(r.length)var u=g(r,fi.placeholder),e=e|I;return fe(t,e,n,r,u)}),ai=Kr(O),ci=Kr(E),li=Je(function(n,t){return er(n,1,t)}),si=Je(function(n,t,r){return er(n,t,r)}),pi=Jr(),hi=Jr(true),_i=te(I),gi=te(k),vi=Je(function(n,t){return fe(n,S,null,null,null,ar(t))});Eo.argsTag||(Xe=function(n){return we(h(n)?n.length:w)&&Pu.call(n,"callee")&&!Xu.call(n,"callee")});var yi=uo||function(n){return h(n)&&we(n.length)&&zu.call(n)==z};Eo.dom||(He=function(n){return!!n&&1===n.nodeType&&h(n)&&!wi(n)});var di=so||function(n){return typeof n=="number"&&io(n)
},mi=e(/x/)||to&&!e(to)?function(n){return zu.call(n)==K}:e,wi=Gu?function(n){if(!n||zu.call(n)!=Y||!Ut.support.argsTag&&Xe(n))return false;var t=n.valueOf,r=tu(t)&&(r=Gu(t))&&Gu(r);return r?n==r||Gu(n)==r:je(n)}:je,bi=Pr(Ht),xi=Je(function(n){var t=n[0];return null==t?t:(n.push(Jt),bi.apply(w,n))}),Ai=Gr(lr),ji=Gr(sr),Oi=Hr(So),Ei=Hr(Co),Ii=Qr(lr),ki=Qr(sr),Ri=fo?function(n){if(n)var t=n.constructor,r=n.length;return typeof t=="function"&&t.prototype===n||(typeof n=="function"?Ut.support.enumPrototypes:r&&we(r))?Oe(n):nu(n)?fo(n):[]
}:Oe,Si=Pr(mr),Ci=Je(function(n,t){if(null==n)return{};if("function"!=typeof t[0])return t=Yt(ar(t),Su),xe(n,ur(au(n),t));var r=Fr(t[0],t[1],3);return Ae(n,function(n,t,e){return!r(n,t,e)})}),Ti=Je(function(n,t){return null==n?{}:"function"==typeof t[0]?Ae(n,Fr(t[0],t[1],3)):xe(n,ar(t))}),Ui=Dr(function(n,t,r){return t=t.toLowerCase(),n+(r?t.charAt(0).toUpperCase()+t.slice(1):t)}),Fi=Dr(function(n,t,r){return n+(r?"-":"")+t.toLowerCase()}),Wi=ne(),Ni=ne(true);8!=po(It+"08")&&(pu=function(n,t,r){return(r?de(n,t,r):null==t)?t=0:t&&(t=+t),n=_u(n),po(n,t||(mt.test(n)?16:10))
});var Li=Dr(function(n,t,r){return n+(r?"_":"")+t.toLowerCase()}),$i=Dr(function(n,t,r){return n+(r?" ":"")+(t.charAt(0).toUpperCase()+t.slice(1))}),Pi=Je(function(n,t){try{return n.apply(w,t)}catch(r){return Qe(r)?r:new ju(r)}}),Bi=Vr(Zt),zi=Vr(function(n){for(var t=-1,r=n.length,e=go;++t<r;){var u=n[t];u<e&&(e=u)}return e},true);return Ut.prototype=Ft.prototype,Wt.prototype=Io(Ft.prototype),Wt.prototype.constructor=Wt,Nt.prototype=Io(Ft.prototype),Nt.prototype.constructor=Nt,Lt.prototype["delete"]=function(n){return this.has(n)&&delete this.__data__[n]
},Lt.prototype.get=function(n){return"__proto__"==n?w:this.__data__[n]},Lt.prototype.has=function(n){return"__proto__"!=n&&Pu.call(this.__data__,n)},Lt.prototype.set=function(n,t){return"__proto__"!=n&&(this.__data__[n]=t),this},$t.prototype.push=function(n){var t=this.data;typeof n=="string"||nu(n)?t.set.add(n):t.hash[n]=true},Ge.Cache=Lt,Ut.after=function(n,t){if(typeof t!="function"){if(typeof n!="function")throw new Cu($);var r=n;n=t,t=r}return n=io(n=+n)?n:0,function(){return 1>--n?t.apply(this,arguments):void 0
}},Ut.ary=function(n,t,r){return r&&de(n,t,r)&&(t=null),t=n&&null==t?n.length:ao(+t||0,0),fe(n,R,null,null,null,null,t)},Ut.assign=bi,Ut.at=Vo,Ut.before=Ye,Ut.bind=oi,Ut.bindAll=ii,Ut.bindKey=fi,Ut.callback=vu,Ut.chain=$e,Ut.chunk=function(n,t,r){t=(r?de(n,t,r):null==t)?1:ao(+t||1,1),r=0;for(var e=n?n.length:0,u=-1,o=xu(Vu(e/t));r<e;)o[++u]=Ar(n,r,r+=t);return o},Ut.compact=function(n){for(var t=-1,r=n?n.length:0,e=-1,u=[];++t<r;){var o=n[t];o&&(u[++e]=o)}return u},Ut.constant=yu,Ut.countBy=Yo,Ut.create=function(n,t,r){var e=Io(n);
return r&&de(n,t,r)&&(t=null),t?nr(t,e,Ri(t)):e},Ut.curry=ai,Ut.curryRight=ci,Ut.debounce=Ze,Ut.defaults=xi,Ut.defer=li,Ut.delay=si,Ut.difference=Lo,Ut.drop=Re,Ut.dropRight=Se,Ut.dropRightWhile=function(n,t,r){return n&&n.length?Sr(n,pe(t,r,3),true,true):[]},Ut.dropWhile=function(n,t,r){return n&&n.length?Sr(n,pe(t,r,3),true):[]},Ut.fill=function(n,t,r,e){var u=n?n.length:0;if(!u)return[];for(r&&typeof r!="number"&&de(n,t,r)&&(r=0,e=u),u=n.length,r=null==r?0:+r||0,0>r&&(r=-r>u?0:u+r),e=typeof e=="undefined"||e>u?u:+e||0,0>e&&(e+=u),u=r>e?0:e>>>0,r>>>=0;r<u;)n[r++]=t;
return n},Ut.filter=ze,Ut.flatten=function(n,t,r){var e=n?n.length:0;return r&&de(n,t,r)&&(t=false),e?ar(n,t):[]},Ut.flattenDeep=function(n){return n&&n.length?ar(n,true):[]},Ut.flow=pi,Ut.flowRight=hi,Ut.forEach=Jo,Ut.forEachRight=Xo,Ut.forIn=Oi,Ut.forInRight=Ei,Ut.forOwn=Ii,Ut.forOwnRight=ki,Ut.functions=fu,Ut.groupBy=Ho,Ut.indexBy=Qo,Ut.initial=function(n){return Se(n,1)},Ut.intersection=function(){for(var n=[],t=-1,e=arguments.length,u=[],o=he(),i=o==r;++t<e;){var f=arguments[t];(yi(f)||Xe(f))&&(n.push(f),u.push(i&&120<=f.length?Uo(t&&f):null))
}var e=n.length,i=n[0],a=-1,c=i?i.length:0,l=[],s=u[0];n:for(;++a<c;)if(f=i[a],0>(s?Pt(s,f):o(l,f,0))){for(t=e;--t;){var p=u[t];if(0>(p?Pt(p,f):o(n[t],f,0)))continue n}s&&s.push(f),l.push(f)}return l},Ut.invert=function(n,t,r){r&&de(n,t,r)&&(t=null),r=-1;for(var e=Ri(n),u=e.length,o={};++r<u;){var i=e[r],f=n[i];t?Pu.call(o,f)?o[f].push(i):o[f]=[i]:o[f]=i}return o},Ut.invoke=ni,Ut.keys=Ri,Ut.keysIn=au,Ut.map=De,Ut.mapValues=function(n,t,r){var e={};return t=pe(t,r,3),lr(n,function(n,r,u){e[r]=t(n,r,u)
}),e},Ut.matches=mu,Ut.matchesProperty=function(n,t){return dr(n+"",rr(t,true))},Ut.memoize=Ge,Ut.merge=Si,Ut.mixin=wu,Ut.negate=function(n){if(typeof n!="function")throw new Cu($);return function(){return!n.apply(this,arguments)}},Ut.omit=Ci,Ut.once=function(n){return Ye(n,2)},Ut.pairs=function(n){for(var t=-1,r=Ri(n),e=r.length,u=xu(e);++t<e;){var o=r[t];u[t]=[o,n[o]]}return u},Ut.partial=_i,Ut.partialRight=gi,Ut.partition=ti,Ut.pick=Ti,Ut.pluck=function(n,t){return De(n,wr(t))},Ut.property=function(n){return wr(n+"")
},Ut.propertyOf=function(n){return function(t){return null==n?w:n[t]}},Ut.pull=function(){var n=arguments,t=n[0];if(!t||!t.length)return t;for(var r=0,e=he(),u=n.length;++r<u;)for(var o=0,i=n[r];-1<(o=e(t,i,o));)no.call(t,o,1);return t},Ut.pullAt=Bo,Ut.range=function(n,t,r){r&&de(n,t,r)&&(t=r=null),n=+n||0,r=null==r?1:+r||0,null==t?(t=n,n=0):t=+t||0;var e=-1;t=ao(Vu((t-n)/(r||1)),0);for(var u=xu(t);++e<t;)u[e]=n,n+=r;return u},Ut.rearg=vi,Ut.reject=function(n,t,r){var e=yi(n)?Vt:ir;return t=pe(t,r,3),e(n,function(n,r,e){return!t(n,r,e)
})},Ut.remove=function(n,t,r){var e=-1,u=n?n.length:0,o=[];for(t=pe(t,r,3);++e<u;)r=n[e],t(r,e,n)&&(o.push(r),no.call(n,e--,1),u--);return o},Ut.rest=Fe,Ut.restParam=Je,Ut.shuffle=Ke,Ut.slice=function(n,t,r){var e=n?n.length:0;return e?(r&&typeof r!="number"&&de(n,t,r)&&(t=0,r=e),Ar(n,t,r)):[]},Ut.sortBy=function(n,t,r){if(null==n)return[];var e=-1,u=n.length,o=we(u)?xu(u):[];return r&&de(n,t,r)&&(t=null),t=pe(t,r,3),ko(n,function(n,r,u){o[++e]={a:t(n,r,u),b:e,c:n}}),Or(o,a)},Ut.sortByAll=function(){var n=arguments,t=n[0],r=n[3],e=0,u=n.length-1;
if(null==t)return[];for(var o=xu(u);e<u;)o[e]=n[++e];return r&&de(n[1],n[2],r)&&(o=n[1]),Er(t,ar(o),[])},Ut.sortByOrder=function(n,t,r,e){return null==n?[]:(e&&de(t,r,e)&&(r=null),yi(t)||(t=null==t?[]:[t]),yi(r)||(r=null==r?[]:[r]),Er(n,t,r))},Ut.spread=function(n){if(typeof n!="function")throw new Cu($);return function(t){return n.apply(this,t)}},Ut.take=function(n,t,r){return n&&n.length?((r?de(n,t,r):null==t)&&(t=1),Ar(n,0,0>t?0:t)):[]},Ut.takeRight=function(n,t,r){var e=n?n.length:0;return e?((r?de(n,t,r):null==t)&&(t=1),t=e-(+t||0),Ar(n,0>t?0:t)):[]
},Ut.takeRightWhile=function(n,t,r){return n&&n.length?Sr(n,pe(t,r,3),false,true):[]},Ut.takeWhile=function(n,t,r){return n&&n.length?Sr(n,pe(t,r,3)):[]},Ut.tap=function(n,t,r){return t.call(r,n),n},Ut.throttle=function(n,t,r){var e=true,u=true;if(typeof n!="function")throw new Cu($);return false===r?e=false:nu(r)&&(e="leading"in r?!!r.leading:e,u="trailing"in r?!!r.trailing:u),Tt.leading=e,Tt.maxWait=+t,Tt.trailing=u,Ze(n,t,Tt)},Ut.thru=Pe,Ut.times=function(n,t,r){if(n=+n,1>n||!io(n))return[];var e=-1,u=xu(co(n,vo));
for(t=Fr(t,r,1);++e<n;)e<vo?u[e]=t(e):t(e);return u},Ut.toArray=function(n){var t=n?n.length:0;return we(t)?t?Ut.support.unindexedChars&&uu(n)?n.split(""):Bt(n):[]:cu(n)},Ut.toPlainObject=iu,Ut.transform=function(n,t,r,e){var u=yi(n)||ou(n);return t=pe(t,e,4),null==r&&(u||nu(n)?(e=n.constructor,r=u?yi(n)?new e:[]:Io(mi(e)&&e.prototype)):r={}),(u?zt:lr)(n,function(n,e,u){return t(r,n,e,u)}),r},Ut.union=Do,Ut.uniq=We,Ut.unzip=Ne,Ut.values=cu,Ut.valuesIn=function(n){return Rr(n,au(n))},Ut.where=function(n,t){return ze(n,yr(t))
},Ut.without=qo,Ut.wrap=function(n,t){return t=null==t?du:t,fe(t,I,null,[n],[])},Ut.xor=function(){for(var n=-1,t=arguments.length;++n<t;){var r=arguments[n];if(yi(r)||Xe(r))var e=e?ur(e,r).concat(ur(r,e)):r}return e?kr(e):[]},Ut.zip=Ko,Ut.zipObject=Le,Ut.backflow=hi,Ut.collect=De,Ut.compose=hi,Ut.each=Jo,Ut.eachRight=Xo,Ut.extend=bi,Ut.iteratee=vu,Ut.methods=fu,Ut.object=Le,Ut.select=ze,Ut.tail=Fe,Ut.unique=We,wu(Ut,Ut),Ut.add=function(n,t){return n+t},Ut.attempt=Pi,Ut.camelCase=Ui,Ut.capitalize=function(n){return(n=u(n))&&n.charAt(0).toUpperCase()+n.slice(1)
},Ut.clone=function(n,t,r,e){return t&&typeof t!="boolean"&&de(n,t,r)?t=false:typeof t=="function"&&(e=r,r=t,t=false),r=typeof r=="function"&&Fr(r,e,1),rr(n,t,r)},Ut.cloneDeep=function(n,t,r){return t=typeof t=="function"&&Fr(t,r,1),rr(n,true,t)},Ut.deburr=lu,Ut.endsWith=function(n,t,r){n=u(n),t+="";var e=n.length;return r=typeof r=="undefined"?e:co(0>r?0:+r||0,e),r-=t.length,0<=r&&n.indexOf(t,r)==r},Ut.escape=function(n){return(n=u(n))&&pt.test(n)?n.replace(lt,l):n},Ut.escapeRegExp=su,Ut.every=Be,Ut.find=Zo,Ut.findIndex=$o,Ut.findKey=Ai,Ut.findLast=Go,Ut.findLastIndex=Po,Ut.findLastKey=ji,Ut.findWhere=function(n,t){return Zo(n,yr(t))
},Ut.first=Ce,Ut.has=function(n,t){return n?Pu.call(n,t):false},Ut.identity=du,Ut.includes=Me,Ut.indexOf=Te,Ut.inRange=function(n,t,r){return t=+t||0,"undefined"===typeof r?(r=t,t=0):r=+r||0,n>=t&&n<r},Ut.isArguments=Xe,Ut.isArray=yi,Ut.isBoolean=function(n){return true===n||false===n||h(n)&&zu.call(n)==M},Ut.isDate=function(n){return h(n)&&zu.call(n)==D},Ut.isElement=He,Ut.isEmpty=function(n){if(null==n)return true;var t=n.length;return we(t)&&(yi(n)||uu(n)||Xe(n)||h(n)&&mi(n.splice))?!t:!Ri(n).length},Ut.isEqual=function(n,t,r,e){return r=typeof r=="function"&&Fr(r,e,3),!r&&be(n)&&be(t)?n===t:(e=r?r(n,t):w,typeof e=="undefined"?hr(n,t,r):!!e)
},Ut.isError=Qe,Ut.isFinite=di,Ut.isFunction=mi,Ut.isMatch=function(n,t,r,e){var u=Ri(t),o=u.length;if(!o)return true;if(null==n)return false;if(r=typeof r=="function"&&Fr(r,e,3),!r&&1==o){var i=u[0];if(e=t[i],be(e))return e===n[i]&&(typeof e!="undefined"||i in Ie(n))}for(var i=xu(o),f=xu(o);o--;)e=i[o]=t[u[o]],f[o]=be(e);return gr(Ie(n),u,i,f,r)},Ut.isNaN=function(n){return ru(n)&&n!=+n},Ut.isNative=tu,Ut.isNull=function(n){return null===n},Ut.isNumber=ru,Ut.isObject=nu,Ut.isPlainObject=wi,Ut.isRegExp=eu,Ut.isString=uu,Ut.isTypedArray=ou,Ut.isUndefined=function(n){return typeof n=="undefined"
},Ut.kebabCase=Fi,Ut.last=Ue,Ut.lastIndexOf=function(n,t,r){var e=n?n.length:0;if(!e)return-1;var u=e;if(typeof r=="number")u=(0>r?ao(e+r,0):co(r||0,e-1))+1;else if(r)return u=Tr(n,t,true)-1,n=n[u],(t===t?t===n:n!==n)?u:-1;if(t!==t)return p(n,u,true);for(;u--;)if(n[u]===t)return u;return-1},Ut.max=Bi,Ut.min=zi,Ut.noConflict=function(){return _._=Mu,this},Ut.noop=bu,Ut.now=ui,Ut.pad=function(n,t,r){n=u(n),t=+t;var e=n.length;return e<t&&io(t)?(e=(t-e)/2,t=Zu(e),e=Vu(e),r=ue("",e,r),r.slice(0,t)+n+r):n
},Ut.padLeft=Wi,Ut.padRight=Ni,Ut.parseInt=pu,Ut.random=function(n,t,r){r&&de(n,t,r)&&(t=r=null);var e=null==n,u=null==t;return null==r&&(u&&typeof n=="boolean"?(r=n,n=1):typeof t=="boolean"&&(r=t,u=true)),e&&u&&(t=1,u=false),n=+n||0,u?(t=n,n=0):t=+t||0,r||n%1||t%1?(r=ho(),co(n+r*(t-n+parseFloat("1e-"+((r+"").length-1))),t)):br(n,t)},Ut.reduce=ri,Ut.reduceRight=ei,Ut.repeat=hu,Ut.result=function(n,t,r){return t=null==n?w:n[t],typeof t=="undefined"&&(t=r),mi(t)?t.call(n):t},Ut.runInContext=m,Ut.size=function(n){var t=n?n.length:0;
return we(t)?t:Ri(n).length},Ut.snakeCase=Li,Ut.some=Ve,Ut.sortedIndex=zo,Ut.sortedLastIndex=Mo,Ut.startCase=$i,Ut.startsWith=function(n,t,r){return n=u(n),r=null==r?0:co(0>r?0:+r||0,n.length),n.lastIndexOf(t,r)==r},Ut.sum=function(n,t,r){r&&de(n,t,r)&&(t=null);var e=pe(),u=null==t;if(e===tr&&u||(u=false,t=e(t,r,3)),u){for(n=yi(n)?n:Ee(n),t=n.length,r=0;t--;)r+=+n[t]||0;n=r}else n=Ir(n,t);return n},Ut.template=function(n,t,r){var e=Ut.templateSettings;r&&de(n,t,r)&&(t=r=null),n=u(n),t=Ht(Ht({},r||t),e,Xt),r=Ht(Ht({},t.imports),e.imports,Xt);
var o,i,f=Ri(r),a=Rr(r,f),c=0;r=t.interpolate||xt;var l="__p+='";r=Ru((t.escape||xt).source+"|"+r.source+"|"+(r===gt?yt:xt).source+"|"+(t.evaluate||xt).source+"|$","g");var p="sourceURL"in t?"//# sourceURL="+t.sourceURL+"\n":"";if(n.replace(r,function(t,r,e,u,f,a){return e||(e=u),l+=n.slice(c,a).replace(Ot,s),r&&(o=true,l+="'+__e("+r+")+'"),f&&(i=true,l+="';"+f+";\n__p+='"),e&&(l+="'+((__t=("+e+"))==null?'':__t)+'"),c=a+t.length,t}),l+="';",(t=t.variable)||(l="with(obj){"+l+"}"),l=(i?l.replace(it,""):l).replace(ft,"$1").replace(at,"$1;"),l="function("+(t||"obj")+"){"+(t?"":"obj||(obj={});")+"var __t,__p=''"+(o?",__e=_.escape":"")+(i?",__j=Array.prototype.join;function print(){__p+=__j.call(arguments,'')}":";")+l+"return __p}",t=Pi(function(){return Ou(f,p+"return "+l).apply(w,a)
}),t.source=l,Qe(t))throw t;return t},Ut.trim=_u,Ut.trimLeft=function(n,t,r){var e=n;return(n=u(n))?n.slice((r?de(e,t,r):null==t)?v(n):i(n,t+"")):n},Ut.trimRight=function(n,t,r){var e=n;return(n=u(n))?(r?de(e,t,r):null==t)?n.slice(0,y(n)+1):n.slice(0,f(n,t+"")+1):n},Ut.trunc=function(n,t,r){r&&de(n,t,r)&&(t=null);var e=C;if(r=T,null!=t)if(nu(t)){var o="separator"in t?t.separator:o,e="length"in t?+t.length||0:e;r="omission"in t?u(t.omission):r}else e=+t||0;if(n=u(n),e>=n.length)return n;if(e-=r.length,1>e)return r;
if(t=n.slice(0,e),null==o)return t+r;if(eu(o)){if(n.slice(e).search(o)){var i,f=n.slice(0,e);for(o.global||(o=Ru(o.source,(dt.exec(o)||"")+"g")),o.lastIndex=0;n=o.exec(f);)i=n.index;t=t.slice(0,null==i?e:i)}}else n.indexOf(o,e)!=e&&(o=t.lastIndexOf(o),-1<o&&(t=t.slice(0,o)));return t+r},Ut.unescape=function(n){return(n=u(n))&&st.test(n)?n.replace(ct,d):n},Ut.uniqueId=function(n){var t=++Bu;return u(n)+t},Ut.words=gu,Ut.all=Be,Ut.any=Ve,Ut.contains=Me,Ut.detect=Zo,Ut.foldl=ri,Ut.foldr=ei,Ut.head=Ce,Ut.include=Me,Ut.inject=ri,wu(Ut,function(){var n={};
return lr(Ut,function(t,r){Ut.prototype[r]||(n[r]=t)}),n}(),false),Ut.sample=qe,Ut.prototype.sample=function(n){return this.__chain__||null!=n?this.thru(function(t){return qe(t,n)}):qe(this.value())},Ut.VERSION=b,zt("bind bindKey curry curryRight partial partialRight".split(" "),function(n){Ut[n].placeholder=Ut}),zt(["dropWhile","filter","map","takeWhile"],function(n,t){var r=t!=L,e=t==W;Nt.prototype[n]=function(n,u){var o=this.__filtered__,i=o&&e?new Nt(this):this.clone();return(i.__iteratees__||(i.__iteratees__=[])).push({done:false,count:0,index:0,iteratee:pe(n,u,1),limit:-1,type:t}),i.__filtered__=o||r,i
}}),zt(["drop","take"],function(n,t){var r=n+"While";Nt.prototype[n]=function(r){var e=this.__filtered__,u=e&&!t?this.dropWhile():this.clone();return r=null==r?1:ao(Zu(r)||0,0),e?t?u.__takeCount__=co(u.__takeCount__,r):Ue(u.__iteratees__).limit=r:(u.__views__||(u.__views__=[])).push({size:r,type:n+(0>u.__dir__?"Right":"")}),u},Nt.prototype[n+"Right"]=function(t){return this.reverse()[n](t).reverse()},Nt.prototype[n+"RightWhile"]=function(n,t){return this.reverse()[r](n,t).reverse()}}),zt(["first","last"],function(n,t){var r="take"+(t?"Right":"");
Nt.prototype[n]=function(){return this[r](1).value()[0]}}),zt(["initial","rest"],function(n,t){var r="drop"+(t?"":"Right");Nt.prototype[n]=function(){return this[r](1)}}),zt(["pluck","where"],function(n,t){var r=t?"filter":"map",e=t?yr:wr;Nt.prototype[n]=function(n){return this[r](e(n))}}),Nt.prototype.compact=function(){return this.filter(du)},Nt.prototype.reject=function(n,t){return n=pe(n,t,1),this.filter(function(t){return!n(t)})},Nt.prototype.slice=function(n,t){n=null==n?0:+n||0;var r=0>n?this.takeRight(-n):this.drop(n);
return typeof t!="undefined"&&(t=+t||0,r=0>t?r.dropRight(-t):r.take(t-n)),r},Nt.prototype.toArray=function(){return this.drop(0)},lr(Nt.prototype,function(n,t){var r=Ut[t];if(r){var e=/^(?:filter|map|reject)|While$/.test(t),u=/^(?:first|last)$/.test(t);Ut.prototype[t]=function(){function t(n){return n=[n],Ju.apply(n,o),r.apply(Ut,n)}var o=arguments,i=this.__chain__,f=this.__wrapped__,a=!!this.__actions__.length,c=f instanceof Nt,l=o[0],s=c||yi(f);return s&&e&&typeof l=="function"&&1!=l.length&&(c=s=false),c=c&&!a,u&&!i?c?n.call(f):r.call(Ut,this.value()):s?(f=n.apply(c?f:new Nt(this),o),u||!a&&!f.__actions__||(f.__actions__||(f.__actions__=[])).push({func:Pe,args:[t],thisArg:Ut}),new Wt(f,i)):this.thru(t)
}}}),zt("concat join pop push replace shift sort splice split unshift".split(" "),function(n){var t=(/^(?:replace|split)$/.test(n)?Wu:Tu)[n],r=/^(?:push|sort|unshift)$/.test(n)?"tap":"thru",e=/^(?:join|pop|replace|shift)$/.test(n),u=Eo.spliceObjects||!/^(?:pop|shift|splice)$/.test(n)?t:function(){var n=t.apply(this,arguments);return 0===this.length&&delete this[0],n};Ut.prototype[n]=function(){var n=arguments;return e&&!this.__chain__?u.apply(this.value(),n):this[r](function(t){return u.apply(t,n)
})}}),lr(Nt.prototype,function(n,t){var r=Ut[t];if(r){var e=r.name;(Ao[e]||(Ao[e]=[])).push({name:t,func:r})}}),Ao[ee(null,A).name]=[{name:"wrapper",func:null}],Nt.prototype.clone=function(){var n=this.__actions__,t=this.__iteratees__,r=this.__views__,e=new Nt(this.__wrapped__);return e.__actions__=n?Bt(n):null,e.__dir__=this.__dir__,e.__filtered__=this.__filtered__,e.__iteratees__=t?Bt(t):null,e.__takeCount__=this.__takeCount__,e.__views__=r?Bt(r):null,e},Nt.prototype.reverse=function(){if(this.__filtered__){var n=new Nt(this);
n.__dir__=-1,n.__filtered__=true}else n=this.clone(),n.__dir__*=-1;return n},Nt.prototype.value=function(){var n=this.__wrapped__.value();if(!yi(n))return Cr(n,this.__actions__);var t,r=this.__dir__,e=0>r;t=n.length;for(var u=this.__views__,o=0,i=-1,f=u?u.length:0;++i<f;){var a=u[i],c=a.size;switch(a.type){case"drop":o+=c;break;case"dropRight":t-=c;break;case"take":t=co(t,o+c);break;case"takeRight":o=ao(o,t-c)}}t={start:o,end:t},u=t.start,o=t.end,t=o-u,u=e?o:u-1,o=co(t,this.__takeCount__),f=(i=this.__iteratees__)?i.length:0,a=0,c=[];
n:for(;t--&&a<o;){for(var u=u+r,l=-1,s=n[u];++l<f;){var p=i[l],h=p.iteratee,_=p.type;if(_==W){if(p.done&&(e?u>p.index:u<p.index)&&(p.count=0,p.done=false),p.index=u,!(p.done||(_=p.limit,p.done=-1<_?p.count++>=_:!h(s))))continue n}else if(p=h(s),_==L)s=p;else if(!p){if(_==N)continue n;break n}}c[a++]=s}return c},Ut.prototype.chain=function(){return $e(this)},Ut.prototype.commit=function(){return new Wt(this.value(),this.__chain__)},Ut.prototype.plant=function(n){for(var t,r=this;r instanceof Ft;){var e=ke(r);
t?u.__wrapped__=e:t=e;var u=e,r=r.__wrapped__}return u.__wrapped__=n,t},Ut.prototype.reverse=function(){var n=this.__wrapped__;return n instanceof Nt?(this.__actions__.length&&(n=new Nt(this)),new Wt(n.reverse(),this.__chain__)):this.thru(function(n){return n.reverse()})},Ut.prototype.toString=function(){return this.value()+""},Ut.prototype.run=Ut.prototype.toJSON=Ut.prototype.valueOf=Ut.prototype.value=function(){return Cr(this.__wrapped__,this.__actions__)},Ut.prototype.collect=Ut.prototype.map,Ut.prototype.head=Ut.prototype.first,Ut.prototype.select=Ut.prototype.filter,Ut.prototype.tail=Ut.prototype.rest,Ut
}var w,b="3.6.0",x=1,A=2,j=4,O=8,E=16,I=32,k=64,R=128,S=256,C=30,T="...",U=150,F=16,W=0,N=1,L=2,$="Expected a function",P="__lodash_placeholder__",B="[object Arguments]",z="[object Array]",M="[object Boolean]",D="[object Date]",q="[object Error]",K="[object Function]",V="[object Number]",Y="[object Object]",Z="[object RegExp]",G="[object String]",J="[object ArrayBuffer]",X="[object Float32Array]",H="[object Float64Array]",Q="[object Int8Array]",nt="[object Int16Array]",tt="[object Int32Array]",rt="[object Uint8Array]",et="[object Uint8ClampedArray]",ut="[object Uint16Array]",ot="[object Uint32Array]",it=/\b__p\+='';/g,ft=/\b(__p\+=)''\+/g,at=/(__e\(.*?\)|\b__t\))\+'';/g,ct=/&(?:amp|lt|gt|quot|#39|#96);/g,lt=/[&<>"'`]/g,st=RegExp(ct.source),pt=RegExp(lt.source),ht=/<%-([\s\S]+?)%>/g,_t=/<%([\s\S]+?)%>/g,gt=/<%=([\s\S]+?)%>/g,vt=/[\u0300-\u036f\ufe20-\ufe23]/g,yt=/\$\{([^\\}]*(?:\\.[^\\}]*)*)\}/g,dt=/\w*$/,mt=/^0[xX]/,wt=/^\[object .+?Constructor\]$/,bt=/[\xc0-\xd6\xd8-\xde\xdf-\xf6\xf8-\xff]/g,xt=/($^)/,At=/[.*+?^${}()|[\]\/\\]/g,jt=RegExp(At.source),Ot=/['\n\r\u2028\u2029\\]/g,Et=RegExp("[A-Z\\xc0-\\xd6\\xd8-\\xde]+(?=[A-Z\\xc0-\\xd6\\xd8-\\xde][a-z\\xdf-\\xf6\\xf8-\\xff]+)|[A-Z\\xc0-\\xd6\\xd8-\\xde]?[a-z\\xdf-\\xf6\\xf8-\\xff]+|[A-Z\\xc0-\\xd6\\xd8-\\xde]+|[0-9]+","g"),It=" \t\x0b\f\xa0\ufeff\n\r\u2028\u2029\u1680\u180e\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u202f\u205f\u3000",kt="Array ArrayBuffer Date Error Float32Array Float64Array Function Int8Array Int16Array Int32Array Math Number Object RegExp Set String _ clearTimeout document isFinite parseInt setTimeout TypeError Uint8Array Uint8ClampedArray Uint16Array Uint32Array WeakMap window".split(" "),Rt="constructor hasOwnProperty isPrototypeOf propertyIsEnumerable toLocaleString toString valueOf".split(" "),St={};
St[X]=St[H]=St[Q]=St[nt]=St[tt]=St[rt]=St[et]=St[ut]=St[ot]=true,St[B]=St[z]=St[J]=St[M]=St[D]=St[q]=St[K]=St["[object Map]"]=St[V]=St[Y]=St[Z]=St["[object Set]"]=St[G]=St["[object WeakMap]"]=false;var Ct={};Ct[B]=Ct[z]=Ct[J]=Ct[M]=Ct[D]=Ct[X]=Ct[H]=Ct[Q]=Ct[nt]=Ct[tt]=Ct[V]=Ct[Y]=Ct[Z]=Ct[G]=Ct[rt]=Ct[et]=Ct[ut]=Ct[ot]=true,Ct[q]=Ct[K]=Ct["[object Map]"]=Ct["[object Set]"]=Ct["[object WeakMap]"]=false;var Tt={leading:false,maxWait:0,trailing:false},Ut={"\xc0":"A","\xc1":"A","\xc2":"A","\xc3":"A","\xc4":"A","\xc5":"A","\xe0":"a","\xe1":"a","\xe2":"a","\xe3":"a","\xe4":"a","\xe5":"a","\xc7":"C","\xe7":"c","\xd0":"D","\xf0":"d","\xc8":"E","\xc9":"E","\xca":"E","\xcb":"E","\xe8":"e","\xe9":"e","\xea":"e","\xeb":"e","\xcc":"I","\xcd":"I","\xce":"I","\xcf":"I","\xec":"i","\xed":"i","\xee":"i","\xef":"i","\xd1":"N","\xf1":"n","\xd2":"O","\xd3":"O","\xd4":"O","\xd5":"O","\xd6":"O","\xd8":"O","\xf2":"o","\xf3":"o","\xf4":"o","\xf5":"o","\xf6":"o","\xf8":"o","\xd9":"U","\xda":"U","\xdb":"U","\xdc":"U","\xf9":"u","\xfa":"u","\xfb":"u","\xfc":"u","\xdd":"Y","\xfd":"y","\xff":"y","\xc6":"Ae","\xe6":"ae","\xde":"Th","\xfe":"th","\xdf":"ss"},Ft={"&":"&amp;","<":"&lt;",">":"&gt;",'"':"&quot;","'":"&#39;","`":"&#96;"},Wt={"&amp;":"&","&lt;":"<","&gt;":">","&quot;":'"',"&#39;":"'","&#96;":"`"},Nt={"function":true,object:true},Lt={"\\":"\\","'":"'","\n":"n","\r":"r","\u2028":"u2028","\u2029":"u2029"},$t=Nt[typeof exports]&&exports&&!exports.nodeType&&exports,Pt=Nt[typeof module]&&module&&!module.nodeType&&module,Bt=Nt[typeof self]&&self&&self.Object&&self,Nt=Nt[typeof window]&&window&&window.Object&&window,zt=Pt&&Pt.exports===$t&&$t,Mt=$t&&Pt&&typeof global=="object"&&global||Nt!==(this&&this.window)&&Nt||Bt||this,Dt=function(){try{Object({toString:0}+"")
}catch(n){return function(){return false}}return function(n){return typeof n.toString!="function"&&typeof(n+"")=="string"}}(),qt=m();typeof define=="function"&&typeof define.amd=="object"&&define.amd?(Mt._=qt, define(function(){return qt})):$t&&Pt?zt?(Pt.exports=qt)._=qt:$t._=qt:Mt._=qt}).call(this);

6564
test/lib/mocha.js Normal file

File diff suppressed because it is too large Load Diff

270
test/lib/mocha.less Normal file
View File

@ -0,0 +1,270 @@
@charset "utf-8";
body {
margin:0;
}
#mocha {
font: 20px/1.5 "Helvetica Neue", Helvetica, Arial, sans-serif;
margin: 60px 50px;
}
#mocha ul,
#mocha li {
margin: 0;
padding: 0;
}
#mocha ul {
list-style: none;
}
#mocha h1,
#mocha h2 {
margin: 0;
}
#mocha h1 {
margin-top: 15px;
font-size: 1em;
font-weight: 200;
}
#mocha h1 a {
text-decoration: none;
color: inherit;
}
#mocha h1 a:hover {
text-decoration: underline;
}
#mocha .suite .suite h1 {
margin-top: 0;
font-size: .8em;
}
#mocha .hidden {
display: none;
}
#mocha h2 {
font-size: 12px;
font-weight: normal;
cursor: pointer;
}
#mocha .suite {
margin-left: 15px;
}
#mocha .test {
margin-left: 15px;
overflow: hidden;
}
#mocha .test.pending:hover h2::after {
content: '(pending)';
font-family: arial, sans-serif;
}
#mocha .test.pass.medium .duration {
background: #c09853;
}
#mocha .test.pass.slow .duration {
background: #b94a48;
}
#mocha .test.pass::before {
content: '✓';
font-size: 12px;
display: block;
float: left;
margin-right: 5px;
color: #00d6b2;
}
#mocha .test.pass .duration {
font-size: 9px;
margin-left: 5px;
padding: 2px 5px;
color: #fff;
-webkit-box-shadow: inset 0 1px 1px rgba(0,0,0,.2);
-moz-box-shadow: inset 0 1px 1px rgba(0,0,0,.2);
box-shadow: inset 0 1px 1px rgba(0,0,0,.2);
-webkit-border-radius: 5px;
-moz-border-radius: 5px;
-ms-border-radius: 5px;
-o-border-radius: 5px;
border-radius: 5px;
}
#mocha .test.pass.fast .duration {
display: none;
}
#mocha .test.pending {
color: #0b97c4;
}
#mocha .test.pending::before {
content: '◦';
color: #0b97c4;
}
#mocha .test.fail {
color: #c00;
}
#mocha .test.fail pre {
color: black;
}
#mocha .test.fail::before {
content: '✖';
font-size: 12px;
display: block;
float: left;
margin-right: 5px;
color: #c00;
}
#mocha .test pre.error {
color: #c00;
max-height: 300px;
overflow: auto;
}
/**
* (1): approximate for browsers not supporting calc
* (2): 42 = 2*15 + 2*10 + 2*1 (padding + margin + border)
* ^^ seriously
*/
#mocha .test pre {
display: block;
float: left;
clear: left;
font: 12px/1.5 monaco, monospace;
margin: 5px;
padding: 15px;
border: 1px solid #eee;
max-width: 85%; /*(1)*/
max-width: calc(100% - 42px); /*(2)*/
word-wrap: break-word;
border-bottom-color: #ddd;
-webkit-border-radius: 3px;
-webkit-box-shadow: 0 1px 3px #eee;
-moz-border-radius: 3px;
-moz-box-shadow: 0 1px 3px #eee;
border-radius: 3px;
}
#mocha .test h2 {
position: relative;
}
#mocha .test a.replay {
position: absolute;
top: 3px;
right: 0;
text-decoration: none;
vertical-align: middle;
display: block;
width: 15px;
height: 15px;
line-height: 15px;
text-align: center;
background: #eee;
font-size: 15px;
-moz-border-radius: 15px;
border-radius: 15px;
-webkit-transition: opacity 200ms;
-moz-transition: opacity 200ms;
transition: opacity 200ms;
opacity: 0.3;
color: #888;
}
#mocha .test:hover a.replay {
opacity: 1;
}
#mocha-report.pass .test.fail {
display: none;
}
#mocha-report.fail .test.pass {
display: none;
}
#mocha-report.pending .test.pass,
#mocha-report.pending .test.fail {
display: none;
}
#mocha-report.pending .test.pass.pending {
display: block;
}
#mocha-error {
color: #c00;
font-size: 1.5em;
font-weight: 100;
letter-spacing: 1px;
}
#mocha-stats {
position: fixed;
top: 15px;
right: 10px;
font-size: 12px;
margin: 0;
color: #888;
z-index: 1;
}
#mocha-stats .progress {
float: right;
padding-top: 0;
}
#mocha-stats em {
color: black;
}
#mocha-stats a {
text-decoration: none;
color: inherit;
}
#mocha-stats a:hover {
border-bottom: 1px solid #eee;
}
#mocha-stats li {
display: inline-block;
margin: 0 5px;
list-style: none;
padding-top: 11px;
}
#mocha-stats canvas {
width: 40px;
height: 40px;
}
#mocha code .comment { color: #ddd; }
#mocha code .init { color: #2f6fad; }
#mocha code .string { color: #5890ad; }
#mocha code .keyword { color: #8a6343; }
#mocha code .number { color: #2f6fad; }
@media screen and (max-device-width: 480px) {
#mocha {
margin: 60px 0px;
}
#mocha #stats {
position: absolute;
}
}

5931
test/lib/sinon.js Normal file

File diff suppressed because it is too large Load Diff

90
test/scripts.js Normal file
View File

@ -0,0 +1,90 @@
// @include "lib/*.js"
// @include "util/*.js"
(function () {
'use strict';
modulejs.define('config', util.uniqObj());
modulejs._private.instances = {};
window.assert = chai.assert;
mocha.setup('bdd');
mocha.checkLeaks();
function update() {
$('#mocha-overlay .suite').each(function () {
var $suite = $(this);
var tests = $suite.find('.test').length;
var passed = $suite.find('.test.pass').length;
var failed = tests - passed;
var $header = $suite.find('> h1 a');
var $count = $('<span class="count"><span class="passed">' + passed + '</span><span class="failed">' + failed + '</span></span>');
if (!failed) {
$count.find('.failed').remove();
}
$suite.addClass(tests === passed ? 'pass' : 'fail');
$header.find('.count').remove();
$header.append($count);
});
}
var count = 0;
function onTest() {
if (count % 25 === 0) {
update();
}
count += 1;
}
function onEnd() {
$('#mocha-overlay').addClass($('.test.fail').length ? 'fail' : 'pass');
$('#mocha-overlay code').each(function () {
var $code = $(this);
$code.text($code.text().trim().replace(/;\n\s*/g, ';\n'));
});
update();
}
function init() {
$('html').removeClass();
util.pinHtml();
mocha
.run()
.on('test', onTest)
.on('end', onEnd);
}
$(init);
}());
(function () {
'use strict';
describe('unit tests', function () {
// @include "tests/unit/premisses.js"
// @include "tests/unit/modulejs.js"
// @include "tests/unit/libs.js"
// @include "tests/unit/config.js"
// @include "tests/unit/boot.js"
// @include "tests/unit/*/*.js"
});
describe('integration tests', function () {
// @include "tests/integration/**/*.js"
});
}());

165
test/styles.less Normal file
View File

@ -0,0 +1,165 @@
@import "lib/mocha";
@col-red: #f44336;
@col-red-text: #c62828;
@col-green: #4caf50;
@col-grey: #555;
#mocha-overlay {
position: fixed;
left: 0;
top: 0;
right: 0;
bottom: 0;
background: #fff;
z-index: 10000;
overflow: auto;
#report {
position: fixed;
left: 0;
top: 0;
right: 0;
background: @col-grey;
z-index: 1;
color: #fff;
font-size: 14px;
font-weight: bold;
line-height: 32px;
padding: 0 8px;
a, a:active, a:visited, a:hover {
display: block;
color: #fff;
text-decoration: none;
}
}
&.pass #report {
background: @col-green;
}
&.fail #report {
background: @col-red;
}
}
#mocha {
max-width: 900px;
margin: 80px auto;
.test.fail, .test pre.error {
color: @col-red-text;
}
.test.pass.fast .duration {
display: inline-block;
color: @col-grey;
border: none;
box-shadow: none;
}
.test::before {
display: block;
width: 10px;
height: 10px;
float: left;
margin-right: 5px;
background: @col-grey;
border-radius: 20px;
position: relative;
top: 4px;
}
.test.pass::before {
content: ' ';
background: @col-green;
}
.test.fail::before {
content: ' ';
background: @col-red;
}
}
#mocha-stats {
top: 40px;
right: 20px;
font-size: 13px;
em {
font-style: normal;
font-size: 14px;
}
}
#mocha-overlay.fail #mocha-stats .failures em {
font-weight: bold;
color: @col-red;
}
#mocha-report {
.suite {
margin: 8px 0 8px 16px;
> h1 {
color: @col-grey;
height: 24px;
line-height: 24px;
font-size: 16px;
font-weight: bold;
margin: 0 0 4px 0;
a, a:active, a:visited, a:hover {
display: block;
padding: 0 8px;
font-size: inherit;
font-weight: inherit;
color: inherit;
background: inherit;
text-decoration: none;
}
a:hover {
background: #eee;
cursor: pointer;
}
.count {
font-size: 0.85em;
.passed {
color: @col-green;
margin-left: 1em;
}
.failed {
color: @col-red;
margin-left: 0.5em;
}
}
}
}
> .suite {
margin: 24px 0;
> h1 {
height: 32px;
line-height: 32px;
font-size: 24px;
font-weight: bold;
margin: 24px 0 8px 0;
}
}
> .suite > ul > .suite {
margin: 12px 0;
> h1 {
height: 26px;
line-height: 26px;
font-size: 20px;
font-weight: bold;
margin: 16px 0 8px 0;
}
}
}

View File

@ -0,0 +1,12 @@
(function () {
'use strict';
describe('first', function () {
it('nothing here', function () {
assert.isTrue(true);
});
});
}());

192
test/tests/unit/boot.js Normal file
View File

@ -0,0 +1,192 @@
(function () {
'use strict';
var ID = 'boot';
var DEPS = ['$'];
describe('module "' + ID + '"', function () {
before(function () {
this.definition = modulejs._private.definitions[ID];
this.xConfig = util.uniqObj();
this.xAjaxResult = {
done: sinon.stub().callsArgWith(0, this.xConfig),
fail: sinon.stub().callsArg(0),
always: sinon.stub().callsArg(0)
};
this.xAjax = sinon.stub($, 'ajax').returns(this.xAjaxResult);
this.xDefine = sinon.stub(modulejs, 'define');
this.xRequire = sinon.stub(modulejs, 'require');
this.applyFn = function () {
this.xAjaxResult.done.reset();
this.xAjaxResult.fail.reset();
this.xAjaxResult.always.reset();
this.xAjax.reset();
this.xDefine.reset();
this.xRequire.reset();
return this.definition.fn($);
};
});
after(function () {
this.xAjax.restore();
this.xDefine.restore();
this.xRequire.restore();
util.restoreHtml();
});
beforeEach(function () {
util.restoreHtml();
});
describe('definition', function () {
it('is defined', function () {
assert.isPlainObject(this.definition);
});
it('has correct id', function () {
assert.strictEqual(this.definition.id, ID);
});
it('requires correct', function () {
assert.deepEqual(this.definition.deps, DEPS);
});
it('args for each request', function () {
assert.strictEqual(this.definition.deps.length, this.definition.fn.length);
});
it('has no instance', function () {
assert.notProperty(modulejs._private.instances, ID);
});
it('inits without errors', function () {
this.applyFn();
});
});
describe('application', function () {
it('returns undefined', function () {
var instance = this.applyFn();
assert.isUndefined(instance);
});
it('no data-module', function () {
this.applyFn();
assert.isFalse(this.xAjax.called);
assert.isFalse(this.xDefine.called);
assert.isFalse(this.xRequire.called);
});
it('data-module="test"', function () {
$('<script/>').attr('data-module', 'test').appendTo('head');
this.applyFn();
assert.isFalse(this.xAjax.called);
assert.isFalse(this.xDefine.called);
assert.isFalse(this.xRequire.called);
});
it('data-module="info"', function () {
$('<script/>').attr('data-module', 'info').appendTo('head');
this.applyFn();
assert.isTrue(this.xAjax.calledOnce);
assert.strictEqual(this.xAjax.lastCall.args[0].url, 'server/php/index.php');
assert.strictEqual(this.xAjax.lastCall.args[0].type, 'POST');
assert.strictEqual(this.xAjax.lastCall.args[0].dataType, 'json');
assert.isTrue(this.xAjaxResult.done.calledOnce);
assert.isFalse(this.xAjaxResult.fail.called);
assert.isFalse(this.xAjaxResult.always.called);
assert.isTrue(this.xDefine.calledOnce);
assert.deepEqual(this.xDefine.lastCall.args, ['config', this.xConfig]);
assert.isTrue(this.xRequire.calledOnce);
assert.deepEqual(this.xRequire.lastCall.args, ['main/info']);
});
it('data-module="index"', function () {
$('<script/>').attr('data-module', 'index').appendTo('head');
this.applyFn();
assert.isTrue(this.xAjax.calledOnce);
assert.strictEqual(this.xAjax.lastCall.args[0].url, '.');
assert.strictEqual(this.xAjax.lastCall.args[0].type, 'POST');
assert.strictEqual(this.xAjax.lastCall.args[0].dataType, 'json');
assert.isTrue(this.xAjaxResult.done.calledOnce);
assert.isFalse(this.xAjaxResult.fail.called);
assert.isFalse(this.xAjaxResult.always.called);
assert.isTrue(this.xDefine.calledOnce);
assert.deepEqual(this.xDefine.lastCall.args, ['config', this.xConfig]);
assert.isTrue(this.xRequire.calledOnce);
assert.deepEqual(this.xRequire.lastCall.args, ['main/index']);
});
it('"no-browser"-class and no data-module', function () {
$('html').addClass('no-browser');
this.applyFn();
assert.isFalse(this.xAjax.called);
assert.isFalse(this.xDefine.called);
assert.isFalse(this.xRequire.called);
});
it('"no-browser"-class and data-module="test"', function () {
$('html').addClass('no-browser');
$('<script/>').attr('data-module', 'test').appendTo('head');
this.applyFn();
assert.isFalse(this.xAjax.called);
assert.isFalse(this.xDefine.called);
assert.isFalse(this.xRequire.called);
});
it('"no-browser"-class and data-module="info"', function () {
$('html').addClass('no-browser');
$('<script/>').attr('data-module', 'info').appendTo('head');
this.applyFn();
assert.isFalse(this.xAjax.called);
assert.isFalse(this.xDefine.called);
assert.isFalse(this.xRequire.called);
});
it('"no-browser"-class and data-module="index"', function () {
$('html').addClass('no-browser');
$('<script/>').attr('data-module', 'index').appendTo('head');
this.applyFn();
assert.isFalse(this.xAjax.called);
assert.isFalse(this.xDefine.called);
assert.isFalse(this.xRequire.called);
});
});
});
}());

61
test/tests/unit/config.js Normal file
View File

@ -0,0 +1,61 @@
(function () {
'use strict';
var ID = 'config';
var DEPS = [];
describe('module "' + ID + '"', function () {
before(function () {
this.definition = modulejs._private.definitions[ID];
this.applyFn = function () {
return this.definition.fn($);
};
});
describe('definition', function () {
it('is defined', function () {
assert.isPlainObject(this.definition);
});
it('has correct id', function () {
assert.strictEqual(this.definition.id, ID);
});
it('requires correct', function () {
assert.deepEqual(this.definition.deps, DEPS);
});
it('args for each request', function () {
assert.strictEqual(this.definition.deps.length, this.definition.fn.length);
});
it('has no instance', function () {
assert.notProperty(modulejs._private.instances, ID);
});
it('inits without errors', function () {
this.applyFn();
});
it('is only dummy definition', function () {
var instance = this.applyFn();
assert.isPlainObject(instance);
assert.lengthOfKeys(instance, 1);
assert.isTrue(util.isUniqId(instance.uniqId));
});
});
});
}());

View File

@ -0,0 +1,118 @@
(function () {
'use strict';
var ID = 'core/event';
var DEPS = ['_'];
describe('module "' + ID + '"', function () {
before(function () {
this.definition = modulejs._private.definitions[ID];
this.applyFn = function () {
return this.definition.fn(_);
};
});
describe('definition', function () {
it('is defined', function () {
assert.isPlainObject(this.definition);
});
it('has correct id', function () {
assert.strictEqual(this.definition.id, ID);
});
it('requires correct', function () {
assert.deepEqual(this.definition.deps, DEPS);
});
it('args for each request', function () {
assert.strictEqual(this.definition.deps.length, this.definition.fn.length);
});
it('has no instance', function () {
assert.notProperty(modulejs._private.instances, ID);
});
it('inits without errors', function () {
this.applyFn();
});
});
describe('application', function () {
it('returns plain object with 3 properties', function () {
var instance = this.applyFn();
assert.isPlainObject(instance);
assert.lengthOfKeys(instance, 3);
});
});
describe('publics', function () {
it('.sub() is function', function () {
var instance = this.applyFn();
assert.isFunction(instance.sub);
});
it('.unsub() is function', function () {
var instance = this.applyFn();
assert.isFunction(instance.unsub);
});
it('.pub() is function', function () {
var instance = this.applyFn();
assert.isFunction(instance.pub);
});
it('works', function () {
var topic = 'topic';
var arg1 = 'arg1';
var arg2 = 'arg2';
var arg3 = 'arg3';
var subSpy = sinon.spy();
var instance = this.applyFn();
instance.sub(topic, subSpy);
instance.pub(topic, arg1, arg2, arg3);
assert.isTrue(subSpy.calledOnce);
assert.deepEqual(subSpy.firstCall.args, [arg1, arg2, arg3]);
instance.pub(topic, arg1, arg2);
assert.isTrue(subSpy.calledTwice);
assert.deepEqual(subSpy.firstCall.args, [arg1, arg2, arg3]);
assert.deepEqual(subSpy.secondCall.args, [arg1, arg2]);
instance.unsub(topic, subSpy);
assert.isTrue(subSpy.calledTwice);
assert.deepEqual(subSpy.firstCall.args, [arg1, arg2, arg3]);
assert.deepEqual(subSpy.secondCall.args, [arg1, arg2]);
instance.pub(topic, arg1);
assert.isTrue(subSpy.calledTwice);
assert.deepEqual(subSpy.firstCall.args, [arg1, arg2, arg3]);
assert.deepEqual(subSpy.secondCall.args, [arg1, arg2]);
});
});
});
}());

View File

@ -0,0 +1,215 @@
(function () {
'use strict';
var ID = 'core/format';
var DEPS = ['_'];
describe('module "' + ID + '"', function () {
before(function () {
this.definition = modulejs._private.definitions[ID];
this.applyFn = function () {
return this.definition.fn(_);
};
});
describe('definition', function () {
it('is defined', function () {
assert.isPlainObject(this.definition);
});
it('has correct id', function () {
assert.strictEqual(this.definition.id, ID);
});
it('requires correct', function () {
assert.deepEqual(this.definition.deps, DEPS);
});
it('args for each request', function () {
assert.strictEqual(this.definition.deps.length, this.definition.fn.length);
});
it('has no instance', function () {
assert.notProperty(modulejs._private.instances, ID);
});
it('inits without errors', function () {
this.applyFn();
});
});
describe('application', function () {
it('returns plain object with 4 properties', function () {
var instance = this.applyFn();
assert.isPlainObject(instance);
assert.lengthOfKeys(instance, 4);
});
});
describe('publics', function () {
it('.setDefaultMetric() is function', function () {
var instance = this.applyFn();
assert.isFunction(instance.setDefaultMetric);
});
it('.formatSize() is function', function () {
var instance = this.applyFn();
assert.isFunction(instance.formatSize);
});
it('.setDefaultDateFormat() is function', function () {
var instance = this.applyFn();
assert.isFunction(instance.setDefaultDateFormat);
});
it('.formatDate() is function', function () {
var instance = this.applyFn();
assert.isFunction(instance.formatDate);
});
it('.formatSize() defaults to decimal metric', function () {
var instance = this.applyFn();
assert.strictEqual(instance.formatSize(1024), '1 KB');
instance.setDefaultMetric(true);
assert.strictEqual(instance.formatSize(1024), '1 KiB');
instance.setDefaultMetric(false);
assert.strictEqual(instance.formatSize(1024), '1 KB');
});
describe('.formatSize() with decimal metric', function () {
_.each([
[0, '0 B'],
[10, '10 B'],
[999, '999 B'],
[1000, '1 KB'],
[1001, '1 KB'],
[1499, '1 KB'],
[1500, '2 KB'],
[999999, '1000 KB'],
[1000000, '1.0 MB'],
[1000001, '1.0 MB'],
[1230000, '1.2 MB'],
[1250000, '1.3 MB'],
[999999999, '1000.0 MB'],
[1000000000, '1.0 GB'],
[1250000000, '1.3 GB'],
[999999999999, '1000.0 GB'],
[1000000000000, '1.0 TB'],
[1250000000000, '1.3 TB']
], function (data) {
var arg = data[0];
var exp = data[1];
it('.formatSize(' + arg + ') => "' + exp + '"', function () {
var instance = this.applyFn();
instance.setDefaultMetric(false);
assert.strictEqual(instance.formatSize(arg), exp);
});
});
});
describe('.formatSize() with binary metric', function () {
_.each([
[0, '0 B'],
[10, '10 B'],
[999, '999 B'],
[1000, '1000 B'],
[1001, '1001 B'],
[1024, '1 KiB'],
[1499, '1 KiB'],
[1500, '1 KiB'],
[999999, '977 KiB'],
[1000000, '977 KiB'],
[1000001, '977 KiB'],
[1230000, '1.2 MiB'],
[1250000, '1.2 MiB'],
[999999999, '953.7 MiB'],
[1000000000, '953.7 MiB'],
[1250000000, '1.2 GiB'],
[999999999999, '931.3 GiB'],
[1000000000000, '931.3 GiB'],
[1250000000000, '1.1 TiB']
], function (data) {
var arg = data[0];
var exp = data[1];
it('.formatSize(' + arg + ') => "' + exp + '"', function () {
var instance = this.applyFn();
instance.setDefaultMetric(true);
assert.strictEqual(instance.formatSize(arg), exp);
});
});
});
it('.formatDate() with default format', function () {
var instance = this.applyFn();
assert.strictEqual(instance.formatDate(0), '');
assert.strictEqual(instance.formatDate(1000), '1970-01-01 01:00');
assert.strictEqual(instance.formatDate(-1000), '1970-01-01 00:59');
assert.strictEqual(instance.formatDate(1400000000000), '2014-05-13 18:53');
instance.setDefaultDateFormat('YYYY-MM-DD HH:mm:ss');
assert.strictEqual(instance.formatDate(0), '');
assert.strictEqual(instance.formatDate(1000), '1970-01-01 01:00:01');
assert.strictEqual(instance.formatDate(-1000), '1970-01-01 00:59:59');
assert.strictEqual(instance.formatDate(1400000000000), '2014-05-13 18:53:20');
instance.setDefaultDateFormat('H YY s');
assert.strictEqual(instance.formatDate(0), '');
assert.strictEqual(instance.formatDate(1000), '1 70 1');
assert.strictEqual(instance.formatDate(-1000), '0 70 59');
assert.strictEqual(instance.formatDate(1400000000000), '18 14 20');
});
describe('.formatDate()', function () {
_.each([
[0, 'YYYY-MM-DD HH:mm:ss', ''],
[1000, 'YYYY-MM-DD HH:mm:ss', '1970-01-01 01:00:01'],
[-1000, 'YYYY-MM-DD HH:mm:ss', '1970-01-01 00:59:59'],
[1400000000000, 'YYYY-MM-DD HH:mm:ss', '2014-05-13 18:53:20'],
[1400000000000, 'XYYYYXMMXDDXHHXmmXssX', 'X2014X05X13X18X53X20X'],
[1400000000000, 'YYYY YY Y MM M DD D HH H mm m ss s', '2014 14 2014 05 5 13 13 18 18 53 53 20 20']
], function (data) {
var arg1 = data[0];
var arg2 = data[1];
var exp = data[2];
it('.formatDate(' + arg1 + ', ' + arg2 + ') => "' + exp + '"', function () {
var instance = this.applyFn();
assert.strictEqual(instance.formatDate(arg1, arg2), exp);
});
});
});
});
});
}());

View File

@ -0,0 +1,64 @@
(function () {
'use strict';
var ID = 'core/langs';
var DEPS = ['_', 'config'];
describe('module "' + ID + '"', function () {
before(function () {
this.definition = modulejs._private.definitions[ID];
this.xConfig = {langs: util.uniqObj()};
this.applyFn = function () {
return this.definition.fn(_, this.xConfig);
};
});
describe('definition', function () {
it('is defined', function () {
assert.isPlainObject(this.definition);
});
it('has correct id', function () {
assert.strictEqual(this.definition.id, ID);
});
it('requires correct', function () {
assert.deepEqual(this.definition.deps, DEPS);
});
it('args for each request', function () {
assert.strictEqual(this.definition.deps.length, this.definition.fn.length);
});
it('has no instance', function () {
assert.notProperty(modulejs._private.instances, ID);
});
it('inits without errors', function () {
this.applyFn();
});
});
describe('application', function () {
it('returns plain object with right content', function () {
var instance = this.applyFn();
assert.isPlainObject(instance);
assert.deepEqual(instance, this.xConfig.langs);
});
});
});
}());

View File

@ -0,0 +1,155 @@
(function () {
'use strict';
var ID = 'core/location';
var DEPS = ['_', 'modernizr', 'core/event', 'core/notify', 'core/settings'];
describe('module "' + ID + '"', function () {
before(function () {
this.definition = modulejs._private.definitions[ID];
this.xModernizr = {
history: true
};
this.xSettings = {
smartBrowsing: true,
unmanagedInNewWindow: true
};
this.xEvent = {
pub: sinon.stub(),
sub: sinon.stub()
};
this.xNotify = {
set: sinon.stub()
};
this.applyFn = function () {
return this.definition.fn(_, this.xModernizr, this.xEvent, this.xNotify, this.xSettings);
};
});
describe('definition', function () {
it('is defined', function () {
assert.isPlainObject(this.definition);
});
it('has correct id', function () {
assert.strictEqual(this.definition.id, ID);
});
it('requires correct', function () {
assert.deepEqual(this.definition.deps, DEPS);
});
it('args for each request', function () {
assert.strictEqual(this.definition.deps.length, this.definition.fn.length);
});
it('has no instance', function () {
assert.notProperty(modulejs._private.instances, ID);
});
it('inits without errors', function () {
this.applyFn();
});
});
describe('application', function () {
it('returns plain object with 7 properties', function () {
var instance = this.applyFn();
assert.isPlainObject(instance);
assert.lengthOfKeys(instance, 7);
});
});
describe('publics', function () {
describe('.forceEncoding()', function () {
it('is function', function () {
var instance = this.applyFn();
assert.isFunction(instance.forceEncoding);
});
});
describe('.getDomain()', function () {
it('is function', function () {
var instance = this.applyFn();
assert.isFunction(instance.getDomain);
});
it('returns document.domain', function () {
var instance = this.applyFn();
assert.strictEqual(instance.getDomain(), document.domain);
});
});
describe('.getAbsHref()', function () {
it('is function', function () {
var instance = this.applyFn();
assert.isFunction(instance.getAbsHref);
});
it('returns null before .setLocation()', function () {
var instance = this.applyFn();
assert.isNull(instance.getAbsHref());
});
});
describe('.getItem()', function () {
it('is function', function () {
var instance = this.applyFn();
assert.isFunction(instance.getItem);
});
});
describe('.setLocation()', function () {
it('is function', function () {
var instance = this.applyFn();
assert.isFunction(instance.setLocation);
});
});
describe('.refresh()', function () {
it('is function', function () {
var instance = this.applyFn();
assert.isFunction(instance.refresh);
});
});
describe('.setLink()', function () {
it('is function', function () {
var instance = this.applyFn();
assert.isFunction(instance.setLink);
});
});
});
});
}());

View File

@ -0,0 +1,111 @@
(function () {
'use strict';
var ID = 'core/notify';
var DEPS = ['$'];
describe('module "' + ID + '"', function () {
before(function () {
this.definition = modulejs._private.definitions[ID];
this.applyFn = function () {
return this.definition.fn($);
};
});
after(function () {
util.restoreHtml();
});
beforeEach(function () {
util.restoreHtml();
});
describe('definition', function () {
it('is defined', function () {
assert.isPlainObject(this.definition);
});
it('has correct id', function () {
assert.strictEqual(this.definition.id, ID);
});
it('requires correct', function () {
assert.deepEqual(this.definition.deps, DEPS);
});
it('args for each request', function () {
assert.strictEqual(this.definition.deps.length, this.definition.fn.length);
});
it('has no instance', function () {
assert.notProperty(modulejs._private.instances, ID);
});
it('inits without errors', function () {
this.applyFn();
});
});
describe('application', function () {
it('returns plain object with 1 property', function () {
var instance = this.applyFn();
assert.isPlainObject(instance);
assert.lengthOfKeys(instance, 1);
});
it('adds HTML', function () {
this.applyFn();
assert.lengthOf($('#notify'), 1);
assert.lengthOf($('#notify:visible'), 0);
assert.strictEqual($('#notify').text(), '');
});
});
describe('publics', function () {
it('.set() is function', function () {
var instance = this.applyFn();
assert.ok(_.isFunction(instance.set));
});
it('.set() works', function () {
var instance = this.applyFn();
instance.set();
assert.lengthOf($('#notify:visible'), 0);
assert.strictEqual($('#notify').text(), '');
instance.set('hello');
assert.lengthOf($('#notify:visible'), 1);
assert.strictEqual($('#notify').text(), 'hello');
instance.set('world');
assert.lengthOf($('#notify:visible'), 1);
assert.strictEqual($('#notify').text(), 'world');
instance.set();
// assert.lengthOf($('#notify:visible'), 0);
assert.strictEqual($('#notify').text(), 'world');
});
});
});
}());

View File

@ -0,0 +1,110 @@
(function () {
'use strict';
var ID = 'core/resource';
var DEPS = ['_', 'config', 'core/settings'];
describe('module "' + ID + '"', function () {
before(function () {
this.definition = modulejs._private.definitions[ID];
this.xConfig = {
theme: {
a: 'myTheme/a.svg',
b: 'myTheme/b.jpg'
}
};
this.xSettings = {appHref: '/some/app/href/'};
this.applyFn = function () {
return this.definition.fn(_, this.xConfig, this.xSettings);
};
});
describe('definition', function () {
it('is defined', function () {
assert.isPlainObject(this.definition);
});
it('has correct id', function () {
assert.strictEqual(this.definition.id, ID);
});
it('requires correct', function () {
assert.deepEqual(this.definition.deps, DEPS);
});
it('args for each request', function () {
assert.strictEqual(this.definition.deps.length, this.definition.fn.length);
});
it('has no instance', function () {
assert.notProperty(modulejs._private.instances, ID);
});
it('inits without errors', function () {
this.applyFn();
});
});
describe('application', function () {
it('returns plain object with 2 properties', function () {
var instance = this.applyFn();
assert.isPlainObject(instance);
assert.lengthOf(_.keys(instance), 2);
});
});
describe('publics', function () {
it('.image() is function', function () {
var instance = this.applyFn();
assert.isFunction(instance.image);
});
it('.icon() is function', function () {
var instance = this.applyFn();
assert.isFunction(instance.icon);
});
it('.image() works', function () {
var instance = this.applyFn();
var ui = this.xSettings.appHref + 'client/images/ui/';
assert.strictEqual(instance.image(), ui + 'undefined.svg');
assert.strictEqual(instance.image(1), ui + '1.svg');
assert.strictEqual(instance.image(''), ui + '.svg');
assert.strictEqual(instance.image('a'), ui + 'a.svg');
});
it('.icon() works', function () {
var instance = this.applyFn();
var themes = this.xSettings.appHref + 'client/images/themes/';
assert.strictEqual(instance.icon(''), themes + 'default/file.svg');
assert.strictEqual(instance.icon('a'), themes + 'myTheme/a.svg');
assert.strictEqual(instance.icon('a-sub'), themes + 'myTheme/a.svg');
assert.strictEqual(instance.icon('b'), themes + 'myTheme/b.jpg');
assert.strictEqual(instance.icon('x'), themes + 'default/x.svg');
assert.strictEqual(instance.icon('y'), themes + 'default/file.svg');
assert.strictEqual(instance.icon('y-sub'), themes + 'default/file.svg');
});
});
});
}());

View File

@ -0,0 +1,300 @@
(function () {
'use strict';
var ID = 'core/server';
var DEPS = ['_', '$', 'config', 'core/location'];
var $submitSnap;
describe('module "' + ID + '"', function () {
before(function () {
this.definition = modulejs._private.definitions[ID];
this.xConfig = {
setup: {
API: true,
BACKEND: util.uniqId(),
SERVER_NAME: util.uniqId(),
SERVER_VERSION: util.uniqId()
}
};
this.xAbsHref = util.uniqId();
this.xLocation = {
getAbsHref: sinon.stub().returns(this.xAbsHref)
};
this.xAjaxResult = {
done: sinon.stub().returnsThis(),
fail: sinon.stub().returnsThis(),
always: sinon.stub().returnsThis()
};
this.xAjax = sinon.stub($, 'ajax').returns(this.xAjaxResult);
this.xSubmit = sinon.stub($.fn, 'submit', function () {
$submitSnap = this;
return this;
});
this.applyFn = function () {
this.xLocation.getAbsHref.reset();
this.xAjaxResult.done.reset();
this.xAjaxResult.fail.reset();
this.xAjaxResult.always.reset();
this.xAjax.reset();
this.xSubmit.reset();
$submitSnap = undefined;
return this.definition.fn(_, $, this.xConfig, this.xLocation);
};
});
after(function () {
this.xAjax.restore();
this.xSubmit.restore();
});
describe('definition', function () {
it('is defined', function () {
assert.isPlainObject(this.definition);
});
it('has correct id', function () {
assert.strictEqual(this.definition.id, ID);
});
it('requires correct', function () {
assert.deepEqual(this.definition.deps, DEPS);
});
it('args for each request', function () {
assert.strictEqual(this.definition.deps.length, this.definition.fn.length);
});
it('has no instance', function () {
assert.notProperty(modulejs._private.instances, ID);
});
it('inits without errors', function () {
this.applyFn();
});
});
describe('application', function () {
it('returns plain object with 6 properties', function () {
var instance = this.applyFn();
assert.isPlainObject(instance);
assert.lengthOf(_.keys(instance), 6);
});
});
describe('publics', function () {
it('.backend is set correct', function () {
var instance = this.applyFn();
assert.strictEqual(instance.backend, this.xConfig.setup.BACKEND);
});
it('.name is set correct', function () {
var instance = this.applyFn();
assert.strictEqual(instance.name, this.xConfig.setup.SERVER_NAME);
});
it('.version is set correct', function () {
var instance = this.applyFn();
assert.strictEqual(instance.version, this.xConfig.setup.SERVER_VERSION);
});
});
describe('.api', function () {
it('set correct (false)', function () {
this.xConfig.setup.API = false;
var instance = this.applyFn();
assert.isFalse(instance.api);
});
it('set correct (falsy)', function () {
this.xConfig.setup.API = null;
var instance = this.applyFn();
assert.isFalse(instance.api);
});
it('set correct (truthy)', function () {
this.xConfig.setup.API = 1;
var instance = this.applyFn();
assert.isFalse(instance.api);
});
it('set correct (true)', function () {
this.xConfig.setup.API = true;
var instance = this.applyFn();
assert.isTrue(instance.api);
});
});
describe('.request()', function () {
it('is function', function () {
var instance = this.applyFn();
assert.isFunction(instance.request);
});
it('no result if no API', function () {
this.xConfig.setup.API = false;
var instance = this.applyFn();
var xData = util.uniqObj();
var spy = sinon.spy();
var res = instance.request(xData, spy);
assert.isUndefined(res);
assert.isFalse(this.xAjax.called);
assert.isFalse(this.xAjaxResult.done.called);
assert.isFalse(this.xAjaxResult.fail.called);
assert.isFalse(this.xAjax.called);
assert.isTrue(spy.calledOnce);
assert.deepEqual(spy.lastCall.args, []);
});
it('done() works', function () {
this.xConfig.setup.API = true;
var instance = this.applyFn();
var xData = util.uniqObj();
var xResult = util.uniqObj();
var spy = sinon.spy();
var res = instance.request(xData, spy);
assert.isUndefined(res);
assert.isTrue(this.xLocation.getAbsHref.calledOnce);
assert.isTrue(this.xAjax.calledOnce);
assert.deepEqual(this.xAjax.lastCall.args, [{
url: this.xAbsHref,
data: xData,
type: 'POST',
dataType: 'json'
}]);
assert.isTrue(this.xAjaxResult.done.calledOnce);
assert.isTrue(this.xAjaxResult.fail.calledOnce);
assert.isFalse(spy.called);
this.xAjaxResult.done.callArgWith(0, xResult);
assert.isTrue(spy.calledOnce);
assert.deepEqual(spy.firstCall.args, [xResult]);
});
it('fail() works', function () {
this.xConfig.setup.API = true;
var instance = this.applyFn();
var xData = util.uniqObj();
var spy = sinon.spy();
var res = instance.request(xData, spy);
assert.isUndefined(res);
assert.isTrue(this.xLocation.getAbsHref.calledOnce);
assert.isTrue(this.xAjax.calledOnce);
assert.deepEqual(this.xAjax.lastCall.args, [{
url: this.xAbsHref,
data: xData,
type: 'POST',
dataType: 'json'
}]);
assert.isTrue(this.xAjaxResult.done.calledOnce);
assert.isTrue(this.xAjaxResult.fail.calledOnce);
assert.isFalse(spy.called);
this.xAjaxResult.fail.callArg(0);
assert.isTrue(spy.calledOnce);
assert.deepEqual(spy.firstCall.args, []);
});
});
describe('.formRequest()', function () {
it('is function', function () {
var instance = this.applyFn();
assert.isFunction(instance.formRequest);
});
it('does nothing if no API', function () {
this.xConfig.setup.API = false;
var instance = this.applyFn();
var xData = util.uniqObj();
var res = instance.formRequest(xData);
assert.isUndefined(res);
assert.isFalse(this.xSubmit.called);
assert.isUndefined($submitSnap);
});
it('works', function () {
this.xConfig.setup.API = true;
var instance = this.applyFn();
var xData = {
a: util.uniqId(),
b: util.uniqId()
};
var res = instance.formRequest(xData);
assert.isUndefined(res);
assert.isTrue(this.xSubmit.calledOnce);
assert.lengthOf($submitSnap, 1);
assert.strictEqual($submitSnap.get(0).tagName.toLowerCase(), 'form');
assert.strictEqual($submitSnap.attr('method'), 'post');
assert.strictEqual($submitSnap.attr('style'), 'display:none;');
assert.strictEqual($submitSnap.attr('action'), this.xAbsHref);
var $children = $submitSnap.children();
assert.lengthOf($children, 2);
assert.strictEqual($children.eq(0).attr('type'), 'hidden');
assert.strictEqual($children.eq(0).attr('name'), 'a');
assert.strictEqual($children.eq(0).attr('value'), xData.a);
assert.strictEqual($children.eq(1).attr('type'), 'hidden');
assert.strictEqual($children.eq(1).attr('name'), 'b');
assert.strictEqual($children.eq(1).attr('value'), xData.b);
});
});
});
}());

View File

@ -0,0 +1,105 @@
(function () {
'use strict';
var ID = 'core/settings';
var DEPS = ['_', 'config'];
describe('module "' + ID + '"', function () {
before(function () {
this.definition = modulejs._private.definitions[ID];
this.xConfig = {
options: {
someOptions: util.uniqObj(),
otherOptions: util.uniqObj(),
more: util.uniqObj()
},
setup: {
APP_HREF: util.uniqId(),
ROOT_HREF: util.uniqId(),
CURRENT_HREF: util.uniqId()
}
};
this.applyFn = function () {
return this.definition.fn(_, this.xConfig);
};
});
describe('definition', function () {
it('is defined', function () {
assert.isPlainObject(this.definition);
});
it('has correct id', function () {
assert.strictEqual(this.definition.id, ID);
});
it('requires correct', function () {
assert.deepEqual(this.definition.deps, DEPS);
});
it('args for each request', function () {
assert.strictEqual(this.definition.deps.length, this.definition.fn.length);
});
it('has no instance', function () {
assert.notProperty(modulejs._private.instances, ID);
});
it('inits without errors', function () {
this.applyFn();
});
});
describe('application', function () {
it('returns plain object with properties', function () {
var instance = this.applyFn();
assert.isPlainObject(instance);
assert.isAbove(_.keys(instance).length, 0);
});
});
describe('publics', function () {
it('are extended from options', function () {
var instance = this.applyFn();
assert.strictEqual(instance.someOptions, this.xConfig.options.someOptions);
assert.strictEqual(instance.otherOptions, this.xConfig.options.otherOptions);
assert.strictEqual(instance.more, this.xConfig.options.more);
assert.strictEqual(_.keys(instance).length, _.keys(this.xConfig.options).length + 3);
});
it('.appHref is set correct', function () {
var instance = this.applyFn();
assert.strictEqual(instance.appHref, this.xConfig.setup.APP_HREF);
});
it('.rootHref is set correct', function () {
var instance = this.applyFn();
assert.strictEqual(instance.rootHref, this.xConfig.setup.ROOT_HREF);
});
it('.currentHref is set correct', function () {
var instance = this.applyFn();
assert.strictEqual(instance.currentHref, this.xConfig.setup.CURRENT_HREF);
});
});
});
}());

View File

@ -0,0 +1,126 @@
(function () {
'use strict';
var ID = 'core/store';
var DEPS = ['modernizr'];
describe('module "' + ID + '"', function () {
before(function () {
this.definition = modulejs._private.definitions[ID];
this.storeKey = '_h5ai';
this.storeBackup = window.localStorage.getItem(this.storeKey);
this.xModernizr = {localstorage: true};
this.applyFn = function () {
return this.definition.fn(this.xModernizr);
};
});
after(function () {
if (this.storeBackup) {
window.localStorage.setItem(this.storeKey, this.storeBackup);
} else {
window.localStorage.removeItem(this.storeKey);
}
});
describe('definition', function () {
it('is defined', function () {
assert.isPlainObject(this.definition);
});
it('has correct id', function () {
assert.strictEqual(this.definition.id, ID);
});
it('requires correct', function () {
assert.deepEqual(this.definition.deps, DEPS);
});
it('args for each request', function () {
assert.strictEqual(this.definition.deps.length, this.definition.fn.length);
});
it('has no instance', function () {
assert.notProperty(modulejs._private.instances, ID);
});
it('inits without errors', function () {
this.applyFn();
});
});
describe('application', function () {
it('returns plain object with 2 properties', function () {
var instance = this.applyFn();
assert.isPlainObject(instance);
assert.lengthOfKeys(instance, 2);
});
});
describe('publics', function () {
var key1 = 'test1';
var value1 = '1234';
var key2 = 'test2';
var value2 = '5678';
it('.put() is function', function () {
var instance = this.applyFn();
assert.isFunction(instance.put);
});
it('.get() is function', function () {
var instance = this.applyFn();
assert.isFunction(instance.get);
});
it('works', function () {
var instance = this.applyFn();
assert.isNull(window.localStorage.getItem(this.storeKey));
assert.isUndefined(instance.get(key1));
assert.isNull(window.localStorage.getItem(this.storeKey));
assert.isUndefined(instance.put(key1, value1));
assert.strictEqual(window.localStorage.getItem(this.storeKey), '{"test1":"1234"}');
assert.strictEqual(instance.get(key1), value1);
assert.strictEqual(window.localStorage.getItem(this.storeKey), '{"test1":"1234"}');
assert.isUndefined(instance.put(key1, undefined));
assert.strictEqual(window.localStorage.getItem(this.storeKey), '{}');
assert.isUndefined(instance.get(key1));
assert.strictEqual(window.localStorage.getItem(this.storeKey), '{}');
assert.isUndefined(instance.put(key1, value1));
assert.strictEqual(window.localStorage.getItem(this.storeKey), '{"test1":"1234"}');
assert.isUndefined(instance.put(key2, value2));
assert.strictEqual(window.localStorage.getItem(this.storeKey), '{"test1":"1234","test2":"5678"}');
assert.isUndefined(instance.put(key1, undefined));
assert.strictEqual(window.localStorage.getItem(this.storeKey), '{"test2":"5678"}');
});
});
});
}());

View File

@ -0,0 +1,95 @@
(function () {
'use strict';
var ID = 'core/types';
var DEPS = ['_', 'config'];
describe('module "' + ID + '"', function () {
before(function () {
this.definition = modulejs._private.definitions[ID];
this.xConfig = {types: {
a: ['*.a', '*.aa'],
b: ['*.b'],
c: ['*.c']
}};
this.applyFn = function () {
return this.definition.fn(_, this.xConfig);
};
});
describe('definition', function () {
it('is defined', function () {
assert.isPlainObject(this.definition);
});
it('has correct id', function () {
assert.strictEqual(this.definition.id, ID);
});
it('requires correct', function () {
assert.deepEqual(this.definition.deps, DEPS);
});
it('args for each request', function () {
assert.strictEqual(this.definition.deps.length, this.definition.fn.length);
});
it('has no instance', function () {
assert.notProperty(modulejs._private.instances, ID);
});
it('inits without errors', function () {
this.applyFn();
});
});
describe('application', function () {
it('returns plain object with 1 property', function () {
var instance = this.applyFn();
assert.isPlainObject(instance);
assert.lengthOfKeys(instance, 1);
});
});
describe('publics', function () {
it('.getType() is function', function () {
var instance = this.applyFn();
assert.isFunction(instance.getType);
});
it('.getType() works', function () {
var instance = this.applyFn();
assert.strictEqual(instance.getType('file.a'), 'a');
assert.strictEqual(instance.getType('file.aa'), 'a');
assert.strictEqual(instance.getType('foo.b'), 'b');
assert.strictEqual(instance.getType('some/path/file.c'), 'c');
assert.strictEqual(instance.getType('/some/abs/path/file.c'), 'c');
assert.strictEqual(instance.getType('file.x'), 'file');
assert.strictEqual(instance.getType('foo'), 'file');
assert.strictEqual(instance.getType('some/path/foo'), 'file');
assert.strictEqual(instance.getType('/some/path/foo'), 'file');
assert.strictEqual(instance.getType('foo/'), 'folder');
assert.strictEqual(instance.getType('/'), 'folder');
assert.strictEqual(instance.getType('some/path/foo/'), 'folder');
assert.strictEqual(instance.getType('/some/path/foo/'), 'folder');
});
});
});
}());

View File

@ -0,0 +1,120 @@
(function () {
'use strict';
var ID = 'core/util';
var DEPS = [];
describe('module "' + ID + '"', function () {
before(function () {
this.definition = modulejs._private.definitions[ID];
this.applyFn = function () {
return this.definition.fn();
};
});
describe('definition', function () {
it('is defined', function () {
assert.isPlainObject(this.definition);
});
it('has correct id', function () {
assert.strictEqual(this.definition.id, ID);
});
it('requires correct', function () {
assert.deepEqual(this.definition.deps, DEPS);
});
it('args for each request', function () {
assert.strictEqual(this.definition.deps.length, this.definition.fn.length);
});
it('has no instance', function () {
assert.notProperty(modulejs._private.instances, ID);
});
it('inits without errors', function () {
this.applyFn();
});
});
describe('application', function () {
it('returns plain object with 2 properties', function () {
var instance = this.applyFn();
assert.isPlainObject(instance);
assert.lengthOfKeys(instance, 2);
});
});
describe('publics', function () {
it('.regularCmpFn() is function', function () {
var instance = this.applyFn();
assert.isFunction(instance.regularCmpFn);
});
it('.naturalCmpFn() is function', function () {
var instance = this.applyFn();
assert.isFunction(instance.naturalCmpFn);
});
_.each([
[0, 0, 0],
[1, 0, 1],
[1, 2, -1],
['a', 'a', 0],
['b', 'a', 1],
['a', 'b', -1],
['a 2', 'a 10', 1]
], function (data) {
var arg1 = data[0];
var arg2 = data[1];
var exp = data[2];
it('.regularCmpFn("' + arg1 + '", "' + arg2 + '") => "' + exp + '"', function () {
var instance = this.applyFn();
assert.strictEqual(instance.regularCmpFn(arg1, arg2), exp);
});
});
_.each([
[0, 0, 0],
[1, 0, 1],
[1, 2, -1],
['a', 'a', 0],
['b', 'a', 1],
['a', 'b', -1],
['a 2', 'a 10', -1]
], function (data) {
var arg1 = data[0];
var arg2 = data[1];
var exp = data[2];
it('.naturalCmpFn("' + arg1 + '", "' + arg2 + '") => "' + exp + '"', function () {
var instance = this.applyFn();
assert.strictEqual(instance.naturalCmpFn(arg1, arg2), exp);
});
});
});
});
}());

40
test/tests/unit/libs.js Normal file
View File

@ -0,0 +1,40 @@
(function () {
'use strict';
describe('libs', function () {
var libs = {
_: window._,
$: window.jQuery,
marked: window.marked,
modernizr: window.Modernizr,
prism: window.Prism
};
_.each(libs, function (lib, id) {
describe('module "' + id + '"', function () {
it('is defined', function () {
assert.isDefined(modulejs._private.definitions[id]);
});
it('has no instance', function () {
assert.notProperty(modulejs._private.instances, id);
});
it('returns global lib', function () {
var definition = modulejs._private.definitions[id];
var instance = definition.fn();
assert.isDefined(instance);
assert.strictEqual(instance, lib);
});
});
});
});
}());

View File

@ -0,0 +1,119 @@
(function () {
'use strict';
var ID = 'main/index';
var DEPS = ['_', 'core/event'];
describe('module "' + ID + '"', function () {
before(function () {
this.definition = modulejs._private.definitions[ID];
this.xEvent = {pub: sinon.stub()};
this.xDefine = sinon.stub(modulejs, 'define');
this.xRequire = sinon.stub(modulejs, 'require');
this.applyFn = function () {
this.xEvent.pub.reset();
this.xDefine.reset();
this.xRequire.reset();
return this.definition.fn(_, this.xEvent);
};
});
after(function () {
this.xDefine.restore();
this.xRequire.restore();
});
describe('definition', function () {
it('is defined', function () {
assert.isPlainObject(this.definition);
});
it('has correct id', function () {
assert.strictEqual(this.definition.id, ID);
});
it('requires correct', function () {
assert.deepEqual(this.definition.deps, DEPS);
});
it('args for each request', function () {
assert.strictEqual(this.definition.deps.length, this.definition.fn.length);
});
it('has no instance', function () {
assert.notProperty(modulejs._private.instances, ID);
});
it('inits without errors', function () {
this.applyFn();
});
});
describe('application', function () {
it('returns undefined', function () {
var instance = this.applyFn();
assert.isUndefined(instance);
});
it('publishes "ready" event', function () {
this.applyFn();
assert.isTrue(this.xEvent.pub.calledOnce);
assert.deepEqual(this.xEvent.pub.firstCall.args, ['ready']);
});
it('requires all views and extensions (only)', function () {
this.applyFn();
var re = /^(view|ext)\//;
var self = this;
var counter = 0;
_.each(modulejs.state(), function (state, id) {
if (re.test(id)) {
counter += 1;
assert.isTrue(self.xRequire.calledWithExactly(id));
}
});
assert.strictEqual(self.xRequire.callCount, counter);
});
it('requires views before extensions', function () {
this.applyFn();
var foundExtension = false;
var reView = /^view\//;
var reExt = /^ext\//;
_.each(this.xRequire.args, function (args) {
if (foundExtension) {
assert.match(args[0], reExt);
} else if (reExt.test(args[0])) {
foundExtension = true;
} else {
assert.match(args[0], reView);
}
});
});
});
});
}());

View File

@ -0,0 +1,208 @@
(function () {
'use strict';
var ID = 'main/info';
var DEPS = ['$', 'config'];
describe('module "' + ID + '"', function () {
before(function () {
this.definition = modulejs._private.definitions[ID];
this.xConfig = {
setup: {
VERSION: util.uniqId()
}
};
this.xAjaxResult = {
done: sinon.stub(),
fail: sinon.stub(),
always: sinon.stub()
};
this.xAjax = sinon.stub($, 'ajax').returns(this.xAjaxResult);
this.applyFn = function () {
this.xAjaxResult.done.reset();
this.xAjaxResult.fail.reset();
this.xAjaxResult.always.reset();
this.xAjax.reset();
return this.definition.fn($, this.xConfig);
};
});
after(function () {
this.xAjax.restore();
util.restoreHtml();
});
beforeEach(function () {
util.restoreHtml();
$('<div id="content"/>').appendTo('body');
});
describe('definition', function () {
it('is defined', function () {
assert.isPlainObject(this.definition);
});
it('has correct id', function () {
assert.strictEqual(this.definition.id, ID);
});
it('requires correct', function () {
assert.deepEqual(this.definition.deps, DEPS);
});
it('args for each request', function () {
assert.strictEqual(this.definition.deps.length, this.definition.fn.length);
});
it('has no instance', function () {
assert.notProperty(modulejs._private.instances, ID);
});
it('inits without errors', function () {
this.applyFn();
});
});
describe('application', function () {
it('returns undefined', function () {
var instance = this.applyFn();
assert.isUndefined(instance);
});
it('adds HTML #login-wrapper', function () {
this.applyFn();
assert.lengthOf($('#content > #login-wrapper'), 1);
});
describe('no admin', function () {
it('adds HTML #pass', function () {
this.xConfig.setup.AS_ADMIN = false;
this.applyFn();
assert.lengthOf($('#login-wrapper > #pass'), 1);
});
it('sets #pass val to empty string', function () {
this.xConfig.setup.AS_ADMIN = false;
this.applyFn();
assert.strictEqual($('#login-wrapper > #pass').val(), '');
});
it('adds HTML #login', function () {
this.xConfig.setup.AS_ADMIN = false;
this.applyFn();
assert.lengthOf($('#login-wrapper > #login'), 1);
});
it('does not add HTML #logout', function () {
this.xConfig.setup.AS_ADMIN = false;
this.applyFn();
assert.lengthOf($('#login-wrapper > #logout'), 0);
});
it('does not add HTML #tests', function () {
this.xConfig.setup.AS_ADMIN = false;
this.applyFn();
assert.lengthOf($('#content > #tests'), 0);
});
it('login works', function () {
var pass = util.uniqId();
this.xConfig.setup.AS_ADMIN = false;
this.applyFn();
$('#pass').val(pass);
$('#login').trigger('click');
assert.isTrue(this.xAjax.calledOnce);
assert.deepEqual(this.xAjax.lastCall.args, [{
url: 'server/php/index.php',
type: 'POST',
dataType: 'JSON',
data: {
action: 'login',
pass: pass
}
}]);
});
});
describe('as admin', function () {
it('does not add HTML #pass', function () {
this.xConfig.setup.AS_ADMIN = true;
this.applyFn();
assert.lengthOf($('#login-wrapper > #pass'), 0);
});
it('does not add #login', function () {
this.xConfig.setup.AS_ADMIN = true;
this.applyFn();
assert.lengthOf($('#login-wrapper > #login'), 0);
});
it('adds HTML #logout', function () {
this.xConfig.setup.AS_ADMIN = true;
this.applyFn();
assert.lengthOf($('#login-wrapper > #logout'), 1);
});
it('adds HTML #tests', function () {
this.xConfig.setup.AS_ADMIN = true;
this.applyFn();
assert.lengthOf($('#content > #tests'), 1);
});
it('adds HTML #test (14x)', function () {
this.xConfig.setup.AS_ADMIN = true;
this.applyFn();
assert.strictEqual($('#tests > .test').length, 14);
});
it('logout works', function () {
this.xConfig.setup.AS_ADMIN = true;
this.applyFn();
$('#logout').trigger('click');
assert.isTrue(this.xAjax.calledOnce);
assert.deepEqual(this.xAjax.lastCall.args, [{
url: 'server/php/index.php',
type: 'POST',
dataType: 'JSON',
data: {
action: 'logout'
}
}]);
});
});
});
});
}());

View File

@ -0,0 +1,83 @@
(function () {
'use strict';
var ID = 'model/item';
var DEPS = ['_', 'core/event', 'core/location', 'core/server', 'core/settings', 'core/types'];
describe('module "' + ID + '"', function () {
before(function () {
this.definition = modulejs._private.definitions[ID];
this.xTypes = util.uniqObj();
this.xEvent = util.uniqObj();
this.xSettings = util.uniqObj();
this.xServer = util.uniqObj();
this.xLocation = util.uniqObj();
this.applyFn = function () {
return this.definition.fn(_, this.xEvent, this.xLocation, this.xServer, this.xSettings, this.xTypes);
};
});
describe('definition', function () {
it('is defined', function () {
assert.isPlainObject(this.definition);
});
it('has correct id', function () {
assert.strictEqual(this.definition.id, ID);
});
it('requires correct', function () {
assert.deepEqual(this.definition.deps, DEPS);
});
it('args for each request', function () {
assert.strictEqual(this.definition.deps.length, this.definition.fn.length);
});
it('has no instance', function () {
assert.notProperty(modulejs._private.instances, ID);
});
it('inits without errors', function () {
this.applyFn();
});
});
describe('application', function () {
it('returns plain object with 2 properties', function () {
var instance = this.applyFn();
assert.isPlainObject(instance);
assert.lengthOfKeys(instance, 2);
});
});
describe('publics', function () {
it('.get() is function', function () {
var instance = this.applyFn();
assert.isFunction(instance.get);
});
it('.remove() is function', function () {
var instance = this.applyFn();
assert.isFunction(instance.remove);
});
});
});
}());

View File

@ -0,0 +1,48 @@
(function () {
'use strict';
describe('modulejs', function () {
it('is global', function () {
assert.isObject(modulejs);
assert.strictEqual(modulejs, window.modulejs);
});
it('.define() is function', function () {
assert.isFunction(modulejs.define);
});
it('.require() is function', function () {
assert.isFunction(modulejs.require);
});
it('.state() is function', function () {
assert.isFunction(modulejs.state);
});
it('.log() is function', function () {
assert.isFunction(modulejs.log);
});
it('._private is object', function () {
assert.isObject(modulejs._private);
});
it('has definitions', function () {
assert.isAbove(_.keys(modulejs._private.definitions).length, 0);
});
it('has no instances', function () {
assert.lengthOfKeys(modulejs._private.instances, 0);
});
});
}());

View File

@ -0,0 +1,85 @@
(function () {
'use strict';
describe('premisses', function () {
it('window is the global object', function () {
assert.isObject(window);
assert.strictEqual(window, util.GLOBAL);
});
it('util is global object', function () {
assert.isPlainObject(util);
assert.strictEqual(util, window.util);
});
it('util.uniqId() works', function () {
assert.isFunction(util.uniqId);
var uid1 = parseInt(util.uniqId().replace(/\D/g, ''), 10);
assert.isTrue(util.isUniqId(util.uniqId()));
assert.notEqual(util.uniqId(), util.uniqId());
assert.notDeepEqual(util.uniqId(), util.uniqId());
assert.notStrictEqual(util.uniqId(), util.uniqId());
var uid2 = parseInt(util.uniqId().replace(/\D/g, ''), 10);
assert.strictEqual(uid2, uid1 + 8);
});
it('util.uniqObj() works', function () {
assert.isFunction(util.uniqId);
var uid1 = parseInt(util.uniqObj().uniqId.replace(/\D/g, ''), 10);
assert.lengthOfKeys(util.uniqObj(), 1);
assert.isTrue(util.isUniqId(util.uniqObj().uniqId));
assert.notEqual(util.uniqObj(), util.uniqObj());
assert.notDeepEqual(util.uniqObj(), util.uniqObj());
assert.notStrictEqual(util.uniqObj(), util.uniqObj());
assert.notEqual(util.uniqObj().uniqId, util.uniqObj().uniqId);
assert.notDeepEqual(util.uniqObj().uniqId, util.uniqObj().uniqId);
assert.notStrictEqual(util.uniqObj().uniqId, util.uniqObj().uniqId);
var uid2 = parseInt(util.uniqObj().uniqId.replace(/\D/g, ''), 10);
assert.strictEqual(uid2, uid1 + 15);
});
it('assert.isPlainObject() works', function () {
assert.isFunction(assert.isPlainObject);
assert.isPlainObject({});
assert.isPlainObject({a: 1});
assert.isPlainObject(Object());
assert.isPlainObject(new Object());
assert.throws(function () { assert.isPlainObject(); });
assert.throws(function () { assert.isPlainObject(1); });
assert.throws(function () { assert.isPlainObject('a'); });
assert.throws(function () { assert.isPlainObject(new Date()); });
assert.throws(function () { assert.isPlainObject(/a/); });
assert.throws(function () { assert.isPlainObject(function () {}); });
});
it('assert.lengthOfKeys() works', function () {
assert.isFunction(assert.lengthOfKeys);
assert.lengthOfKeys({}, 0);
assert.lengthOfKeys({a: true}, 1);
assert.lengthOfKeys({a: true, b: 0, c: undefined}, 3);
assert.throws(function () { assert.lengthOfKeys(); });
assert.throws(function () { assert.lengthOfKeys(1); });
assert.throws(function () { assert.lengthOfKeys('a'); });
assert.throws(function () { assert.lengthOfKeys({}); });
assert.throws(function () { assert.lengthOfKeys({}, 1); });
});
});
}());

View File

@ -0,0 +1,142 @@
(function () {
'use strict';
var ID = 'view/base';
var DEPS = ['$', 'config'];
describe('module "' + ID + '"', function () {
before(function () {
this.definition = modulejs._private.definitions[ID];
this.xConfig = {setup: {VERSION: util.uniqId()}};
this.applyFn = function () {
return this.definition.fn($, this.xConfig);
};
});
after(function () {
util.restoreHtml();
});
beforeEach(function () {
util.restoreHtml();
$('<div ID="fallback"/>').appendTo('body');
$('<div id="fallback-hints"/>').appendTo('body');
});
describe('definition', function () {
it('is defined', function () {
assert.isPlainObject(this.definition);
});
it('has correct id', function () {
assert.strictEqual(this.definition.id, ID);
});
it('requires correct', function () {
assert.deepEqual(this.definition.deps, DEPS);
});
it('args for each request', function () {
assert.strictEqual(this.definition.deps.length, this.definition.fn.length);
});
it('has no instance', function () {
assert.notProperty(modulejs._private.instances, ID);
});
it('inits without errors', function () {
this.applyFn();
});
});
describe('application', function () {
it('returns undefined', function () {
var instance = this.applyFn();
assert.isUndefined(instance);
});
it('removes HTML #fallback', function () {
this.applyFn();
assert.lengthOf($('#fallback'), 0);
});
it('removes HTML #fallback-hints', function () {
this.applyFn();
assert.lengthOf($('#fallback-hints'), 0);
});
it('adds HTML #topbar', function () {
this.applyFn();
assert.lengthOf($('body > #topbar'), 1);
});
it('adds HTML #toolbar', function () {
this.applyFn();
assert.lengthOf($('#topbar > #toolbar'), 1);
});
it('adds HTML #crumbbar', function () {
this.applyFn();
assert.lengthOf($('#topbar > #crumbbar'), 1);
});
it('adds HTML #main-row', function () {
this.applyFn();
assert.lengthOf($('body > #main-row'), 1);
});
it('adds HTML #sidebar', function () {
this.applyFn();
assert.lengthOf($('#main-row > #sidebar'), 1);
});
it('adds HTML #backlink', function () {
this.applyFn();
assert.lengthOf($('#topbar > #backlink'), 1);
});
it('#backlink has correct href', function () {
this.applyFn();
assert.strictEqual($('#backlink').attr('href'), 'http://larsjung.de/h5ai/');
});
it('#backlink has correct title', function () {
this.applyFn();
assert.strictEqual($('#backlink').attr('title'), 'powered by h5ai ' + this.xConfig.setup.VERSION);
});
it('#backlink has correct text', function () {
this.applyFn();
assert.strictEqual($('#backlink > div').eq(0).text(), 'powered');
assert.strictEqual($('#backlink > div').eq(1).text(), 'by h5ai');
});
});
});
}());

View File

@ -0,0 +1,129 @@
(function () {
'use strict';
var ID = 'view/content';
var DEPS = ['_', '$', 'core/event', 'core/format', 'core/location', 'core/resource', 'core/settings'];
describe('module "' + ID + '"', function () {
before(function () {
this.definition = modulejs._private.definitions[ID];
this.xSettings = util.uniqObj();
this.xResource = {
icon: sinon.stub().returns('/some/path/' + util.uniqId() + '-icon.png')
};
this.xFormat = {
formatSize: sinon.stub().returns(util.uniqId()),
formatDate: sinon.stub().returns(util.uniqId()),
setDefaultMetric: sinon.stub()
};
this.xEvent = {
sub: sinon.stub(),
pub: sinon.stub()
};
this.xLocation = {
setLink: sinon.stub()
};
this.applyFn = function () {
this.xResource.icon.reset();
this.xFormat.formatSize.reset();
this.xFormat.formatDate.reset();
this.xFormat.setDefaultMetric.reset();
this.xEvent.sub.reset();
this.xEvent.pub.reset();
this.xLocation.setLink.reset();
return this.definition.fn(_, $, this.xEvent, this.xFormat, this.xLocation, this.xResource, this.xSettings);
};
});
after(function () {
util.restoreHtml();
});
beforeEach(function () {
util.restoreHtml();
$('<div id="main-row"/>').appendTo('body');
});
describe('definition', function () {
it('is defined', function () {
assert.isPlainObject(this.definition);
});
it('has correct id', function () {
assert.strictEqual(this.definition.id, ID);
});
it('requires correct', function () {
assert.deepEqual(this.definition.deps, DEPS);
});
it('args for each request', function () {
assert.strictEqual(this.definition.deps.length, this.definition.fn.length);
});
it('has no instance', function () {
assert.notProperty(modulejs._private.instances, ID);
});
it('inits without errors', function () {
this.applyFn();
});
});
describe('application', function () {
it('returns undefined', function () {
var instance = this.applyFn();
assert.isUndefined(instance);
});
it('adds HTML #content', function () {
this.applyFn();
assert.lengthOf($('#main-row > #content'), 1);
});
it('sets default metric', function () {
this.applyFn();
assert.isTrue(this.xFormat.setDefaultMetric.calledOnce);
});
it('subscribes to 2 events', function () {
this.applyFn();
assert.isTrue(this.xEvent.sub.calledTwice);
});
it('subscribes to "location.changed"', function () {
this.applyFn();
assert.strictEqual(this.xEvent.sub.firstCall.args[0], 'location.changed');
assert.isFunction(this.xEvent.sub.firstCall.args[1]);
});
it('subscribes to "location.refreshed"', function () {
this.applyFn();
assert.strictEqual(this.xEvent.sub.secondCall.args[0], 'location.refreshed');
assert.isFunction(this.xEvent.sub.secondCall.args[1]);
});
});
});
}());

View File

@ -0,0 +1,127 @@
(function () {
'use strict';
var ID = 'view/sidebar';
var DEPS = ['$', 'core/resource', 'core/store'];
describe('module "' + ID + '"', function () {
before(function () {
this.definition = modulejs._private.definitions[ID];
this.xResource = {
image: sinon.stub().throws('invalid image request')
};
this.xResource.image.withArgs('back').returns('/some/path/' + util.uniqId() + '-back.png');
this.xResource.image.withArgs('sidebar').returns('/some/path/' + util.uniqId() + '-sidebar.png');
this.xStore = {
get: sinon.stub().returns(false),
put: sinon.stub()
};
this.xStore.get.returns(false);
this.applyFn = function () {
this.xResource.image.reset();
this.xStore.get.reset();
this.xStore.put.reset();
return this.definition.fn($, this.xResource, this.xStore);
};
});
after(function () {
util.restoreHtml();
});
beforeEach(function () {
util.restoreHtml();
$('<div id="toolbar"/>').appendTo('body');
$('<div id="sidebar"/>').appendTo('body');
});
describe('definition', function () {
it('is defined', function () {
assert.isPlainObject(this.definition);
});
it('has correct id', function () {
assert.strictEqual(this.definition.id, ID);
});
it('requires correct', function () {
assert.deepEqual(this.definition.deps, DEPS);
});
it('args for each request', function () {
assert.strictEqual(this.definition.deps.length, this.definition.fn.length);
});
it('has no instance', function () {
assert.notProperty(modulejs._private.instances, ID);
});
it('inits without errors', function () {
this.instance = this.applyFn();
});
});
describe('application', function () {
it('returns undefined', function () {
var instance = this.applyFn();
assert.isUndefined(instance);
});
it('adds HTML #sidebar-toggle', function () {
this.applyFn();
assert.lengthOf($('#toolbar > #sidebar-toggle'), 1);
});
it('toggle works', function () {
this.applyFn();
assert.lengthOf($('#sidebar:visible'), 0);
this.xStore.get.returns(false).reset();
this.xStore.put.reset();
$('#sidebar-toggle').trigger('click');
assert.isTrue(this.xStore.get.calledOnce);
assert.strictEqual(this.xStore.get.lastCall.args[0], 'sidebarIsVisible');
assert.isTrue(this.xStore.put.calledOnce);
assert.strictEqual(this.xStore.put.lastCall.args[0], 'sidebarIsVisible');
assert.isTrue(this.xStore.put.lastCall.args[1]);
assert.lengthOf($('#sidebar:visible'), 1);
this.xStore.get.returns(true).reset();
this.xStore.put.reset();
$('#sidebar-toggle').trigger('click');
assert.isTrue(this.xStore.get.calledOnce);
assert.strictEqual(this.xStore.get.lastCall.args[0], 'sidebarIsVisible');
assert.isTrue(this.xStore.put.calledOnce);
assert.strictEqual(this.xStore.put.lastCall.args[0], 'sidebarIsVisible');
assert.isFalse(this.xStore.put.lastCall.args[1]);
assert.lengthOf($('#sidebar:visible'), 0);
});
});
});
}());

View File

@ -0,0 +1,117 @@
(function () {
'use strict';
var ID = 'view/viewmode';
var DEPS = ['_', '$', 'core/event', 'core/resource', 'core/settings', 'core/store'];
describe('module "' + ID + '"', function () {
before(function () {
this.definition = modulejs._private.definitions[ID];
this.xSettings = {
view: {}
};
this.xResource = {
image: sinon.stub().returns('/some/path/' + util.uniqId() + '.png')
};
this.xStore = {
get: sinon.stub(),
put: sinon.stub()
};
this.xEvent = {
sub: sinon.stub()
};
this.applyFn = function () {
this.xResource.image.reset();
this.xStore.get.reset();
this.xStore.put.reset();
this.xEvent.sub.reset();
return this.definition.fn(_, $, this.xEvent, this.xResource, this.xSettings, this.xStore);
};
});
after(function () {
util.restoreHtml();
});
beforeEach(function () {
util.restoreHtml();
$('<div id="sidebar"/>').appendTo('body');
});
describe('definition', function () {
it('is defined', function () {
assert.isPlainObject(this.definition);
});
it('has correct id', function () {
assert.strictEqual(this.definition.id, ID);
});
it('requires correct', function () {
assert.deepEqual(this.definition.deps, DEPS);
});
it('args for each request', function () {
assert.strictEqual(this.definition.deps.length, this.definition.fn.length);
});
it('has no instance', function () {
assert.notProperty(modulejs._private.instances, ID);
});
it('inits without errors', function () {
this.applyFn();
});
});
describe('application', function () {
it('returns undefined', function () {
var instance = this.applyFn();
assert.isUndefined(instance);
});
it('adds HTML', function () {
this.applyFn();
assert.lengthOf($('#sidebar > .block > .l10n-view'), 1);
});
it('adds Style', function () {
var styleTagCount = $('head > style').length;
this.applyFn();
assert.lengthOf($('head > style'), styleTagCount + 1);
});
it('subscribes to 1 event', function () {
this.applyFn();
assert.isTrue(this.xEvent.sub.calledOnce);
});
it('subscribes to "location.changed"', function () {
this.applyFn();
assert.strictEqual(this.xEvent.sub.firstCall.args[0], 'location.changed');
assert.isFunction(this.xEvent.sub.firstCall.args[1]);
});
});
});
}());

View File

@ -0,0 +1,18 @@
(function () {
'use strict';
chai.Assertion.addChainableMethod('isPlainObject', function () {
this.assert(
_.isPlainObject(this._obj),
'expected ' + this._obj + ' to be a plain Object',
'expected ' + this._obj + ' not to be a plain Object'
);
});
chai.assert.isPlainObject = function (val, msg) {
new chai.Assertion(val, msg).to.be.isPlainObject();
};
}());

View File

@ -0,0 +1,20 @@
(function () {
'use strict';
chai.Assertion.addChainableMethod('lengthOfKeys', function (count) {
var keyCount = _.keys(this._obj).length;
this.assert(
keyCount === count,
'expected ' + this._obj + ' to have ' + count + ' keys, but has ' + keyCount,
'expected ' + this._obj + ' not to have ' + count + ' keys, but has ' + keyCount
);
});
chai.assert.lengthOfKeys = function (val, count, msg) {
new chai.Assertion(val, msg).to.be.lengthOfKeys(count);
};
}());

2
test/util/global.js Normal file
View File

@ -0,0 +1,2 @@
window.util = window.util || {};
window.util.GLOBAL = this;

23
test/util/pin.js Normal file
View File

@ -0,0 +1,23 @@
(function () {
'use strict';
var htmlClasses;
var $pinnedElements;
function pinHtml() {
htmlClasses = $('html').attr('class');
$pinnedElements = $('head,body').children();
}
function restoreHtml() {
$('html').attr('class', htmlClasses);
$('head,body').children().not($pinnedElements).remove();
}
window.util = window.util || {};
window.util.pinHtml = pinHtml;
window.util.restoreHtml = restoreHtml;
}());

32
test/util/uniq.js Normal file
View File

@ -0,0 +1,32 @@
(function () {
'use strict';
var PREFIX = 'UQ';
var SUFFIX = 'ID';
var LENGTH = 4;
var RE = new RegExp('^' + PREFIX + '\\d{' + LENGTH + '}' + SUFFIX + '$');
var counter = 0;
function uniqId() {
counter += 1;
return PREFIX + ('00000000' + counter).substr(-LENGTH) + SUFFIX;
}
function uniqObj() {
return {uniqId: uniqId()};
}
function isUniqId(uid) {
return RE.test(uid);
}
window.util = window.util || {};
window.util.uniqId = uniqId;
window.util.uniqObj = uniqObj;
window.util.isUniqId = isUniqId;
}());