• R/O
  • HTTP
  • SSH
  • HTTPS

master: Commit

embrj master repositories


Commit MetaInfo

Revisione4e2495ca24f6da4fd222ae6e043105f3055ca8f (tree)
Zeit2019-05-19 03:51:47
Autorjianghgr <jianghgr@user...>
Commiterjianghgr

Log Message

GeorgeValergas/embrr

Ändern Zusammenfassung

Diff

--- /dev/null
+++ b/Gruntfile.js
@@ -0,0 +1,365 @@
1+// Generated on 2013-12-27 using generator-ember 0.8.0
2+'use strict';
3+var LIVERELOAD_PORT = 35729;
4+var lrSnippet = require('connect-livereload')({port: LIVERELOAD_PORT});
5+var mountFolder = function (connect, dir) {
6+ return connect.static(require('path').resolve(dir));
7+};
8+
9+// # Globbing
10+// for performance reasons we're only matching one level down:
11+// 'test/spec/{,*/}*.js'
12+// use this if you want to match all subfolders:
13+// 'test/spec/**/*.js'
14+
15+module.exports = function (grunt) {
16+ // show elapsed time at the end
17+ require('time-grunt')(grunt);
18+ // load all grunt tasks
19+ require('load-grunt-tasks')(grunt);
20+
21+ // configurable paths
22+ var yeomanConfig = {
23+ app: 'app',
24+ dist: 'dist'
25+ };
26+
27+ grunt.initConfig({
28+ yeoman: yeomanConfig,
29+ watch: {
30+ emberTemplates: {
31+ files: '<%= yeoman.app %>/templates/**/*.hbs',
32+ tasks: ['emberTemplates']
33+ },
34+ compass: {
35+ files: ['<%= yeoman.app %>/styles/{,*/}*.{scss,sass}'],
36+ tasks: ['compass:server']
37+ },
38+ neuter: {
39+ files: ['<%= yeoman.app %>/scripts/{,*/}*.js'],
40+ tasks: ['neuter']
41+ },
42+ livereload: {
43+ options: {
44+ livereload: LIVERELOAD_PORT
45+ },
46+ files: [
47+ '.tmp/scripts/*.js',
48+ '<%= yeoman.app %>/*.html',
49+ '{.tmp,<%= yeoman.app %>}/styles/{,*/}*.css',
50+ '<%= yeoman.app %>/images/{,*/}*.{png,jpg,jpeg,gif,webp,svg}'
51+ ]
52+ }
53+ },
54+ connect: {
55+ options: {
56+ port: 9000,
57+ // change this to '0.0.0.0' to access the server from outside
58+ hostname: 'localhost'
59+ },
60+ livereload: {
61+ options: {
62+ middleware: function (connect) {
63+ return [
64+ lrSnippet,
65+ mountFolder(connect, '.tmp'),
66+ mountFolder(connect, yeomanConfig.app)
67+ ];
68+ }
69+ }
70+ },
71+ test: {
72+ options: {
73+ middleware: function (connect) {
74+ return [
75+ mountFolder(connect, '.tmp'),
76+ mountFolder(connect, 'test')
77+ ];
78+ }
79+ }
80+ },
81+ dist: {
82+ options: {
83+ middleware: function (connect) {
84+ return [
85+ mountFolder(connect, yeomanConfig.dist)
86+ ];
87+ }
88+ }
89+ }
90+ },
91+ open: {
92+ server: {
93+ path: 'http://localhost:<%= connect.options.port %>'
94+ }
95+ },
96+ clean: {
97+ dist: {
98+ files: [{
99+ dot: true,
100+ src: [
101+ '.tmp',
102+ '<%= yeoman.dist %>/*',
103+ '!<%= yeoman.dist %>/.git*'
104+ ]
105+ }]
106+ },
107+ server: '.tmp'
108+ },
109+ jshint: {
110+ options: {
111+ jshintrc: '.jshintrc',
112+ reporter: require('jshint-stylish')
113+ },
114+ all: [
115+ 'Gruntfile.js',
116+ '<%= yeoman.app %>/scripts/{,*/}*.js',
117+ '!<%= yeoman.app %>/scripts/vendor/*',
118+ 'test/spec/{,*/}*.js'
119+ ]
120+ },
121+ mocha: {
122+ all: {
123+ options: {
124+ run: true,
125+ urls: ['http://localhost:<%= connect.options.port %>/index.html']
126+ }
127+ }
128+ },
129+ compass: {
130+ options: {
131+ sassDir: '<%= yeoman.app %>/styles',
132+ cssDir: '.tmp/styles',
133+ generatedImagesDir: '.tmp/images/generated',
134+ imagesDir: '<%= yeoman.app %>/images',
135+ javascriptsDir: '<%= yeoman.app %>/scripts',
136+ fontsDir: '<%= yeoman.app %>/styles/fonts',
137+ importPath: 'app/bower_components',
138+ httpImagesPath: '/images',
139+ httpGeneratedImagesPath: '/images/generated',
140+ httpFontsPath: '/styles/fonts',
141+ relativeAssets: false
142+ },
143+ dist: {},
144+ server: {
145+ options: {
146+ debugInfo: true
147+ }
148+ }
149+ },
150+ // not used since Uglify task does concat,
151+ // but still available if needed
152+ /*concat: {
153+ dist: {}
154+ },*/
155+ // not enabled since usemin task does concat and uglify
156+ // check index.html to edit your build targets
157+ // enable this task if you prefer defining your build targets here
158+ /*uglify: {
159+ dist: {}
160+ },*/
161+ rev: {
162+ dist: {
163+ files: {
164+ src: [
165+ '<%= yeoman.dist %>/scripts/{,*/}*.js',
166+ '<%= yeoman.dist %>/styles/{,*/}*.css',
167+ '<%= yeoman.dist %>/images/{,*/}*.{png,jpg,jpeg,gif,webp}',
168+ '<%= yeoman.dist %>/styles/fonts/*'
169+ ]
170+ }
171+ }
172+ },
173+ useminPrepare: {
174+ html: '.tmp/index.html',
175+ options: {
176+ dest: '<%= yeoman.dist %>'
177+ }
178+ },
179+ usemin: {
180+ html: ['<%= yeoman.dist %>/{,*/}*.html'],
181+ css: ['<%= yeoman.dist %>/styles/{,*/}*.css'],
182+ options: {
183+ dirs: ['<%= yeoman.dist %>']
184+ }
185+ },
186+ imagemin: {
187+ dist: {
188+ files: [{
189+ expand: true,
190+ cwd: '<%= yeoman.app %>/images',
191+ src: '{,*/}*.{png,jpg,jpeg}',
192+ dest: '<%= yeoman.dist %>/images'
193+ }]
194+ }
195+ },
196+ svgmin: {
197+ dist: {
198+ files: [{
199+ expand: true,
200+ cwd: '<%= yeoman.app %>/images',
201+ src: '{,*/}*.svg',
202+ dest: '<%= yeoman.dist %>/images'
203+ }]
204+ }
205+ },
206+ cssmin: {
207+ dist: {
208+ files: {
209+ '<%= yeoman.dist %>/styles/main.css': [
210+ '.tmp/styles/{,*/}*.css',
211+ '<%= yeoman.app %>/styles/{,*/}*.css'
212+ ]
213+ }
214+ }
215+ },
216+ htmlmin: {
217+ dist: {
218+ options: {
219+ /*removeCommentsFromCDATA: true,
220+ // https://github.com/yeoman/grunt-usemin/issues/44
221+ //collapseWhitespace: true,
222+ collapseBooleanAttributes: true,
223+ removeAttributeQuotes: true,
224+ removeRedundantAttributes: true,
225+ useShortDoctype: true,
226+ removeEmptyAttributes: true,
227+ removeOptionalTags: true*/
228+ },
229+ files: [{
230+ expand: true,
231+ cwd: '<%= yeoman.app %>',
232+ src: '*.html',
233+ dest: '<%= yeoman.dist %>'
234+ }]
235+ }
236+ },
237+ replace: {
238+ app: {
239+ options: {
240+ variables: {
241+ ember: 'bower_components/ember/ember.js',
242+ ember_data: 'bower_components/ember-data-shim/ember-data.js'
243+ }
244+ },
245+ files: [
246+ {src: '<%= yeoman.app %>/index.html', dest: '.tmp/index.html'}
247+ ]
248+ },
249+ dist: {
250+ options: {
251+ variables: {
252+ ember: 'bower_components/ember/ember.prod.js',
253+ ember_data: 'bower_components/ember-data-shim/ember-data.prod.js'
254+ }
255+ },
256+ files: [
257+ {src: '<%= yeoman.app %>/index.html', dest: '.tmp/index.html'}
258+ ]
259+ }
260+ },
261+ // Put files not handled in other tasks here
262+ copy: {
263+ dist: {
264+ files: [{
265+ expand: true,
266+ dot: true,
267+ cwd: '<%= yeoman.app %>',
268+ dest: '<%= yeoman.dist %>',
269+ src: [
270+ '*.{ico,txt}',
271+ '.htaccess',
272+ 'images/{,*/}*.{webp,gif}',
273+ 'styles/fonts/*'
274+ ]
275+ }]
276+ }
277+ },
278+ concurrent: {
279+ server: [
280+ 'emberTemplates',
281+ 'compass:server'
282+ ],
283+ test: [
284+ 'emberTemplates',
285+ 'compass'
286+ ],
287+ dist: [
288+ 'emberTemplates',
289+ 'compass:dist',
290+ 'imagemin',
291+ 'svgmin',
292+ 'htmlmin'
293+ ]
294+ },
295+ emberTemplates: {
296+ options: {
297+ templateName: function (sourceFile) {
298+ var templatePath = yeomanConfig.app + '/templates/';
299+ return sourceFile.replace(templatePath, '');
300+ }
301+ },
302+ dist: {
303+ files: {
304+ '.tmp/scripts/compiled-templates.js': '<%= yeoman.app %>/templates/{,*/}*.hbs'
305+ }
306+ }
307+ },
308+ neuter: {
309+ app: {
310+ options: {
311+ filepathTransform: function (filepath) {
312+ return 'app/' + filepath;
313+ }
314+ },
315+ src: '<%= yeoman.app %>/scripts/app.js',
316+ dest: '.tmp/scripts/combined-scripts.js'
317+ }
318+ }
319+ });
320+
321+ grunt.registerTask('server', function (target) {
322+ if (target === 'dist') {
323+ return grunt.task.run(['build', 'open', 'connect:dist:keepalive']);
324+ }
325+
326+ grunt.task.run([
327+ 'clean:server',
328+ 'replace:app',
329+ 'concurrent:server',
330+ 'neuter:app',
331+ 'connect:livereload',
332+ 'open',
333+ 'watch'
334+ ]);
335+ });
336+
337+ grunt.registerTask('test', [
338+ 'clean:server',
339+ 'replace:app',
340+ 'concurrent:test',
341+ 'connect:test',
342+ 'neuter:app',
343+ 'mocha'
344+ ]);
345+
346+ grunt.registerTask('build', [
347+ 'clean:dist',
348+ 'replace:dist',
349+ 'useminPrepare',
350+ 'concurrent:dist',
351+ 'neuter:app',
352+ 'concat',
353+ 'cssmin',
354+ 'uglify',
355+ 'copy',
356+ 'rev',
357+ 'usemin'
358+ ]);
359+
360+ grunt.registerTask('default', [
361+ 'jshint',
362+ 'test',
363+ 'build'
364+ ]);
365+};
--- a/README.md
+++ b/README.md
@@ -1,87 +1,3 @@
1-embrr, a fork from embr
2-========
3-This is a twitter web client fork from [embr](https://code.google.com/p/embr/), mainly based on `r91` and merged necessary changes until the latest revisions, updated to Twitter REST API `v1.1` and have some improved features.
1+#They __recommended__ that I should add a README...
42
5-You can download the zip archive of current version [here](https://github.com/AstroProfundis/embrr/zipball/master) if you don't want to use `git-clone`.
6-
7-How to Install
8---------
9-The installation of embrr is pretty much the same with embr's, you just need to get the source, rename `config.sample.php` in `/lib` to `config.php`, edit it with your own app information and upload it to your hosting directory.
10-
11-And here are some tips you may want to know:
12-
13- * embrr requires `php-curl` and `php-bcmath`
14- * while not necessarily required, `php-mcrypt` is recommended
15- * embrr is compatible with PHP from version 5.2 to 5.5, we didn't test it on 5.1 or older versions
16-
17-Installing in sub-directory
18---------
19-If you need to install embrr in a sub-directory of your website, say, in `/embrr`, you'll need to adjust the `.htaccess` file with `/embrr/user.php` and `/embrr/status.php` instead of `/user.php` and `/status.php`.
20-
21-nginx
22---------
23-For nginx users, you'll need to add these lines to your nginx config file:
24-
25- location / {
26- if (!-f $request_filename) {
27- rewrite ^/(\d+)$ /status.php?id=$1 last;
28- rewrite ^/(\w+)$ /user.php?id=$1 last;
29- break;
30- }
31- }
32-And of course, adjust it if you are in a sub-directory.
33-
34-Notes
35---------
36-If you're having issues changing pages or sending DMs, try modify your `php.ini` as follows:
37-
38- precision = 24 ;Use a value lager than 19 to replace the default 14
39-
40-----
41-
42-embrr, 一个修改版的 embr
43-========
44-
45-这是一个从 [embr](https://code.google.com/p/embr/) 修改而来的 twitter 网页端,主要基于 `r91` 版本并合并了后续修订版的必要更新,升级到了 Twitter REST API `v1.1` 并有一些功能上的改进。
46-
47-如果不想使用 `git-clone` 获取代码,可以点[这里](https://github.com/AstroProfundis/embrr/zipball/master)下载当前版本的 zip 压缩包。
48-
49-安装方法
50---------
51-安装 embrr 的方法和 embr 原版基本相同,只需要下载代码包,重命名 `/lib` 中的 `config.sample.php` 文件为 `config.php`, 编辑此配置文件填入适当的 app 信息,再将代码上传至网站空间即可。
52-
53-有几点值得注意的地方是:
54-
55- * embrr 依赖于 `php-curl` 和 `php-bcmath` 组件
56- * 虽然不是必需依赖,但建议安装 `php-mcrypt` 组件
57- * embrr 兼容 PHP 5.2 至 5.5 的版本,我们没有测试过 5.1 及之前版本
58-
59-在二级目录中安装
60---------
61-如果需要将 embrr 安装在二级目录中,例如安装在 `/embrr` 中,则需要修改 `.htaccess` 文件,使用 `/embrr/user.php` 与 `/embrr/status.php` 替换 `/user.php` 和 `/status.php`.
62-
63-nginx
64---------
65-对于 nginx 用户,需要在配置文件中加入以下代码:
66-
67- location / {
68- if (!-f $request_filename) {
69- rewrite ^/(\d+)$ /status.php?id=$1 last;
70- rewrite ^/(\w+)$ /user.php?id=$1 last;
71- break;
72- }
73- }
74-同样,如果在二级目录中安装则需适当调整。
75-
76-附注
77---------
78-如果翻页或者发送 DM 时遇到问题,尝试在 `php.ini` 中做如下修改:
79-
80- precision = 24 ;使用大于 19 的值替换默认值 14
81-
82-----
83-As I'm not an expert of PHP nor twitter API, do expect bugs everywhere.
84-
85-All helps are welcomed!
86-
87-请做好 bug 满天飞的心理准备以及欢迎拍砖和协助修改。
3+_No reason to yell, yeesh_
--- /dev/null
+++ b/app/index.html
@@ -0,0 +1,42 @@
1+<!doctype html>
2+<html>
3+ <head>
4+ <meta charset="utf-8">
5+ <title>Yeoman Ember Starter Kit</title>
6+
7+ <!-- build:css styles/main.css -->
8+ <link rel="stylesheet" href="styles/style.css">
9+ <!-- endbuild -->
10+</head>
11+ <body>
12+ <!-- build:js(app) scripts/components.js -->
13+ <script src="bower_components/jquery/jquery.js"></script>
14+ <script src="bower_components/handlebars/handlebars.runtime.js"></script>
15+ <script src="@@ember"></script>
16+ <script src="@@ember_data"></script>
17+ <!-- endbuild -->
18+
19+ <!-- build:js(.tmp) scripts/templates.js -->
20+ <script src="scripts/compiled-templates.js"></script>
21+ <!-- endbuild -->
22+
23+ <!-- build:js(.tmp) scripts/main.js -->
24+ <script src="scripts/combined-scripts.js"></script>
25+ <!-- endbuild -->
26+
27+ <!-- build:js scripts/plugins.js -->
28+ <script src="bower_components/bootstrap-sass/js/affix.js"></script>
29+ <script src="bower_components/bootstrap-sass/js/alert.js"></script>
30+ <script src="bower_components/bootstrap-sass/js/dropdown.js"></script>
31+ <script src="bower_components/bootstrap-sass/js/tooltip.js"></script>
32+ <script src="bower_components/bootstrap-sass/js/modal.js"></script>
33+ <script src="bower_components/bootstrap-sass/js/transition.js"></script>
34+ <script src="bower_components/bootstrap-sass/js/button.js"></script>
35+ <script src="bower_components/bootstrap-sass/js/popover.js"></script>
36+ <script src="bower_components/bootstrap-sass/js/carousel.js"></script>
37+ <script src="bower_components/bootstrap-sass/js/scrollspy.js"></script>
38+ <script src="bower_components/bootstrap-sass/js/collapse.js"></script>
39+ <script src="bower_components/bootstrap-sass/js/tab.js"></script>
40+ <!-- endbuild -->
41+</body>
42+</html>
--- /dev/null
+++ b/app/scripts/app.js
@@ -0,0 +1,9 @@
1+var Embrr = window.Embrr = Ember.Application.create();
2+
3+/* Order and include as you please. */
4+require('scripts/controllers/*');
5+require('scripts/store');
6+require('scripts/models/*');
7+require('scripts/routes/*');
8+require('scripts/views/*');
9+require('scripts/router');
--- /dev/null
+++ b/app/scripts/routes/application_route.js
@@ -0,0 +1,7 @@
1+Embrr.ApplicationRoute = Ember.Route.extend({
2+ // admittedly, this should be in IndexRoute and not in the
3+ // top level ApplicationRoute; we're in transition... :-)
4+ model: function () {
5+ return ['red', 'yellow', 'blue'];
6+ }
7+});
--- /dev/null
+++ b/app/scripts/store.js
@@ -0,0 +1,2 @@
1+Embrr.Store = DS.Store.extend();
2+Embrr.ApplicationAdapter = DS.FixtureAdapter;
--- /dev/null
+++ b/app/styles/style.scss
@@ -0,0 +1,6 @@
1+@import "bootstrap-sass/lib/bootstrap";
2+
3+/* Put your CSS here */
4+html, body {
5+ margin: 30px 0;
6+}
--- /dev/null
+++ b/app/templates/application.hbs
@@ -0,0 +1,34 @@
1+<div>
2+ <nav class="navbar navbar-default navbar-fixed-top" role="navigation">
3+ <div class="navbar-header">
4+ <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-ex1-collapse">
5+ <span class="sr-only">Toggle navigation</span>
6+ <span class="icon-bar"></span>
7+ <span class="icon-bar"></span>
8+ <span class="icon-bar"></span>
9+ </button>
10+ <a class="navbar-brand" href="#">Your App</a>
11+ </div>
12+ <div class="collapse navbar-collapse navbar-ex1-collapse">
13+ </div>
14+ </nav>
15+ <div class="container" id="main">
16+ <div class="row">
17+ <div>
18+ <div class="col-md-3">
19+ <div class="well sidebar-nav">
20+ <strong>Colors</strong>
21+ <ul class="list-group">
22+ {{#each item in controller}}
23+ <li class="list-group-item">{{item}}</li>
24+ {{/each}}
25+ </ul>
26+ </div>
27+ </div>
28+ <div class="col-md-9">
29+ {{outlet}}
30+ </div>
31+ </div>
32+ </div>
33+ </div>
34+</div>
--- /dev/null
+++ b/app/templates/index.hbs
@@ -0,0 +1,3 @@
1+<div class="well">
2+ Welcome to Yeoman and Ember.js!
3+</div>
--- /dev/null
+++ b/bower.json
@@ -0,0 +1,16 @@
1+{
2+ "name": "embrr",
3+ "version": "0.0.0",
4+ "dependencies": {
5+ "ember": "1.2.0",
6+ "ember-data-shim": "1.0.0-beta.2",
7+ "bootstrap-sass": "~3.0.0"
8+
9+ },
10+ "resolutions": {
11+ "ember": "1.0.0"
12+ },
13+ "devDependencies": {
14+ "ember-mocha-adapter": "0.1.2"
15+ }
16+}
--- /dev/null
+++ b/package.json
@@ -0,0 +1,36 @@
1+{
2+ "name": "embrr",
3+ "version": "0.0.0",
4+ "dependencies": {},
5+ "devDependencies": {
6+ "grunt": "~0.4.1",
7+ "grunt-contrib-copy": "~0.4.1",
8+ "grunt-contrib-concat": "~0.3.0",
9+ "grunt-contrib-coffee": "~0.7.0",
10+ "grunt-contrib-uglify": "~0.2.0",
11+ "grunt-contrib-compass": "~0.5.0",
12+ "grunt-contrib-jshint": "~0.6.3",
13+ "grunt-contrib-cssmin": "~0.6.0",
14+ "grunt-contrib-connect": "~0.3.0",
15+ "grunt-contrib-clean": "~0.5.0",
16+ "grunt-contrib-htmlmin": "~0.1.3",
17+ "grunt-contrib-imagemin": "~0.2.0",
18+ "grunt-contrib-watch": "~0.5.2",
19+ "grunt-rev": "~0.1.0",
20+ "grunt-usemin": "~0.1.12",
21+ "grunt-mocha": "~0.4.1",
22+ "grunt-open": "~0.2.0",
23+ "grunt-svgmin": "~0.2.0",
24+ "grunt-concurrent": "~0.3.0",
25+ "load-grunt-tasks": "~0.1.0",
26+ "connect-livereload": "~0.2.0",
27+ "grunt-ember-templates": "0.4.14",
28+ "time-grunt": "~0.1.1",
29+ "grunt-replace": "~0.4.4",
30+ "jshint-stylish": "~0.1.3",
31+ "grunt-neuter": "~0.5.0"
32+ },
33+ "engines": {
34+ "node": ">=0.8.0"
35+ }
36+}
--- /dev/null
+++ b/test/.bowerrc
@@ -0,0 +1,3 @@
1+{
2+ "directory": "bower_components"
3+}
--- /dev/null
+++ b/test/bower.json
@@ -0,0 +1,9 @@
1+{
2+ "name": "embrr",
3+ "private": true,
4+ "dependencies": {
5+ "chai": "~1.8.0",
6+ "mocha": "~1.14.0"
7+ },
8+ "devDependencies": {}
9+}
--- /dev/null
+++ b/test/bower_components/chai/.bower.json
@@ -0,0 +1,37 @@
1+{
2+ "name": "chai",
3+ "version": "1.8.1",
4+ "description": "BDD/TDD assertion library for node.js and the browser. Test framework agnostic.",
5+ "license": "MIT",
6+ "keywords": [
7+ "test",
8+ "assertion",
9+ "assert",
10+ "testing",
11+ "chai"
12+ ],
13+ "main": "chai.js",
14+ "ignore": [
15+ "build",
16+ "components",
17+ "lib",
18+ "node_modules",
19+ "support",
20+ "test",
21+ "index.js",
22+ "Makefile",
23+ ".*"
24+ ],
25+ "dependencies": {},
26+ "devDependencies": {},
27+ "homepage": "https://github.com/chaijs/chai",
28+ "_release": "1.8.1",
29+ "_resolution": {
30+ "type": "version",
31+ "tag": "1.8.1",
32+ "commit": "4107c02cb1507c8554177aeeefd9732abcfd4e64"
33+ },
34+ "_source": "git://github.com/chaijs/chai.git",
35+ "_target": "~1.8.0",
36+ "_originalSource": "chai"
37+}
\ No newline at end of file
--- /dev/null
+++ b/test/bower_components/chai/History.md
@@ -0,0 +1,829 @@
1+
2+1.8.1 / 2013-10-10
3+==================
4+
5+ * pkg: update deep-eql version
6+
7+1.8.0 / 2013-09-18
8+==================
9+
10+ * test: [sauce] add a few more browsers
11+ * Merge branch 'refactor/deep-equal'
12+ * util: remove embedded deep equal utility
13+ * util: replace embedded deep equal with external module
14+ * Merge branch 'feature/karma'
15+ * docs: add sauce badge to readme [ci skip]
16+ * test: [sauce] use karma@canary to prevent timeouts
17+ * travis: only run on node 0.10
18+ * test: [karma] use karma phantomjs runner
19+ * Merge pull request #181 from tricknotes/fix-highlight
20+ * Fix highlight for example code
21+
22+1.7.2 / 2013-06-27
23+==================
24+
25+ * coverage: add coveralls badge
26+ * test: [coveralls] add coveralls api integration. testing travis-ci integration
27+ * Merge branch 'master' of github.com:chaijs/chai
28+ * Merge branch 'feature/bower'
29+ * Merge pull request #180 from tricknotes/modify-method-title
30+ * Merge pull request #179 from tricknotes/highlight-code-example
31+ * Modify method title to include argument name
32+ * Fix to highlight code example
33+ * bower: granular ignores
34+
35+1.7.1 / 2013-06-24
36+==================
37+
38+ * Merge branch 'feature/bower'. #175
39+ * bower: add json file
40+ * build: browser
41+
42+1.7.0 / 2013-06-17
43+==================
44+
45+ * error: remove internal assertion error constructor
46+ * core: [assertion-error] replace internal assertion error with dep
47+ * deps: add chaijs/assertion-error@1.0.0
48+ * docs: fix typo in source file. #174
49+ * Merge pull request #174 from piecioshka/master
50+ * typo
51+ * Merge branch 'master' of github.com:chaijs/chai
52+ * pkg: lock mocha/mocha-phantomjs versions (for now)
53+ * Merge pull request #173 from chaijs/inspect-fix
54+ * Fix `utils.inspect` with custom object-returning inspect()s.
55+ * Merge pull request #171 from Bartvds/master
56+ * replaced tabs with 2 spaces
57+ * added assert.notOk()
58+ * Merge pull request #169 from katsgeorgeek/topics/master
59+ * Fix comparison objects.
60+
61+1.6.1 / 2013-06-05
62+==================
63+
64+ * Merge pull request #168 from katsgeorgeek/topics/master
65+ * Add test for different RegExp flags.
66+ * Add test for regexp comparison.
67+ * Downgrade mocha version for fix running Phantom tests.
68+ * Fix comparison equality of two regexps.
69+ * Merge pull request #161 from brandonpayton/master
70+ * Fix documented name for assert interfaces isDefined method
71+
72+1.6.0 / 2013-04-29
73+==================
74+
75+ * build: browser
76+ * assert: [(not)include] throw on incompatible haystack. Closes #142
77+ * assert: [notInclude] add assert.notInclude. Closes #158
78+ * browser build
79+ * makefile: force browser build on browser-test
80+ * makefile: use component for browser build
81+ * core: [assertions] remove extraneous comments
82+ * Merge branch 'master' of github.com:chaijs/chai
83+ * test: [assert] deep equal ordering
84+ * Merge pull request #153 from NickHeiner/array-assertions
85+ * giving members a no-flag assertion
86+ * Code review comments - changing syntax
87+ * Code review comments
88+ * Adding members and memberEquals assertions for checking for subsets and set equality. Implements chaijs/chai#148.
89+ * Merge pull request #140 from RubenVerborgh/function-prototype
90+ * Restore the `call` and `apply` methods of Function when adding a chainable method.
91+ * readme: 2013
92+ * notes: migration notes for deep equal changes
93+ * test: for ever err() there must be a passing version
94+
95+1.5.0 / 2013-02-03
96+==================
97+
98+ * docs: add Release Notes for non-gitlog summary of changes.
99+ * lib: update copyright to 2013
100+ * Merge branch 'refactor/travis'
101+ * makefile: remove test-component for full test run
102+ * pkg: script test now runs make test so travis will test browser
103+ * browser: build
104+ * tests: refactor some tests to support new objDisplay output
105+ * test: [bootstrap] normalize boostrap across all test scenarios
106+ * assertions: refactor some assertions to use objDisplay instead of inspect
107+ * util: [objDisplay] normalize output of functions
108+ * makefile: refactor for full build scenarios
109+ * component: fix build bug where missing util:type file
110+ * assertions: [throw] code cleanup
111+ * Merge branch 'refactor/typeDetection'
112+ * browser: build
113+ * makefile: chai.js is .PHONY so it builds every time
114+ * test: [expect] add arguments type detection test
115+ * core/assertions: [type] (a/an) refactor to use type detection utility
116+ * util: add cross-browser type detection utility
117+ * Merge branch 'feature/component'
118+ * browser: build
119+ * component: add component.json file
120+ * makefile: refactor for fine grain control of testing scenarios
121+ * test: add mochaPhantomJS support and component test file
122+ * deps: add component and mocha-phantomjs for browser testing
123+ * ignore: update ignore files for component support
124+ * travis: run for all branches
125+ * Merge branch 'feature/showDiff'
126+ * test: [Assertion] configruable showDiff flag. Closes #132
127+ * lib: [Assertion] add configurable showDiff flag. #132
128+ * Merge branch 'feature/saucelabs'
129+ * Merge branch 'master' into feature/saucelabs
130+ * browser: build
131+ * support: add mocha cloud runner, client, and html test page
132+ * test: [saucelabs] add auth placeholder
133+ * deps: add mocha-cloud
134+ * Merge pull request #136 from whatthejeff/message_fix
135+ * Merge pull request #138 from timnew/master
136+ * Fix issue #137, test message existence by using message!=null rather than using message
137+ * Fixed backwards negation messages.
138+ * Merge pull request #133 from RubenVerborgh/throw
139+ * Functions throwing strings can reliably be tested.
140+ * Merge pull request #131 from RubenVerborgh/proto
141+ * Cache whether __proto__ is supported.
142+ * Use __proto__ if available.
143+ * Determine the property names to exclude beforehand.
144+ * Merge pull request #126 from RubenVerborgh/eqls
145+ * Add alias eqls for eql.
146+ * Use inherited enumerable properties in deep equality comparison.
147+ * Show inherited properties when inspecting an object.
148+ * Add new getProperties and getEnumerableProperties utils.
149+ * showDiff: force true for equal and eql
150+
151+1.4.2 / 2012-12-21
152+==================
153+
154+ * browser build: (object diff support when used with mocha) #106
155+ * test: [display] array test for mocha object diff
156+ * browser: no longer need different AssertionError constructor
157+
158+1.4.1 / 2012-12-21
159+==================
160+
161+ * showDiff: force diff for equal and eql. #106
162+ * test: [expect] type null. #122
163+ * Merge pull request #115 from eshao/fix-assert-Throw
164+ * FIX: assert.Throw checks error type/message
165+ * TST: assert.Throw should check error type/message
166+
167+1.4.0 / 2012-11-29
168+==================
169+
170+ * pre-release browser build
171+ * clean up index.js to not check for cov, revert package.json to use index.js
172+ * convert tests to use new bootstrap
173+ * refactor testing bootstrap
174+ * use spaces (not tabs). Clean up #114
175+ * Merge pull request #114 from trantorLiu/master
176+ * Add most() (alias: lte) and least() (alias: gte) to the API with new chainers "at" and "of".
177+ * Change `main` to ./lib/chai. Fixes #28.
178+ * Merge pull request #104 from connec/deep_equals_circular_references_
179+ * Merge pull request #109 from nnarhinen/patch-1
180+ * Check for 'actual' type
181+ * Added support for circular references when checking deep (in)equality.
182+
183+1.3.0 / 2012-10-01
184+==================
185+
186+ * browser build w/ folio >= 0.3.4. Closes #99
187+ * add back buffer test for deep equal
188+ * do not write flags to assertion.prototype
189+ * remove buffer test from expect
190+ * browser build
191+ * improve documentation of custom error messages
192+ * Merge branch 'master' of git://github.com/Liffft/chai into Liffft-master
193+ * browser build
194+ * improved buffer deep equal checking
195+ * mocha is npm test command
196+ * Cleaning up the js style…
197+ * expect tests now include message pass-through
198+ * packaging up browser-side changes…
199+ * Increasing Throws error message verbosity
200+ * Should syntax: piping message through
201+ * Make globalShould test work in browser too.
202+ * Add a setter for `Object.prototype.should`. Closes #86.
203+
204+1.2.0 / 2012-08-07
205+==================
206+
207+ * Merge branch 'feature/errmsg'
208+ * browser build
209+ * comment updates for utilities
210+ * tweak objDislay to only kick in if object inspection is too long
211+ * Merge branch 'master' into feature/errmsg
212+ * add display sample for error message refactor
213+ * first draft of error message refactor. #93
214+ * add `closeTo` assertion to `assert` interface. Closes #89.
215+ * update folio build for better require.js handling. Closes #85
216+ * Merge pull request #92 from paulmillr/topics/add-dom-checks
217+ * Add check for DOM objects.
218+ * browser build
219+ * Merge branch 'master' of github.com:chaijs/chai
220+ * bug - getActual not defaulting to assertion subject
221+ * Merge pull request #88 from pwnall/master
222+ * Don't inspect() assertion arguments if the assertion passes.
223+
224+1.1.1 / 2012-07-09
225+==================
226+
227+ * improve commonjs support on browser build
228+ * Merge pull request #83 from tkazec/equals
229+ * Document .equals
230+ * Add .equals as an alias of .equal
231+ * remove unused browser prefix/suffix
232+ * Merge branch 'feature/folio-build'
233+ * browser build
234+ * using folio to compile
235+ * clean up makefile
236+ * early folio 0.3.x support
237+
238+1.1.0 / 2012-06-26
239+==================
240+
241+ * browser build
242+ * Disable "Assertion.includeStack is false" test in IE.
243+ * Use `utils.getName` for all function inspections.
244+ * Merge pull request #80 from kilianc/closeTo
245+ * fixes #79
246+ * browser build
247+ * expand docs to indicate change of subject for chaining. Closes #78
248+ * add `that` chain noop
249+ * Merge branch 'bug/74'
250+ * comments on how to property use `length` as chain. Closes #74
251+ * tests for length as chainable property. #74
252+ * add support for `length` as chainable prop/method.
253+ * Merge branch 'bug/77'
254+ * tests for getPathValue when working with nested arrays. Closes #77
255+ * add getPathValue support for nested arrays
256+ * browser build
257+ * fix bug for missing browser utils
258+ * compile tool aware of new folder layout
259+ * Merge branch 'refactor/1dot1'
260+ * move core assertions to own file and refactor all using utils
261+ * rearrange folder structure
262+
263+1.0.4 / 2012-06-03
264+==================
265+
266+ * Merge pull request #68 from fizker/itself
267+ * Added itself chain.
268+ * simplify error inspections for cross browser compatibility
269+ * fix safari `addChainableMethod` errors. Closes #69
270+
271+1.0.3 / 2012-05-27
272+==================
273+
274+ * Point Travis badge to the right place.
275+ * Make error message for eql/deep.equal more clear.
276+ * Fix .not.deep.equal.
277+ * contributors list
278+
279+1.0.2 / 2012-05-26
280+==================
281+
282+ * Merge pull request #67 from chaijs/chaining-and-flags
283+ * Browser build.
284+ * Use `addChainableMethod` to get away from `__proto__` manipulation.
285+ * New `addChainableMethod` utility.
286+ * Replace `getAllFlags` with `transferFlags` utility.
287+ * browser build
288+ * test - get all flags
289+ * utility - get all flags
290+ * Add .mailmap to .npmignore.
291+ * Add a .mailmap file to fix my name in shortlogs.
292+
293+1.0.1 / 2012-05-18
294+==================
295+
296+ * browser build
297+ * Fixing "an" vs. "a" grammar in type assertions.
298+ * Uniformize `assert` interface inline docs.
299+ * Don't use `instanceof` for `assert.isArray`.
300+ * Add `deep` flag for equality and property value.
301+ * Merge pull request #64 from chaijs/assertion-docs
302+ * Uniformize assertion inline docs.
303+ * Add npm-debug.log to .gitignore.
304+ * no reserved words as actuals. #62
305+
306+1.0.0 / 2012-05-15
307+==================
308+
309+ * readme cleanup
310+ * browser build
311+ * utility comments
312+ * removed docs
313+ * update to package.json
314+ * docs build
315+ * comments / docs updates
316+ * plugins app cleanup
317+ * Merge pull request #61 from joliss/doc
318+ * Fix and improve documentation of assert.equal and friends
319+ * browser build
320+ * doc checkpoint - texture
321+ * Update chai-jquery link
322+ * Use defined return value of Assertion extension functions
323+ * Update utility docs
324+
325+1.0.0-rc3 / 2012-05-09
326+==================
327+
328+ * Merge branch 'feature/rc3'
329+ * docs update
330+ * browser build
331+ * assert test conformity for minor refactor api
332+ * assert minor refactor
333+ * update util tests for new add/overwrite prop/method format
334+ * added chai.Assertion.add/overwrite prop/method for plugin toolbox
335+ * add/overwrite prop/method don't make assumptions about context
336+ * doc test suite
337+ * docs don't need coverage
338+ * refactor all simple chains into one forEach loop, for clean documentation
339+ * updated npm ignore
340+ * remove old docs
341+ * docs checkpoint - guide styled
342+ * Merge pull request #59 from joliss/doc
343+ * Document how to run the test suite
344+ * don't need to rebuild docs to view
345+ * dep update
346+ * docs checkpoint - api section
347+ * comment updates for docs
348+ * new doc site checkpoint - plugin directory!
349+ * Merge pull request #57 from kossnocorp/patch-1
350+ * Fix typo: devDependancies → devDependencies
351+ * Using message flag in `getMessage` util instead of old `msg` property.
352+ * Adding self to package.json contributors.
353+ * `getMessage` shouldn't choke on null/omitted messages.
354+ * `return this` not necessary in example.
355+ * `return this` not necessary in example.
356+ * Sinon–Chai has a dash
357+ * updated plugins list for docs
358+
359+1.0.0-rc2 / 2012-05-06
360+==================
361+
362+ * Merge branch 'feature/test-cov'
363+ * browser build
364+ * missing assert tests for ownProperty
365+ * appropriate assert equivalent for expect.to.have.property(key, val)
366+ * reset AssertionError to include full stack
367+ * test for plugin utilities
368+ * overwrite Property and Method now ensure chain
369+ * version notes in readme
370+
371+1.0.0-rc1 / 2012-05-04
372+==================
373+
374+ * browser build (rc1)
375+ * assert match/notMatch tests
376+ * assert interface - notMatch, ownProperty, notOwnProperty, ownPropertyVal, ownPropertyNotVal
377+ * cleaner should interface export.
378+ * added chai.Assertion.prototype._obj (getter) for quick access to object flag
379+ * moved almostEqual / almostDeepEqual to stats plugin
380+ * added mocha.opts
381+ * Add test for `utils.addMethod`
382+ * Fix a typo
383+ * Add test for `utils.overwriteMethod`
384+ * Fix a typo
385+ * Browser build
386+ * Add undefined assertion
387+ * Add null assertion
388+ * Fix an issue with `mocha --watch`
389+ * travis no longer tests on node 0.4.x
390+ * removing unnecissary carbon dep
391+ * Merge branch 'feature/plugins-app'
392+ * docs build
393+ * templates for docs express app for plugin directory
394+ * express app for plugin and static serving
395+ * added web server deps
396+ * Merge pull request #54 from josher19/master
397+ * Remove old test.assert code
398+ * Use util.inspect instead of inspect for deepAlmostEqual and almostEqual
399+ * browser build
400+ * Added almostEqual and deepAlmostEqual to assert test suite.
401+ * bug - context determinants for utils
402+ * dec=0 means rounding, so assert.deepAlmostEqual({pi: 3.1416}, {pi: 3}, 0) is true
403+ * wrong travis link
404+ * readme updates for version information
405+ * travis tests 0.5.x branch as well
406+ * [bug] util `addProperty` not correctly exporting
407+ * read me version notes
408+ * browser build 1.0.0alpha1
409+ * not using reserved words in internal assertions. #52
410+ * version tick
411+ * clean up redundant tests
412+ * Merge branch 'refs/heads/0.6.x'
413+ * update version tag in package 1.0.0alpha1
414+ * browser build
415+ * added utility tests to browser specs
416+ * beginning utility testing
417+ * updated utility comments
418+ * utility - overwriteMethod
419+ * utility - overwriteProperty
420+ * utility - addMethod
421+ * utility - addProperty
422+ * missing ;
423+ * contributors list update
424+ * Merge branch 'refs/heads/0.6.x-docs' into 0.6.x
425+ * Added guide link to docs. WIP
426+ * Include/contain are now both properties and methods
427+ * Add an alias annotation
428+ * Remove usless function wrapper
429+ * Fix a typo
430+ * A/an are now both properties and methods
431+ * [docs] new site homepage layout / color checkpoint
432+ * Ignore IE-specific error properties.
433+ * Fixing order of error message test.
434+ * New cross-browser `getName` util.
435+ * Fixing up `AssertionError` inheritance.
436+ * backup docs
437+ * Add doctypes
438+ * [bug] was still using `constructor.name` in `throw` assertion
439+ * [bug] flag Object.create(null) instead of new Object
440+ * [test] browser build
441+ * [refactor] all usage of Assertion.prototype.assert now uses template tags and flags
442+ * [refactor] remove Assertion.prototype.inspect for testable object inspection
443+ * [refactor] object to test is now stored in flag, with ssfi and custom message
444+ * [bug] flag util - don't return on `set`
445+ * [docs] comments for getMessage utility
446+ * [feature] getMessage
447+ * [feature] testing utilities
448+ * [refactor] flag doesn't require `call`
449+ * Make order of source files well-defined
450+ * Added support for throw(errorInstance).
451+ * Use a foolproof method of grabbing an error's name.
452+ * Removed constructor.name check from throw.
453+ * disabled stackTrack configuration tests until api is stable again
454+ * first version of line displayed error for node js (unstable)
455+ * refactor core Assertion to use flag utility for negation
456+ * added flag utility
457+ * tests for assert interface negatives. Closed #42
458+ * added assertion negatives that were missing. #42
459+ * Support for expected and actual parameters in assert-style error object
460+ * chai as promised - readme
461+ * Added assert.fail. Closes #40
462+ * better error message for assert.operator. Closes #39
463+ * [refactor] Assertion#property to use getPathValue property
464+ * added getPathValue utility helper
465+ * removed todo about browser build
466+ * version notes
467+ * version bumb 0.6.0
468+ * browser build
469+ * [refactor] browser compile function to replace with `require('./error')' with 'require('./browser/error')'
470+ * [feature] browser uses different error.js
471+ * [refactor] error without chai.fail
472+ * Assertion & interfaces use new utils helper export
473+ * [refactor] primary export for new plugin util usage
474+ * added util index.js helper
475+ * added 2012 to copyright headers
476+ * Added DeepEqual assertions
477+
478+0.5.3 / 2012-04-21
479+==================
480+
481+ * Merge branch 'refs/heads/jgonera-oldbrowsers'
482+ * browser build
483+ * fixed reserved names for old browsers in interface/assert
484+ * fixed reserved names for old browsers in interface/should
485+ * fixed: chai.js no longer contains fail()
486+ * fixed reserved names for old browsers in Assertion
487+ * Merge pull request #49 from joliss/build-order
488+ * Make order of source files well-defined
489+ * Merge pull request #43 from zzen/patch-1
490+ * Support for expected and actual parameters in assert-style error object
491+ * chai as promised - readme
492+
493+0.5.2 / 2012-03-21
494+==================
495+
496+ * browser build
497+ * Merge branch 'feature/assert-fail'
498+ * Added assert.fail. Closes #40
499+ * Merge branch 'bug/operator-msg'
500+ * better error message for assert.operator. Closes #39
501+ * version notes
502+
503+0.5.1 / 2012-03-14
504+==================
505+
506+ * chai.fail no longer exists
507+ * Merge branch 'feature/assertdefined'
508+ * Added asset#isDefined. Closes #37.
509+ * dev docs update for Assertion#assert
510+
511+0.5.0 / 2012-03-07
512+==================
513+
514+ * [bug] on inspect of reg on n 0.4.12
515+ * Merge branch 'bug/33-throws'
516+ * Merge pull request #35 from logicalparadox/empty-object
517+ * browser build
518+ * updated #throw docs
519+ * Assertion#throw `should` tests updated
520+ * Assertion#throw `expect` tests
521+ * Should interface supports multiple throw parameters
522+ * Update Assertion#throw to support strings and type checks.
523+ * Add more tests for `empty` in `should`.
524+ * Add more tests for `empty` in `expect`.
525+ * Merge branch 'master' into empty-object
526+ * don't switch act/exp
527+ * Merge pull request #34 from logicalparadox/assert-operator
528+ * Update the compiled verison.
529+ * Add `assert.operator`.
530+ * Notes on messages. #22
531+ * browser build
532+ * have been test
533+ * below tests
534+ * Merge branch 'feature/actexp'
535+ * browser build
536+ * remove unnecessary fail export
537+ * full support for actual/expected where relevant
538+ * Assertion.assert support expected value
539+ * clean up error
540+ * Update the compiled version.
541+ * Add object & sane arguments support to `Assertion#empty`.
542+
543+0.4.2 / 2012-02-28
544+==================
545+
546+ * fix for `process` not available in browser when used via browserify. Closes #28
547+ * Merge pull request #31 from joliss/doc
548+ * Document that "should" works in browsers other than IE
549+ * Merge pull request #30 from logicalparadox/assert-tests
550+ * Update the browser version of chai.
551+ * Update `assert.doesNotThrow` test in order to check the use case when type is a string.
552+ * Add test for `assert.ifError`.
553+ * Falsey -> falsy.
554+ * Full coverage for `assert.throws` and `assert.doesNotThrow`.
555+ * Add test for `assert.doesNotThrow`.
556+ * Add test for `assert.throws`.
557+ * Add test for `assert.length`.
558+ * Add test for `assert.include`.
559+ * Add test for `assert.isBoolean`.
560+ * Fix the implementation of `assert.isNumber`.
561+ * Add test for `assert.isNumber`.
562+ * Add test for `assert.isString`.
563+ * Add test for `assert.isArray`.
564+ * Add test for `assert.isUndefined`.
565+ * Add test for `assert.isNotNull`.
566+ * Fix `assert.isNotNull` implementation.
567+ * Fix `assert.isNull` implementation.
568+ * Add test for `assert.isNull`.
569+ * Add test for `assert.notDeepEqual`.
570+ * Add test for `assert.deepEqual`.
571+ * Add test for `assert.notStrictEqual`.
572+ * Add test for `assert.strictEqual`.
573+ * Add test for `assert.notEqual`.
574+
575+0.4.1 / 2012-02-26
576+==================
577+
578+ * Merge pull request #27 from logicalparadox/type-fix
579+ * Update the browser version.
580+ * Add should tests for type checks.
581+ * Add function type check test.
582+ * Add more type checks tests.
583+ * Add test for `new Number` type check.
584+ * Fix type of actual checks.
585+
586+0.4.0 / 2012-02-25
587+==================
588+
589+ * docs and readme for upcoming 0.4.0
590+ * docs generated
591+ * putting coverage and tests for docs in docs/out/support
592+ * make docs
593+ * makefile copy necessary resources for tests in docs
594+ * rename configuration test
595+ * Merge pull request #21 from logicalparadox/close-to
596+ * Update the browser version.
597+ * Update `closeTo()` docs.
598+ * Add `Assertion.closeTo()` method.
599+ * Add `.closeTo()` should test.
600+ * Add `.closeTo()` expect test.
601+ * Merge pull request #20 from logicalparadox/satisfy
602+ * Update the browser version.
603+ * `..` -> `()` in `.satisfy()` should test.
604+ * Update example for `.satisfy()`.
605+ * Update the compiled browser version.
606+ * Add `Assertion.satisfy()` method.
607+ * Add `.satisfy()` should test.
608+ * Add `.satisfy()` expect test.
609+ * Merge pull request #19 from logicalparadox/respond-to
610+ * Update the compiled browser version.
611+ * Add `respondTo` Assertion.
612+ * Add `respondTo` should test.
613+ * Add `respondTo` expect test.
614+ * Merge branch 'feature/coverage'
615+ * mocha coverage support
616+ * doc contributors
617+ * README contributors
618+
619+0.3.4 / 2012-02-23
620+==================
621+
622+ * inline comment typos for #15
623+ * Merge branch 'refs/heads/jeffbski-configErrorStackCompat'
624+ * includeStack documentation for all interfaces
625+ * suite name more generic
626+ * Update test to be compatible with browsers that do not support err.stack
627+ * udpated compiled chai.js and added to browser tests
628+ * Allow inclusion of stack trace for Assert error messages to be configurable
629+ * docs sharing buttons
630+ * sinon-chai link
631+ * doc updates
632+ * read me updates include plugins
633+
634+0.3.3 / 2012-02-12
635+==================
636+
637+ * Merge pull request #14 from jfirebaugh/configurable_properties
638+ * Make Assertion.prototype properties configurable
639+
640+0.3.2 / 2012-02-10
641+==================
642+
643+ * codex version
644+ * docs
645+ * docs cleanup
646+
647+0.3.1 / 2012-02-07
648+==================
649+
650+ * node 0.4.x compat
651+
652+0.3.0 / 2012-02-07
653+==================
654+
655+ * Merge branch 'feature/03x'
656+ * browser build
657+ * remove html/json/headers testign
658+ * regex error.message testing
659+ * tests for using plugins
660+ * Merge pull request #11 from domenic/master
661+ * Make `chai.use` a no-op if the function has already been used.
662+
663+0.2.4 / 2012-02-02
664+==================
665+
666+ * added in past tense switch for `been`
667+
668+0.2.3 / 2012-02-01
669+==================
670+
671+ * try that again
672+
673+0.2.2 / 2012-02-01
674+==================
675+
676+ * added `been` (past of `be`) alias
677+
678+0.2.1 / 2012-01-29
679+==================
680+
681+ * added Throw, with a capital T, as an alias to `throw` (#7)
682+
683+0.2.0 / 2012-01-26
684+==================
685+
686+ * update gitignore for vim *.swp
687+ * Merge branch 'feature/plugins'
688+ * browser build
689+ * interfaces now work with use
690+ * simple .use function. See #9.
691+ * readme notice on browser compat
692+
693+0.1.7 / 2012-01-25
694+==================
695+
696+ * added assert tests to browser test runner
697+ * browser update
698+ * `should` interface patch for primitives support in FF
699+ * fix isObject() Thanks @milewise
700+ * travis only on branch `master`
701+ * add instanceof alias `instanceOf`. #6
702+ * some tests for assert module
703+
704+0.1.6 / 2012-01-02
705+==================
706+
707+ * commenting for assert interface
708+ * updated codex dep
709+
710+0.1.5 / 2012-01-02
711+==================
712+
713+ * browser tests pass
714+ * type in should.not.equal
715+ * test for should (not) exist
716+ * added should.exist and should.not.exist
717+ * browser uses tdd
718+ * convert tests to tdd
719+
720+0.1.4 / 2011-12-26
721+==================
722+
723+ * browser lib update for new assert interface compatiblitiy
724+ * inspect typos
725+ * added strict equal + negatives and ifError
726+ * interface assert had doesNotThrow
727+ * added should tests to browser
728+ * new expect empty tests
729+ * should test browser compat
730+ * Fix typo for instanceof docs. Closes #3 [ci skip]
731+
732+0.1.3 / 2011-12-18
733+==================
734+
735+ * much cleaner reporting string on error.
736+
737+0.1.2 / 2011-12-18
738+==================
739+
740+ * [docs] for upcoming 0.1.2
741+ * browser version built with pre/suffix … all tests passing
742+ * make / compile now use prefix/suffix correctly
743+ * code clean
744+ * prefix/suffix to wrap browser output to prevent conflicts with other `require` methods.
745+ * Merge branch 'feature/should4xcompatibility'
746+ * compile for browser tests.. all pass
747+ * added header/status/html/json
748+ * throw tests
749+ * should.throw & should.not.throw shortcuts
750+ * improved `throw` type detection and messaging
751+ * contain is now `include` … keys modifier is now `contain`
752+ * removed object() test
753+ * removed #respondTo
754+ * Merge branch 'bug/2'
755+ * replaced __defineGetter__ with defineProperty for all uses
756+ * [docs] change mp tracking code
757+ * docs site updated with assert (TDD) interface
758+ * updated doc comments for assert interface
759+
760+0.1.1 / 2011-12-16
761+==================
762+
763+ * docs ready for upcoming 0.1.1
764+ * readme image fixed [ci skip]
765+ * more readme tweaks [ci skip]
766+ * réadmet image fixed [ci skip]
767+ * documentation
768+ * codex locked in version 0.0.5
769+ * more comments to assertions for docs
770+ * assertions fully commented, browser library updated
771+ * adding codex as doc dependancy
772+ * prepping for docs
773+ * assertion component completely commented for documentation
774+ * added exist test
775+ * var expect outside of browser if check
776+ * added keywords to package.json
777+
778+0.1.0 / 2011-12-15
779+==================
780+
781+ * failing on purpose successful .. back to normal
782+ * testing travis failure
783+ * assert#arguments getter
784+ * readme typo
785+ * updated README
786+ * added travis and npmignore
787+ * copyright notices … think i got them all
788+ * moved expect interface to own file for consistency
789+ * assert ui deepEqual
790+ * browser tests expect (all working)
791+ * browser version built
792+ * chai.fail (should ui)
793+ * expect tests browser compatible
794+ * tests for should and expect (all pass)
795+ * moved fail to primary export
796+ * should compatibility testing
797+ * within, greaterThan, object, keys,
798+ * Aliases
799+ * Assertion#property now correctly works with negate and undefined values
800+ * error message language matches should
801+ * Assertion#respondTo
802+ * Assertion now uses inspect util
803+ * git ignore node modules
804+ * should is exported
805+ * AssertionError __proto__ from Error.prototype
806+ * add should interface for should.js compatibility
807+ * moved eql to until folder and added inspect from (joyent/node)
808+ * added mocha for testing
809+ * browser build for current api
810+ * multiple .property assertions
811+ * added deep equal from node
812+
813+0.0.2 / 2011-12-07
814+==================
815+
816+ * cleaner output on error
817+ * improved exists detection
818+ * package remnant artifact
819+ * empty deep equal
820+ * test browser build
821+ * assertion cleanup
822+ * client compile script
823+ * makefile
824+ * most of the basic assertions
825+ * allow no parameters to assertion error
826+ * name change
827+ * assertion error instance
828+ * main exports: assert() & expect()
829+ * initialize
--- /dev/null
+++ b/test/bower_components/chai/README.md
@@ -0,0 +1,79 @@
1+[![Chai Documentation](http://chaijs.com/public/img/chai-logo.png)](http://chaijs.com)
2+
3+Chai is a BDD / TDD assertion library for [node](http://nodejs.org) and the browser that
4+can be delightfully paired with any javascript testing framework.
5+
6+For more information or to download plugins, view the [documentation](http://chaijs.com).
7+
8+[![Build Status](https://travis-ci.org/chaijs/chai.png?branch=master)](https://travis-ci.org/chaijs/chai) [![Coverage Status](https://coveralls.io/repos/chaijs/chai/badge.png?branch=master)](https://coveralls.io/r/chaijs/chai?branch=master)
9+
10+[![Selenium Test Status](https://saucelabs.com/browser-matrix/chaijs.svg)](https://saucelabs.com/u/chaijs)
11+
12+### Related Projects
13+
14+- [chaijs / assertion-error](https://github.com/chaijs/assertion-error): Custom `Error` constructor thrown upon an assertion failing.
15+- [chaijs / deep-eql](https://github.com/chaijs/deep-eql): Improved deep equality testing for Node.js and the browser.
16+
17+### Contributors
18+
19+ project : chai
20+ repo age : 1 year, 9 months
21+ active : 139 days
22+ commits : 693
23+ files : 54
24+ authors :
25+ 518 Jake Luer 74.7%
26+ 66 Veselin Todorov 9.5%
27+ 43 Domenic Denicola 6.2%
28+ 6 Ruben Verborgh 0.9%
29+ 5 George Kats 0.7%
30+ 5 Jo Liss 0.7%
31+ 5 Juliusz Gonera 0.7%
32+ 5 Scott Nonnenberg 0.7%
33+ 4 John Firebaugh 0.6%
34+ 4 Nick Heiner 0.6%
35+ 4 josher19 0.6%
36+ 3 Jeff Barczewski 0.4%
37+ 3 Ryunosuke SATO 0.4%
38+ 2 Bartvds 0.3%
39+ 2 Edwin Shao 0.3%
40+ 2 Jakub Nešetřil 0.3%
41+ 2 Teddy Cross 0.3%
42+ 1 Anand Patil 0.1%
43+ 1 Benjamin Horsleben 0.1%
44+ 1 Brandon Payton 0.1%
45+ 1 Chris Connelly 0.1%
46+ 1 Chun-Yi 0.1%
47+ 1 DD 0.1%
48+ 1 Jeff Welch 0.1%
49+ 1 Kilian Ciuffolo 0.1%
50+ 1 Niklas Närhinen 0.1%
51+ 1 Paul Miller 0.1%
52+ 1 Sasha Koss 0.1%
53+ 1 Victor Costan 0.1%
54+ 1 Vinay Pulim 0.1%
55+ 1 piecioshka 0.1%
56+
57+## License
58+
59+(The MIT License)
60+
61+Copyright (c) 2011-2013 Jake Luer <jake@alogicalparadox.com>
62+
63+Permission is hereby granted, free of charge, to any person obtaining a copy
64+of this software and associated documentation files (the "Software"), to deal
65+in the Software without restriction, including without limitation the rights
66+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
67+copies of the Software, and to permit persons to whom the Software is
68+furnished to do so, subject to the following conditions:
69+
70+The above copyright notice and this permission notice shall be included in
71+all copies or substantial portions of the Software.
72+
73+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
74+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
75+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
76+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
77+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
78+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
79+THE SOFTWARE.
--- /dev/null
+++ b/test/bower_components/chai/ReleaseNotes.md
@@ -0,0 +1,367 @@
1+# Release Notes
2+
3+## 1.8.1 / 2013-10-10
4+
5+The following changes are required if you are upgrading from the previous version:
6+
7+- **Users:**
8+ - Refresh `node_modules` folder for updated dependencies.
9+- **Plugin Developers:**
10+ - No changes required
11+- **Core Contributors:**
12+ - Refresh `node_modules` folder for updated dependencies.
13+
14+### Browserify
15+
16+This is a small patch that updates the dependency tree so browserify users can install
17+chai. (Remove conditional requires)
18+
19+## 1.8.0 / 2013-09-18
20+
21+The following changes are required if you are upgrading from the previous version:
22+
23+- **Users:**
24+ - See `deep.equal` notes.
25+- **Plugin Developers:**
26+ - No changes required
27+- **Core Contributors:**
28+ - Refresh `node_modules` folder for updated dependencies.
29+
30+### Deep Equals
31+
32+This version of Chai focused on a overhaul to the deep equal utility. The code for this
33+tool has been removed from the core lib and can now be found at:
34+[chai / deep-eql](https://github.com/chaijs/deep-eql). As stated in previous releases,
35+this is part of a larger initiative to provide transparency, independent testing, and coverage for
36+some of the more complicated internal tools.
37+
38+For the most part `.deep.equal` will behave the same as it has. However, in order to provide a
39+consistent ruleset across all types being tested, the following changes have been made and _might_
40+require changes to your tests.
41+
42+**1.** Strict equality for non-traversable nodes according to [egal](http://wiki.ecmascript.org/doku.php?id=harmony:egal).
43+
44+_Previously:_ Non-traversable equal via `===`.
45+
46+```js
47+expect(NaN).to.deep.equal(NaN);
48+expect(-0).to.not.deep.equal(+0);
49+```
50+
51+**2.** Arguments are not Arrays (and all types must be equal):
52+
53+_Previously:_ Some crazy nonsense that led to empty arrays deep equaling empty objects deep equaling dates.
54+
55+```js
56+expect(arguments).to.not.deep.equal([]);
57+expect(Array.prototype.slice.call(arguments)).to.deep.equal([]);
58+```
59+
60+- [#156](https://github.com/chaijs/chai/issues/156) Empty object is eql to empty array
61+- [#192](https://github.com/chaijs/chai/issues/192) empty object is eql to a Date object
62+- [#194](https://github.com/chaijs/chai/issues/194) refactor deep-equal utility
63+
64+### CI and Browser Testing
65+
66+Chai now runs the browser CI suite using [Karma](http://karma-runner.github.io/) directed at
67+[SauceLabs](https://saucelabs.com/). This means we get to know where our browser support stands...
68+and we get a cool badge:
69+
70+[![Selenium Test Status](https://saucelabs.com/browser-matrix/logicalparadox.svg)](https://saucelabs.com/u/logicalparadox)
71+
72+Look for the list of browsers/versions to expand over the coming releases.
73+
74+- [#195](https://github.com/chaijs/chai/issues/195) karma test framework
75+
76+## 1.7.2 / 2013-06-27
77+
78+The following changes are required if you are upgrading from the previous version:
79+
80+- **Users:**
81+ - No changes required.
82+- **Plugin Developers:**
83+ - No changes required
84+- **Core Contributors:**
85+ - Refresh `node_modules` folder for updated dependencies.
86+
87+### Coverage Reporting
88+
89+Coverage reporting has always been available for core-developers but the data has never been published
90+for our end users. In our ongoing effort to improve accountability this data will now be published via
91+the [coveralls.io](https://coveralls.io/) service. A badge has been added to the README and the full report
92+can be viewed online at the [chai coveralls project](https://coveralls.io/r/chaijs/chai). Furthermore, PRs
93+will receive automated messages indicating how their PR impacts test coverage. This service is tied to TravisCI.
94+
95+### Other Fixes
96+
97+- [#175](https://github.com/chaijs/chai/issues/175) Add `bower.json`. (Fix ignore all)
98+
99+## 1.7.1 / 2013-06-24
100+
101+The following changes are required if you are upgrading from the previous version:
102+
103+- **Users:**
104+ - No changes required.
105+- **Plugin Developers:**
106+ - No changes required
107+- **Core Contributors:**
108+ - Refresh `node_modules` folder for updated dependencies.
109+
110+### Official Bower Support
111+
112+Support has been added for the Bower Package Manager ([bower.io])(http://bower.io/). Though
113+Chai could be installed via Bower in the past, this update adds official support via the `bower.json`
114+specification file.
115+
116+- [#175](https://github.com/chaijs/chai/issues/175) Add `bower.json`.
117+
118+## 1.7.0 / 2013-06-17
119+
120+The following changes are required if you are upgrading from the previous version:
121+
122+- **Users:**
123+ - No changes required.
124+- **Plugin Developers:**
125+ - Review AssertionError update notice.
126+- **Core Contributors:**
127+ - Refresh `node_modules` folder for updated dependencies.
128+
129+### AssertionError Update Notice
130+
131+Chai now uses [chaijs/assertion-error](https://github.com/chaijs/assertion-error) instead an internal
132+constructor. This will allow for further iteration/experimentation of the AssertionError constructor
133+independant of Chai. Future plans include stack parsing for callsite support.
134+
135+This update constructor has a different constructor param signature that conforms more with the standard
136+`Error` object. If your plugin throws and `AssertionError` directly you will need to update your plugin
137+with the new signature.
138+
139+```js
140+var AssertionError = require('chai').AssertionError;
141+
142+/**
143+ * previous
144+ *
145+ * @param {Object} options
146+ */
147+
148+throw new AssertionError({
149+ message: 'An assertion error occurred'
150+ , actual: actual
151+ , expect: expect
152+ , startStackFunction: arguments.callee
153+ , showStack: true
154+});
155+
156+/**
157+ * new
158+ *
159+ * @param {String} message
160+ * @param {Object} options
161+ * @param {Function} start stack function
162+ */
163+
164+throw new AssertionError('An assertion error occurred', {
165+ actual: actual
166+ , expect: expect
167+ , showStack: true
168+}, arguments.callee);
169+
170+// other signatures
171+throw new AssertionError('An assertion error occurred');
172+throw new AssertionError('An assertion error occurred', null, arguments.callee);
173+```
174+
175+#### External Dependencies
176+
177+This is the first non-developement dependency for Chai. As Chai continues to evolve we will begin adding
178+more; the next will likely be improved type detection and deep equality. With Chai's userbase continually growing
179+there is an higher need for accountability and documentation. External dependencies will allow us to iterate and
180+test on features independent from our interfaces.
181+
182+Note: The browser packaged version `chai.js` will ALWAYS contain all dependencies needed to run Chai.
183+
184+### Community Contributions
185+
186+- [#169](https://github.com/chaijs/chai/pull/169) Fix deep equal comparison for Date/Regexp types. [@katsgeorgeek](https://github.com/katsgeorgeek)
187+- [#171](https://github.com/chaijs/chai/pull/171) Add `assert.notOk()`. [@Bartvds](https://github.com/Bartvds)
188+- [#173](https://github.com/chaijs/chai/pull/173) Fix `inspect` utility. [@domenic](https://github.com/domenic)
189+
190+Thank you to all who took the time to contribute!
191+
192+## 1.6.1 / 2013-06-05
193+
194+The following changes are required if you are upgrading from the previous version:
195+
196+- **Users:**
197+ - No changes required.
198+- **Plugin Developers:**
199+ - No changes required.
200+- **Core Contributors:**
201+ - Refresh `node_modules` folder for updated developement dependencies.
202+
203+### Deep Equality
204+
205+Regular Expressions are now tested as part of all deep equality assertions. In previous versions
206+they silently passed for all scenarios. Thanks to [@katsgeorgeek](https://github.com/katsgeorgeek) for the contribution.
207+
208+### Community Contributions
209+
210+- [#161](https://github.com/chaijs/chai/pull/161) Fix documented name for assert interface's isDefined method. [@brandonpayton](https://github.com/brandonpayton)
211+- [#168](https://github.com/chaijs/chai/pull/168) Fix comparison equality of two regexps for when using deep equality. [@katsgeorgeek](https://github.com/katsgeorgeek)
212+
213+Thank you to all who took the time to contribute!
214+
215+### Additional Notes
216+
217+- Mocha has been locked at version `1.8.x` to ensure `mocha-phantomjs` compatibility.
218+
219+## 1.6.0 / 2013-04-29
220+
221+The following changes are required if you are upgrading from the previous version:
222+
223+- **Users:**
224+ - No changes required.
225+- **Plugin Developers:**
226+ - No changes required.
227+- **Core Contributors:**
228+ - Refresh `node_modules` folder for updated developement dependencies.
229+
230+### New Assertions
231+
232+#### Array Members Inclusion
233+
234+Asserts that the target is a superset of `set`, or that the target and `set` have the same members.
235+Order is not taken into account. Thanks to [@NickHeiner](https://github.com/NickHeiner) for the contribution.
236+
237+```js
238+// (expect/should) full set
239+expect([4, 2]).to.have.members([2, 4]);
240+expect([5, 2]).to.not.have.members([5, 2, 1]);
241+
242+// (expect/should) inclusion
243+expect([1, 2, 3]).to.include.members([3, 2]);
244+expect([1, 2, 3]).to.not.include.members([3, 2, 8]);
245+
246+// (assert) full set
247+assert.sameMembers([ 1, 2, 3 ], [ 2, 1, 3 ], 'same members');
248+
249+// (assert) inclusion
250+assert.includeMembers([ 1, 2, 3 ], [ 2, 1 ], 'include members');
251+
252+```
253+
254+#### Non-inclusion for Assert Interface
255+
256+Most `assert` functions have a negative version, like `instanceOf()` has a corresponding `notInstaceOf()`.
257+However `include()` did not have a corresponding `notInclude()`. This has been added.
258+
259+```js
260+assert.notInclude([ 1, 2, 3 ], 8);
261+assert.notInclude('foobar', 'baz');
262+```
263+
264+### Community Contributions
265+
266+- [#140](https://github.com/chaijs/chai/pull/140) Restore `call`/`apply` methods for plugin interface. [@RubenVerborgh](https://github.com/RubenVerborgh)
267+- [#148](https://github.com/chaijs/chai/issues/148)/[#153](https://github.com/chaijs/chai/pull/153) Add `members` and `include.members` assertions. [#NickHeiner](https://github.com/NickHeiner)
268+
269+Thank you to all who took time to contribute!
270+
271+### Other Bug Fixes
272+
273+- [#142](https://github.com/chaijs/chai/issues/142) `assert#include` will no longer silently pass on wrong-type haystack.
274+- [#158](https://github.com/chaijs/chai/issues/158) `assert#notInclude` has been added.
275+- Travis-CI now tests Node.js `v0.10.x`. Support for `v0.6.x` has been removed. `v0.8.x` is still tested as before.
276+
277+## 1.5.0 / 2013-02-03
278+
279+### Migration Requirements
280+
281+The following changes are required if you are upgrading from the previous version:
282+
283+- **Users:**
284+ - _Update [2013-02-04]:_ Some users may notice a small subset of deep equality assertions will no longer pass. This is the result of
285+ [#120](https://github.com/chaijs/chai/issues/120), an improvement to our deep equality algorithm. Users will need to revise their assertions
286+ to be more granular should this occur. Further information: [#139](https://github.com/chaijs/chai/issues/139).
287+- **Plugin Developers:**
288+ - No changes required.
289+- **Core Contributors:**
290+ - Refresh `node_modules` folder for updated developement dependencies.
291+
292+### Community Contributions
293+
294+- [#126](https://github.com/chaijs/chai/pull/126): Add `eqls` alias for `eql`. [@RubenVerborgh](https://github.com/RubenVerborgh)
295+- [#127](https://github.com/chaijs/chai/issues/127): Performance refactor for chainable methods. [@RubenVerborgh](https://github.com/RubenVerborgh)
296+- [#133](https://github.com/chaijs/chai/pull/133): Assertion `.throw` support for primitives. [@RubenVerborgh](https://github.com/RubenVerborgh)
297+- [#137](https://github.com/chaijs/chai/issues/137): Assertion `.throw` support for empty messages. [@timnew](https://github.com/timnew)
298+- [#136](https://github.com/chaijs/chai/pull/136): Fix backward negation messages when using `.above()` and `.below()`. [@whatthejeff](https://github.com/whatthejeff)
299+
300+Thank you to all who took time to contribute!
301+
302+### Other Bug Fixes
303+
304+- Improve type detection of `.a()`/`.an()` to work in cross-browser scenarios.
305+- [#116](https://github.com/chaijs/chai/issues/116): `.throw()` has cleaner display of errors when WebKit browsers.
306+- [#120](https://github.com/chaijs/chai/issues/120): `.eql()` now works to compare dom nodes in browsers.
307+
308+
309+### Usage Updates
310+
311+#### For Users
312+
313+**1. Component Support:** Chai now included the proper configuration to be installed as a
314+[component](https://github.com/component/component). Component users are encouraged to consult
315+[chaijs.com](http://chaijs.com) for the latest version number as using the master branch
316+does not gaurantee stability.
317+
318+```js
319+// relevant component.json
320+ devDependencies: {
321+ "chaijs/chai": "1.5.0"
322+ }
323+```
324+
325+Alternatively, bleeding-edge is available:
326+
327+ $ component install chaijs/chai
328+
329+**2. Configurable showDiff:** Some test runners (such as [mocha](http://visionmedia.github.com/mocha/))
330+include support for showing the diff of strings and objects when an equality error occurs. Chai has
331+already included support for this, however some users may not prefer this display behavior. To revert to
332+no diff display, the following configuration is available:
333+
334+```js
335+chai.Assertion.showDiff = false; // diff output disabled
336+chai.Assertion.showDiff = true; // default, diff output enabled
337+```
338+
339+#### For Plugin Developers
340+
341+**1. New Utility - type**: The new utility `.type()` is available as a better implementation of `typeof`
342+that can be used cross-browser. It handles the inconsistencies of Array, `null`, and `undefined` detection.
343+
344+- **@param** _{Mixed}_ object to detect type of
345+- **@return** _{String}_ object type
346+
347+```js
348+chai.use(function (c, utils) {
349+ // some examples
350+ utils.type({}); // 'object'
351+ utils.type(null); // `null'
352+ utils.type(undefined); // `undefined`
353+ utils.type([]); // `array`
354+});
355+```
356+
357+#### For Core Contributors
358+
359+**1. Browser Testing**: Browser testing of the `./chai.js` file is now available in the command line
360+via PhantomJS. `make test` and Travis-CI will now also rebuild and test `./chai.js`. Consequently, all
361+pull requests will now be browser tested in this way.
362+
363+_Note: Contributors opening pull requests should still NOT include the browser build._
364+
365+**2. SauceLabs Testing**: Early SauceLab support has been enabled with the file `./support/mocha-cloud.js`.
366+Those interested in trying it out should create a free [Open Sauce](https://saucelabs.com/signup/plan) account
367+and include their credentials in `./test/auth/sauce.json`.
--- /dev/null
+++ b/test/bower_components/chai/bower.json
@@ -0,0 +1,27 @@
1+{
2+ "name": "chai"
3+ , "version": "1.8.1"
4+ , "description": "BDD/TDD assertion library for node.js and the browser. Test framework agnostic."
5+ , "license": "MIT"
6+ , "keywords": [
7+ "test"
8+ , "assertion"
9+ , "assert"
10+ , "testing"
11+ , "chai"
12+ ]
13+ , "main": "chai.js"
14+ , "ignore": [
15+ "build"
16+ , "components"
17+ , "lib"
18+ , "node_modules"
19+ , "support"
20+ , "test"
21+ , "index.js"
22+ , "Makefile"
23+ , ".*"
24+ ]
25+ , "dependencies": {}
26+ , "devDependencies": {}
27+}
--- /dev/null
+++ b/test/bower_components/chai/chai.js
@@ -0,0 +1,4613 @@
1+;(function(){
2+
3+/**
4+ * Require the given path.
5+ *
6+ * @param {String} path
7+ * @return {Object} exports
8+ * @api public
9+ */
10+
11+function require(path, parent, orig) {
12+ var resolved = require.resolve(path);
13+
14+ // lookup failed
15+ if (null == resolved) {
16+ orig = orig || path;
17+ parent = parent || 'root';
18+ var err = new Error('Failed to require "' + orig + '" from "' + parent + '"');
19+ err.path = orig;
20+ err.parent = parent;
21+ err.require = true;
22+ throw err;
23+ }
24+
25+ var module = require.modules[resolved];
26+
27+ // perform real require()
28+ // by invoking the module's
29+ // registered function
30+ if (!module._resolving && !module.exports) {
31+ var mod = {};
32+ mod.exports = {};
33+ mod.client = mod.component = true;
34+ module._resolving = true;
35+ module.call(this, mod.exports, require.relative(resolved), mod);
36+ delete module._resolving;
37+ module.exports = mod.exports;
38+ }
39+
40+ return module.exports;
41+}
42+
43+/**
44+ * Registered modules.
45+ */
46+
47+require.modules = {};
48+
49+/**
50+ * Registered aliases.
51+ */
52+
53+require.aliases = {};
54+
55+/**
56+ * Resolve `path`.
57+ *
58+ * Lookup:
59+ *
60+ * - PATH/index.js
61+ * - PATH.js
62+ * - PATH
63+ *
64+ * @param {String} path
65+ * @return {String} path or null
66+ * @api private
67+ */
68+
69+require.resolve = function(path) {
70+ if (path.charAt(0) === '/') path = path.slice(1);
71+
72+ var paths = [
73+ path,
74+ path + '.js',
75+ path + '.json',
76+ path + '/index.js',
77+ path + '/index.json'
78+ ];
79+
80+ for (var i = 0; i < paths.length; i++) {
81+ var path = paths[i];
82+ if (require.modules.hasOwnProperty(path)) return path;
83+ if (require.aliases.hasOwnProperty(path)) return require.aliases[path];
84+ }
85+};
86+
87+/**
88+ * Normalize `path` relative to the current path.
89+ *
90+ * @param {String} curr
91+ * @param {String} path
92+ * @return {String}
93+ * @api private
94+ */
95+
96+require.normalize = function(curr, path) {
97+ var segs = [];
98+
99+ if ('.' != path.charAt(0)) return path;
100+
101+ curr = curr.split('/');
102+ path = path.split('/');
103+
104+ for (var i = 0; i < path.length; ++i) {
105+ if ('..' == path[i]) {
106+ curr.pop();
107+ } else if ('.' != path[i] && '' != path[i]) {
108+ segs.push(path[i]);
109+ }
110+ }
111+
112+ return curr.concat(segs).join('/');
113+};
114+
115+/**
116+ * Register module at `path` with callback `definition`.
117+ *
118+ * @param {String} path
119+ * @param {Function} definition
120+ * @api private
121+ */
122+
123+require.register = function(path, definition) {
124+ require.modules[path] = definition;
125+};
126+
127+/**
128+ * Alias a module definition.
129+ *
130+ * @param {String} from
131+ * @param {String} to
132+ * @api private
133+ */
134+
135+require.alias = function(from, to) {
136+ if (!require.modules.hasOwnProperty(from)) {
137+ throw new Error('Failed to alias "' + from + '", it does not exist');
138+ }
139+ require.aliases[to] = from;
140+};
141+
142+/**
143+ * Return a require function relative to the `parent` path.
144+ *
145+ * @param {String} parent
146+ * @return {Function}
147+ * @api private
148+ */
149+
150+require.relative = function(parent) {
151+ var p = require.normalize(parent, '..');
152+
153+ /**
154+ * lastIndexOf helper.
155+ */
156+
157+ function lastIndexOf(arr, obj) {
158+ var i = arr.length;
159+ while (i--) {
160+ if (arr[i] === obj) return i;
161+ }
162+ return -1;
163+ }
164+
165+ /**
166+ * The relative require() itself.
167+ */
168+
169+ function localRequire(path) {
170+ var resolved = localRequire.resolve(path);
171+ return require(resolved, parent, path);
172+ }
173+
174+ /**
175+ * Resolve relative to the parent.
176+ */
177+
178+ localRequire.resolve = function(path) {
179+ var c = path.charAt(0);
180+ if ('/' == c) return path.slice(1);
181+ if ('.' == c) return require.normalize(p, path);
182+
183+ // resolve deps by returning
184+ // the dep in the nearest "deps"
185+ // directory
186+ var segs = parent.split('/');
187+ var i = lastIndexOf(segs, 'deps') + 1;
188+ if (!i) i = 0;
189+ path = segs.slice(0, i + 1).join('/') + '/deps/' + path;
190+ return path;
191+ };
192+
193+ /**
194+ * Check if module is defined at `path`.
195+ */
196+
197+ localRequire.exists = function(path) {
198+ return require.modules.hasOwnProperty(localRequire.resolve(path));
199+ };
200+
201+ return localRequire;
202+};
203+require.register("chaijs-assertion-error/index.js", function(exports, require, module){
204+/*!
205+ * assertion-error
206+ * Copyright(c) 2013 Jake Luer <jake@qualiancy.com>
207+ * MIT Licensed
208+ */
209+
210+/*!
211+ * Return a function that will copy properties from
212+ * one object to another excluding any originally
213+ * listed. Returned function will create a new `{}`.
214+ *
215+ * @param {String} excluded properties ...
216+ * @return {Function}
217+ */
218+
219+function exclude () {
220+ var excludes = [].slice.call(arguments);
221+
222+ function excludeProps (res, obj) {
223+ Object.keys(obj).forEach(function (key) {
224+ if (!~excludes.indexOf(key)) res[key] = obj[key];
225+ });
226+ }
227+
228+ return function extendExclude () {
229+ var args = [].slice.call(arguments)
230+ , i = 0
231+ , res = {};
232+
233+ for (; i < args.length; i++) {
234+ excludeProps(res, args[i]);
235+ }
236+
237+ return res;
238+ };
239+};
240+
241+/*!
242+ * Primary Exports
243+ */
244+
245+module.exports = AssertionError;
246+
247+/**
248+ * ### AssertionError
249+ *
250+ * An extension of the JavaScript `Error` constructor for
251+ * assertion and validation scenarios.
252+ *
253+ * @param {String} message
254+ * @param {Object} properties to include (optional)
255+ * @param {callee} start stack function (optional)
256+ */
257+
258+function AssertionError (message, _props, ssf) {
259+ var extend = exclude('name', 'message', 'stack', 'constructor', 'toJSON')
260+ , props = extend(_props || {});
261+
262+ // default values
263+ this.message = message || 'Unspecified AssertionError';
264+ this.showDiff = false;
265+
266+ // copy from properties
267+ for (var key in props) {
268+ this[key] = props[key];
269+ }
270+
271+ // capture stack trace
272+ ssf = ssf || arguments.callee;
273+ if (ssf && Error.captureStackTrace) {
274+ Error.captureStackTrace(this, ssf);
275+ }
276+}
277+
278+/*!
279+ * Inherit from Error.prototype
280+ */
281+
282+AssertionError.prototype = Object.create(Error.prototype);
283+
284+/*!
285+ * Statically set name
286+ */
287+
288+AssertionError.prototype.name = 'AssertionError';
289+
290+/*!
291+ * Ensure correct constructor
292+ */
293+
294+AssertionError.prototype.constructor = AssertionError;
295+
296+/**
297+ * Allow errors to be converted to JSON for static transfer.
298+ *
299+ * @param {Boolean} include stack (default: `true`)
300+ * @return {Object} object that can be `JSON.stringify`
301+ */
302+
303+AssertionError.prototype.toJSON = function (stack) {
304+ var extend = exclude('constructor', 'toJSON', 'stack')
305+ , props = extend({ name: this.name }, this);
306+
307+ // include stack if exists and not turned off
308+ if (false !== stack && this.stack) {
309+ props.stack = this.stack;
310+ }
311+
312+ return props;
313+};
314+
315+});
316+require.register("chaijs-type-detect/lib/type.js", function(exports, require, module){
317+/*!
318+ * type-detect
319+ * Copyright(c) 2013 jake luer <jake@alogicalparadox.com>
320+ * MIT Licensed
321+ */
322+
323+/*!
324+ * Primary Exports
325+ */
326+
327+var exports = module.exports = getType;
328+
329+/*!
330+ * Detectable javascript natives
331+ */
332+
333+var natives = {
334+ '[object Array]': 'array'
335+ , '[object RegExp]': 'regexp'
336+ , '[object Function]': 'function'
337+ , '[object Arguments]': 'arguments'
338+ , '[object Date]': 'date'
339+};
340+
341+/**
342+ * ### typeOf (obj)
343+ *
344+ * Use several different techniques to determine
345+ * the type of object being tested.
346+ *
347+ *
348+ * @param {Mixed} object
349+ * @return {String} object type
350+ * @api public
351+ */
352+
353+function getType (obj) {
354+ var str = Object.prototype.toString.call(obj);
355+ if (natives[str]) return natives[str];
356+ if (obj === null) return 'null';
357+ if (obj === undefined) return 'undefined';
358+ if (obj === Object(obj)) return 'object';
359+ return typeof obj;
360+}
361+
362+exports.Library = Library;
363+
364+/**
365+ * ### Library
366+ *
367+ * Create a repository for custom type detection.
368+ *
369+ * ```js
370+ * var lib = new type.Library;
371+ * ```
372+ *
373+ */
374+
375+function Library () {
376+ this.tests = {};
377+}
378+
379+/**
380+ * #### .of (obj)
381+ *
382+ * Expose replacement `typeof` detection to the library.
383+ *
384+ * ```js
385+ * if ('string' === lib.of('hello world')) {
386+ * // ...
387+ * }
388+ * ```
389+ *
390+ * @param {Mixed} object to test
391+ * @return {String} type
392+ */
393+
394+Library.prototype.of = getType;
395+
396+/**
397+ * #### .define (type, test)
398+ *
399+ * Add a test to for the `.test()` assertion.
400+ *
401+ * Can be defined as a regular expression:
402+ *
403+ * ```js
404+ * lib.define('int', /^[0-9]+$/);
405+ * ```
406+ *
407+ * ... or as a function:
408+ *
409+ * ```js
410+ * lib.define('bln', function (obj) {
411+ * if ('boolean' === lib.of(obj)) return true;
412+ * var blns = [ 'yes', 'no', 'true', 'false', 1, 0 ];
413+ * if ('string' === lib.of(obj)) obj = obj.toLowerCase();
414+ * return !! ~blns.indexOf(obj);
415+ * });
416+ * ```
417+ *
418+ * @param {String} type
419+ * @param {RegExp|Function} test
420+ * @api public
421+ */
422+
423+Library.prototype.define = function (type, test) {
424+ if (arguments.length === 1) return this.tests[type];
425+ this.tests[type] = test;
426+ return this;
427+};
428+
429+/**
430+ * #### .test (obj, test)
431+ *
432+ * Assert that an object is of type. Will first
433+ * check natives, and if that does not pass it will
434+ * use the user defined custom tests.
435+ *
436+ * ```js
437+ * assert(lib.test('1', 'int'));
438+ * assert(lib.test('yes', 'bln'));
439+ * ```
440+ *
441+ * @param {Mixed} object
442+ * @param {String} type
443+ * @return {Boolean} result
444+ * @api public
445+ */
446+
447+Library.prototype.test = function (obj, type) {
448+ if (type === getType(obj)) return true;
449+ var test = this.tests[type];
450+
451+ if (test && 'regexp' === getType(test)) {
452+ return test.test(obj);
453+ } else if (test && 'function' === getType(test)) {
454+ return test(obj);
455+ } else {
456+ throw new ReferenceError('Type test "' + type + '" not defined or invalid.');
457+ }
458+};
459+
460+});
461+require.register("chaijs-deep-eql/lib/eql.js", function(exports, require, module){
462+/*!
463+ * deep-eql
464+ * Copyright(c) 2013 Jake Luer <jake@alogicalparadox.com>
465+ * MIT Licensed
466+ */
467+
468+/*!
469+ * Module dependencies
470+ */
471+
472+var type = require('type-detect');
473+
474+/*!
475+ * Buffer.isBuffer browser shim
476+ */
477+
478+var Buffer;
479+try { Buffer = require('buffer').Buffer; }
480+catch(ex) {
481+ Buffer = {};
482+ Buffer.isBuffer = function() { return false; }
483+}
484+
485+/*!
486+ * Primary Export
487+ */
488+
489+module.exports = deepEqual;
490+
491+/**
492+ * Assert super-strict (egal) equality between
493+ * two objects of any type.
494+ *
495+ * @param {Mixed} a
496+ * @param {Mixed} b
497+ * @param {Array} memoised (optional)
498+ * @return {Boolean} equal match
499+ */
500+
501+function deepEqual(a, b, m) {
502+ if (sameValue(a, b)) {
503+ return true;
504+ } else if ('date' === type(a)) {
505+ return dateEqual(a, b);
506+ } else if ('regexp' === type(a)) {
507+ return regexpEqual(a, b);
508+ } else if (Buffer.isBuffer(a)) {
509+ return bufferEqual(a, b);
510+ } else if ('arguments' === type(a)) {
511+ return argumentsEqual(a, b, m);
512+ } else if (!typeEqual(a, b)) {
513+ return false;
514+ } else if (('object' !== type(a) && 'object' !== type(b))
515+ && ('array' !== type(a) && 'array' !== type(b))) {
516+ return sameValue(a, b);
517+ } else {
518+ return objectEqual(a, b, m);
519+ }
520+}
521+
522+/*!
523+ * Strict (egal) equality test. Ensures that NaN always
524+ * equals NaN and `-0` does not equal `+0`.
525+ *
526+ * @param {Mixed} a
527+ * @param {Mixed} b
528+ * @return {Boolean} equal match
529+ */
530+
531+function sameValue(a, b) {
532+ if (a === b) return a !== 0 || 1 / a === 1 / b;
533+ return a !== a && b !== b;
534+}
535+
536+/*!
537+ * Compare the types of two given objects and
538+ * return if they are equal. Note that an Array
539+ * has a type of `array` (not `object`) and arguments
540+ * have a type of `arguments` (not `array`/`object`).
541+ *
542+ * @param {Mixed} a
543+ * @param {Mixed} b
544+ * @return {Boolean} result
545+ */
546+
547+function typeEqual(a, b) {
548+ return type(a) === type(b);
549+}
550+
551+/*!
552+ * Compare two Date objects by asserting that
553+ * the time values are equal using `saveValue`.
554+ *
555+ * @param {Date} a
556+ * @param {Date} b
557+ * @return {Boolean} result
558+ */
559+
560+function dateEqual(a, b) {
561+ if ('date' !== type(b)) return false;
562+ return sameValue(a.getTime(), b.getTime());
563+}
564+
565+/*!
566+ * Compare two regular expressions by converting them
567+ * to string and checking for `sameValue`.
568+ *
569+ * @param {RegExp} a
570+ * @param {RegExp} b
571+ * @return {Boolean} result
572+ */
573+
574+function regexpEqual(a, b) {
575+ if ('regexp' !== type(b)) return false;
576+ return sameValue(a.toString(), b.toString());
577+}
578+
579+/*!
580+ * Assert deep equality of two `arguments` objects.
581+ * Unfortunately, these must be sliced to arrays
582+ * prior to test to ensure no bad behavior.
583+ *
584+ * @param {Arguments} a
585+ * @param {Arguments} b
586+ * @param {Array} memoize (optional)
587+ * @return {Boolean} result
588+ */
589+
590+function argumentsEqual(a, b, m) {
591+ if ('arguments' !== type(b)) return false;
592+ a = [].slice.call(a);
593+ b = [].slice.call(b);
594+ return deepEqual(a, b, m);
595+}
596+
597+/*!
598+ * Get enumerable properties of a given object.
599+ *
600+ * @param {Object} a
601+ * @return {Array} property names
602+ */
603+
604+function enumerable(a) {
605+ var res = [];
606+ for (var key in a) res.push(key);
607+ return res;
608+}
609+
610+/*!
611+ * Simple equality for flat iterable objects
612+ * such as Arrays or Node.js buffers.
613+ *
614+ * @param {Iterable} a
615+ * @param {Iterable} b
616+ * @return {Boolean} result
617+ */
618+
619+function iterableEqual(a, b) {
620+ if (a.length !== b.length) return false;
621+
622+ var i = 0;
623+ var match = true;
624+
625+ for (; i < a.length; i++) {
626+ if (a[i] !== b[i]) {
627+ match = false;
628+ break;
629+ }
630+ }
631+
632+ return match;
633+}
634+
635+/*!
636+ * Extension to `iterableEqual` specifically
637+ * for Node.js Buffers.
638+ *
639+ * @param {Buffer} a
640+ * @param {Mixed} b
641+ * @return {Boolean} result
642+ */
643+
644+function bufferEqual(a, b) {
645+ if (!Buffer.isBuffer(b)) return false;
646+ return iterableEqual(a, b);
647+}
648+
649+/*!
650+ * Block for `objectEqual` ensuring non-existing
651+ * values don't get in.
652+ *
653+ * @param {Mixed} object
654+ * @return {Boolean} result
655+ */
656+
657+function isValue(a) {
658+ return a !== null && a !== undefined;
659+}
660+
661+/*!
662+ * Recursively check the equality of two objects.
663+ * Once basic sameness has been established it will
664+ * defer to `deepEqual` for each enumerable key
665+ * in the object.
666+ *
667+ * @param {Mixed} a
668+ * @param {Mixed} b
669+ * @return {Boolean} result
670+ */
671+
672+function objectEqual(a, b, m) {
673+ if (!isValue(a) || !isValue(b)) {
674+ return false;
675+ }
676+
677+ if (a.prototype !== b.prototype) {
678+ return false;
679+ }
680+
681+ var i;
682+ if (m) {
683+ for (i = 0; i < m.length; i++) {
684+ if ((m[i][0] === a && m[i][1] === b)
685+ || (m[i][0] === b && m[i][1] === a)) {
686+ return true;
687+ }
688+ }
689+ } else {
690+ m = [];
691+ }
692+
693+ try {
694+ var ka = enumerable(a);
695+ var kb = enumerable(b);
696+ } catch (ex) {
697+ return false;
698+ }
699+
700+ ka.sort();
701+ kb.sort();
702+
703+ if (!iterableEqual(ka, kb)) {
704+ return false;
705+ }
706+
707+ m.push([ a, b ]);
708+
709+ var key;
710+ for (i = ka.length - 1; i >= 0; i--) {
711+ key = ka[i];
712+ if (!deepEqual(a[key], b[key], m)) {
713+ return false;
714+ }
715+ }
716+
717+ return true;
718+}
719+
720+});
721+require.register("chai/index.js", function(exports, require, module){
722+module.exports = require('./lib/chai');
723+
724+});
725+require.register("chai/lib/chai.js", function(exports, require, module){
726+/*!
727+ * chai
728+ * Copyright(c) 2011-2013 Jake Luer <jake@alogicalparadox.com>
729+ * MIT Licensed
730+ */
731+
732+var used = []
733+ , exports = module.exports = {};
734+
735+/*!
736+ * Chai version
737+ */
738+
739+exports.version = '1.8.1';
740+
741+/*!
742+ * Assertion Error
743+ */
744+
745+exports.AssertionError = require('assertion-error');
746+
747+/*!
748+ * Utils for plugins (not exported)
749+ */
750+
751+var util = require('./chai/utils');
752+
753+/**
754+ * # .use(function)
755+ *
756+ * Provides a way to extend the internals of Chai
757+ *
758+ * @param {Function}
759+ * @returns {this} for chaining
760+ * @api public
761+ */
762+
763+exports.use = function (fn) {
764+ if (!~used.indexOf(fn)) {
765+ fn(this, util);
766+ used.push(fn);
767+ }
768+
769+ return this;
770+};
771+
772+/*!
773+ * Primary `Assertion` prototype
774+ */
775+
776+var assertion = require('./chai/assertion');
777+exports.use(assertion);
778+
779+/*!
780+ * Core Assertions
781+ */
782+
783+var core = require('./chai/core/assertions');
784+exports.use(core);
785+
786+/*!
787+ * Expect interface
788+ */
789+
790+var expect = require('./chai/interface/expect');
791+exports.use(expect);
792+
793+/*!
794+ * Should interface
795+ */
796+
797+var should = require('./chai/interface/should');
798+exports.use(should);
799+
800+/*!
801+ * Assert interface
802+ */
803+
804+var assert = require('./chai/interface/assert');
805+exports.use(assert);
806+
807+});
808+require.register("chai/lib/chai/assertion.js", function(exports, require, module){
809+/*!
810+ * chai
811+ * http://chaijs.com
812+ * Copyright(c) 2011-2013 Jake Luer <jake@alogicalparadox.com>
813+ * MIT Licensed
814+ */
815+
816+module.exports = function (_chai, util) {
817+ /*!
818+ * Module dependencies.
819+ */
820+
821+ var AssertionError = _chai.AssertionError
822+ , flag = util.flag;
823+
824+ /*!
825+ * Module export.
826+ */
827+
828+ _chai.Assertion = Assertion;
829+
830+ /*!
831+ * Assertion Constructor
832+ *
833+ * Creates object for chaining.
834+ *
835+ * @api private
836+ */
837+
838+ function Assertion (obj, msg, stack) {
839+ flag(this, 'ssfi', stack || arguments.callee);
840+ flag(this, 'object', obj);
841+ flag(this, 'message', msg);
842+ }
843+
844+ /*!
845+ * ### Assertion.includeStack
846+ *
847+ * User configurable property, influences whether stack trace
848+ * is included in Assertion error message. Default of false
849+ * suppresses stack trace in the error message
850+ *
851+ * Assertion.includeStack = true; // enable stack on error
852+ *
853+ * @api public
854+ */
855+
856+ Assertion.includeStack = false;
857+
858+ /*!
859+ * ### Assertion.showDiff
860+ *
861+ * User configurable property, influences whether or not
862+ * the `showDiff` flag should be included in the thrown
863+ * AssertionErrors. `false` will always be `false`; `true`
864+ * will be true when the assertion has requested a diff
865+ * be shown.
866+ *
867+ * @api public
868+ */
869+
870+ Assertion.showDiff = true;
871+
872+ Assertion.addProperty = function (name, fn) {
873+ util.addProperty(this.prototype, name, fn);
874+ };
875+
876+ Assertion.addMethod = function (name, fn) {
877+ util.addMethod(this.prototype, name, fn);
878+ };
879+
880+ Assertion.addChainableMethod = function (name, fn, chainingBehavior) {
881+ util.addChainableMethod(this.prototype, name, fn, chainingBehavior);
882+ };
883+
884+ Assertion.overwriteProperty = function (name, fn) {
885+ util.overwriteProperty(this.prototype, name, fn);
886+ };
887+
888+ Assertion.overwriteMethod = function (name, fn) {
889+ util.overwriteMethod(this.prototype, name, fn);
890+ };
891+
892+ /*!
893+ * ### .assert(expression, message, negateMessage, expected, actual)
894+ *
895+ * Executes an expression and check expectations. Throws AssertionError for reporting if test doesn't pass.
896+ *
897+ * @name assert
898+ * @param {Philosophical} expression to be tested
899+ * @param {String} message to display if fails
900+ * @param {String} negatedMessage to display if negated expression fails
901+ * @param {Mixed} expected value (remember to check for negation)
902+ * @param {Mixed} actual (optional) will default to `this.obj`
903+ * @api private
904+ */
905+
906+ Assertion.prototype.assert = function (expr, msg, negateMsg, expected, _actual, showDiff) {
907+ var ok = util.test(this, arguments);
908+ if (true !== showDiff) showDiff = false;
909+ if (true !== Assertion.showDiff) showDiff = false;
910+
911+ if (!ok) {
912+ var msg = util.getMessage(this, arguments)
913+ , actual = util.getActual(this, arguments);
914+ throw new AssertionError(msg, {
915+ actual: actual
916+ , expected: expected
917+ , showDiff: showDiff
918+ }, (Assertion.includeStack) ? this.assert : flag(this, 'ssfi'));
919+ }
920+ };
921+
922+ /*!
923+ * ### ._obj
924+ *
925+ * Quick reference to stored `actual` value for plugin developers.
926+ *
927+ * @api private
928+ */
929+
930+ Object.defineProperty(Assertion.prototype, '_obj',
931+ { get: function () {
932+ return flag(this, 'object');
933+ }
934+ , set: function (val) {
935+ flag(this, 'object', val);
936+ }
937+ });
938+};
939+
940+});
941+require.register("chai/lib/chai/core/assertions.js", function(exports, require, module){
942+/*!
943+ * chai
944+ * http://chaijs.com
945+ * Copyright(c) 2011-2013 Jake Luer <jake@alogicalparadox.com>
946+ * MIT Licensed
947+ */
948+
949+module.exports = function (chai, _) {
950+ var Assertion = chai.Assertion
951+ , toString = Object.prototype.toString
952+ , flag = _.flag;
953+
954+ /**
955+ * ### Language Chains
956+ *
957+ * The following are provide as chainable getters to
958+ * improve the readability of your assertions. They
959+ * do not provide an testing capability unless they
960+ * have been overwritten by a plugin.
961+ *
962+ * **Chains**
963+ *
964+ * - to
965+ * - be
966+ * - been
967+ * - is
968+ * - that
969+ * - and
970+ * - have
971+ * - with
972+ * - at
973+ * - of
974+ * - same
975+ *
976+ * @name language chains
977+ * @api public
978+ */
979+
980+ [ 'to', 'be', 'been'
981+ , 'is', 'and', 'have'
982+ , 'with', 'that', 'at'
983+ , 'of', 'same' ].forEach(function (chain) {
984+ Assertion.addProperty(chain, function () {
985+ return this;
986+ });
987+ });
988+
989+ /**
990+ * ### .not
991+ *
992+ * Negates any of assertions following in the chain.
993+ *
994+ * expect(foo).to.not.equal('bar');
995+ * expect(goodFn).to.not.throw(Error);
996+ * expect({ foo: 'baz' }).to.have.property('foo')
997+ * .and.not.equal('bar');
998+ *
999+ * @name not
1000+ * @api public
1001+ */
1002+
1003+ Assertion.addProperty('not', function () {
1004+ flag(this, 'negate', true);
1005+ });
1006+
1007+ /**
1008+ * ### .deep
1009+ *
1010+ * Sets the `deep` flag, later used by the `equal` and
1011+ * `property` assertions.
1012+ *
1013+ * expect(foo).to.deep.equal({ bar: 'baz' });
1014+ * expect({ foo: { bar: { baz: 'quux' } } })
1015+ * .to.have.deep.property('foo.bar.baz', 'quux');
1016+ *
1017+ * @name deep
1018+ * @api public
1019+ */
1020+
1021+ Assertion.addProperty('deep', function () {
1022+ flag(this, 'deep', true);
1023+ });
1024+
1025+ /**
1026+ * ### .a(type)
1027+ *
1028+ * The `a` and `an` assertions are aliases that can be
1029+ * used either as language chains or to assert a value's
1030+ * type.
1031+ *
1032+ * // typeof
1033+ * expect('test').to.be.a('string');
1034+ * expect({ foo: 'bar' }).to.be.an('object');
1035+ * expect(null).to.be.a('null');
1036+ * expect(undefined).to.be.an('undefined');
1037+ *
1038+ * // language chain
1039+ * expect(foo).to.be.an.instanceof(Foo);
1040+ *
1041+ * @name a
1042+ * @alias an
1043+ * @param {String} type
1044+ * @param {String} message _optional_
1045+ * @api public
1046+ */
1047+
1048+ function an (type, msg) {
1049+ if (msg) flag(this, 'message', msg);
1050+ type = type.toLowerCase();
1051+ var obj = flag(this, 'object')
1052+ , article = ~[ 'a', 'e', 'i', 'o', 'u' ].indexOf(type.charAt(0)) ? 'an ' : 'a ';
1053+
1054+ this.assert(
1055+ type === _.type(obj)
1056+ , 'expected #{this} to be ' + article + type
1057+ , 'expected #{this} not to be ' + article + type
1058+ );
1059+ }
1060+
1061+ Assertion.addChainableMethod('an', an);
1062+ Assertion.addChainableMethod('a', an);
1063+
1064+ /**
1065+ * ### .include(value)
1066+ *
1067+ * The `include` and `contain` assertions can be used as either property
1068+ * based language chains or as methods to assert the inclusion of an object
1069+ * in an array or a substring in a string. When used as language chains,
1070+ * they toggle the `contain` flag for the `keys` assertion.
1071+ *
1072+ * expect([1,2,3]).to.include(2);
1073+ * expect('foobar').to.contain('foo');
1074+ * expect({ foo: 'bar', hello: 'universe' }).to.include.keys('foo');
1075+ *
1076+ * @name include
1077+ * @alias contain
1078+ * @param {Object|String|Number} obj
1079+ * @param {String} message _optional_
1080+ * @api public
1081+ */
1082+
1083+ function includeChainingBehavior () {
1084+ flag(this, 'contains', true);
1085+ }
1086+
1087+ function include (val, msg) {
1088+ if (msg) flag(this, 'message', msg);
1089+ var obj = flag(this, 'object')
1090+ this.assert(
1091+ ~obj.indexOf(val)
1092+ , 'expected #{this} to include ' + _.inspect(val)
1093+ , 'expected #{this} to not include ' + _.inspect(val));
1094+ }
1095+
1096+ Assertion.addChainableMethod('include', include, includeChainingBehavior);
1097+ Assertion.addChainableMethod('contain', include, includeChainingBehavior);
1098+
1099+ /**
1100+ * ### .ok
1101+ *
1102+ * Asserts that the target is truthy.
1103+ *
1104+ * expect('everthing').to.be.ok;
1105+ * expect(1).to.be.ok;
1106+ * expect(false).to.not.be.ok;
1107+ * expect(undefined).to.not.be.ok;
1108+ * expect(null).to.not.be.ok;
1109+ *
1110+ * @name ok
1111+ * @api public
1112+ */
1113+
1114+ Assertion.addProperty('ok', function () {
1115+ this.assert(
1116+ flag(this, 'object')
1117+ , 'expected #{this} to be truthy'
1118+ , 'expected #{this} to be falsy');
1119+ });
1120+
1121+ /**
1122+ * ### .true
1123+ *
1124+ * Asserts that the target is `true`.
1125+ *
1126+ * expect(true).to.be.true;
1127+ * expect(1).to.not.be.true;
1128+ *
1129+ * @name true
1130+ * @api public
1131+ */
1132+
1133+ Assertion.addProperty('true', function () {
1134+ this.assert(
1135+ true === flag(this, 'object')
1136+ , 'expected #{this} to be true'
1137+ , 'expected #{this} to be false'
1138+ , this.negate ? false : true
1139+ );
1140+ });
1141+
1142+ /**
1143+ * ### .false
1144+ *
1145+ * Asserts that the target is `false`.
1146+ *
1147+ * expect(false).to.be.false;
1148+ * expect(0).to.not.be.false;
1149+ *
1150+ * @name false
1151+ * @api public
1152+ */
1153+
1154+ Assertion.addProperty('false', function () {
1155+ this.assert(
1156+ false === flag(this, 'object')
1157+ , 'expected #{this} to be false'
1158+ , 'expected #{this} to be true'
1159+ , this.negate ? true : false
1160+ );
1161+ });
1162+
1163+ /**
1164+ * ### .null
1165+ *
1166+ * Asserts that the target is `null`.
1167+ *
1168+ * expect(null).to.be.null;
1169+ * expect(undefined).not.to.be.null;
1170+ *
1171+ * @name null
1172+ * @api public
1173+ */
1174+
1175+ Assertion.addProperty('null', function () {
1176+ this.assert(
1177+ null === flag(this, 'object')
1178+ , 'expected #{this} to be null'
1179+ , 'expected #{this} not to be null'
1180+ );
1181+ });
1182+
1183+ /**
1184+ * ### .undefined
1185+ *
1186+ * Asserts that the target is `undefined`.
1187+ *
1188+ * expect(undefined).to.be.undefined;
1189+ * expect(null).to.not.be.undefined;
1190+ *
1191+ * @name undefined
1192+ * @api public
1193+ */
1194+
1195+ Assertion.addProperty('undefined', function () {
1196+ this.assert(
1197+ undefined === flag(this, 'object')
1198+ , 'expected #{this} to be undefined'
1199+ , 'expected #{this} not to be undefined'
1200+ );
1201+ });
1202+
1203+ /**
1204+ * ### .exist
1205+ *
1206+ * Asserts that the target is neither `null` nor `undefined`.
1207+ *
1208+ * var foo = 'hi'
1209+ * , bar = null
1210+ * , baz;
1211+ *
1212+ * expect(foo).to.exist;
1213+ * expect(bar).to.not.exist;
1214+ * expect(baz).to.not.exist;
1215+ *
1216+ * @name exist
1217+ * @api public
1218+ */
1219+
1220+ Assertion.addProperty('exist', function () {
1221+ this.assert(
1222+ null != flag(this, 'object')
1223+ , 'expected #{this} to exist'
1224+ , 'expected #{this} to not exist'
1225+ );
1226+ });
1227+
1228+
1229+ /**
1230+ * ### .empty
1231+ *
1232+ * Asserts that the target's length is `0`. For arrays, it checks
1233+ * the `length` property. For objects, it gets the count of
1234+ * enumerable keys.
1235+ *
1236+ * expect([]).to.be.empty;
1237+ * expect('').to.be.empty;
1238+ * expect({}).to.be.empty;
1239+ *
1240+ * @name empty
1241+ * @api public
1242+ */
1243+
1244+ Assertion.addProperty('empty', function () {
1245+ var obj = flag(this, 'object')
1246+ , expected = obj;
1247+
1248+ if (Array.isArray(obj) || 'string' === typeof object) {
1249+ expected = obj.length;
1250+ } else if (typeof obj === 'object') {
1251+ expected = Object.keys(obj).length;
1252+ }
1253+
1254+ this.assert(
1255+ !expected
1256+ , 'expected #{this} to be empty'
1257+ , 'expected #{this} not to be empty'
1258+ );
1259+ });
1260+
1261+ /**
1262+ * ### .arguments
1263+ *
1264+ * Asserts that the target is an arguments object.
1265+ *
1266+ * function test () {
1267+ * expect(arguments).to.be.arguments;
1268+ * }
1269+ *
1270+ * @name arguments
1271+ * @alias Arguments
1272+ * @api public
1273+ */
1274+
1275+ function checkArguments () {
1276+ var obj = flag(this, 'object')
1277+ , type = Object.prototype.toString.call(obj);
1278+ this.assert(
1279+ '[object Arguments]' === type
1280+ , 'expected #{this} to be arguments but got ' + type
1281+ , 'expected #{this} to not be arguments'
1282+ );
1283+ }
1284+
1285+ Assertion.addProperty('arguments', checkArguments);
1286+ Assertion.addProperty('Arguments', checkArguments);
1287+
1288+ /**
1289+ * ### .equal(value)
1290+ *
1291+ * Asserts that the target is strictly equal (`===`) to `value`.
1292+ * Alternately, if the `deep` flag is set, asserts that
1293+ * the target is deeply equal to `value`.
1294+ *
1295+ * expect('hello').to.equal('hello');
1296+ * expect(42).to.equal(42);
1297+ * expect(1).to.not.equal(true);
1298+ * expect({ foo: 'bar' }).to.not.equal({ foo: 'bar' });
1299+ * expect({ foo: 'bar' }).to.deep.equal({ foo: 'bar' });
1300+ *
1301+ * @name equal
1302+ * @alias equals
1303+ * @alias eq
1304+ * @alias deep.equal
1305+ * @param {Mixed} value
1306+ * @param {String} message _optional_
1307+ * @api public
1308+ */
1309+
1310+ function assertEqual (val, msg) {
1311+ if (msg) flag(this, 'message', msg);
1312+ var obj = flag(this, 'object');
1313+ if (flag(this, 'deep')) {
1314+ return this.eql(val);
1315+ } else {
1316+ this.assert(
1317+ val === obj
1318+ , 'expected #{this} to equal #{exp}'
1319+ , 'expected #{this} to not equal #{exp}'
1320+ , val
1321+ , this._obj
1322+ , true
1323+ );
1324+ }
1325+ }
1326+
1327+ Assertion.addMethod('equal', assertEqual);
1328+ Assertion.addMethod('equals', assertEqual);
1329+ Assertion.addMethod('eq', assertEqual);
1330+
1331+ /**
1332+ * ### .eql(value)
1333+ *
1334+ * Asserts that the target is deeply equal to `value`.
1335+ *
1336+ * expect({ foo: 'bar' }).to.eql({ foo: 'bar' });
1337+ * expect([ 1, 2, 3 ]).to.eql([ 1, 2, 3 ]);
1338+ *
1339+ * @name eql
1340+ * @alias eqls
1341+ * @param {Mixed} value
1342+ * @param {String} message _optional_
1343+ * @api public
1344+ */
1345+
1346+ function assertEql(obj, msg) {
1347+ if (msg) flag(this, 'message', msg);
1348+ this.assert(
1349+ _.eql(obj, flag(this, 'object'))
1350+ , 'expected #{this} to deeply equal #{exp}'
1351+ , 'expected #{this} to not deeply equal #{exp}'
1352+ , obj
1353+ , this._obj
1354+ , true
1355+ );
1356+ }
1357+
1358+ Assertion.addMethod('eql', assertEql);
1359+ Assertion.addMethod('eqls', assertEql);
1360+
1361+ /**
1362+ * ### .above(value)
1363+ *
1364+ * Asserts that the target is greater than `value`.
1365+ *
1366+ * expect(10).to.be.above(5);
1367+ *
1368+ * Can also be used in conjunction with `length` to
1369+ * assert a minimum length. The benefit being a
1370+ * more informative error message than if the length
1371+ * was supplied directly.
1372+ *
1373+ * expect('foo').to.have.length.above(2);
1374+ * expect([ 1, 2, 3 ]).to.have.length.above(2);
1375+ *
1376+ * @name above
1377+ * @alias gt
1378+ * @alias greaterThan
1379+ * @param {Number} value
1380+ * @param {String} message _optional_
1381+ * @api public
1382+ */
1383+
1384+ function assertAbove (n, msg) {
1385+ if (msg) flag(this, 'message', msg);
1386+ var obj = flag(this, 'object');
1387+ if (flag(this, 'doLength')) {
1388+ new Assertion(obj, msg).to.have.property('length');
1389+ var len = obj.length;
1390+ this.assert(
1391+ len > n
1392+ , 'expected #{this} to have a length above #{exp} but got #{act}'
1393+ , 'expected #{this} to not have a length above #{exp}'
1394+ , n
1395+ , len
1396+ );
1397+ } else {
1398+ this.assert(
1399+ obj > n
1400+ , 'expected #{this} to be above ' + n
1401+ , 'expected #{this} to be at most ' + n
1402+ );
1403+ }
1404+ }
1405+
1406+ Assertion.addMethod('above', assertAbove);
1407+ Assertion.addMethod('gt', assertAbove);
1408+ Assertion.addMethod('greaterThan', assertAbove);
1409+
1410+ /**
1411+ * ### .least(value)
1412+ *
1413+ * Asserts that the target is greater than or equal to `value`.
1414+ *
1415+ * expect(10).to.be.at.least(10);
1416+ *
1417+ * Can also be used in conjunction with `length` to
1418+ * assert a minimum length. The benefit being a
1419+ * more informative error message than if the length
1420+ * was supplied directly.
1421+ *
1422+ * expect('foo').to.have.length.of.at.least(2);
1423+ * expect([ 1, 2, 3 ]).to.have.length.of.at.least(3);
1424+ *
1425+ * @name least
1426+ * @alias gte
1427+ * @param {Number} value
1428+ * @param {String} message _optional_
1429+ * @api public
1430+ */
1431+
1432+ function assertLeast (n, msg) {
1433+ if (msg) flag(this, 'message', msg);
1434+ var obj = flag(this, 'object');
1435+ if (flag(this, 'doLength')) {
1436+ new Assertion(obj, msg).to.have.property('length');
1437+ var len = obj.length;
1438+ this.assert(
1439+ len >= n
1440+ , 'expected #{this} to have a length at least #{exp} but got #{act}'
1441+ , 'expected #{this} to have a length below #{exp}'
1442+ , n
1443+ , len
1444+ );
1445+ } else {
1446+ this.assert(
1447+ obj >= n
1448+ , 'expected #{this} to be at least ' + n
1449+ , 'expected #{this} to be below ' + n
1450+ );
1451+ }
1452+ }
1453+
1454+ Assertion.addMethod('least', assertLeast);
1455+ Assertion.addMethod('gte', assertLeast);
1456+
1457+ /**
1458+ * ### .below(value)
1459+ *
1460+ * Asserts that the target is less than `value`.
1461+ *
1462+ * expect(5).to.be.below(10);
1463+ *
1464+ * Can also be used in conjunction with `length` to
1465+ * assert a maximum length. The benefit being a
1466+ * more informative error message than if the length
1467+ * was supplied directly.
1468+ *
1469+ * expect('foo').to.have.length.below(4);
1470+ * expect([ 1, 2, 3 ]).to.have.length.below(4);
1471+ *
1472+ * @name below
1473+ * @alias lt
1474+ * @alias lessThan
1475+ * @param {Number} value
1476+ * @param {String} message _optional_
1477+ * @api public
1478+ */
1479+
1480+ function assertBelow (n, msg) {
1481+ if (msg) flag(this, 'message', msg);
1482+ var obj = flag(this, 'object');
1483+ if (flag(this, 'doLength')) {
1484+ new Assertion(obj, msg).to.have.property('length');
1485+ var len = obj.length;
1486+ this.assert(
1487+ len < n
1488+ , 'expected #{this} to have a length below #{exp} but got #{act}'
1489+ , 'expected #{this} to not have a length below #{exp}'
1490+ , n
1491+ , len
1492+ );
1493+ } else {
1494+ this.assert(
1495+ obj < n
1496+ , 'expected #{this} to be below ' + n
1497+ , 'expected #{this} to be at least ' + n
1498+ );
1499+ }
1500+ }
1501+
1502+ Assertion.addMethod('below', assertBelow);
1503+ Assertion.addMethod('lt', assertBelow);
1504+ Assertion.addMethod('lessThan', assertBelow);
1505+
1506+ /**
1507+ * ### .most(value)
1508+ *
1509+ * Asserts that the target is less than or equal to `value`.
1510+ *
1511+ * expect(5).to.be.at.most(5);
1512+ *
1513+ * Can also be used in conjunction with `length` to
1514+ * assert a maximum length. The benefit being a
1515+ * more informative error message than if the length
1516+ * was supplied directly.
1517+ *
1518+ * expect('foo').to.have.length.of.at.most(4);
1519+ * expect([ 1, 2, 3 ]).to.have.length.of.at.most(3);
1520+ *
1521+ * @name most
1522+ * @alias lte
1523+ * @param {Number} value
1524+ * @param {String} message _optional_
1525+ * @api public
1526+ */
1527+
1528+ function assertMost (n, msg) {
1529+ if (msg) flag(this, 'message', msg);
1530+ var obj = flag(this, 'object');
1531+ if (flag(this, 'doLength')) {
1532+ new Assertion(obj, msg).to.have.property('length');
1533+ var len = obj.length;
1534+ this.assert(
1535+ len <= n
1536+ , 'expected #{this} to have a length at most #{exp} but got #{act}'
1537+ , 'expected #{this} to have a length above #{exp}'
1538+ , n
1539+ , len
1540+ );
1541+ } else {
1542+ this.assert(
1543+ obj <= n
1544+ , 'expected #{this} to be at most ' + n
1545+ , 'expected #{this} to be above ' + n
1546+ );
1547+ }
1548+ }
1549+
1550+ Assertion.addMethod('most', assertMost);
1551+ Assertion.addMethod('lte', assertMost);
1552+
1553+ /**
1554+ * ### .within(start, finish)
1555+ *
1556+ * Asserts that the target is within a range.
1557+ *
1558+ * expect(7).to.be.within(5,10);
1559+ *
1560+ * Can also be used in conjunction with `length` to
1561+ * assert a length range. The benefit being a
1562+ * more informative error message than if the length
1563+ * was supplied directly.
1564+ *
1565+ * expect('foo').to.have.length.within(2,4);
1566+ * expect([ 1, 2, 3 ]).to.have.length.within(2,4);
1567+ *
1568+ * @name within
1569+ * @param {Number} start lowerbound inclusive
1570+ * @param {Number} finish upperbound inclusive
1571+ * @param {String} message _optional_
1572+ * @api public
1573+ */
1574+
1575+ Assertion.addMethod('within', function (start, finish, msg) {
1576+ if (msg) flag(this, 'message', msg);
1577+ var obj = flag(this, 'object')
1578+ , range = start + '..' + finish;
1579+ if (flag(this, 'doLength')) {
1580+ new Assertion(obj, msg).to.have.property('length');
1581+ var len = obj.length;
1582+ this.assert(
1583+ len >= start && len <= finish
1584+ , 'expected #{this} to have a length within ' + range
1585+ , 'expected #{this} to not have a length within ' + range
1586+ );
1587+ } else {
1588+ this.assert(
1589+ obj >= start && obj <= finish
1590+ , 'expected #{this} to be within ' + range
1591+ , 'expected #{this} to not be within ' + range
1592+ );
1593+ }
1594+ });
1595+
1596+ /**
1597+ * ### .instanceof(constructor)
1598+ *
1599+ * Asserts that the target is an instance of `constructor`.
1600+ *
1601+ * var Tea = function (name) { this.name = name; }
1602+ * , Chai = new Tea('chai');
1603+ *
1604+ * expect(Chai).to.be.an.instanceof(Tea);
1605+ * expect([ 1, 2, 3 ]).to.be.instanceof(Array);
1606+ *
1607+ * @name instanceof
1608+ * @param {Constructor} constructor
1609+ * @param {String} message _optional_
1610+ * @alias instanceOf
1611+ * @api public
1612+ */
1613+
1614+ function assertInstanceOf (constructor, msg) {
1615+ if (msg) flag(this, 'message', msg);
1616+ var name = _.getName(constructor);
1617+ this.assert(
1618+ flag(this, 'object') instanceof constructor
1619+ , 'expected #{this} to be an instance of ' + name
1620+ , 'expected #{this} to not be an instance of ' + name
1621+ );
1622+ };
1623+
1624+ Assertion.addMethod('instanceof', assertInstanceOf);
1625+ Assertion.addMethod('instanceOf', assertInstanceOf);
1626+
1627+ /**
1628+ * ### .property(name, [value])
1629+ *
1630+ * Asserts that the target has a property `name`, optionally asserting that
1631+ * the value of that property is strictly equal to `value`.
1632+ * If the `deep` flag is set, you can use dot- and bracket-notation for deep
1633+ * references into objects and arrays.
1634+ *
1635+ * // simple referencing
1636+ * var obj = { foo: 'bar' };
1637+ * expect(obj).to.have.property('foo');
1638+ * expect(obj).to.have.property('foo', 'bar');
1639+ *
1640+ * // deep referencing
1641+ * var deepObj = {
1642+ * green: { tea: 'matcha' }
1643+ * , teas: [ 'chai', 'matcha', { tea: 'konacha' } ]
1644+ * };
1645+
1646+ * expect(deepObj).to.have.deep.property('green.tea', 'matcha');
1647+ * expect(deepObj).to.have.deep.property('teas[1]', 'matcha');
1648+ * expect(deepObj).to.have.deep.property('teas[2].tea', 'konacha');
1649+ *
1650+ * You can also use an array as the starting point of a `deep.property`
1651+ * assertion, or traverse nested arrays.
1652+ *
1653+ * var arr = [
1654+ * [ 'chai', 'matcha', 'konacha' ]
1655+ * , [ { tea: 'chai' }
1656+ * , { tea: 'matcha' }
1657+ * , { tea: 'konacha' } ]
1658+ * ];
1659+ *
1660+ * expect(arr).to.have.deep.property('[0][1]', 'matcha');
1661+ * expect(arr).to.have.deep.property('[1][2].tea', 'konacha');
1662+ *
1663+ * Furthermore, `property` changes the subject of the assertion
1664+ * to be the value of that property from the original object. This
1665+ * permits for further chainable assertions on that property.
1666+ *
1667+ * expect(obj).to.have.property('foo')
1668+ * .that.is.a('string');
1669+ * expect(deepObj).to.have.property('green')
1670+ * .that.is.an('object')
1671+ * .that.deep.equals({ tea: 'matcha' });
1672+ * expect(deepObj).to.have.property('teas')
1673+ * .that.is.an('array')
1674+ * .with.deep.property('[2]')
1675+ * .that.deep.equals({ tea: 'konacha' });
1676+ *
1677+ * @name property
1678+ * @alias deep.property
1679+ * @param {String} name
1680+ * @param {Mixed} value (optional)
1681+ * @param {String} message _optional_
1682+ * @returns value of property for chaining
1683+ * @api public
1684+ */
1685+
1686+ Assertion.addMethod('property', function (name, val, msg) {
1687+ if (msg) flag(this, 'message', msg);
1688+
1689+ var descriptor = flag(this, 'deep') ? 'deep property ' : 'property '
1690+ , negate = flag(this, 'negate')
1691+ , obj = flag(this, 'object')
1692+ , value = flag(this, 'deep')
1693+ ? _.getPathValue(name, obj)
1694+ : obj[name];
1695+
1696+ if (negate && undefined !== val) {
1697+ if (undefined === value) {
1698+ msg = (msg != null) ? msg + ': ' : '';
1699+ throw new Error(msg + _.inspect(obj) + ' has no ' + descriptor + _.inspect(name));
1700+ }
1701+ } else {
1702+ this.assert(
1703+ undefined !== value
1704+ , 'expected #{this} to have a ' + descriptor + _.inspect(name)
1705+ , 'expected #{this} to not have ' + descriptor + _.inspect(name));
1706+ }
1707+
1708+ if (undefined !== val) {
1709+ this.assert(
1710+ val === value
1711+ , 'expected #{this} to have a ' + descriptor + _.inspect(name) + ' of #{exp}, but got #{act}'
1712+ , 'expected #{this} to not have a ' + descriptor + _.inspect(name) + ' of #{act}'
1713+ , val
1714+ , value
1715+ );
1716+ }
1717+
1718+ flag(this, 'object', value);
1719+ });
1720+
1721+
1722+ /**
1723+ * ### .ownProperty(name)
1724+ *
1725+ * Asserts that the target has an own property `name`.
1726+ *
1727+ * expect('test').to.have.ownProperty('length');
1728+ *
1729+ * @name ownProperty
1730+ * @alias haveOwnProperty
1731+ * @param {String} name
1732+ * @param {String} message _optional_
1733+ * @api public
1734+ */
1735+
1736+ function assertOwnProperty (name, msg) {
1737+ if (msg) flag(this, 'message', msg);
1738+ var obj = flag(this, 'object');
1739+ this.assert(
1740+ obj.hasOwnProperty(name)
1741+ , 'expected #{this} to have own property ' + _.inspect(name)
1742+ , 'expected #{this} to not have own property ' + _.inspect(name)
1743+ );
1744+ }
1745+
1746+ Assertion.addMethod('ownProperty', assertOwnProperty);
1747+ Assertion.addMethod('haveOwnProperty', assertOwnProperty);
1748+
1749+ /**
1750+ * ### .length(value)
1751+ *
1752+ * Asserts that the target's `length` property has
1753+ * the expected value.
1754+ *
1755+ * expect([ 1, 2, 3]).to.have.length(3);
1756+ * expect('foobar').to.have.length(6);
1757+ *
1758+ * Can also be used as a chain precursor to a value
1759+ * comparison for the length property.
1760+ *
1761+ * expect('foo').to.have.length.above(2);
1762+ * expect([ 1, 2, 3 ]).to.have.length.above(2);
1763+ * expect('foo').to.have.length.below(4);
1764+ * expect([ 1, 2, 3 ]).to.have.length.below(4);
1765+ * expect('foo').to.have.length.within(2,4);
1766+ * expect([ 1, 2, 3 ]).to.have.length.within(2,4);
1767+ *
1768+ * @name length
1769+ * @alias lengthOf
1770+ * @param {Number} length
1771+ * @param {String} message _optional_
1772+ * @api public
1773+ */
1774+
1775+ function assertLengthChain () {
1776+ flag(this, 'doLength', true);
1777+ }
1778+
1779+ function assertLength (n, msg) {
1780+ if (msg) flag(this, 'message', msg);
1781+ var obj = flag(this, 'object');
1782+ new Assertion(obj, msg).to.have.property('length');
1783+ var len = obj.length;
1784+
1785+ this.assert(
1786+ len == n
1787+ , 'expected #{this} to have a length of #{exp} but got #{act}'
1788+ , 'expected #{this} to not have a length of #{act}'
1789+ , n
1790+ , len
1791+ );
1792+ }
1793+
1794+ Assertion.addChainableMethod('length', assertLength, assertLengthChain);
1795+ Assertion.addMethod('lengthOf', assertLength, assertLengthChain);
1796+
1797+ /**
1798+ * ### .match(regexp)
1799+ *
1800+ * Asserts that the target matches a regular expression.
1801+ *
1802+ * expect('foobar').to.match(/^foo/);
1803+ *
1804+ * @name match
1805+ * @param {RegExp} RegularExpression
1806+ * @param {String} message _optional_
1807+ * @api public
1808+ */
1809+
1810+ Assertion.addMethod('match', function (re, msg) {
1811+ if (msg) flag(this, 'message', msg);
1812+ var obj = flag(this, 'object');
1813+ this.assert(
1814+ re.exec(obj)
1815+ , 'expected #{this} to match ' + re
1816+ , 'expected #{this} not to match ' + re
1817+ );
1818+ });
1819+
1820+ /**
1821+ * ### .string(string)
1822+ *
1823+ * Asserts that the string target contains another string.
1824+ *
1825+ * expect('foobar').to.have.string('bar');
1826+ *
1827+ * @name string
1828+ * @param {String} string
1829+ * @param {String} message _optional_
1830+ * @api public
1831+ */
1832+
1833+ Assertion.addMethod('string', function (str, msg) {
1834+ if (msg) flag(this, 'message', msg);
1835+ var obj = flag(this, 'object');
1836+ new Assertion(obj, msg).is.a('string');
1837+
1838+ this.assert(
1839+ ~obj.indexOf(str)
1840+ , 'expected #{this} to contain ' + _.inspect(str)
1841+ , 'expected #{this} to not contain ' + _.inspect(str)
1842+ );
1843+ });
1844+
1845+
1846+ /**
1847+ * ### .keys(key1, [key2], [...])
1848+ *
1849+ * Asserts that the target has exactly the given keys, or
1850+ * asserts the inclusion of some keys when using the
1851+ * `include` or `contain` modifiers.
1852+ *
1853+ * expect({ foo: 1, bar: 2 }).to.have.keys(['foo', 'bar']);
1854+ * expect({ foo: 1, bar: 2, baz: 3 }).to.contain.keys('foo', 'bar');
1855+ *
1856+ * @name keys
1857+ * @alias key
1858+ * @param {String...|Array} keys
1859+ * @api public
1860+ */
1861+
1862+ function assertKeys (keys) {
1863+ var obj = flag(this, 'object')
1864+ , str
1865+ , ok = true;
1866+
1867+ keys = keys instanceof Array
1868+ ? keys
1869+ : Array.prototype.slice.call(arguments);
1870+
1871+ if (!keys.length) throw new Error('keys required');
1872+
1873+ var actual = Object.keys(obj)
1874+ , len = keys.length;
1875+
1876+ // Inclusion
1877+ ok = keys.every(function(key){
1878+ return ~actual.indexOf(key);
1879+ });
1880+
1881+ // Strict
1882+ if (!flag(this, 'negate') && !flag(this, 'contains')) {
1883+ ok = ok && keys.length == actual.length;
1884+ }
1885+
1886+ // Key string
1887+ if (len > 1) {
1888+ keys = keys.map(function(key){
1889+ return _.inspect(key);
1890+ });
1891+ var last = keys.pop();
1892+ str = keys.join(', ') + ', and ' + last;
1893+ } else {
1894+ str = _.inspect(keys[0]);
1895+ }
1896+
1897+ // Form
1898+ str = (len > 1 ? 'keys ' : 'key ') + str;
1899+
1900+ // Have / include
1901+ str = (flag(this, 'contains') ? 'contain ' : 'have ') + str;
1902+
1903+ // Assertion
1904+ this.assert(
1905+ ok
1906+ , 'expected #{this} to ' + str
1907+ , 'expected #{this} to not ' + str
1908+ );
1909+ }
1910+
1911+ Assertion.addMethod('keys', assertKeys);
1912+ Assertion.addMethod('key', assertKeys);
1913+
1914+ /**
1915+ * ### .throw(constructor)
1916+ *
1917+ * Asserts that the function target will throw a specific error, or specific type of error
1918+ * (as determined using `instanceof`), optionally with a RegExp or string inclusion test
1919+ * for the error's message.
1920+ *
1921+ * var err = new ReferenceError('This is a bad function.');
1922+ * var fn = function () { throw err; }
1923+ * expect(fn).to.throw(ReferenceError);
1924+ * expect(fn).to.throw(Error);
1925+ * expect(fn).to.throw(/bad function/);
1926+ * expect(fn).to.not.throw('good function');
1927+ * expect(fn).to.throw(ReferenceError, /bad function/);
1928+ * expect(fn).to.throw(err);
1929+ * expect(fn).to.not.throw(new RangeError('Out of range.'));
1930+ *
1931+ * Please note that when a throw expectation is negated, it will check each
1932+ * parameter independently, starting with error constructor type. The appropriate way
1933+ * to check for the existence of a type of error but for a message that does not match
1934+ * is to use `and`.
1935+ *
1936+ * expect(fn).to.throw(ReferenceError)
1937+ * .and.not.throw(/good function/);
1938+ *
1939+ * @name throw
1940+ * @alias throws
1941+ * @alias Throw
1942+ * @param {ErrorConstructor} constructor
1943+ * @param {String|RegExp} expected error message
1944+ * @param {String} message _optional_
1945+ * @see https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Error#Error_types
1946+ * @api public
1947+ */
1948+
1949+ function assertThrows (constructor, errMsg, msg) {
1950+ if (msg) flag(this, 'message', msg);
1951+ var obj = flag(this, 'object');
1952+ new Assertion(obj, msg).is.a('function');
1953+
1954+ var thrown = false
1955+ , desiredError = null
1956+ , name = null
1957+ , thrownError = null;
1958+
1959+ if (arguments.length === 0) {
1960+ errMsg = null;
1961+ constructor = null;
1962+ } else if (constructor && (constructor instanceof RegExp || 'string' === typeof constructor)) {
1963+ errMsg = constructor;
1964+ constructor = null;
1965+ } else if (constructor && constructor instanceof Error) {
1966+ desiredError = constructor;
1967+ constructor = null;
1968+ errMsg = null;
1969+ } else if (typeof constructor === 'function') {
1970+ name = (new constructor()).name;
1971+ } else {
1972+ constructor = null;
1973+ }
1974+
1975+ try {
1976+ obj();
1977+ } catch (err) {
1978+ // first, check desired error
1979+ if (desiredError) {
1980+ this.assert(
1981+ err === desiredError
1982+ , 'expected #{this} to throw #{exp} but #{act} was thrown'
1983+ , 'expected #{this} to not throw #{exp}'
1984+ , desiredError
1985+ , err
1986+ );
1987+
1988+ return this;
1989+ }
1990+ // next, check constructor
1991+ if (constructor) {
1992+ this.assert(
1993+ err instanceof constructor
1994+ , 'expected #{this} to throw #{exp} but #{act} was thrown'
1995+ , 'expected #{this} to not throw #{exp} but #{act} was thrown'
1996+ , name
1997+ , err
1998+ );
1999+
2000+ if (!errMsg) return this;
2001+ }
2002+ // next, check message
2003+ var message = 'object' === _.type(err) && "message" in err
2004+ ? err.message
2005+ : '' + err;
2006+
2007+ if ((message != null) && errMsg && errMsg instanceof RegExp) {
2008+ this.assert(
2009+ errMsg.exec(message)
2010+ , 'expected #{this} to throw error matching #{exp} but got #{act}'
2011+ , 'expected #{this} to throw error not matching #{exp}'
2012+ , errMsg
2013+ , message
2014+ );
2015+
2016+ return this;
2017+ } else if ((message != null) && errMsg && 'string' === typeof errMsg) {
2018+ this.assert(
2019+ ~message.indexOf(errMsg)
2020+ , 'expected #{this} to throw error including #{exp} but got #{act}'
2021+ , 'expected #{this} to throw error not including #{act}'
2022+ , errMsg
2023+ , message
2024+ );
2025+
2026+ return this;
2027+ } else {
2028+ thrown = true;
2029+ thrownError = err;
2030+ }
2031+ }
2032+
2033+ var actuallyGot = ''
2034+ , expectedThrown = name !== null
2035+ ? name
2036+ : desiredError
2037+ ? '#{exp}' //_.inspect(desiredError)
2038+ : 'an error';
2039+
2040+ if (thrown) {
2041+ actuallyGot = ' but #{act} was thrown'
2042+ }
2043+
2044+ this.assert(
2045+ thrown === true
2046+ , 'expected #{this} to throw ' + expectedThrown + actuallyGot
2047+ , 'expected #{this} to not throw ' + expectedThrown + actuallyGot
2048+ , desiredError
2049+ , thrownError
2050+ );
2051+ };
2052+
2053+ Assertion.addMethod('throw', assertThrows);
2054+ Assertion.addMethod('throws', assertThrows);
2055+ Assertion.addMethod('Throw', assertThrows);
2056+
2057+ /**
2058+ * ### .respondTo(method)
2059+ *
2060+ * Asserts that the object or class target will respond to a method.
2061+ *
2062+ * Klass.prototype.bar = function(){};
2063+ * expect(Klass).to.respondTo('bar');
2064+ * expect(obj).to.respondTo('bar');
2065+ *
2066+ * To check if a constructor will respond to a static function,
2067+ * set the `itself` flag.
2068+ *
2069+ * Klass.baz = function(){};
2070+ * expect(Klass).itself.to.respondTo('baz');
2071+ *
2072+ * @name respondTo
2073+ * @param {String} method
2074+ * @param {String} message _optional_
2075+ * @api public
2076+ */
2077+
2078+ Assertion.addMethod('respondTo', function (method, msg) {
2079+ if (msg) flag(this, 'message', msg);
2080+ var obj = flag(this, 'object')
2081+ , itself = flag(this, 'itself')
2082+ , context = ('function' === _.type(obj) && !itself)
2083+ ? obj.prototype[method]
2084+ : obj[method];
2085+
2086+ this.assert(
2087+ 'function' === typeof context
2088+ , 'expected #{this} to respond to ' + _.inspect(method)
2089+ , 'expected #{this} to not respond to ' + _.inspect(method)
2090+ );
2091+ });
2092+
2093+ /**
2094+ * ### .itself
2095+ *
2096+ * Sets the `itself` flag, later used by the `respondTo` assertion.
2097+ *
2098+ * function Foo() {}
2099+ * Foo.bar = function() {}
2100+ * Foo.prototype.baz = function() {}
2101+ *
2102+ * expect(Foo).itself.to.respondTo('bar');
2103+ * expect(Foo).itself.not.to.respondTo('baz');
2104+ *
2105+ * @name itself
2106+ * @api public
2107+ */
2108+
2109+ Assertion.addProperty('itself', function () {
2110+ flag(this, 'itself', true);
2111+ });
2112+
2113+ /**
2114+ * ### .satisfy(method)
2115+ *
2116+ * Asserts that the target passes a given truth test.
2117+ *
2118+ * expect(1).to.satisfy(function(num) { return num > 0; });
2119+ *
2120+ * @name satisfy
2121+ * @param {Function} matcher
2122+ * @param {String} message _optional_
2123+ * @api public
2124+ */
2125+
2126+ Assertion.addMethod('satisfy', function (matcher, msg) {
2127+ if (msg) flag(this, 'message', msg);
2128+ var obj = flag(this, 'object');
2129+ this.assert(
2130+ matcher(obj)
2131+ , 'expected #{this} to satisfy ' + _.objDisplay(matcher)
2132+ , 'expected #{this} to not satisfy' + _.objDisplay(matcher)
2133+ , this.negate ? false : true
2134+ , matcher(obj)
2135+ );
2136+ });
2137+
2138+ /**
2139+ * ### .closeTo(expected, delta)
2140+ *
2141+ * Asserts that the target is equal `expected`, to within a +/- `delta` range.
2142+ *
2143+ * expect(1.5).to.be.closeTo(1, 0.5);
2144+ *
2145+ * @name closeTo
2146+ * @param {Number} expected
2147+ * @param {Number} delta
2148+ * @param {String} message _optional_
2149+ * @api public
2150+ */
2151+
2152+ Assertion.addMethod('closeTo', function (expected, delta, msg) {
2153+ if (msg) flag(this, 'message', msg);
2154+ var obj = flag(this, 'object');
2155+ this.assert(
2156+ Math.abs(obj - expected) <= delta
2157+ , 'expected #{this} to be close to ' + expected + ' +/- ' + delta
2158+ , 'expected #{this} not to be close to ' + expected + ' +/- ' + delta
2159+ );
2160+ });
2161+
2162+ function isSubsetOf(subset, superset) {
2163+ return subset.every(function(elem) {
2164+ return superset.indexOf(elem) !== -1;
2165+ })
2166+ }
2167+
2168+ /**
2169+ * ### .members(set)
2170+ *
2171+ * Asserts that the target is a superset of `set`,
2172+ * or that the target and `set` have the same members.
2173+ *
2174+ * expect([1, 2, 3]).to.include.members([3, 2]);
2175+ * expect([1, 2, 3]).to.not.include.members([3, 2, 8]);
2176+ *
2177+ * expect([4, 2]).to.have.members([2, 4]);
2178+ * expect([5, 2]).to.not.have.members([5, 2, 1]);
2179+ *
2180+ * @name members
2181+ * @param {Array} set
2182+ * @param {String} message _optional_
2183+ * @api public
2184+ */
2185+
2186+ Assertion.addMethod('members', function (subset, msg) {
2187+ if (msg) flag(this, 'message', msg);
2188+ var obj = flag(this, 'object');
2189+
2190+ new Assertion(obj).to.be.an('array');
2191+ new Assertion(subset).to.be.an('array');
2192+
2193+ if (flag(this, 'contains')) {
2194+ return this.assert(
2195+ isSubsetOf(subset, obj)
2196+ , 'expected #{this} to be a superset of #{act}'
2197+ , 'expected #{this} to not be a superset of #{act}'
2198+ , obj
2199+ , subset
2200+ );
2201+ }
2202+
2203+ this.assert(
2204+ isSubsetOf(obj, subset) && isSubsetOf(subset, obj)
2205+ , 'expected #{this} to have the same members as #{act}'
2206+ , 'expected #{this} to not have the same members as #{act}'
2207+ , obj
2208+ , subset
2209+ );
2210+ });
2211+};
2212+
2213+});
2214+require.register("chai/lib/chai/interface/assert.js", function(exports, require, module){
2215+/*!
2216+ * chai
2217+ * Copyright(c) 2011-2013 Jake Luer <jake@alogicalparadox.com>
2218+ * MIT Licensed
2219+ */
2220+
2221+
2222+module.exports = function (chai, util) {
2223+
2224+ /*!
2225+ * Chai dependencies.
2226+ */
2227+
2228+ var Assertion = chai.Assertion
2229+ , flag = util.flag;
2230+
2231+ /*!
2232+ * Module export.
2233+ */
2234+
2235+ /**
2236+ * ### assert(expression, message)
2237+ *
2238+ * Write your own test expressions.
2239+ *
2240+ * assert('foo' !== 'bar', 'foo is not bar');
2241+ * assert(Array.isArray([]), 'empty arrays are arrays');
2242+ *
2243+ * @param {Mixed} expression to test for truthiness
2244+ * @param {String} message to display on error
2245+ * @name assert
2246+ * @api public
2247+ */
2248+
2249+ var assert = chai.assert = function (express, errmsg) {
2250+ var test = new Assertion(null);
2251+ test.assert(
2252+ express
2253+ , errmsg
2254+ , '[ negation message unavailable ]'
2255+ );
2256+ };
2257+
2258+ /**
2259+ * ### .fail(actual, expected, [message], [operator])
2260+ *
2261+ * Throw a failure. Node.js `assert` module-compatible.
2262+ *
2263+ * @name fail
2264+ * @param {Mixed} actual
2265+ * @param {Mixed} expected
2266+ * @param {String} message
2267+ * @param {String} operator
2268+ * @api public
2269+ */
2270+
2271+ assert.fail = function (actual, expected, message, operator) {
2272+ throw new chai.AssertionError({
2273+ actual: actual
2274+ , expected: expected
2275+ , message: message
2276+ , operator: operator
2277+ , stackStartFunction: assert.fail
2278+ });
2279+ };
2280+
2281+ /**
2282+ * ### .ok(object, [message])
2283+ *
2284+ * Asserts that `object` is truthy.
2285+ *
2286+ * assert.ok('everything', 'everything is ok');
2287+ * assert.ok(false, 'this will fail');
2288+ *
2289+ * @name ok
2290+ * @param {Mixed} object to test
2291+ * @param {String} message
2292+ * @api public
2293+ */
2294+
2295+ assert.ok = function (val, msg) {
2296+ new Assertion(val, msg).is.ok;
2297+ };
2298+
2299+ /**
2300+ * ### .notOk(object, [message])
2301+ *
2302+ * Asserts that `object` is falsy.
2303+ *
2304+ * assert.notOk('everything', 'this will fail');
2305+ * assert.notOk(false, 'this will pass');
2306+ *
2307+ * @name notOk
2308+ * @param {Mixed} object to test
2309+ * @param {String} message
2310+ * @api public
2311+ */
2312+
2313+ assert.notOk = function (val, msg) {
2314+ new Assertion(val, msg).is.not.ok;
2315+ };
2316+
2317+ /**
2318+ * ### .equal(actual, expected, [message])
2319+ *
2320+ * Asserts non-strict equality (`==`) of `actual` and `expected`.
2321+ *
2322+ * assert.equal(3, '3', '== coerces values to strings');
2323+ *
2324+ * @name equal
2325+ * @param {Mixed} actual
2326+ * @param {Mixed} expected
2327+ * @param {String} message
2328+ * @api public
2329+ */
2330+
2331+ assert.equal = function (act, exp, msg) {
2332+ var test = new Assertion(act, msg);
2333+
2334+ test.assert(
2335+ exp == flag(test, 'object')
2336+ , 'expected #{this} to equal #{exp}'
2337+ , 'expected #{this} to not equal #{act}'
2338+ , exp
2339+ , act
2340+ );
2341+ };
2342+
2343+ /**
2344+ * ### .notEqual(actual, expected, [message])
2345+ *
2346+ * Asserts non-strict inequality (`!=`) of `actual` and `expected`.
2347+ *
2348+ * assert.notEqual(3, 4, 'these numbers are not equal');
2349+ *
2350+ * @name notEqual
2351+ * @param {Mixed} actual
2352+ * @param {Mixed} expected
2353+ * @param {String} message
2354+ * @api public
2355+ */
2356+
2357+ assert.notEqual = function (act, exp, msg) {
2358+ var test = new Assertion(act, msg);
2359+
2360+ test.assert(
2361+ exp != flag(test, 'object')
2362+ , 'expected #{this} to not equal #{exp}'
2363+ , 'expected #{this} to equal #{act}'
2364+ , exp
2365+ , act
2366+ );
2367+ };
2368+
2369+ /**
2370+ * ### .strictEqual(actual, expected, [message])
2371+ *
2372+ * Asserts strict equality (`===`) of `actual` and `expected`.
2373+ *
2374+ * assert.strictEqual(true, true, 'these booleans are strictly equal');
2375+ *
2376+ * @name strictEqual
2377+ * @param {Mixed} actual
2378+ * @param {Mixed} expected
2379+ * @param {String} message
2380+ * @api public
2381+ */
2382+
2383+ assert.strictEqual = function (act, exp, msg) {
2384+ new Assertion(act, msg).to.equal(exp);
2385+ };
2386+
2387+ /**
2388+ * ### .notStrictEqual(actual, expected, [message])
2389+ *
2390+ * Asserts strict inequality (`!==`) of `actual` and `expected`.
2391+ *
2392+ * assert.notStrictEqual(3, '3', 'no coercion for strict equality');
2393+ *
2394+ * @name notStrictEqual
2395+ * @param {Mixed} actual
2396+ * @param {Mixed} expected
2397+ * @param {String} message
2398+ * @api public
2399+ */
2400+
2401+ assert.notStrictEqual = function (act, exp, msg) {
2402+ new Assertion(act, msg).to.not.equal(exp);
2403+ };
2404+
2405+ /**
2406+ * ### .deepEqual(actual, expected, [message])
2407+ *
2408+ * Asserts that `actual` is deeply equal to `expected`.
2409+ *
2410+ * assert.deepEqual({ tea: 'green' }, { tea: 'green' });
2411+ *
2412+ * @name deepEqual
2413+ * @param {Mixed} actual
2414+ * @param {Mixed} expected
2415+ * @param {String} message
2416+ * @api public
2417+ */
2418+
2419+ assert.deepEqual = function (act, exp, msg) {
2420+ new Assertion(act, msg).to.eql(exp);
2421+ };
2422+
2423+ /**
2424+ * ### .notDeepEqual(actual, expected, [message])
2425+ *
2426+ * Assert that `actual` is not deeply equal to `expected`.
2427+ *
2428+ * assert.notDeepEqual({ tea: 'green' }, { tea: 'jasmine' });
2429+ *
2430+ * @name notDeepEqual
2431+ * @param {Mixed} actual
2432+ * @param {Mixed} expected
2433+ * @param {String} message
2434+ * @api public
2435+ */
2436+
2437+ assert.notDeepEqual = function (act, exp, msg) {
2438+ new Assertion(act, msg).to.not.eql(exp);
2439+ };
2440+
2441+ /**
2442+ * ### .isTrue(value, [message])
2443+ *
2444+ * Asserts that `value` is true.
2445+ *
2446+ * var teaServed = true;
2447+ * assert.isTrue(teaServed, 'the tea has been served');
2448+ *
2449+ * @name isTrue
2450+ * @param {Mixed} value
2451+ * @param {String} message
2452+ * @api public
2453+ */
2454+
2455+ assert.isTrue = function (val, msg) {
2456+ new Assertion(val, msg).is['true'];
2457+ };
2458+
2459+ /**
2460+ * ### .isFalse(value, [message])
2461+ *
2462+ * Asserts that `value` is false.
2463+ *
2464+ * var teaServed = false;
2465+ * assert.isFalse(teaServed, 'no tea yet? hmm...');
2466+ *
2467+ * @name isFalse
2468+ * @param {Mixed} value
2469+ * @param {String} message
2470+ * @api public
2471+ */
2472+
2473+ assert.isFalse = function (val, msg) {
2474+ new Assertion(val, msg).is['false'];
2475+ };
2476+
2477+ /**
2478+ * ### .isNull(value, [message])
2479+ *
2480+ * Asserts that `value` is null.
2481+ *
2482+ * assert.isNull(err, 'there was no error');
2483+ *
2484+ * @name isNull
2485+ * @param {Mixed} value
2486+ * @param {String} message
2487+ * @api public
2488+ */
2489+
2490+ assert.isNull = function (val, msg) {
2491+ new Assertion(val, msg).to.equal(null);
2492+ };
2493+
2494+ /**
2495+ * ### .isNotNull(value, [message])
2496+ *
2497+ * Asserts that `value` is not null.
2498+ *
2499+ * var tea = 'tasty chai';
2500+ * assert.isNotNull(tea, 'great, time for tea!');
2501+ *
2502+ * @name isNotNull
2503+ * @param {Mixed} value
2504+ * @param {String} message
2505+ * @api public
2506+ */
2507+
2508+ assert.isNotNull = function (val, msg) {
2509+ new Assertion(val, msg).to.not.equal(null);
2510+ };
2511+
2512+ /**
2513+ * ### .isUndefined(value, [message])
2514+ *
2515+ * Asserts that `value` is `undefined`.
2516+ *
2517+ * var tea;
2518+ * assert.isUndefined(tea, 'no tea defined');
2519+ *
2520+ * @name isUndefined
2521+ * @param {Mixed} value
2522+ * @param {String} message
2523+ * @api public
2524+ */
2525+
2526+ assert.isUndefined = function (val, msg) {
2527+ new Assertion(val, msg).to.equal(undefined);
2528+ };
2529+
2530+ /**
2531+ * ### .isDefined(value, [message])
2532+ *
2533+ * Asserts that `value` is not `undefined`.
2534+ *
2535+ * var tea = 'cup of chai';
2536+ * assert.isDefined(tea, 'tea has been defined');
2537+ *
2538+ * @name isDefined
2539+ * @param {Mixed} value
2540+ * @param {String} message
2541+ * @api public
2542+ */
2543+
2544+ assert.isDefined = function (val, msg) {
2545+ new Assertion(val, msg).to.not.equal(undefined);
2546+ };
2547+
2548+ /**
2549+ * ### .isFunction(value, [message])
2550+ *
2551+ * Asserts that `value` is a function.
2552+ *
2553+ * function serveTea() { return 'cup of tea'; };
2554+ * assert.isFunction(serveTea, 'great, we can have tea now');
2555+ *
2556+ * @name isFunction
2557+ * @param {Mixed} value
2558+ * @param {String} message
2559+ * @api public
2560+ */
2561+
2562+ assert.isFunction = function (val, msg) {
2563+ new Assertion(val, msg).to.be.a('function');
2564+ };
2565+
2566+ /**
2567+ * ### .isNotFunction(value, [message])
2568+ *
2569+ * Asserts that `value` is _not_ a function.
2570+ *
2571+ * var serveTea = [ 'heat', 'pour', 'sip' ];
2572+ * assert.isNotFunction(serveTea, 'great, we have listed the steps');
2573+ *
2574+ * @name isNotFunction
2575+ * @param {Mixed} value
2576+ * @param {String} message
2577+ * @api public
2578+ */
2579+
2580+ assert.isNotFunction = function (val, msg) {
2581+ new Assertion(val, msg).to.not.be.a('function');
2582+ };
2583+
2584+ /**
2585+ * ### .isObject(value, [message])
2586+ *
2587+ * Asserts that `value` is an object (as revealed by
2588+ * `Object.prototype.toString`).
2589+ *
2590+ * var selection = { name: 'Chai', serve: 'with spices' };
2591+ * assert.isObject(selection, 'tea selection is an object');
2592+ *
2593+ * @name isObject
2594+ * @param {Mixed} value
2595+ * @param {String} message
2596+ * @api public
2597+ */
2598+
2599+ assert.isObject = function (val, msg) {
2600+ new Assertion(val, msg).to.be.a('object');
2601+ };
2602+
2603+ /**
2604+ * ### .isNotObject(value, [message])
2605+ *
2606+ * Asserts that `value` is _not_ an object.
2607+ *
2608+ * var selection = 'chai'
2609+ * assert.isObject(selection, 'tea selection is not an object');
2610+ * assert.isObject(null, 'null is not an object');
2611+ *
2612+ * @name isNotObject
2613+ * @param {Mixed} value
2614+ * @param {String} message
2615+ * @api public
2616+ */
2617+
2618+ assert.isNotObject = function (val, msg) {
2619+ new Assertion(val, msg).to.not.be.a('object');
2620+ };
2621+
2622+ /**
2623+ * ### .isArray(value, [message])
2624+ *
2625+ * Asserts that `value` is an array.
2626+ *
2627+ * var menu = [ 'green', 'chai', 'oolong' ];
2628+ * assert.isArray(menu, 'what kind of tea do we want?');
2629+ *
2630+ * @name isArray
2631+ * @param {Mixed} value
2632+ * @param {String} message
2633+ * @api public
2634+ */
2635+
2636+ assert.isArray = function (val, msg) {
2637+ new Assertion(val, msg).to.be.an('array');
2638+ };
2639+
2640+ /**
2641+ * ### .isNotArray(value, [message])
2642+ *
2643+ * Asserts that `value` is _not_ an array.
2644+ *
2645+ * var menu = 'green|chai|oolong';
2646+ * assert.isNotArray(menu, 'what kind of tea do we want?');
2647+ *
2648+ * @name isNotArray
2649+ * @param {Mixed} value
2650+ * @param {String} message
2651+ * @api public
2652+ */
2653+
2654+ assert.isNotArray = function (val, msg) {
2655+ new Assertion(val, msg).to.not.be.an('array');
2656+ };
2657+
2658+ /**
2659+ * ### .isString(value, [message])
2660+ *
2661+ * Asserts that `value` is a string.
2662+ *
2663+ * var teaOrder = 'chai';
2664+ * assert.isString(teaOrder, 'order placed');
2665+ *
2666+ * @name isString
2667+ * @param {Mixed} value
2668+ * @param {String} message
2669+ * @api public
2670+ */
2671+
2672+ assert.isString = function (val, msg) {
2673+ new Assertion(val, msg).to.be.a('string');
2674+ };
2675+
2676+ /**
2677+ * ### .isNotString(value, [message])
2678+ *
2679+ * Asserts that `value` is _not_ a string.
2680+ *
2681+ * var teaOrder = 4;
2682+ * assert.isNotString(teaOrder, 'order placed');
2683+ *
2684+ * @name isNotString
2685+ * @param {Mixed} value
2686+ * @param {String} message
2687+ * @api public
2688+ */
2689+
2690+ assert.isNotString = function (val, msg) {
2691+ new Assertion(val, msg).to.not.be.a('string');
2692+ };
2693+
2694+ /**
2695+ * ### .isNumber(value, [message])
2696+ *
2697+ * Asserts that `value` is a number.
2698+ *
2699+ * var cups = 2;
2700+ * assert.isNumber(cups, 'how many cups');
2701+ *
2702+ * @name isNumber
2703+ * @param {Number} value
2704+ * @param {String} message
2705+ * @api public
2706+ */
2707+
2708+ assert.isNumber = function (val, msg) {
2709+ new Assertion(val, msg).to.be.a('number');
2710+ };
2711+
2712+ /**
2713+ * ### .isNotNumber(value, [message])
2714+ *
2715+ * Asserts that `value` is _not_ a number.
2716+ *
2717+ * var cups = '2 cups please';
2718+ * assert.isNotNumber(cups, 'how many cups');
2719+ *
2720+ * @name isNotNumber
2721+ * @param {Mixed} value
2722+ * @param {String} message
2723+ * @api public
2724+ */
2725+
2726+ assert.isNotNumber = function (val, msg) {
2727+ new Assertion(val, msg).to.not.be.a('number');
2728+ };
2729+
2730+ /**
2731+ * ### .isBoolean(value, [message])
2732+ *
2733+ * Asserts that `value` is a boolean.
2734+ *
2735+ * var teaReady = true
2736+ * , teaServed = false;
2737+ *
2738+ * assert.isBoolean(teaReady, 'is the tea ready');
2739+ * assert.isBoolean(teaServed, 'has tea been served');
2740+ *
2741+ * @name isBoolean
2742+ * @param {Mixed} value
2743+ * @param {String} message
2744+ * @api public
2745+ */
2746+
2747+ assert.isBoolean = function (val, msg) {
2748+ new Assertion(val, msg).to.be.a('boolean');
2749+ };
2750+
2751+ /**
2752+ * ### .isNotBoolean(value, [message])
2753+ *
2754+ * Asserts that `value` is _not_ a boolean.
2755+ *
2756+ * var teaReady = 'yep'
2757+ * , teaServed = 'nope';
2758+ *
2759+ * assert.isNotBoolean(teaReady, 'is the tea ready');
2760+ * assert.isNotBoolean(teaServed, 'has tea been served');
2761+ *
2762+ * @name isNotBoolean
2763+ * @param {Mixed} value
2764+ * @param {String} message
2765+ * @api public
2766+ */
2767+
2768+ assert.isNotBoolean = function (val, msg) {
2769+ new Assertion(val, msg).to.not.be.a('boolean');
2770+ };
2771+
2772+ /**
2773+ * ### .typeOf(value, name, [message])
2774+ *
2775+ * Asserts that `value`'s type is `name`, as determined by
2776+ * `Object.prototype.toString`.
2777+ *
2778+ * assert.typeOf({ tea: 'chai' }, 'object', 'we have an object');
2779+ * assert.typeOf(['chai', 'jasmine'], 'array', 'we have an array');
2780+ * assert.typeOf('tea', 'string', 'we have a string');
2781+ * assert.typeOf(/tea/, 'regexp', 'we have a regular expression');
2782+ * assert.typeOf(null, 'null', 'we have a null');
2783+ * assert.typeOf(undefined, 'undefined', 'we have an undefined');
2784+ *
2785+ * @name typeOf
2786+ * @param {Mixed} value
2787+ * @param {String} name
2788+ * @param {String} message
2789+ * @api public
2790+ */
2791+
2792+ assert.typeOf = function (val, type, msg) {
2793+ new Assertion(val, msg).to.be.a(type);
2794+ };
2795+
2796+ /**
2797+ * ### .notTypeOf(value, name, [message])
2798+ *
2799+ * Asserts that `value`'s type is _not_ `name`, as determined by
2800+ * `Object.prototype.toString`.
2801+ *
2802+ * assert.notTypeOf('tea', 'number', 'strings are not numbers');
2803+ *
2804+ * @name notTypeOf
2805+ * @param {Mixed} value
2806+ * @param {String} typeof name
2807+ * @param {String} message
2808+ * @api public
2809+ */
2810+
2811+ assert.notTypeOf = function (val, type, msg) {
2812+ new Assertion(val, msg).to.not.be.a(type);
2813+ };
2814+
2815+ /**
2816+ * ### .instanceOf(object, constructor, [message])
2817+ *
2818+ * Asserts that `value` is an instance of `constructor`.
2819+ *
2820+ * var Tea = function (name) { this.name = name; }
2821+ * , chai = new Tea('chai');
2822+ *
2823+ * assert.instanceOf(chai, Tea, 'chai is an instance of tea');
2824+ *
2825+ * @name instanceOf
2826+ * @param {Object} object
2827+ * @param {Constructor} constructor
2828+ * @param {String} message
2829+ * @api public
2830+ */
2831+
2832+ assert.instanceOf = function (val, type, msg) {
2833+ new Assertion(val, msg).to.be.instanceOf(type);
2834+ };
2835+
2836+ /**
2837+ * ### .notInstanceOf(object, constructor, [message])
2838+ *
2839+ * Asserts `value` is not an instance of `constructor`.
2840+ *
2841+ * var Tea = function (name) { this.name = name; }
2842+ * , chai = new String('chai');
2843+ *
2844+ * assert.notInstanceOf(chai, Tea, 'chai is not an instance of tea');
2845+ *
2846+ * @name notInstanceOf
2847+ * @param {Object} object
2848+ * @param {Constructor} constructor
2849+ * @param {String} message
2850+ * @api public
2851+ */
2852+
2853+ assert.notInstanceOf = function (val, type, msg) {
2854+ new Assertion(val, msg).to.not.be.instanceOf(type);
2855+ };
2856+
2857+ /**
2858+ * ### .include(haystack, needle, [message])
2859+ *
2860+ * Asserts that `haystack` includes `needle`. Works
2861+ * for strings and arrays.
2862+ *
2863+ * assert.include('foobar', 'bar', 'foobar contains string "bar"');
2864+ * assert.include([ 1, 2, 3 ], 3, 'array contains value');
2865+ *
2866+ * @name include
2867+ * @param {Array|String} haystack
2868+ * @param {Mixed} needle
2869+ * @param {String} message
2870+ * @api public
2871+ */
2872+
2873+ assert.include = function (exp, inc, msg) {
2874+ var obj = new Assertion(exp, msg);
2875+
2876+ if (Array.isArray(exp)) {
2877+ obj.to.include(inc);
2878+ } else if ('string' === typeof exp) {
2879+ obj.to.contain.string(inc);
2880+ } else {
2881+ throw new chai.AssertionError(
2882+ 'expected an array or string'
2883+ , null
2884+ , assert.include
2885+ );
2886+ }
2887+ };
2888+
2889+ /**
2890+ * ### .notInclude(haystack, needle, [message])
2891+ *
2892+ * Asserts that `haystack` does not include `needle`. Works
2893+ * for strings and arrays.
2894+ *i
2895+ * assert.notInclude('foobar', 'baz', 'string not include substring');
2896+ * assert.notInclude([ 1, 2, 3 ], 4, 'array not include contain value');
2897+ *
2898+ * @name notInclude
2899+ * @param {Array|String} haystack
2900+ * @param {Mixed} needle
2901+ * @param {String} message
2902+ * @api public
2903+ */
2904+
2905+ assert.notInclude = function (exp, inc, msg) {
2906+ var obj = new Assertion(exp, msg);
2907+
2908+ if (Array.isArray(exp)) {
2909+ obj.to.not.include(inc);
2910+ } else if ('string' === typeof exp) {
2911+ obj.to.not.contain.string(inc);
2912+ } else {
2913+ throw new chai.AssertionError(
2914+ 'expected an array or string'
2915+ , null
2916+ , assert.notInclude
2917+ );
2918+ }
2919+ };
2920+
2921+ /**
2922+ * ### .match(value, regexp, [message])
2923+ *
2924+ * Asserts that `value` matches the regular expression `regexp`.
2925+ *
2926+ * assert.match('foobar', /^foo/, 'regexp matches');
2927+ *
2928+ * @name match
2929+ * @param {Mixed} value
2930+ * @param {RegExp} regexp
2931+ * @param {String} message
2932+ * @api public
2933+ */
2934+
2935+ assert.match = function (exp, re, msg) {
2936+ new Assertion(exp, msg).to.match(re);
2937+ };
2938+
2939+ /**
2940+ * ### .notMatch(value, regexp, [message])
2941+ *
2942+ * Asserts that `value` does not match the regular expression `regexp`.
2943+ *
2944+ * assert.notMatch('foobar', /^foo/, 'regexp does not match');
2945+ *
2946+ * @name notMatch
2947+ * @param {Mixed} value
2948+ * @param {RegExp} regexp
2949+ * @param {String} message
2950+ * @api public
2951+ */
2952+
2953+ assert.notMatch = function (exp, re, msg) {
2954+ new Assertion(exp, msg).to.not.match(re);
2955+ };
2956+
2957+ /**
2958+ * ### .property(object, property, [message])
2959+ *
2960+ * Asserts that `object` has a property named by `property`.
2961+ *
2962+ * assert.property({ tea: { green: 'matcha' }}, 'tea');
2963+ *
2964+ * @name property
2965+ * @param {Object} object
2966+ * @param {String} property
2967+ * @param {String} message
2968+ * @api public
2969+ */
2970+
2971+ assert.property = function (obj, prop, msg) {
2972+ new Assertion(obj, msg).to.have.property(prop);
2973+ };
2974+
2975+ /**
2976+ * ### .notProperty(object, property, [message])
2977+ *
2978+ * Asserts that `object` does _not_ have a property named by `property`.
2979+ *
2980+ * assert.notProperty({ tea: { green: 'matcha' }}, 'coffee');
2981+ *
2982+ * @name notProperty
2983+ * @param {Object} object
2984+ * @param {String} property
2985+ * @param {String} message
2986+ * @api public
2987+ */
2988+
2989+ assert.notProperty = function (obj, prop, msg) {
2990+ new Assertion(obj, msg).to.not.have.property(prop);
2991+ };
2992+
2993+ /**
2994+ * ### .deepProperty(object, property, [message])
2995+ *
2996+ * Asserts that `object` has a property named by `property`, which can be a
2997+ * string using dot- and bracket-notation for deep reference.
2998+ *
2999+ * assert.deepProperty({ tea: { green: 'matcha' }}, 'tea.green');
3000+ *
3001+ * @name deepProperty
3002+ * @param {Object} object
3003+ * @param {String} property
3004+ * @param {String} message
3005+ * @api public
3006+ */
3007+
3008+ assert.deepProperty = function (obj, prop, msg) {
3009+ new Assertion(obj, msg).to.have.deep.property(prop);
3010+ };
3011+
3012+ /**
3013+ * ### .notDeepProperty(object, property, [message])
3014+ *
3015+ * Asserts that `object` does _not_ have a property named by `property`, which
3016+ * can be a string using dot- and bracket-notation for deep reference.
3017+ *
3018+ * assert.notDeepProperty({ tea: { green: 'matcha' }}, 'tea.oolong');
3019+ *
3020+ * @name notDeepProperty
3021+ * @param {Object} object
3022+ * @param {String} property
3023+ * @param {String} message
3024+ * @api public
3025+ */
3026+
3027+ assert.notDeepProperty = function (obj, prop, msg) {
3028+ new Assertion(obj, msg).to.not.have.deep.property(prop);
3029+ };
3030+
3031+ /**
3032+ * ### .propertyVal(object, property, value, [message])
3033+ *
3034+ * Asserts that `object` has a property named by `property` with value given
3035+ * by `value`.
3036+ *
3037+ * assert.propertyVal({ tea: 'is good' }, 'tea', 'is good');
3038+ *
3039+ * @name propertyVal
3040+ * @param {Object} object
3041+ * @param {String} property
3042+ * @param {Mixed} value
3043+ * @param {String} message
3044+ * @api public
3045+ */
3046+
3047+ assert.propertyVal = function (obj, prop, val, msg) {
3048+ new Assertion(obj, msg).to.have.property(prop, val);
3049+ };
3050+
3051+ /**
3052+ * ### .propertyNotVal(object, property, value, [message])
3053+ *
3054+ * Asserts that `object` has a property named by `property`, but with a value
3055+ * different from that given by `value`.
3056+ *
3057+ * assert.propertyNotVal({ tea: 'is good' }, 'tea', 'is bad');
3058+ *
3059+ * @name propertyNotVal
3060+ * @param {Object} object
3061+ * @param {String} property
3062+ * @param {Mixed} value
3063+ * @param {String} message
3064+ * @api public
3065+ */
3066+
3067+ assert.propertyNotVal = function (obj, prop, val, msg) {
3068+ new Assertion(obj, msg).to.not.have.property(prop, val);
3069+ };
3070+
3071+ /**
3072+ * ### .deepPropertyVal(object, property, value, [message])
3073+ *
3074+ * Asserts that `object` has a property named by `property` with value given
3075+ * by `value`. `property` can use dot- and bracket-notation for deep
3076+ * reference.
3077+ *
3078+ * assert.deepPropertyVal({ tea: { green: 'matcha' }}, 'tea.green', 'matcha');
3079+ *
3080+ * @name deepPropertyVal
3081+ * @param {Object} object
3082+ * @param {String} property
3083+ * @param {Mixed} value
3084+ * @param {String} message
3085+ * @api public
3086+ */
3087+
3088+ assert.deepPropertyVal = function (obj, prop, val, msg) {
3089+ new Assertion(obj, msg).to.have.deep.property(prop, val);
3090+ };
3091+
3092+ /**
3093+ * ### .deepPropertyNotVal(object, property, value, [message])
3094+ *
3095+ * Asserts that `object` has a property named by `property`, but with a value
3096+ * different from that given by `value`. `property` can use dot- and
3097+ * bracket-notation for deep reference.
3098+ *
3099+ * assert.deepPropertyNotVal({ tea: { green: 'matcha' }}, 'tea.green', 'konacha');
3100+ *
3101+ * @name deepPropertyNotVal
3102+ * @param {Object} object
3103+ * @param {String} property
3104+ * @param {Mixed} value
3105+ * @param {String} message
3106+ * @api public
3107+ */
3108+
3109+ assert.deepPropertyNotVal = function (obj, prop, val, msg) {
3110+ new Assertion(obj, msg).to.not.have.deep.property(prop, val);
3111+ };
3112+
3113+ /**
3114+ * ### .lengthOf(object, length, [message])
3115+ *
3116+ * Asserts that `object` has a `length` property with the expected value.
3117+ *
3118+ * assert.lengthOf([1,2,3], 3, 'array has length of 3');
3119+ * assert.lengthOf('foobar', 5, 'string has length of 6');
3120+ *
3121+ * @name lengthOf
3122+ * @param {Mixed} object
3123+ * @param {Number} length
3124+ * @param {String} message
3125+ * @api public
3126+ */
3127+
3128+ assert.lengthOf = function (exp, len, msg) {
3129+ new Assertion(exp, msg).to.have.length(len);
3130+ };
3131+
3132+ /**
3133+ * ### .throws(function, [constructor/string/regexp], [string/regexp], [message])
3134+ *
3135+ * Asserts that `function` will throw an error that is an instance of
3136+ * `constructor`, or alternately that it will throw an error with message
3137+ * matching `regexp`.
3138+ *
3139+ * assert.throw(fn, 'function throws a reference error');
3140+ * assert.throw(fn, /function throws a reference error/);
3141+ * assert.throw(fn, ReferenceError);
3142+ * assert.throw(fn, ReferenceError, 'function throws a reference error');
3143+ * assert.throw(fn, ReferenceError, /function throws a reference error/);
3144+ *
3145+ * @name throws
3146+ * @alias throw
3147+ * @alias Throw
3148+ * @param {Function} function
3149+ * @param {ErrorConstructor} constructor
3150+ * @param {RegExp} regexp
3151+ * @param {String} message
3152+ * @see https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Error#Error_types
3153+ * @api public
3154+ */
3155+
3156+ assert.Throw = function (fn, errt, errs, msg) {
3157+ if ('string' === typeof errt || errt instanceof RegExp) {
3158+ errs = errt;
3159+ errt = null;
3160+ }
3161+
3162+ new Assertion(fn, msg).to.Throw(errt, errs);
3163+ };
3164+
3165+ /**
3166+ * ### .doesNotThrow(function, [constructor/regexp], [message])
3167+ *
3168+ * Asserts that `function` will _not_ throw an error that is an instance of
3169+ * `constructor`, or alternately that it will not throw an error with message
3170+ * matching `regexp`.
3171+ *
3172+ * assert.doesNotThrow(fn, Error, 'function does not throw');
3173+ *
3174+ * @name doesNotThrow
3175+ * @param {Function} function
3176+ * @param {ErrorConstructor} constructor
3177+ * @param {RegExp} regexp
3178+ * @param {String} message
3179+ * @see https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Error#Error_types
3180+ * @api public
3181+ */
3182+
3183+ assert.doesNotThrow = function (fn, type, msg) {
3184+ if ('string' === typeof type) {
3185+ msg = type;
3186+ type = null;
3187+ }
3188+
3189+ new Assertion(fn, msg).to.not.Throw(type);
3190+ };
3191+
3192+ /**
3193+ * ### .operator(val1, operator, val2, [message])
3194+ *
3195+ * Compares two values using `operator`.
3196+ *
3197+ * assert.operator(1, '<', 2, 'everything is ok');
3198+ * assert.operator(1, '>', 2, 'this will fail');
3199+ *
3200+ * @name operator
3201+ * @param {Mixed} val1
3202+ * @param {String} operator
3203+ * @param {Mixed} val2
3204+ * @param {String} message
3205+ * @api public
3206+ */
3207+
3208+ assert.operator = function (val, operator, val2, msg) {
3209+ if (!~['==', '===', '>', '>=', '<', '<=', '!=', '!=='].indexOf(operator)) {
3210+ throw new Error('Invalid operator "' + operator + '"');
3211+ }
3212+ var test = new Assertion(eval(val + operator + val2), msg);
3213+ test.assert(
3214+ true === flag(test, 'object')
3215+ , 'expected ' + util.inspect(val) + ' to be ' + operator + ' ' + util.inspect(val2)
3216+ , 'expected ' + util.inspect(val) + ' to not be ' + operator + ' ' + util.inspect(val2) );
3217+ };
3218+
3219+ /**
3220+ * ### .closeTo(actual, expected, delta, [message])
3221+ *
3222+ * Asserts that the target is equal `expected`, to within a +/- `delta` range.
3223+ *
3224+ * assert.closeTo(1.5, 1, 0.5, 'numbers are close');
3225+ *
3226+ * @name closeTo
3227+ * @param {Number} actual
3228+ * @param {Number} expected
3229+ * @param {Number} delta
3230+ * @param {String} message
3231+ * @api public
3232+ */
3233+
3234+ assert.closeTo = function (act, exp, delta, msg) {
3235+ new Assertion(act, msg).to.be.closeTo(exp, delta);
3236+ };
3237+
3238+ /**
3239+ * ### .sameMembers(set1, set2, [message])
3240+ *
3241+ * Asserts that `set1` and `set2` have the same members.
3242+ * Order is not taken into account.
3243+ *
3244+ * assert.sameMembers([ 1, 2, 3 ], [ 2, 1, 3 ], 'same members');
3245+ *
3246+ * @name sameMembers
3247+ * @param {Array} superset
3248+ * @param {Array} subset
3249+ * @param {String} message
3250+ * @api public
3251+ */
3252+
3253+ assert.sameMembers = function (set1, set2, msg) {
3254+ new Assertion(set1, msg).to.have.same.members(set2);
3255+ }
3256+
3257+ /**
3258+ * ### .includeMembers(superset, subset, [message])
3259+ *
3260+ * Asserts that `subset` is included in `superset`.
3261+ * Order is not taken into account.
3262+ *
3263+ * assert.includeMembers([ 1, 2, 3 ], [ 2, 1 ], 'include members');
3264+ *
3265+ * @name includeMembers
3266+ * @param {Array} superset
3267+ * @param {Array} subset
3268+ * @param {String} message
3269+ * @api public
3270+ */
3271+
3272+ assert.includeMembers = function (superset, subset, msg) {
3273+ new Assertion(superset, msg).to.include.members(subset);
3274+ }
3275+
3276+ /*!
3277+ * Undocumented / untested
3278+ */
3279+
3280+ assert.ifError = function (val, msg) {
3281+ new Assertion(val, msg).to.not.be.ok;
3282+ };
3283+
3284+ /*!
3285+ * Aliases.
3286+ */
3287+
3288+ (function alias(name, as){
3289+ assert[as] = assert[name];
3290+ return alias;
3291+ })
3292+ ('Throw', 'throw')
3293+ ('Throw', 'throws');
3294+};
3295+
3296+});
3297+require.register("chai/lib/chai/interface/expect.js", function(exports, require, module){
3298+/*!
3299+ * chai
3300+ * Copyright(c) 2011-2013 Jake Luer <jake@alogicalparadox.com>
3301+ * MIT Licensed
3302+ */
3303+
3304+module.exports = function (chai, util) {
3305+ chai.expect = function (val, message) {
3306+ return new chai.Assertion(val, message);
3307+ };
3308+};
3309+
3310+
3311+});
3312+require.register("chai/lib/chai/interface/should.js", function(exports, require, module){
3313+/*!
3314+ * chai
3315+ * Copyright(c) 2011-2013 Jake Luer <jake@alogicalparadox.com>
3316+ * MIT Licensed
3317+ */
3318+
3319+module.exports = function (chai, util) {
3320+ var Assertion = chai.Assertion;
3321+
3322+ function loadShould () {
3323+ // modify Object.prototype to have `should`
3324+ Object.defineProperty(Object.prototype, 'should',
3325+ {
3326+ set: function (value) {
3327+ // See https://github.com/chaijs/chai/issues/86: this makes
3328+ // `whatever.should = someValue` actually set `someValue`, which is
3329+ // especially useful for `global.should = require('chai').should()`.
3330+ //
3331+ // Note that we have to use [[DefineProperty]] instead of [[Put]]
3332+ // since otherwise we would trigger this very setter!
3333+ Object.defineProperty(this, 'should', {
3334+ value: value,
3335+ enumerable: true,
3336+ configurable: true,
3337+ writable: true
3338+ });
3339+ }
3340+ , get: function(){
3341+ if (this instanceof String || this instanceof Number) {
3342+ return new Assertion(this.constructor(this));
3343+ } else if (this instanceof Boolean) {
3344+ return new Assertion(this == true);
3345+ }
3346+ return new Assertion(this);
3347+ }
3348+ , configurable: true
3349+ });
3350+
3351+ var should = {};
3352+
3353+ should.equal = function (val1, val2, msg) {
3354+ new Assertion(val1, msg).to.equal(val2);
3355+ };
3356+
3357+ should.Throw = function (fn, errt, errs, msg) {
3358+ new Assertion(fn, msg).to.Throw(errt, errs);
3359+ };
3360+
3361+ should.exist = function (val, msg) {
3362+ new Assertion(val, msg).to.exist;
3363+ }
3364+
3365+ // negation
3366+ should.not = {}
3367+
3368+ should.not.equal = function (val1, val2, msg) {
3369+ new Assertion(val1, msg).to.not.equal(val2);
3370+ };
3371+
3372+ should.not.Throw = function (fn, errt, errs, msg) {
3373+ new Assertion(fn, msg).to.not.Throw(errt, errs);
3374+ };
3375+
3376+ should.not.exist = function (val, msg) {
3377+ new Assertion(val, msg).to.not.exist;
3378+ }
3379+
3380+ should['throw'] = should['Throw'];
3381+ should.not['throw'] = should.not['Throw'];
3382+
3383+ return should;
3384+ };
3385+
3386+ chai.should = loadShould;
3387+ chai.Should = loadShould;
3388+};
3389+
3390+});
3391+require.register("chai/lib/chai/utils/addChainableMethod.js", function(exports, require, module){
3392+/*!
3393+ * Chai - addChainingMethod utility
3394+ * Copyright(c) 2012-2013 Jake Luer <jake@alogicalparadox.com>
3395+ * MIT Licensed
3396+ */
3397+
3398+/*!
3399+ * Module dependencies
3400+ */
3401+
3402+var transferFlags = require('./transferFlags');
3403+
3404+/*!
3405+ * Module variables
3406+ */
3407+
3408+// Check whether `__proto__` is supported
3409+var hasProtoSupport = '__proto__' in Object;
3410+
3411+// Without `__proto__` support, this module will need to add properties to a function.
3412+// However, some Function.prototype methods cannot be overwritten,
3413+// and there seems no easy cross-platform way to detect them (@see chaijs/chai/issues/69).
3414+var excludeNames = /^(?:length|name|arguments|caller)$/;
3415+
3416+// Cache `Function` properties
3417+var call = Function.prototype.call,
3418+ apply = Function.prototype.apply;
3419+
3420+/**
3421+ * ### addChainableMethod (ctx, name, method, chainingBehavior)
3422+ *
3423+ * Adds a method to an object, such that the method can also be chained.
3424+ *
3425+ * utils.addChainableMethod(chai.Assertion.prototype, 'foo', function (str) {
3426+ * var obj = utils.flag(this, 'object');
3427+ * new chai.Assertion(obj).to.be.equal(str);
3428+ * });
3429+ *
3430+ * Can also be accessed directly from `chai.Assertion`.
3431+ *
3432+ * chai.Assertion.addChainableMethod('foo', fn, chainingBehavior);
3433+ *
3434+ * The result can then be used as both a method assertion, executing both `method` and
3435+ * `chainingBehavior`, or as a language chain, which only executes `chainingBehavior`.
3436+ *
3437+ * expect(fooStr).to.be.foo('bar');
3438+ * expect(fooStr).to.be.foo.equal('foo');
3439+ *
3440+ * @param {Object} ctx object to which the method is added
3441+ * @param {String} name of method to add
3442+ * @param {Function} method function to be used for `name`, when called
3443+ * @param {Function} chainingBehavior function to be called every time the property is accessed
3444+ * @name addChainableMethod
3445+ * @api public
3446+ */
3447+
3448+module.exports = function (ctx, name, method, chainingBehavior) {
3449+ if (typeof chainingBehavior !== 'function')
3450+ chainingBehavior = function () { };
3451+
3452+ Object.defineProperty(ctx, name,
3453+ { get: function () {
3454+ chainingBehavior.call(this);
3455+
3456+ var assert = function () {
3457+ var result = method.apply(this, arguments);
3458+ return result === undefined ? this : result;
3459+ };
3460+
3461+ // Use `__proto__` if available
3462+ if (hasProtoSupport) {
3463+ // Inherit all properties from the object by replacing the `Function` prototype
3464+ var prototype = assert.__proto__ = Object.create(this);
3465+ // Restore the `call` and `apply` methods from `Function`
3466+ prototype.call = call;
3467+ prototype.apply = apply;
3468+ }
3469+ // Otherwise, redefine all properties (slow!)
3470+ else {
3471+ var asserterNames = Object.getOwnPropertyNames(ctx);
3472+ asserterNames.forEach(function (asserterName) {
3473+ if (!excludeNames.test(asserterName)) {
3474+ var pd = Object.getOwnPropertyDescriptor(ctx, asserterName);
3475+ Object.defineProperty(assert, asserterName, pd);
3476+ }
3477+ });
3478+ }
3479+
3480+ transferFlags(this, assert);
3481+ return assert;
3482+ }
3483+ , configurable: true
3484+ });
3485+};
3486+
3487+});
3488+require.register("chai/lib/chai/utils/addMethod.js", function(exports, require, module){
3489+/*!
3490+ * Chai - addMethod utility
3491+ * Copyright(c) 2012-2013 Jake Luer <jake@alogicalparadox.com>
3492+ * MIT Licensed
3493+ */
3494+
3495+/**
3496+ * ### .addMethod (ctx, name, method)
3497+ *
3498+ * Adds a method to the prototype of an object.
3499+ *
3500+ * utils.addMethod(chai.Assertion.prototype, 'foo', function (str) {
3501+ * var obj = utils.flag(this, 'object');
3502+ * new chai.Assertion(obj).to.be.equal(str);
3503+ * });
3504+ *
3505+ * Can also be accessed directly from `chai.Assertion`.
3506+ *
3507+ * chai.Assertion.addMethod('foo', fn);
3508+ *
3509+ * Then can be used as any other assertion.
3510+ *
3511+ * expect(fooStr).to.be.foo('bar');
3512+ *
3513+ * @param {Object} ctx object to which the method is added
3514+ * @param {String} name of method to add
3515+ * @param {Function} method function to be used for name
3516+ * @name addMethod
3517+ * @api public
3518+ */
3519+
3520+module.exports = function (ctx, name, method) {
3521+ ctx[name] = function () {
3522+ var result = method.apply(this, arguments);
3523+ return result === undefined ? this : result;
3524+ };
3525+};
3526+
3527+});
3528+require.register("chai/lib/chai/utils/addProperty.js", function(exports, require, module){
3529+/*!
3530+ * Chai - addProperty utility
3531+ * Copyright(c) 2012-2013 Jake Luer <jake@alogicalparadox.com>
3532+ * MIT Licensed
3533+ */
3534+
3535+/**
3536+ * ### addProperty (ctx, name, getter)
3537+ *
3538+ * Adds a property to the prototype of an object.
3539+ *
3540+ * utils.addProperty(chai.Assertion.prototype, 'foo', function () {
3541+ * var obj = utils.flag(this, 'object');
3542+ * new chai.Assertion(obj).to.be.instanceof(Foo);
3543+ * });
3544+ *
3545+ * Can also be accessed directly from `chai.Assertion`.
3546+ *
3547+ * chai.Assertion.addProperty('foo', fn);
3548+ *
3549+ * Then can be used as any other assertion.
3550+ *
3551+ * expect(myFoo).to.be.foo;
3552+ *
3553+ * @param {Object} ctx object to which the property is added
3554+ * @param {String} name of property to add
3555+ * @param {Function} getter function to be used for name
3556+ * @name addProperty
3557+ * @api public
3558+ */
3559+
3560+module.exports = function (ctx, name, getter) {
3561+ Object.defineProperty(ctx, name,
3562+ { get: function () {
3563+ var result = getter.call(this);
3564+ return result === undefined ? this : result;
3565+ }
3566+ , configurable: true
3567+ });
3568+};
3569+
3570+});
3571+require.register("chai/lib/chai/utils/flag.js", function(exports, require, module){
3572+/*!
3573+ * Chai - flag utility
3574+ * Copyright(c) 2012-2013 Jake Luer <jake@alogicalparadox.com>
3575+ * MIT Licensed
3576+ */
3577+
3578+/**
3579+ * ### flag(object ,key, [value])
3580+ *
3581+ * Get or set a flag value on an object. If a
3582+ * value is provided it will be set, else it will
3583+ * return the currently set value or `undefined` if
3584+ * the value is not set.
3585+ *
3586+ * utils.flag(this, 'foo', 'bar'); // setter
3587+ * utils.flag(this, 'foo'); // getter, returns `bar`
3588+ *
3589+ * @param {Object} object (constructed Assertion
3590+ * @param {String} key
3591+ * @param {Mixed} value (optional)
3592+ * @name flag
3593+ * @api private
3594+ */
3595+
3596+module.exports = function (obj, key, value) {
3597+ var flags = obj.__flags || (obj.__flags = Object.create(null));
3598+ if (arguments.length === 3) {
3599+ flags[key] = value;
3600+ } else {
3601+ return flags[key];
3602+ }
3603+};
3604+
3605+});
3606+require.register("chai/lib/chai/utils/getActual.js", function(exports, require, module){
3607+/*!
3608+ * Chai - getActual utility
3609+ * Copyright(c) 2012-2013 Jake Luer <jake@alogicalparadox.com>
3610+ * MIT Licensed
3611+ */
3612+
3613+/**
3614+ * # getActual(object, [actual])
3615+ *
3616+ * Returns the `actual` value for an Assertion
3617+ *
3618+ * @param {Object} object (constructed Assertion)
3619+ * @param {Arguments} chai.Assertion.prototype.assert arguments
3620+ */
3621+
3622+module.exports = function (obj, args) {
3623+ var actual = args[4];
3624+ return 'undefined' !== typeof actual ? actual : obj._obj;
3625+};
3626+
3627+});
3628+require.register("chai/lib/chai/utils/getEnumerableProperties.js", function(exports, require, module){
3629+/*!
3630+ * Chai - getEnumerableProperties utility
3631+ * Copyright(c) 2012-2013 Jake Luer <jake@alogicalparadox.com>
3632+ * MIT Licensed
3633+ */
3634+
3635+/**
3636+ * ### .getEnumerableProperties(object)
3637+ *
3638+ * This allows the retrieval of enumerable property names of an object,
3639+ * inherited or not.
3640+ *
3641+ * @param {Object} object
3642+ * @returns {Array}
3643+ * @name getEnumerableProperties
3644+ * @api public
3645+ */
3646+
3647+module.exports = function getEnumerableProperties(object) {
3648+ var result = [];
3649+ for (var name in object) {
3650+ result.push(name);
3651+ }
3652+ return result;
3653+};
3654+
3655+});
3656+require.register("chai/lib/chai/utils/getMessage.js", function(exports, require, module){
3657+/*!
3658+ * Chai - message composition utility
3659+ * Copyright(c) 2012-2013 Jake Luer <jake@alogicalparadox.com>
3660+ * MIT Licensed
3661+ */
3662+
3663+/*!
3664+ * Module dependancies
3665+ */
3666+
3667+var flag = require('./flag')
3668+ , getActual = require('./getActual')
3669+ , inspect = require('./inspect')
3670+ , objDisplay = require('./objDisplay');
3671+
3672+/**
3673+ * ### .getMessage(object, message, negateMessage)
3674+ *
3675+ * Construct the error message based on flags
3676+ * and template tags. Template tags will return
3677+ * a stringified inspection of the object referenced.
3678+ *
3679+ * Message template tags:
3680+ * - `#{this}` current asserted object
3681+ * - `#{act}` actual value
3682+ * - `#{exp}` expected value
3683+ *
3684+ * @param {Object} object (constructed Assertion)
3685+ * @param {Arguments} chai.Assertion.prototype.assert arguments
3686+ * @name getMessage
3687+ * @api public
3688+ */
3689+
3690+module.exports = function (obj, args) {
3691+ var negate = flag(obj, 'negate')
3692+ , val = flag(obj, 'object')
3693+ , expected = args[3]
3694+ , actual = getActual(obj, args)
3695+ , msg = negate ? args[2] : args[1]
3696+ , flagMsg = flag(obj, 'message');
3697+
3698+ msg = msg || '';
3699+ msg = msg
3700+ .replace(/#{this}/g, objDisplay(val))
3701+ .replace(/#{act}/g, objDisplay(actual))
3702+ .replace(/#{exp}/g, objDisplay(expected));
3703+
3704+ return flagMsg ? flagMsg + ': ' + msg : msg;
3705+};
3706+
3707+});
3708+require.register("chai/lib/chai/utils/getName.js", function(exports, require, module){
3709+/*!
3710+ * Chai - getName utility
3711+ * Copyright(c) 2012-2013 Jake Luer <jake@alogicalparadox.com>
3712+ * MIT Licensed
3713+ */
3714+
3715+/**
3716+ * # getName(func)
3717+ *
3718+ * Gets the name of a function, in a cross-browser way.
3719+ *
3720+ * @param {Function} a function (usually a constructor)
3721+ */
3722+
3723+module.exports = function (func) {
3724+ if (func.name) return func.name;
3725+
3726+ var match = /^\s?function ([^(]*)\(/.exec(func);
3727+ return match && match[1] ? match[1] : "";
3728+};
3729+
3730+});
3731+require.register("chai/lib/chai/utils/getPathValue.js", function(exports, require, module){
3732+/*!
3733+ * Chai - getPathValue utility
3734+ * Copyright(c) 2012-2013 Jake Luer <jake@alogicalparadox.com>
3735+ * @see https://github.com/logicalparadox/filtr
3736+ * MIT Licensed
3737+ */
3738+
3739+/**
3740+ * ### .getPathValue(path, object)
3741+ *
3742+ * This allows the retrieval of values in an
3743+ * object given a string path.
3744+ *
3745+ * var obj = {
3746+ * prop1: {
3747+ * arr: ['a', 'b', 'c']
3748+ * , str: 'Hello'
3749+ * }
3750+ * , prop2: {
3751+ * arr: [ { nested: 'Universe' } ]
3752+ * , str: 'Hello again!'
3753+ * }
3754+ * }
3755+ *
3756+ * The following would be the results.
3757+ *
3758+ * getPathValue('prop1.str', obj); // Hello
3759+ * getPathValue('prop1.att[2]', obj); // b
3760+ * getPathValue('prop2.arr[0].nested', obj); // Universe
3761+ *
3762+ * @param {String} path
3763+ * @param {Object} object
3764+ * @returns {Object} value or `undefined`
3765+ * @name getPathValue
3766+ * @api public
3767+ */
3768+
3769+var getPathValue = module.exports = function (path, obj) {
3770+ var parsed = parsePath(path);
3771+ return _getPathValue(parsed, obj);
3772+};
3773+
3774+/*!
3775+ * ## parsePath(path)
3776+ *
3777+ * Helper function used to parse string object
3778+ * paths. Use in conjunction with `_getPathValue`.
3779+ *
3780+ * var parsed = parsePath('myobject.property.subprop');
3781+ *
3782+ * ### Paths:
3783+ *
3784+ * * Can be as near infinitely deep and nested
3785+ * * Arrays are also valid using the formal `myobject.document[3].property`.
3786+ *
3787+ * @param {String} path
3788+ * @returns {Object} parsed
3789+ * @api private
3790+ */
3791+
3792+function parsePath (path) {
3793+ var str = path.replace(/\[/g, '.[')
3794+ , parts = str.match(/(\\\.|[^.]+?)+/g);
3795+ return parts.map(function (value) {
3796+ var re = /\[(\d+)\]$/
3797+ , mArr = re.exec(value)
3798+ if (mArr) return { i: parseFloat(mArr[1]) };
3799+ else return { p: value };
3800+ });
3801+};
3802+
3803+/*!
3804+ * ## _getPathValue(parsed, obj)
3805+ *
3806+ * Helper companion function for `.parsePath` that returns
3807+ * the value located at the parsed address.
3808+ *
3809+ * var value = getPathValue(parsed, obj);
3810+ *
3811+ * @param {Object} parsed definition from `parsePath`.
3812+ * @param {Object} object to search against
3813+ * @returns {Object|Undefined} value
3814+ * @api private
3815+ */
3816+
3817+function _getPathValue (parsed, obj) {
3818+ var tmp = obj
3819+ , res;
3820+ for (var i = 0, l = parsed.length; i < l; i++) {
3821+ var part = parsed[i];
3822+ if (tmp) {
3823+ if ('undefined' !== typeof part.p)
3824+ tmp = tmp[part.p];
3825+ else if ('undefined' !== typeof part.i)
3826+ tmp = tmp[part.i];
3827+ if (i == (l - 1)) res = tmp;
3828+ } else {
3829+ res = undefined;
3830+ }
3831+ }
3832+ return res;
3833+};
3834+
3835+});
3836+require.register("chai/lib/chai/utils/getProperties.js", function(exports, require, module){
3837+/*!
3838+ * Chai - getProperties utility
3839+ * Copyright(c) 2012-2013 Jake Luer <jake@alogicalparadox.com>
3840+ * MIT Licensed
3841+ */
3842+
3843+/**
3844+ * ### .getProperties(object)
3845+ *
3846+ * This allows the retrieval of property names of an object, enumerable or not,
3847+ * inherited or not.
3848+ *
3849+ * @param {Object} object
3850+ * @returns {Array}
3851+ * @name getProperties
3852+ * @api public
3853+ */
3854+
3855+module.exports = function getProperties(object) {
3856+ var result = Object.getOwnPropertyNames(subject);
3857+
3858+ function addProperty(property) {
3859+ if (result.indexOf(property) === -1) {
3860+ result.push(property);
3861+ }
3862+ }
3863+
3864+ var proto = Object.getPrototypeOf(subject);
3865+ while (proto !== null) {
3866+ Object.getOwnPropertyNames(proto).forEach(addProperty);
3867+ proto = Object.getPrototypeOf(proto);
3868+ }
3869+
3870+ return result;
3871+};
3872+
3873+});
3874+require.register("chai/lib/chai/utils/index.js", function(exports, require, module){
3875+/*!
3876+ * chai
3877+ * Copyright(c) 2011 Jake Luer <jake@alogicalparadox.com>
3878+ * MIT Licensed
3879+ */
3880+
3881+/*!
3882+ * Main exports
3883+ */
3884+
3885+var exports = module.exports = {};
3886+
3887+/*!
3888+ * test utility
3889+ */
3890+
3891+exports.test = require('./test');
3892+
3893+/*!
3894+ * type utility
3895+ */
3896+
3897+exports.type = require('./type');
3898+
3899+/*!
3900+ * message utility
3901+ */
3902+
3903+exports.getMessage = require('./getMessage');
3904+
3905+/*!
3906+ * actual utility
3907+ */
3908+
3909+exports.getActual = require('./getActual');
3910+
3911+/*!
3912+ * Inspect util
3913+ */
3914+
3915+exports.inspect = require('./inspect');
3916+
3917+/*!
3918+ * Object Display util
3919+ */
3920+
3921+exports.objDisplay = require('./objDisplay');
3922+
3923+/*!
3924+ * Flag utility
3925+ */
3926+
3927+exports.flag = require('./flag');
3928+
3929+/*!
3930+ * Flag transferring utility
3931+ */
3932+
3933+exports.transferFlags = require('./transferFlags');
3934+
3935+/*!
3936+ * Deep equal utility
3937+ */
3938+
3939+exports.eql = require('deep-eql');
3940+
3941+/*!
3942+ * Deep path value
3943+ */
3944+
3945+exports.getPathValue = require('./getPathValue');
3946+
3947+/*!
3948+ * Function name
3949+ */
3950+
3951+exports.getName = require('./getName');
3952+
3953+/*!
3954+ * add Property
3955+ */
3956+
3957+exports.addProperty = require('./addProperty');
3958+
3959+/*!
3960+ * add Method
3961+ */
3962+
3963+exports.addMethod = require('./addMethod');
3964+
3965+/*!
3966+ * overwrite Property
3967+ */
3968+
3969+exports.overwriteProperty = require('./overwriteProperty');
3970+
3971+/*!
3972+ * overwrite Method
3973+ */
3974+
3975+exports.overwriteMethod = require('./overwriteMethod');
3976+
3977+/*!
3978+ * Add a chainable method
3979+ */
3980+
3981+exports.addChainableMethod = require('./addChainableMethod');
3982+
3983+
3984+});
3985+require.register("chai/lib/chai/utils/inspect.js", function(exports, require, module){
3986+// This is (almost) directly from Node.js utils
3987+// https://github.com/joyent/node/blob/f8c335d0caf47f16d31413f89aa28eda3878e3aa/lib/util.js
3988+
3989+var getName = require('./getName');
3990+var getProperties = require('./getProperties');
3991+var getEnumerableProperties = require('./getEnumerableProperties');
3992+
3993+module.exports = inspect;
3994+
3995+/**
3996+ * Echos the value of a value. Trys to print the value out
3997+ * in the best way possible given the different types.
3998+ *
3999+ * @param {Object} obj The object to print out.
4000+ * @param {Boolean} showHidden Flag that shows hidden (not enumerable)
4001+ * properties of objects.
4002+ * @param {Number} depth Depth in which to descend in object. Default is 2.
4003+ * @param {Boolean} colors Flag to turn on ANSI escape codes to color the
4004+ * output. Default is false (no coloring).
4005+ */
4006+function inspect(obj, showHidden, depth, colors) {
4007+ var ctx = {
4008+ showHidden: showHidden,
4009+ seen: [],
4010+ stylize: function (str) { return str; }
4011+ };
4012+ return formatValue(ctx, obj, (typeof depth === 'undefined' ? 2 : depth));
4013+}
4014+
4015+// https://gist.github.com/1044128/
4016+var getOuterHTML = function(element) {
4017+ if ('outerHTML' in element) return element.outerHTML;
4018+ var ns = "http://www.w3.org/1999/xhtml";
4019+ var container = document.createElementNS(ns, '_');
4020+ var elemProto = (window.HTMLElement || window.Element).prototype;
4021+ var xmlSerializer = new XMLSerializer();
4022+ var html;
4023+ if (document.xmlVersion) {
4024+ return xmlSerializer.serializeToString(element);
4025+ } else {
4026+ container.appendChild(element.cloneNode(false));
4027+ html = container.innerHTML.replace('><', '>' + element.innerHTML + '<');
4028+ container.innerHTML = '';
4029+ return html;
4030+ }
4031+};
4032+
4033+// Returns true if object is a DOM element.
4034+var isDOMElement = function (object) {
4035+ if (typeof HTMLElement === 'object') {
4036+ return object instanceof HTMLElement;
4037+ } else {
4038+ return object &&
4039+ typeof object === 'object' &&
4040+ object.nodeType === 1 &&
4041+ typeof object.nodeName === 'string';
4042+ }
4043+};
4044+
4045+function formatValue(ctx, value, recurseTimes) {
4046+ // Provide a hook for user-specified inspect functions.
4047+ // Check that value is an object with an inspect function on it
4048+ if (value && typeof value.inspect === 'function' &&
4049+ // Filter out the util module, it's inspect function is special
4050+ value.inspect !== exports.inspect &&
4051+ // Also filter out any prototype objects using the circular check.
4052+ !(value.constructor && value.constructor.prototype === value)) {
4053+ var ret = value.inspect(recurseTimes);
4054+ if (typeof ret !== 'string') {
4055+ ret = formatValue(ctx, ret, recurseTimes);
4056+ }
4057+ return ret;
4058+ }
4059+
4060+ // Primitive types cannot have properties
4061+ var primitive = formatPrimitive(ctx, value);
4062+ if (primitive) {
4063+ return primitive;
4064+ }
4065+
4066+ // If it's DOM elem, get outer HTML.
4067+ if (isDOMElement(value)) {
4068+ return getOuterHTML(value);
4069+ }
4070+
4071+ // Look up the keys of the object.
4072+ var visibleKeys = getEnumerableProperties(value);
4073+ var keys = ctx.showHidden ? getProperties(value) : visibleKeys;
4074+
4075+ // Some type of object without properties can be shortcutted.
4076+ // In IE, errors have a single `stack` property, or if they are vanilla `Error`,
4077+ // a `stack` plus `description` property; ignore those for consistency.
4078+ if (keys.length === 0 || (isError(value) && (
4079+ (keys.length === 1 && keys[0] === 'stack') ||
4080+ (keys.length === 2 && keys[0] === 'description' && keys[1] === 'stack')
4081+ ))) {
4082+ if (typeof value === 'function') {
4083+ var name = getName(value);
4084+ var nameSuffix = name ? ': ' + name : '';
4085+ return ctx.stylize('[Function' + nameSuffix + ']', 'special');
4086+ }
4087+ if (isRegExp(value)) {
4088+ return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp');
4089+ }
4090+ if (isDate(value)) {
4091+ return ctx.stylize(Date.prototype.toUTCString.call(value), 'date');
4092+ }
4093+ if (isError(value)) {
4094+ return formatError(value);
4095+ }
4096+ }
4097+
4098+ var base = '', array = false, braces = ['{', '}'];
4099+
4100+ // Make Array say that they are Array
4101+ if (isArray(value)) {
4102+ array = true;
4103+ braces = ['[', ']'];
4104+ }
4105+
4106+ // Make functions say that they are functions
4107+ if (typeof value === 'function') {
4108+ var name = getName(value);
4109+ var nameSuffix = name ? ': ' + name : '';
4110+ base = ' [Function' + nameSuffix + ']';
4111+ }
4112+
4113+ // Make RegExps say that they are RegExps
4114+ if (isRegExp(value)) {
4115+ base = ' ' + RegExp.prototype.toString.call(value);
4116+ }
4117+
4118+ // Make dates with properties first say the date
4119+ if (isDate(value)) {
4120+ base = ' ' + Date.prototype.toUTCString.call(value);
4121+ }
4122+
4123+ // Make error with message first say the error
4124+ if (isError(value)) {
4125+ return formatError(value);
4126+ }
4127+
4128+ if (keys.length === 0 && (!array || value.length == 0)) {
4129+ return braces[0] + base + braces[1];
4130+ }
4131+
4132+ if (recurseTimes < 0) {
4133+ if (isRegExp(value)) {
4134+ return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp');
4135+ } else {
4136+ return ctx.stylize('[Object]', 'special');
4137+ }
4138+ }
4139+
4140+ ctx.seen.push(value);
4141+
4142+ var output;
4143+ if (array) {
4144+ output = formatArray(ctx, value, recurseTimes, visibleKeys, keys);
4145+ } else {
4146+ output = keys.map(function(key) {
4147+ return formatProperty(ctx, value, recurseTimes, visibleKeys, key, array);
4148+ });
4149+ }
4150+
4151+ ctx.seen.pop();
4152+
4153+ return reduceToSingleString(output, base, braces);
4154+}
4155+
4156+
4157+function formatPrimitive(ctx, value) {
4158+ switch (typeof value) {
4159+ case 'undefined':
4160+ return ctx.stylize('undefined', 'undefined');
4161+
4162+ case 'string':
4163+ var simple = '\'' + JSON.stringify(value).replace(/^"|"$/g, '')
4164+ .replace(/'/g, "\\'")
4165+ .replace(/\\"/g, '"') + '\'';
4166+ return ctx.stylize(simple, 'string');
4167+
4168+ case 'number':
4169+ return ctx.stylize('' + value, 'number');
4170+
4171+ case 'boolean':
4172+ return ctx.stylize('' + value, 'boolean');
4173+ }
4174+ // For some reason typeof null is "object", so special case here.
4175+ if (value === null) {
4176+ return ctx.stylize('null', 'null');
4177+ }
4178+}
4179+
4180+
4181+function formatError(value) {
4182+ return '[' + Error.prototype.toString.call(value) + ']';
4183+}
4184+
4185+
4186+function formatArray(ctx, value, recurseTimes, visibleKeys, keys) {
4187+ var output = [];
4188+ for (var i = 0, l = value.length; i < l; ++i) {
4189+ if (Object.prototype.hasOwnProperty.call(value, String(i))) {
4190+ output.push(formatProperty(ctx, value, recurseTimes, visibleKeys,
4191+ String(i), true));
4192+ } else {
4193+ output.push('');
4194+ }
4195+ }
4196+ keys.forEach(function(key) {
4197+ if (!key.match(/^\d+$/)) {
4198+ output.push(formatProperty(ctx, value, recurseTimes, visibleKeys,
4199+ key, true));
4200+ }
4201+ });
4202+ return output;
4203+}
4204+
4205+
4206+function formatProperty(ctx, value, recurseTimes, visibleKeys, key, array) {
4207+ var name, str;
4208+ if (value.__lookupGetter__) {
4209+ if (value.__lookupGetter__(key)) {
4210+ if (value.__lookupSetter__(key)) {
4211+ str = ctx.stylize('[Getter/Setter]', 'special');
4212+ } else {
4213+ str = ctx.stylize('[Getter]', 'special');
4214+ }
4215+ } else {
4216+ if (value.__lookupSetter__(key)) {
4217+ str = ctx.stylize('[Setter]', 'special');
4218+ }
4219+ }
4220+ }
4221+ if (visibleKeys.indexOf(key) < 0) {
4222+ name = '[' + key + ']';
4223+ }
4224+ if (!str) {
4225+ if (ctx.seen.indexOf(value[key]) < 0) {
4226+ if (recurseTimes === null) {
4227+ str = formatValue(ctx, value[key], null);
4228+ } else {
4229+ str = formatValue(ctx, value[key], recurseTimes - 1);
4230+ }
4231+ if (str.indexOf('\n') > -1) {
4232+ if (array) {
4233+ str = str.split('\n').map(function(line) {
4234+ return ' ' + line;
4235+ }).join('\n').substr(2);
4236+ } else {
4237+ str = '\n' + str.split('\n').map(function(line) {
4238+ return ' ' + line;
4239+ }).join('\n');
4240+ }
4241+ }
4242+ } else {
4243+ str = ctx.stylize('[Circular]', 'special');
4244+ }
4245+ }
4246+ if (typeof name === 'undefined') {
4247+ if (array && key.match(/^\d+$/)) {
4248+ return str;
4249+ }
4250+ name = JSON.stringify('' + key);
4251+ if (name.match(/^"([a-zA-Z_][a-zA-Z_0-9]*)"$/)) {
4252+ name = name.substr(1, name.length - 2);
4253+ name = ctx.stylize(name, 'name');
4254+ } else {
4255+ name = name.replace(/'/g, "\\'")
4256+ .replace(/\\"/g, '"')
4257+ .replace(/(^"|"$)/g, "'");
4258+ name = ctx.stylize(name, 'string');
4259+ }
4260+ }
4261+
4262+ return name + ': ' + str;
4263+}
4264+
4265+
4266+function reduceToSingleString(output, base, braces) {
4267+ var numLinesEst = 0;
4268+ var length = output.reduce(function(prev, cur) {
4269+ numLinesEst++;
4270+ if (cur.indexOf('\n') >= 0) numLinesEst++;
4271+ return prev + cur.length + 1;
4272+ }, 0);
4273+
4274+ if (length > 60) {
4275+ return braces[0] +
4276+ (base === '' ? '' : base + '\n ') +
4277+ ' ' +
4278+ output.join(',\n ') +
4279+ ' ' +
4280+ braces[1];
4281+ }
4282+
4283+ return braces[0] + base + ' ' + output.join(', ') + ' ' + braces[1];
4284+}
4285+
4286+function isArray(ar) {
4287+ return Array.isArray(ar) ||
4288+ (typeof ar === 'object' && objectToString(ar) === '[object Array]');
4289+}
4290+
4291+function isRegExp(re) {
4292+ return typeof re === 'object' && objectToString(re) === '[object RegExp]';
4293+}
4294+
4295+function isDate(d) {
4296+ return typeof d === 'object' && objectToString(d) === '[object Date]';
4297+}
4298+
4299+function isError(e) {
4300+ return typeof e === 'object' && objectToString(e) === '[object Error]';
4301+}
4302+
4303+function objectToString(o) {
4304+ return Object.prototype.toString.call(o);
4305+}
4306+
4307+});
4308+require.register("chai/lib/chai/utils/objDisplay.js", function(exports, require, module){
4309+/*!
4310+ * Chai - flag utility
4311+ * Copyright(c) 2012-2013 Jake Luer <jake@alogicalparadox.com>
4312+ * MIT Licensed
4313+ */
4314+
4315+/*!
4316+ * Module dependancies
4317+ */
4318+
4319+var inspect = require('./inspect');
4320+
4321+/**
4322+ * ### .objDisplay (object)
4323+ *
4324+ * Determines if an object or an array matches
4325+ * criteria to be inspected in-line for error
4326+ * messages or should be truncated.
4327+ *
4328+ * @param {Mixed} javascript object to inspect
4329+ * @name objDisplay
4330+ * @api public
4331+ */
4332+
4333+module.exports = function (obj) {
4334+ var str = inspect(obj)
4335+ , type = Object.prototype.toString.call(obj);
4336+
4337+ if (str.length >= 40) {
4338+ if (type === '[object Function]') {
4339+ return !obj.name || obj.name === ''
4340+ ? '[Function]'
4341+ : '[Function: ' + obj.name + ']';
4342+ } else if (type === '[object Array]') {
4343+ return '[ Array(' + obj.length + ') ]';
4344+ } else if (type === '[object Object]') {
4345+ var keys = Object.keys(obj)
4346+ , kstr = keys.length > 2
4347+ ? keys.splice(0, 2).join(', ') + ', ...'
4348+ : keys.join(', ');
4349+ return '{ Object (' + kstr + ') }';
4350+ } else {
4351+ return str;
4352+ }
4353+ } else {
4354+ return str;
4355+ }
4356+};
4357+
4358+});
4359+require.register("chai/lib/chai/utils/overwriteMethod.js", function(exports, require, module){
4360+/*!
4361+ * Chai - overwriteMethod utility
4362+ * Copyright(c) 2012-2013 Jake Luer <jake@alogicalparadox.com>
4363+ * MIT Licensed
4364+ */
4365+
4366+/**
4367+ * ### overwriteMethod (ctx, name, fn)
4368+ *
4369+ * Overwites an already existing method and provides
4370+ * access to previous function. Must return function
4371+ * to be used for name.
4372+ *
4373+ * utils.overwriteMethod(chai.Assertion.prototype, 'equal', function (_super) {
4374+ * return function (str) {
4375+ * var obj = utils.flag(this, 'object');
4376+ * if (obj instanceof Foo) {
4377+ * new chai.Assertion(obj.value).to.equal(str);
4378+ * } else {
4379+ * _super.apply(this, arguments);
4380+ * }
4381+ * }
4382+ * });
4383+ *
4384+ * Can also be accessed directly from `chai.Assertion`.
4385+ *
4386+ * chai.Assertion.overwriteMethod('foo', fn);
4387+ *
4388+ * Then can be used as any other assertion.
4389+ *
4390+ * expect(myFoo).to.equal('bar');
4391+ *
4392+ * @param {Object} ctx object whose method is to be overwritten
4393+ * @param {String} name of method to overwrite
4394+ * @param {Function} method function that returns a function to be used for name
4395+ * @name overwriteMethod
4396+ * @api public
4397+ */
4398+
4399+module.exports = function (ctx, name, method) {
4400+ var _method = ctx[name]
4401+ , _super = function () { return this; };
4402+
4403+ if (_method && 'function' === typeof _method)
4404+ _super = _method;
4405+
4406+ ctx[name] = function () {
4407+ var result = method(_super).apply(this, arguments);
4408+ return result === undefined ? this : result;
4409+ }
4410+};
4411+
4412+});
4413+require.register("chai/lib/chai/utils/overwriteProperty.js", function(exports, require, module){
4414+/*!
4415+ * Chai - overwriteProperty utility
4416+ * Copyright(c) 2012-2013 Jake Luer <jake@alogicalparadox.com>
4417+ * MIT Licensed
4418+ */
4419+
4420+/**
4421+ * ### overwriteProperty (ctx, name, fn)
4422+ *
4423+ * Overwites an already existing property getter and provides
4424+ * access to previous value. Must return function to use as getter.
4425+ *
4426+ * utils.overwriteProperty(chai.Assertion.prototype, 'ok', function (_super) {
4427+ * return function () {
4428+ * var obj = utils.flag(this, 'object');
4429+ * if (obj instanceof Foo) {
4430+ * new chai.Assertion(obj.name).to.equal('bar');
4431+ * } else {
4432+ * _super.call(this);
4433+ * }
4434+ * }
4435+ * });
4436+ *
4437+ *
4438+ * Can also be accessed directly from `chai.Assertion`.
4439+ *
4440+ * chai.Assertion.overwriteProperty('foo', fn);
4441+ *
4442+ * Then can be used as any other assertion.
4443+ *
4444+ * expect(myFoo).to.be.ok;
4445+ *
4446+ * @param {Object} ctx object whose property is to be overwritten
4447+ * @param {String} name of property to overwrite
4448+ * @param {Function} getter function that returns a getter function to be used for name
4449+ * @name overwriteProperty
4450+ * @api public
4451+ */
4452+
4453+module.exports = function (ctx, name, getter) {
4454+ var _get = Object.getOwnPropertyDescriptor(ctx, name)
4455+ , _super = function () {};
4456+
4457+ if (_get && 'function' === typeof _get.get)
4458+ _super = _get.get
4459+
4460+ Object.defineProperty(ctx, name,
4461+ { get: function () {
4462+ var result = getter(_super).call(this);
4463+ return result === undefined ? this : result;
4464+ }
4465+ , configurable: true
4466+ });
4467+};
4468+
4469+});
4470+require.register("chai/lib/chai/utils/test.js", function(exports, require, module){
4471+/*!
4472+ * Chai - test utility
4473+ * Copyright(c) 2012-2013 Jake Luer <jake@alogicalparadox.com>
4474+ * MIT Licensed
4475+ */
4476+
4477+/*!
4478+ * Module dependancies
4479+ */
4480+
4481+var flag = require('./flag');
4482+
4483+/**
4484+ * # test(object, expression)
4485+ *
4486+ * Test and object for expression.
4487+ *
4488+ * @param {Object} object (constructed Assertion)
4489+ * @param {Arguments} chai.Assertion.prototype.assert arguments
4490+ */
4491+
4492+module.exports = function (obj, args) {
4493+ var negate = flag(obj, 'negate')
4494+ , expr = args[0];
4495+ return negate ? !expr : expr;
4496+};
4497+
4498+});
4499+require.register("chai/lib/chai/utils/transferFlags.js", function(exports, require, module){
4500+/*!
4501+ * Chai - transferFlags utility
4502+ * Copyright(c) 2012-2013 Jake Luer <jake@alogicalparadox.com>
4503+ * MIT Licensed
4504+ */
4505+
4506+/**
4507+ * ### transferFlags(assertion, object, includeAll = true)
4508+ *
4509+ * Transfer all the flags for `assertion` to `object`. If
4510+ * `includeAll` is set to `false`, then the base Chai
4511+ * assertion flags (namely `object`, `ssfi`, and `message`)
4512+ * will not be transferred.
4513+ *
4514+ *
4515+ * var newAssertion = new Assertion();
4516+ * utils.transferFlags(assertion, newAssertion);
4517+ *
4518+ * var anotherAsseriton = new Assertion(myObj);
4519+ * utils.transferFlags(assertion, anotherAssertion, false);
4520+ *
4521+ * @param {Assertion} assertion the assertion to transfer the flags from
4522+ * @param {Object} object the object to transfer the flags too; usually a new assertion
4523+ * @param {Boolean} includeAll
4524+ * @name getAllFlags
4525+ * @api private
4526+ */
4527+
4528+module.exports = function (assertion, object, includeAll) {
4529+ var flags = assertion.__flags || (assertion.__flags = Object.create(null));
4530+
4531+ if (!object.__flags) {
4532+ object.__flags = Object.create(null);
4533+ }
4534+
4535+ includeAll = arguments.length === 3 ? includeAll : true;
4536+
4537+ for (var flag in flags) {
4538+ if (includeAll ||
4539+ (flag !== 'object' && flag !== 'ssfi' && flag != 'message')) {
4540+ object.__flags[flag] = flags[flag];
4541+ }
4542+ }
4543+};
4544+
4545+});
4546+require.register("chai/lib/chai/utils/type.js", function(exports, require, module){
4547+/*!
4548+ * Chai - type utility
4549+ * Copyright(c) 2012-2013 Jake Luer <jake@alogicalparadox.com>
4550+ * MIT Licensed
4551+ */
4552+
4553+/*!
4554+ * Detectable javascript natives
4555+ */
4556+
4557+var natives = {
4558+ '[object Arguments]': 'arguments'
4559+ , '[object Array]': 'array'
4560+ , '[object Date]': 'date'
4561+ , '[object Function]': 'function'
4562+ , '[object Number]': 'number'
4563+ , '[object RegExp]': 'regexp'
4564+ , '[object String]': 'string'
4565+};
4566+
4567+/**
4568+ * ### type(object)
4569+ *
4570+ * Better implementation of `typeof` detection that can
4571+ * be used cross-browser. Handles the inconsistencies of
4572+ * Array, `null`, and `undefined` detection.
4573+ *
4574+ * utils.type({}) // 'object'
4575+ * utils.type(null) // `null'
4576+ * utils.type(undefined) // `undefined`
4577+ * utils.type([]) // `array`
4578+ *
4579+ * @param {Mixed} object to detect type of
4580+ * @name type
4581+ * @api private
4582+ */
4583+
4584+module.exports = function (obj) {
4585+ var str = Object.prototype.toString.call(obj);
4586+ if (natives[str]) return natives[str];
4587+ if (obj === null) return 'null';
4588+ if (obj === undefined) return 'undefined';
4589+ if (obj === Object(obj)) return 'object';
4590+ return typeof obj;
4591+};
4592+
4593+});
4594+
4595+
4596+require.alias("chaijs-assertion-error/index.js", "chai/deps/assertion-error/index.js");
4597+require.alias("chaijs-assertion-error/index.js", "chai/deps/assertion-error/index.js");
4598+require.alias("chaijs-assertion-error/index.js", "assertion-error/index.js");
4599+require.alias("chaijs-assertion-error/index.js", "chaijs-assertion-error/index.js");
4600+require.alias("chaijs-deep-eql/lib/eql.js", "chai/deps/deep-eql/lib/eql.js");
4601+require.alias("chaijs-deep-eql/lib/eql.js", "chai/deps/deep-eql/index.js");
4602+require.alias("chaijs-deep-eql/lib/eql.js", "deep-eql/index.js");
4603+require.alias("chaijs-type-detect/lib/type.js", "chaijs-deep-eql/deps/type-detect/lib/type.js");
4604+require.alias("chaijs-type-detect/lib/type.js", "chaijs-deep-eql/deps/type-detect/index.js");
4605+require.alias("chaijs-type-detect/lib/type.js", "chaijs-type-detect/index.js");
4606+require.alias("chaijs-deep-eql/lib/eql.js", "chaijs-deep-eql/index.js");
4607+require.alias("chai/index.js", "chai/index.js");if (typeof exports == "object") {
4608+ module.exports = require("chai");
4609+} else if (typeof define == "function" && define.amd) {
4610+ define(function(){ return require("chai"); });
4611+} else {
4612+ this["chai"] = require("chai");
4613+}})();
\ No newline at end of file
--- /dev/null
+++ b/test/bower_components/chai/component.json
@@ -0,0 +1,47 @@
1+{
2+ "name": "chai"
3+ , "repo": "chaijs/chai"
4+ , "version": "1.8.1"
5+ , "description": "BDD/TDD assertion library for node.js and the browser. Test framework agnostic."
6+ , "license": "MIT"
7+ , "keywords": [
8+ "test"
9+ , "assertion"
10+ , "assert"
11+ , "testing"
12+ , "chai"
13+ ]
14+ , "main": "index.js"
15+ , "scripts": [
16+ "index.js"
17+ , "lib/chai.js"
18+ , "lib/chai/assertion.js"
19+ , "lib/chai/core/assertions.js"
20+ , "lib/chai/interface/assert.js"
21+ , "lib/chai/interface/expect.js"
22+ , "lib/chai/interface/should.js"
23+ , "lib/chai/utils/addChainableMethod.js"
24+ , "lib/chai/utils/addMethod.js"
25+ , "lib/chai/utils/addProperty.js"
26+ , "lib/chai/utils/flag.js"
27+ , "lib/chai/utils/getActual.js"
28+ , "lib/chai/utils/getEnumerableProperties.js"
29+ , "lib/chai/utils/getMessage.js"
30+ , "lib/chai/utils/getName.js"
31+ , "lib/chai/utils/getPathValue.js"
32+ , "lib/chai/utils/getProperties.js"
33+ , "lib/chai/utils/index.js"
34+ , "lib/chai/utils/inspect.js"
35+ , "lib/chai/utils/objDisplay.js"
36+ , "lib/chai/utils/overwriteMethod.js"
37+ , "lib/chai/utils/overwriteProperty.js"
38+ , "lib/chai/utils/test.js"
39+ , "lib/chai/utils/transferFlags.js"
40+ , "lib/chai/utils/type.js"
41+ ]
42+ , "dependencies": {
43+ "chaijs/assertion-error": "1.0.0"
44+ , "chaijs/deep-eql": "0.1.3"
45+ }
46+ , "development": {}
47+}
--- /dev/null
+++ b/test/bower_components/chai/karma.conf.js
@@ -0,0 +1,29 @@
1+module.exports = function(config) {
2+ config.set({
3+ basePath: ''
4+ , frameworks: [ 'mocha' ]
5+ , files: [
6+ 'build/build.js'
7+ , 'test/bootstrap/karma.js'
8+ , 'test/*.js'
9+ ]
10+ , exclude: []
11+ , reporters: [ 'progress' ]
12+ , port: 9876
13+ , colors: true
14+ , logLevel: config.LOG_INFO
15+ , autoWatch: false
16+ , browsers: [ 'PhantomJS' ]
17+ , captureTimeout: 60000
18+ , singleRun: true
19+ });
20+
21+ switch (process.env.CHAI_TEST_ENV) {
22+ case 'sauce':
23+ require('./karma.sauce')(config);
24+ break;
25+ default:
26+ // ...
27+ break;
28+ };
29+};
--- /dev/null
+++ b/test/bower_components/chai/karma.sauce.js
@@ -0,0 +1,41 @@
1+var version = require('./package.json').version;
2+var ts = new Date().getTime();
3+
4+module.exports = function(config) {
5+ var auth;
6+
7+ try {
8+ auth = require('./test/auth/index');
9+ } catch(ex) {
10+ auth = {};
11+ auth.SAUCE_USERNAME = process.env.SAUCE_USERNAME || null;
12+ auth.SAUCE_ACCESS_KEY = process.env.SAUCE_ACCESS_KEY || null;
13+ }
14+
15+ if (!auth.SAUCE_USERNAME || !auth.SAUCE_ACCESS_KEY) return;
16+ if (process.env.SKIP_SAUCE) return;
17+
18+ var branch = process.env.TRAVIS_BRANCH || 'local'
19+ var browserConfig = require('./sauce.browsers');
20+ var browsers = Object.keys(browserConfig);
21+ var tags = [ 'chaijs_' + version, auth.SAUCE_USERNAME + '@' + branch ];
22+ var tunnel = process.env.TRAVIS_JOB_NUMBER || ts;
23+
24+ if (process.env.TRAVIS_JOB_NUMBER) {
25+ tags.push('travis@' + process.env.TRAVIS_JOB_NUMBER);
26+ }
27+
28+ config.browsers = config.browsers.concat(browsers);
29+ config.customLaunchers = browserConfig;
30+ config.reporters.push('saucelabs');
31+ config.transports = [ 'xhr-polling' ];
32+
33+ config.sauceLabs = {
34+ username: auth.SAUCE_USERNAME
35+ , accessKey: auth.SAUCE_ACCESS_KEY
36+ , startConnect: true
37+ , tags: tags
38+ , testName: 'ChaiJS'
39+ , tunnelIdentifier: tunnel
40+ };
41+};
--- /dev/null
+++ b/test/bower_components/chai/package.json
@@ -0,0 +1,43 @@
1+{
2+ "author": "Jake Luer <jake@alogicalparadox.com>",
3+ "name": "chai",
4+ "description": "BDD/TDD assertion library for node.js and the browser. Test framework agnostic.",
5+ "keywords": [ "test", "assertion", "assert", "testing", "chai" ],
6+ "homepage": "http://chaijs.com",
7+ "license": "MIT",
8+ "contributors": [
9+ "Jake Luer <jake@alogicalparadox.com>",
10+ "Domenic Denicola <domenic@domenicdenicola.com> (http://domenicdenicola.com)",
11+ "Veselin Todorov <hi@vesln.com>",
12+ "John Firebaugh <john.firebaugh@gmail.com>"
13+ ],
14+ "version": "1.8.1",
15+ "repository": {
16+ "type": "git",
17+ "url": "https://github.com/chaijs/chai"
18+ },
19+ "bugs": {
20+ "url": "https://github.com/chaijs/chai/issues"
21+ },
22+ "main": "./index",
23+ "scripts": {
24+ "test": "make test"
25+ },
26+ "engines": {
27+ "node": ">= 0.4.0"
28+ },
29+ "dependencies": {
30+ "assertion-error": "1.0.0"
31+ , "deep-eql": "0.1.3"
32+ },
33+ "devDependencies": {
34+ "component": "*"
35+ , "coveralls": "2.0.16"
36+ , "jscoverage": "0.3.7"
37+ , "karma": "canary"
38+ , "karma-mocha": "*"
39+ , "karma-sauce-launcher": "git://github.com/embarkmobile/karma-sauce-launcher.git#feature-passfail"
40+ , "mocha": "1.8.2"
41+ , "mocha-lcov-reporter": "0.0.1"
42+ }
43+}
--- /dev/null
+++ b/test/bower_components/chai/sauce.browsers.js
@@ -0,0 +1,128 @@
1+
2+/*!
3+ * Chrome
4+ */
5+
6+exports['SL_Chrome'] = {
7+ base: 'SauceLabs'
8+ , browserName: 'chrome'
9+};
10+
11+/*!
12+ * Firefox
13+ */
14+
15+/*!
16+ * TODO: Karma doesn't seem to like this, though sauce boots its up
17+ *
18+
19+exports['SL_Firefox_23'] = {
20+ base: 'SauceLabs'
21+ , browserName: 'firefox'
22+ , platform: 'Windows XP'
23+ , version: '23'
24+};
25+
26+*/
27+
28+exports['SL_Firefox_22'] = {
29+ base: 'SauceLabs'
30+ , browserName: 'firefox'
31+ , platform: 'Windows 7'
32+ , version: '22'
33+};
34+
35+/*!
36+ * Opera
37+ */
38+
39+exports['SL_Opera_12'] = {
40+ base: 'SauceLabs'
41+ , browserName: 'opera'
42+ , platform: 'Windows 7'
43+ , version: '12'
44+};
45+
46+exports['SL_Opera_11'] = {
47+ base: 'SauceLabs'
48+ , browserName: 'opera'
49+ , platform: 'Windows 7'
50+ , version: '11'
51+};
52+
53+/*!
54+ * Internet Explorer
55+ */
56+
57+exports['SL_IE_10'] = {
58+ base: 'SauceLabs'
59+ , browserName: 'internet explorer'
60+ , platform: 'Windows 2012'
61+ , version: '10'
62+};
63+
64+/*!
65+ * Safari
66+ */
67+
68+exports['SL_Safari_6'] = {
69+ base: 'SauceLabs'
70+ , browserName: 'safari'
71+ , platform: 'Mac 10.8'
72+ , version: '6'
73+};
74+
75+exports['SL_Safari_5'] = {
76+ base: 'SauceLabs'
77+ , browserName: 'safari'
78+ , platform: 'Mac 10.6'
79+ , version: '5'
80+};
81+
82+/*!
83+ * iPhone
84+ */
85+
86+/*!
87+ * TODO: These take forever to boot or shut down. Causes timeout.
88+ *
89+
90+exports['SL_iPhone_6'] = {
91+ base: 'SauceLabs'
92+ , browserName: 'iphone'
93+ , platform: 'Mac 10.8'
94+ , version: '6'
95+};
96+
97+exports['SL_iPhone_5-1'] = {
98+ base: 'SauceLabs'
99+ , browserName: 'iphone'
100+ , platform: 'Mac 10.8'
101+ , version: '5.1'
102+};
103+
104+exports['SL_iPhone_5'] = {
105+ base: 'SauceLabs'
106+ , browserName: 'iphone'
107+ , platform: 'Mac 10.6'
108+ , version: '5'
109+};
110+
111+*/
112+
113+/*!
114+ * Android
115+ */
116+
117+/*!
118+ * TODO: fails because of error serialization
119+ *
120+
121+exports['SL_Android_4'] = {
122+ base: 'SauceLabs'
123+ , browserName: 'android'
124+ , platform: 'Linux'
125+ , version: '4'
126+};
127+
128+*/
--- /dev/null
+++ b/test/bower_components/mocha/.bower.json
@@ -0,0 +1,30 @@
1+{
2+ "name": "mocha",
3+ "version": "1.14.0",
4+ "main": "mocha.js",
5+ "ignore": [
6+ "bin",
7+ "editors",
8+ "images",
9+ "lib",
10+ "support",
11+ "test",
12+ ".gitignore",
13+ ".npmignore",
14+ ".travis.yml",
15+ "component.json",
16+ "index.js",
17+ "Makefile",
18+ "package.json"
19+ ],
20+ "homepage": "https://github.com/visionmedia/mocha",
21+ "_release": "1.14.0",
22+ "_resolution": {
23+ "type": "version",
24+ "tag": "1.14.0",
25+ "commit": "10c65f379c4501269c83a719a04bd2fb0013f853"
26+ },
27+ "_source": "git://github.com/visionmedia/mocha.git",
28+ "_target": "~1.14.0",
29+ "_originalSource": "mocha"
30+}
\ No newline at end of file
--- /dev/null
+++ b/test/bower_components/mocha/History.md
@@ -0,0 +1,592 @@
1+
2+1.14.0 / 2013-11-02
3+==================
4+
5+ * add: unified diff (#862)
6+ * add: set MOCHA_COLORS env var to use colors (#965)
7+ * add: able to override tests links in html reporters (#776)
8+ * remove: teamcity reporter (#954)
9+ * update: commander dependency to 2.0.0 (#1010)
10+ * fix: mocha --ui will try to require the ui if not built in, as --reporter does (#1022)
11+ * fix: send cursor commands only if isatty (#184, #1003)
12+ * fix: include assertion message in base reporter (#993, #991)
13+ * fix: consistent return of it, it.only, and describe, describe.only (#840)
14+
15+1.13.0 / 2013-09-15
16+==================
17+
18+ * add: sort test files with --sort (#813)
19+ * update: diff depedency to 1.0.7
20+ * update: glob dependency to 3.2.3 (#927)
21+ * fix: diffs show whitespace differences (#976)
22+ * fix: improve global leaks (#783)
23+ * fix: firefox window.getInterface leak
24+ * fix: accessing iframe via window[iframeIndex] leak
25+ * fix: faster global leak checking
26+ * fix: reporter pending css selector (#970)
27+
28+1.12.1 / 2013-08-29
29+==================
30+
31+ * remove test.js from .gitignore
32+ * update included version of ms.js
33+
34+1.12.0 / 2013-07-01
35+==================
36+
37+ * add: prevent diffs for differing types. Closes #900
38+ * add `Mocha.process` hack for phantomjs
39+ * fix: use compilers with requires
40+ * fix regexps in diffs. Closes #890
41+ * fix xunit NaN on failure. Closes #894
42+ * fix: strip tab indentation in `clean` utility method
43+ * fix: textmate bundle installation
44+
45+1.11.0 / 2013-06-12
46+==================
47+
48+ * add --prof support
49+ * add --harmony support
50+ * add --harmony-generators support
51+ * add "Uncaught " prefix to uncaught exceptions
52+ * add web workers support
53+ * add `suite.skip()`
54+ * change to output # of pending / passing even on failures. Closes #872
55+ * fix: prevent hooks from being called if we are bailing
56+ * fix `this.timeout(0)`
57+
58+1.10.0 / 2013-05-21
59+==================
60+
61+ * add add better globbing support for windows via `glob` module
62+ * add support to pass through flags such as --debug-brk=1234. Closes #852
63+ * add test.only, test.skip to qunit interface
64+ * change to always use word-based diffs for now. Closes #733
65+ * change `mocha init` tests.html to index.html
66+ * fix `process` global leak in the browser
67+ * fix: use resolve() instead of join() for --require
68+ * fix: filterLeaks() condition to not consider indices in global object as leaks
69+ * fix: restrict mocha.css styling to #mocha id
70+ * fix: save timer references to avoid Sinon interfering in the browser build.
71+
72+1.9.0 / 2013-04-03
73+==================
74+
75+ * add improved setImmediate implementation
76+ * replace --ignore-leaks with --check-leaks
77+ * change default of ignoreLeaks to true. Closes #791
78+ * remove scrolling for HTML reporter
79+ * fix retina support
80+ * fix tmbundle, restrict to js scope
81+
82+1.8.2 / 2013-03-11
83+==================
84+
85+ * add `setImmediate` support for 0.10.x
86+ * fix mocha -w spinner on windows
87+
88+1.8.1 / 2013-01-09
89+==================
90+
91+ * fix .bail() arity check causing it to default to true
92+
93+1.8.0 / 2013-01-08
94+==================
95+
96+ * add Mocha() options bail support
97+ * add `Mocha#bail()` method
98+ * add instanceof check back for inheriting from Error
99+ * add component.json
100+ * add diff.js to browser build
101+ * update growl
102+ * fix TAP reporter failures comment :D
103+
104+1.7.4 / 2012-12-06
105+==================
106+
107+ * add total number of passes and failures to TAP
108+ * remove .bind() calls. re #680
109+ * fix indexOf. Closes #680
110+
111+1.7.3 / 2012-11-30
112+==================
113+
114+ * fix uncaught error support for the browser
115+ * revert uncaught "fix" which breaks node
116+
117+1.7.2 / 2012-11-28
118+==================
119+
120+ * fix uncaught errors to expose the original error message
121+
122+1.7.0 / 2012-11-07
123+==================
124+
125+ * add `--async-only` support to prevent false positives for missing `done()`
126+ * add sorting by filename in code coverage
127+ * add HTML 5 doctype to browser template.
128+ * add play button to html reporter to rerun a single test
129+ * add `this.timeout(ms)` as Suite#timeout(ms). Closes #599
130+ * update growl dependency to 1.6.x
131+ * fix encoding of test-case ?grep. Closes #637
132+ * fix unicode chars on windows
133+ * fix dom globals in Opera/IE. Closes #243
134+ * fix markdown reporter a tags
135+ * fix `this.timeout("5s")` support
136+
137+1.6.0 / 2012-10-02
138+==================
139+
140+ * add object diffs when `err.showDiff` is present
141+ * add hiding of empty suites when pass/failures are toggled
142+ * add faster `.length` checks to `checkGlobals()` before performing the filter
143+
144+1.5.0 / 2012-09-21
145+==================
146+
147+ * add `ms()` to `.slow()` and `.timeout()`
148+ * add `Mocha#checkLeaks()` to re-enable global leak checks
149+ * add `this.slow()` option [aheckmann]
150+ * add tab, CR, LF to error diffs for now
151+ * add faster `.checkGlobals()` solution [guille]
152+ * remove `fn.call()` from reduce util
153+ * remove `fn.call()` from filter util
154+ * fix forEach. Closes #582
155+ * fix relaying of signals [TooTallNate]
156+ * fix TAP reporter grep number
157+
158+1.4.2 / 2012-09-01
159+==================
160+
161+ * add support to multiple `Mocha#globals()` calls, and strings
162+ * add `mocha.reporter()` constructor support [jfirebaugh]
163+ * add `mocha.timeout()`
164+ * move query-string parser to utils.js
165+ * move highlight code to utils.js
166+ * fix third-party reporter support [exogen]
167+ * fix client-side API to match node-side [jfirebaugh]
168+ * fix mocha in iframe [joliss]
169+
170+1.4.1 / 2012-08-28
171+==================
172+
173+ * add missing `Markdown` export
174+ * fix `Mocha#grep()`, escape regexp strings
175+ * fix reference error when `devicePixelRatio` is not defined. Closes #549
176+
177+1.4.0 / 2012-08-22
178+==================
179+
180+ * add mkdir -p to `mocha init`. Closes #539
181+ * add `.only()`. Closes #524
182+ * add `.skip()`. Closes #524
183+ * change str.trim() to use utils.trim(). Closes #533
184+ * fix HTML progress indicator retina display
185+ * fix url-encoding of click-to-grep HTML functionality
186+
187+1.3.2 / 2012-08-01
188+==================
189+
190+ * fix exports double-execution regression. Closes #531
191+
192+1.3.1 / 2012-08-01
193+==================
194+
195+ * add passes/failures toggling to HTML reporter
196+ * add pending state to `xit()` and `xdescribe()` [Brian Moore]
197+ * add the @charset "UTF-8"; to fix #522 with FireFox. [Jonathan Creamer]
198+ * add border-bottom to #stats links
199+ * add check for runnable in `Runner#uncaught()`. Closes #494
200+ * add 0.4 and 0.6 back to travis.yml
201+ * add `-E, --growl-errors` to growl on failures only
202+ * add prefixes to debug() names. Closes #497
203+ * add `Mocha#invert()` to js api
204+ * change dot reporter to use sexy unicode dots
205+ * fix error when clicking pending test in HTML reporter
206+ * fix `make tm`
207+
208+1.3.0 / 2012-07-05
209+==================
210+
211+ * add window scrolling to `HTML` reporter
212+ * add v8 `--trace-*` option support
213+ * add support for custom reports via `--reporter MODULE`
214+ * add `--invert` switch to invert `--grep` matches
215+ * fix export of `Nyan` reporter. Closes #495
216+ * fix escaping of `HTML` suite titles. Closes #486
217+ * fix `done()` called multiple times with an error test
218+ * change `--grep` - regexp escape the input
219+
220+1.2.2 / 2012-06-28
221+==================
222+
223+ * Added 0.8.0 support
224+
225+1.2.1 / 2012-06-25
226+==================
227+
228+ * Added `this.test.error(err)` support to after each hooks. Closes #287
229+ * Added: export top-level suite on global mocha object (mocha.suite). Closes #448
230+ * Fixed `js` code block format error in markdown reporter
231+ * Fixed deprecation warning when using `path.existsSync`
232+ * Fixed --globals with wildcard
233+ * Fixed chars in nyan when his head moves back
234+ * Remove `--growl` from test/mocha.opts. Closes #289
235+
236+1.2.0 / 2012-06-17
237+==================
238+
239+ * Added `nyan` reporter [Atsuya Takagi]
240+ * Added `mocha init <path>` to copy client files
241+ * Added "specify" synonym for "it" [domenic]
242+ * Added global leak wildcard support [nathanbowser]
243+ * Fixed runner emitter leak. closes #432
244+ * Fixed omission of .js extension. Closes #454
245+
246+1.1.0 / 2012-05-30
247+==================
248+
249+ * Added: check each `mocha(1)` arg for directories to walk
250+ * Added `--recursive` [tricknotes]
251+ * Added `context` for BDD [hokaccha]
252+ * Added styling for new clickable titles
253+ * Added clickable suite titles to HTML reporter
254+ * Added warning when strings are thrown as errors
255+ * Changed: green arrows again in HTML reporter styling
256+ * Changed ul/li elements instead of divs for better copy-and-pasting [joliss]
257+ * Fixed issue #325 - add better grep support to js api
258+ * Fixed: save timer references to avoid Sinon interfering.
259+
260+1.0.3 / 2012-04-30
261+==================
262+
263+ * Fixed string diff newlines
264+ * Fixed: removed mocha.css target. Closes #401
265+
266+1.0.2 / 2012-04-25
267+==================
268+
269+ * Added HTML reporter duration. Closes #47
270+ * Fixed: one postMessage event listener [exogen]
271+ * Fixed: allow --globals to be used multiple times. Closes #100 [brendannee]
272+ * Fixed #158: removes jquery include from browser tests
273+ * Fixed grep. Closes #372 [brendannee]
274+ * Fixed #166 - When grepping don't display the empty suites
275+ * Removed test/browser/style.css. Closes #385
276+
277+1.0.1 / 2012-04-04
278+==================
279+
280+ * Fixed `.timeout()` in hooks
281+ * Fixed: allow callback for `mocha.run()` in client version
282+ * Fixed browser hook error display. Closes #361
283+
284+1.0.0 / 2012-03-24
285+==================
286+
287+ * Added js API. Closes #265
288+ * Added: initial run of tests with `--watch`. Closes #345
289+ * Added: mark `location` as a global on the CS. Closes #311
290+ * Added `markdown` reporter (github flavour)
291+ * Added: scrolling menu to coverage.html. Closes #335
292+ * Added source line to html report for Safari [Tyson Tate]
293+ * Added "min" reporter, useful for `--watch` [Jakub Nešetřil]
294+ * Added support for arbitrary compilers via . Closes #338 [Ian Young]
295+ * Added Teamcity export to lib/reporters/index [Michael Riley]
296+ * Fixed chopping of first char in error reporting. Closes #334 [reported by topfunky]
297+ * Fixed terrible FF / Opera stack traces
298+
299+0.14.1 / 2012-03-06
300+==================
301+
302+ * Added lib-cov to _.npmignore_
303+ * Added reporter to `mocha.run([reporter])` as argument
304+ * Added some margin-top to the HTML reporter
305+ * Removed jQuery dependency
306+ * Fixed `--watch`: purge require cache. Closes #266
307+
308+0.14.0 / 2012-03-01
309+==================
310+
311+ * Added string diff support for terminal reporters
312+
313+0.13.0 / 2012-02-23
314+==================
315+
316+ * Added preliminary test coverage support. Closes #5
317+ * Added `HTMLCov` reporter
318+ * Added `JSONCov` reporter [kunklejr]
319+ * Added `xdescribe()` and `xit()` to the BDD interface. Closes #263 (docs * Changed: make json reporter output pretty json
320+ * Fixed node-inspector support, swapped `--debug` for `debug` to match node.
321+needed)
322+Closes #247
323+
324+0.12.1 / 2012-02-14
325+==================
326+
327+ * Added `npm docs mocha` support [TooTallNate]
328+ * Added a `Context` object used for hook and test-case this. Closes #253
329+ * Fixed `Suite#clone()` `.ctx` reference. Closes #262
330+
331+0.12.0 / 2012-02-02
332+==================
333+
334+ * Added .coffee `--watch` support. Closes #242
335+ * Added support to `--require` files relative to the CWD. Closes #241
336+ * Added quick n dirty syntax highlighting. Closes #248
337+ * Changed: made HTML progress indicator smaller
338+ * Fixed xunit errors attribute [dhendo]
339+
340+0.10.2 / 2012-01-21
341+==================
342+
343+ * Fixed suite count in reporter stats. Closes #222
344+ * Fixed `done()` after timeout error reporting [Phil Sung]
345+ * Changed the 0-based errors to 1
346+
347+0.10.1 / 2012-01-17
348+==================
349+
350+ * Added support for node 0.7.x
351+ * Fixed absolute path support. Closes #215 [kompiro]
352+ * Fixed `--no-colors` option [Jussi Virtanen]
353+ * Fixed Arial CSS typo in the correct file
354+
355+0.10.0 / 2012-01-13
356+==================
357+
358+ * Added `-b, --bail` to exit on first exception [guillermo]
359+ * Added support for `-gc` / `--expose-gc` [TooTallNate]
360+ * Added `qunit`-inspired interface
361+ * Added MIT LICENSE. Closes #194
362+ * Added: `--watch` all .js in the CWD. Closes #139
363+ * Fixed `self.test` reference in runner. Closes #189
364+ * Fixed double reporting of uncaught exceptions after timeout. Closes #195
365+
366+0.8.2 / 2012-01-05
367+==================
368+
369+ * Added test-case context support. Closes #113
370+ * Fixed exit status. Closes #187
371+ * Update commander. Closes #190
372+
373+0.8.1 / 2011-12-30
374+==================
375+
376+ * Fixed reporting of uncaught exceptions. Closes #183
377+ * Fixed error message defaulting [indutny]
378+ * Changed mocha(1) from bash to node for windows [Nathan Rajlich]
379+
380+0.8.0 / 2011-12-28
381+==================
382+
383+ * Added `XUnit` reporter [FeeFighters/visionmedia]
384+ * Added `say(1)` notification support [Maciej Małecki]
385+ * Changed: fail when done() is invoked with a non-Error. Closes #171
386+ * Fixed `err.stack`, defaulting to message. Closes #180
387+ * Fixed: `make tm` mkdir -p the dest. Closes #137
388+ * Fixed mocha(1) --help bin name
389+ * Fixed `-d` for `--debug` support
390+
391+0.7.1 / 2011-12-22
392+==================
393+
394+ * Removed `mocha-debug(1)`, use `mocha --debug`
395+ * Fixed CWD relative requires
396+ * Fixed growl issue on windows [Raynos]
397+ * Fixed: platform specific line endings [TooTallNate]
398+ * Fixed: escape strings in HTML reporter. Closes #164
399+
400+0.7.0 / 2011-12-18
401+==================
402+
403+ * Added support for IE{7,8} [guille]
404+ * Changed: better browser nextTick implementation [guille]
405+
406+0.6.0 / 2011-12-18
407+==================
408+
409+ * Added setZeroTimeout timeout for browser (nicer stack traces). Closes #153
410+ * Added "view source" on hover for HTML reporter to make it obvious
411+ * Changed: replace custom growl with growl lib
412+ * Fixed duplicate reporting for HTML reporter. Closes #154
413+ * Fixed silent hook errors in the HTML reporter. Closes #150
414+
415+0.5.0 / 2011-12-14
416+==================
417+
418+ * Added: push node_modules directory onto module.paths for relative require Closes #93
419+ * Added teamcity reporter [blindsey]
420+ * Fixed: recover from uncaught exceptions for tests. Closes #94
421+ * Fixed: only emit "test end" for uncaught within test, not hook
422+
423+0.4.0 / 2011-12-14
424+==================
425+
426+ * Added support for test-specific timeouts via `this.timeout(0)`. Closes #134
427+ * Added guillermo's client-side EventEmitter. Closes #132
428+ * Added progress indicator to the HTML reporter
429+ * Fixed slow browser tests. Closes #135
430+ * Fixed "suite" color for light terminals
431+ * Fixed `require()` leak spotted by [guillermo]
432+
433+0.3.6 / 2011-12-09
434+==================
435+
436+ * Removed suite merging (for now)
437+
438+0.3.5 / 2011-12-08
439+==================
440+
441+ * Added support for `window.onerror` [guillermo]
442+ * Fixed: clear timeout on uncaught exceptions. Closes #131 [guillermo]
443+ * Added `mocha.css` to PHONY list.
444+ * Added `mocha.js` to PHONY list.
445+
446+0.3.4 / 2011-12-08
447+==================
448+
449+ * Added: allow `done()` to be called with non-Error
450+ * Added: return Runner from `mocha.run()`. Closes #126
451+ * Fixed: run afterEach even on failures. Closes #125
452+ * Fixed clobbering of current runnable. Closes #121
453+
454+0.3.3 / 2011-12-08
455+==================
456+
457+ * Fixed hook timeouts. Closes #120
458+ * Fixed uncaught exceptions in hooks
459+
460+0.3.2 / 2011-12-05
461+==================
462+
463+ * Fixed weird reporting when `err.message` is not present
464+
465+0.3.1 / 2011-12-04
466+==================
467+
468+ * Fixed hook event emitter leak. Closes #117
469+ * Fixed: export `Spec` constructor. Closes #116
470+
471+0.3.0 / 2011-12-04
472+==================
473+
474+ * Added `-w, --watch`. Closes #72
475+ * Added `--ignore-leaks` to ignore global leak checking
476+ * Added browser `?grep=pattern` support
477+ * Added `--globals <names>` to specify accepted globals. Closes #99
478+ * Fixed `mocha-debug(1)` on some systems. Closes #232
479+ * Fixed growl total, use `runner.total`
480+
481+0.2.0 / 2011-11-30
482+==================
483+
484+ * Added `--globals <names>` to specify accepted globals. Closes #99
485+ * Fixed funky highlighting of messages. Closes #97
486+ * Fixed `mocha-debug(1)`. Closes #232
487+ * Fixed growl total, use runner.total
488+
489+0.1.0 / 2011-11-29
490+==================
491+
492+ * Added `suiteSetup` and `suiteTeardown` to TDD interface [David Henderson]
493+ * Added growl icons. Closes #84
494+ * Fixed coffee-script support
495+
496+0.0.8 / 2011-11-25
497+==================
498+
499+ * Fixed: use `Runner#total` for accurate reporting
500+
501+0.0.7 / 2011-11-25
502+==================
503+
504+ * Added `Hook`
505+ * Added `Runnable`
506+ * Changed: `Test` is `Runnable`
507+ * Fixed global leak reporting in hooks
508+ * Fixed: > 2 calls to done() only report the error once
509+ * Fixed: clear timer on failure. Closes #80
510+
511+0.0.6 / 2011-11-25
512+==================
513+
514+ * Fixed return on immediate async error. Closes #80
515+
516+0.0.5 / 2011-11-24
517+==================
518+
519+ * Fixed: make mocha.opts whitespace less picky [kkaefer]
520+
521+0.0.4 / 2011-11-24
522+==================
523+
524+ * Added `--interfaces`
525+ * Added `--reporters`
526+ * Added `-c, --colors`. Closes #69
527+ * Fixed hook timeouts
528+
529+0.0.3 / 2011-11-23
530+==================
531+
532+ * Added `-C, --no-colors` to explicitly disable
533+ * Added coffee-script support
534+
535+0.0.2 / 2011-11-22
536+==================
537+
538+ * Fixed global leak detection due to Safari bind() change
539+ * Fixed: escape html entities in Doc reporter
540+ * Fixed: escape html entities in HTML reporter
541+ * Fixed pending test support for HTML reporter. Closes #66
542+
543+0.0.1 / 2011-11-22
544+==================
545+
546+ * Added `--timeout` second shorthand support, ex `--timeout 3s`.
547+ * Fixed "test end" event for uncaughtExceptions. Closes #61
548+
549+0.0.1-alpha6 / 2011-11-19
550+==================
551+
552+ * Added travis CI support (needs enabling when public)
553+ * Added preliminary browser support
554+ * Added `make mocha.css` target. Closes #45
555+ * Added stack trace to TAP errors. Closes #52
556+ * Renamed tearDown to teardown. Closes #49
557+ * Fixed: cascading hooksc. Closes #30
558+ * Fixed some colors for non-tty
559+ * Fixed errors thrown in sync test-cases due to nextTick
560+ * Fixed Base.window.width... again give precedence to 0.6.x
561+
562+0.0.1-alpha5 / 2011-11-17
563+==================
564+
565+ * Added `doc` reporter. Closes #33
566+ * Added suite merging. Closes #28
567+ * Added TextMate bundle and `make tm`. Closes #20
568+
569+0.0.1-alpha4 / 2011-11-15
570+==================
571+
572+ * Fixed getWindowSize() for 0.4.x
573+
574+0.0.1-alpha3 / 2011-11-15
575+==================
576+
577+ * Added `-s, --slow <ms>` to specify "slow" test threshold
578+ * Added `mocha-debug(1)`
579+ * Added `mocha.opts` support. Closes #31
580+ * Added: default [files] to _test/*.js_
581+ * Added protection against multiple calls to `done()`. Closes #35
582+ * Changed: bright yellow for slow Dot reporter tests
583+
584+0.0.1-alpha1 / 2011-11-08
585+==================
586+
587+ * Missed this one :)
588+
589+0.0.1-alpha1 / 2011-11-08
590+==================
591+
592+ * Initial release
--- /dev/null
+++ b/test/bower_components/mocha/LICENSE
@@ -0,0 +1,22 @@
1+(The MIT License)
2+
3+Copyright (c) 2011-2013 TJ Holowaychuk <tj@vision-media.ca>
4+
5+Permission is hereby granted, free of charge, to any person obtaining
6+a copy of this software and associated documentation files (the
7+'Software'), to deal in the Software without restriction, including
8+without limitation the rights to use, copy, modify, merge, publish,
9+distribute, sublicense, and/or sell copies of the Software, and to
10+permit persons to whom the Software is furnished to do so, subject to
11+the following conditions:
12+
13+The above copyright notice and this permission notice shall be
14+included in all copies or substantial portions of the Software.
15+
16+THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
17+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
19+IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
20+CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
21+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
22+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
--- /dev/null
+++ b/test/bower_components/mocha/Readme.md
@@ -0,0 +1,124 @@
1+ [![Build Status](https://secure.travis-ci.org/visionmedia/mocha.png)](http://travis-ci.org/visionmedia/mocha)
2+
3+ [![Mocha test framework](http://f.cl.ly/items/3l1k0n2A1U3M1I1L210p/Screen%20Shot%202012-02-24%20at%202.21.43%20PM.png)](http://visionmedia.github.io/mocha)
4+
5+ Mocha is a simple, flexible, fun JavaScript test framework for node.js and the browser. For more information view the [documentation](http://visionmedia.github.io/mocha).
6+
7+## Contributors
8+
9+```
10+
11+ project : mocha
12+ repo age : 1 year, 7 months
13+ active : 272 days
14+ commits : 1116
15+ files : 123
16+ authors :
17+ 504 TJ Holowaychuk 45.2%
18+ 389 Tj Holowaychuk 34.9%
19+ 31 Guillermo Rauch 2.8%
20+ 13 Attila Domokos 1.2%
21+ 9 John Firebaugh 0.8%
22+ 8 Jo Liss 0.7%
23+ 7 Nathan Rajlich 0.6%
24+ 6 James Carr 0.5%
25+ 6 Brendan Nee 0.5%
26+ 5 Aaron Heckmann 0.4%
27+ 4 hokaccha 0.4%
28+ 4 Xavier Antoviaque 0.4%
29+ 4 Joshua Krall 0.4%
30+ 3 Wil Moore III 0.3%
31+ 3 Jesse Dailey 0.3%
32+ 3 Nathan Bowser 0.3%
33+ 3 Tyson Tate 0.3%
34+ 3 Cory Thomas 0.3%
35+ 3 Ryunosuke SATO 0.3%
36+ 3 Paul Miller 0.3%
37+ 3 Ben Lindsey 0.3%
38+ 2 Forbes Lindesay 0.2%
39+ 2 Konstantin Käfer 0.2%
40+ 2 Brian Beck 0.2%
41+ 2 Merrick Christensen 0.2%
42+ 2 Michael Riley 0.2%
43+ 2 David Henderson 0.2%
44+ 2 Nathan Alderson 0.2%
45+ 2 Paul Armstrong 0.2%
46+ 2 Pete Hawkins 0.2%
47+ 2 Quang Van 0.2%
48+ 2 Raynos 0.2%
49+ 2 Jonas Westerlund 0.2%
50+ 2 Domenic Denicola 0.2%
51+ 2 Shawn Krisman 0.2%
52+ 2 Simon Gaeremynck 0.2%
53+ 2 FARKAS Máté 0.2%
54+ 2 Timo Tijhof 0.2%
55+ 2 Justin DuJardin 0.2%
56+ 2 Juzer Ali 0.2%
57+ 2 Ian Storm Taylor 0.2%
58+ 2 Arian Stolwijk 0.2%
59+ 2 domenic 0.2%
60+ 1 Richard Dingwall 0.1%
61+ 1 Russ Bradberry 0.1%
62+ 1 Sasha Koss 0.1%
63+ 1 Seiya Konno 0.1%
64+ 1 Standa Opichal 0.1%
65+ 1 Steve Mason 0.1%
66+ 1 Will Langstroth 0.1%
67+ 1 Yanis Wang 0.1%
68+ 1 Yuest Wang 0.1%
69+ 1 abrkn 0.1%
70+ 1 airportyh 0.1%
71+ 1 fengmk2 0.1%
72+ 1 tgautier@yahoo.com 0.1%
73+ 1 traleig1 0.1%
74+ 1 vlad 0.1%
75+ 1 yuitest 0.1%
76+ 1 Adam Crabtree 0.1%
77+ 1 Andreas Brekken 0.1%
78+ 1 Atsuya Takagi 0.1%
79+ 1 Austin Birch 0.1%
80+ 1 Bjørge Næss 0.1%
81+ 1 Brian Moore 0.1%
82+ 1 Bryan Donovan 0.1%
83+ 1 Casey Foster 0.1%
84+ 1 Corey Butler 0.1%
85+ 1 Dave McKenna 0.1%
86+ 1 Fedor Indutny 0.1%
87+ 1 Florian Margaine 0.1%
88+ 1 Frederico Silva 0.1%
89+ 1 Fredrik Lindin 0.1%
90+ 1 Gareth Murphy 0.1%
91+ 1 Gavin Mogan 0.1%
92+ 1 Greg Perkins 0.1%
93+ 1 Harry Brundage 0.1%
94+ 1 Herman Junge 0.1%
95+ 1 Ian Young 0.1%
96+ 1 Ivan 0.1%
97+ 1 Jaakko Salonen 0.1%
98+ 1 Jakub Nešetřil 0.1%
99+ 1 James Bowes 0.1%
100+ 1 James Lal 0.1%
101+ 1 Jason Barry 0.1%
102+ 1 Javier Aranda 0.1%
103+ 1 Jeff Kunkle 0.1%
104+ 1 Jonathan Creamer 0.1%
105+ 1 Jussi Virtanen 0.1%
106+ 1 Katie Gengler 0.1%
107+ 1 Kazuhito Hokamura 0.1%
108+ 1 Koen Punt 0.1%
109+ 1 Laszlo Bacsi 0.1%
110+ 1 László Bácsi 0.1%
111+ 1 Maciej Małecki 0.1%
112+ 1 Matt Robenolt 0.1%
113+ 1 Matt Smith 0.1%
114+ 1 Matthew Shanley 0.1%
115+ 1 Michael Schoonmaker 0.1%
116+ 1 Phil Sung 0.1%
117+ 1 R56 0.1%
118+```
119+
120+## Links
121+
122+ - [Google Group](http://groups.google.com/group/mochajs)
123+ - [Wiki](https://github.com/visionmedia/mocha/wiki)
124+ - Mocha [Extensions and reporters](https://github.com/visionmedia/mocha/wiki)
--- /dev/null
+++ b/test/bower_components/mocha/bower.json
@@ -0,0 +1,20 @@
1+{
2+ "name": "mocha",
3+ "version": "1.12.0",
4+ "main": "mocha.js",
5+ "ignore": [
6+ "bin",
7+ "editors",
8+ "images",
9+ "lib",
10+ "support",
11+ "test",
12+ ".gitignore",
13+ ".npmignore",
14+ ".travis.yml",
15+ "component.json",
16+ "index.js",
17+ "Makefile",
18+ "package.json"
19+ ]
20+}
\ No newline at end of file
--- /dev/null
+++ b/test/bower_components/mocha/media/logo.svg
@@ -0,0 +1,8 @@
1+<?xml version="1.0" encoding="utf-8"?>
2+<!-- Generator: Adobe Illustrator 17.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
3+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
4+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
5+ width="612px" height="792px" viewBox="0 0 612 792" enable-background="new 0 0 612 792" xml:space="preserve">
6+<circle fill="#8A6343" cx="306" cy="396" r="306"/>
7+<text transform="matrix(1 0 0 1 72.1431 424.7633)" fill="#FFFFFF" font-family="'HelveticaNeue'" font-size="153">mocha</text>
8+</svg>
--- /dev/null
+++ b/test/bower_components/mocha/mocha.css
@@ -0,0 +1,260 @@
1+@charset "utf-8";
2+
3+body {
4+ margin:0;
5+}
6+
7+#mocha {
8+ font: 20px/1.5 "Helvetica Neue", Helvetica, Arial, sans-serif;
9+ margin: 60px 50px;
10+}
11+
12+#mocha ul, #mocha li {
13+ margin: 0;
14+ padding: 0;
15+}
16+
17+#mocha ul {
18+ list-style: none;
19+}
20+
21+#mocha h1, #mocha h2 {
22+ margin: 0;
23+}
24+
25+#mocha h1 {
26+ margin-top: 15px;
27+ font-size: 1em;
28+ font-weight: 200;
29+}
30+
31+#mocha h1 a {
32+ text-decoration: none;
33+ color: inherit;
34+}
35+
36+#mocha h1 a:hover {
37+ text-decoration: underline;
38+}
39+
40+#mocha .suite .suite h1 {
41+ margin-top: 0;
42+ font-size: .8em;
43+}
44+
45+#mocha .hidden {
46+ display: none;
47+}
48+
49+#mocha h2 {
50+ font-size: 12px;
51+ font-weight: normal;
52+ cursor: pointer;
53+}
54+
55+#mocha .suite {
56+ margin-left: 15px;
57+}
58+
59+#mocha .test {
60+ margin-left: 15px;
61+ overflow: hidden;
62+}
63+
64+#mocha .test.pending:hover h2::after {
65+ content: '(pending)';
66+ font-family: arial, sans-serif;
67+}
68+
69+#mocha .test.pass.medium .duration {
70+ background: #C09853;
71+}
72+
73+#mocha .test.pass.slow .duration {
74+ background: #B94A48;
75+}
76+
77+#mocha .test.pass::before {
78+ content: '✓';
79+ font-size: 12px;
80+ display: block;
81+ float: left;
82+ margin-right: 5px;
83+ color: #00d6b2;
84+}
85+
86+#mocha .test.pass .duration {
87+ font-size: 9px;
88+ margin-left: 5px;
89+ padding: 2px 5px;
90+ color: white;
91+ -webkit-box-shadow: inset 0 1px 1px rgba(0,0,0,.2);
92+ -moz-box-shadow: inset 0 1px 1px rgba(0,0,0,.2);
93+ box-shadow: inset 0 1px 1px rgba(0,0,0,.2);
94+ -webkit-border-radius: 5px;
95+ -moz-border-radius: 5px;
96+ -ms-border-radius: 5px;
97+ -o-border-radius: 5px;
98+ border-radius: 5px;
99+}
100+
101+#mocha .test.pass.fast .duration {
102+ display: none;
103+}
104+
105+#mocha .test.pending {
106+ color: #0b97c4;
107+}
108+
109+#mocha .test.pending::before {
110+ content: '◦';
111+ color: #0b97c4;
112+}
113+
114+#mocha .test.fail {
115+ color: #c00;
116+}
117+
118+#mocha .test.fail pre {
119+ color: black;
120+}
121+
122+#mocha .test.fail::before {
123+ content: '✖';
124+ font-size: 12px;
125+ display: block;
126+ float: left;
127+ margin-right: 5px;
128+ color: #c00;
129+}
130+
131+#mocha .test pre.error {
132+ color: #c00;
133+ max-height: 300px;
134+ overflow: auto;
135+}
136+
137+#mocha .test pre {
138+ display: block;
139+ float: left;
140+ clear: left;
141+ font: 12px/1.5 monaco, monospace;
142+ margin: 5px;
143+ padding: 15px;
144+ border: 1px solid #eee;
145+ border-bottom-color: #ddd;
146+ -webkit-border-radius: 3px;
147+ -webkit-box-shadow: 0 1px 3px #eee;
148+ -moz-border-radius: 3px;
149+ -moz-box-shadow: 0 1px 3px #eee;
150+ border-radius: 3px;
151+}
152+
153+#mocha .test h2 {
154+ position: relative;
155+}
156+
157+#mocha .test a.replay {
158+ position: absolute;
159+ top: 3px;
160+ right: 0;
161+ text-decoration: none;
162+ vertical-align: middle;
163+ display: block;
164+ width: 15px;
165+ height: 15px;
166+ line-height: 15px;
167+ text-align: center;
168+ background: #eee;
169+ font-size: 15px;
170+ -moz-border-radius: 15px;
171+ border-radius: 15px;
172+ -webkit-transition: opacity 200ms;
173+ -moz-transition: opacity 200ms;
174+ transition: opacity 200ms;
175+ opacity: 0.3;
176+ color: #888;
177+}
178+
179+#mocha .test:hover a.replay {
180+ opacity: 1;
181+}
182+
183+#mocha-report.pass .test.fail {
184+ display: none;
185+}
186+
187+#mocha-report.fail .test.pass {
188+ display: none;
189+}
190+
191+#mocha-report.pending .test.pass,
192+#mocha-report.pending .test.fail {
193+ display: none;
194+}
195+#mocha-report.pending .test.pass.pending {
196+ display: block;
197+}
198+
199+#mocha-error {
200+ color: #c00;
201+ font-size: 1.5em;
202+ font-weight: 100;
203+ letter-spacing: 1px;
204+}
205+
206+#mocha-stats {
207+ position: fixed;
208+ top: 15px;
209+ right: 10px;
210+ font-size: 12px;
211+ margin: 0;
212+ color: #888;
213+ z-index: 1;
214+}
215+
216+#mocha-stats .progress {
217+ float: right;
218+ padding-top: 0;
219+}
220+
221+#mocha-stats em {
222+ color: black;
223+}
224+
225+#mocha-stats a {
226+ text-decoration: none;
227+ color: inherit;
228+}
229+
230+#mocha-stats a:hover {
231+ border-bottom: 1px solid #eee;
232+}
233+
234+#mocha-stats li {
235+ display: inline-block;
236+ margin: 0 5px;
237+ list-style: none;
238+ padding-top: 11px;
239+}
240+
241+#mocha-stats canvas {
242+ width: 40px;
243+ height: 40px;
244+}
245+
246+#mocha code .comment { color: #ddd }
247+#mocha code .init { color: #2F6FAD }
248+#mocha code .string { color: #5890AD }
249+#mocha code .keyword { color: #8A6343 }
250+#mocha code .number { color: #2F6FAD }
251+
252+@media screen and (max-device-width: 480px) {
253+ #mocha {
254+ margin: 60px 0px;
255+ }
256+
257+ #mocha #stats {
258+ position: absolute;
259+ }
260+}
--- /dev/null
+++ b/test/bower_components/mocha/mocha.js
@@ -0,0 +1,5598 @@
1+;(function(){
2+
3+// CommonJS require()
4+
5+function require(p){
6+ var path = require.resolve(p)
7+ , mod = require.modules[path];
8+ if (!mod) throw new Error('failed to require "' + p + '"');
9+ if (!mod.exports) {
10+ mod.exports = {};
11+ mod.call(mod.exports, mod, mod.exports, require.relative(path));
12+ }
13+ return mod.exports;
14+ }
15+
16+require.modules = {};
17+
18+require.resolve = function (path){
19+ var orig = path
20+ , reg = path + '.js'
21+ , index = path + '/index.js';
22+ return require.modules[reg] && reg
23+ || require.modules[index] && index
24+ || orig;
25+ };
26+
27+require.register = function (path, fn){
28+ require.modules[path] = fn;
29+ };
30+
31+require.relative = function (parent) {
32+ return function(p){
33+ if ('.' != p.charAt(0)) return require(p);
34+
35+ var path = parent.split('/')
36+ , segs = p.split('/');
37+ path.pop();
38+
39+ for (var i = 0; i < segs.length; i++) {
40+ var seg = segs[i];
41+ if ('..' == seg) path.pop();
42+ else if ('.' != seg) path.push(seg);
43+ }
44+
45+ return require(path.join('/'));
46+ };
47+ };
48+
49+
50+require.register("browser/debug.js", function(module, exports, require){
51+
52+module.exports = function(type){
53+ return function(){
54+ }
55+};
56+
57+}); // module: browser/debug.js
58+
59+require.register("browser/diff.js", function(module, exports, require){
60+/* See LICENSE file for terms of use */
61+
62+/*
63+ * Text diff implementation.
64+ *
65+ * This library supports the following APIS:
66+ * JsDiff.diffChars: Character by character diff
67+ * JsDiff.diffWords: Word (as defined by \b regex) diff which ignores whitespace
68+ * JsDiff.diffLines: Line based diff
69+ *
70+ * JsDiff.diffCss: Diff targeted at CSS content
71+ *
72+ * These methods are based on the implementation proposed in
73+ * "An O(ND) Difference Algorithm and its Variations" (Myers, 1986).
74+ * http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.4.6927
75+ */
76+var JsDiff = (function() {
77+ /*jshint maxparams: 5*/
78+ function clonePath(path) {
79+ return { newPos: path.newPos, components: path.components.slice(0) };
80+ }
81+ function removeEmpty(array) {
82+ var ret = [];
83+ for (var i = 0; i < array.length; i++) {
84+ if (array[i]) {
85+ ret.push(array[i]);
86+ }
87+ }
88+ return ret;
89+ }
90+ function escapeHTML(s) {
91+ var n = s;
92+ n = n.replace(/&/g, '&amp;');
93+ n = n.replace(/</g, '&lt;');
94+ n = n.replace(/>/g, '&gt;');
95+ n = n.replace(/"/g, '&quot;');
96+
97+ return n;
98+ }
99+
100+ var Diff = function(ignoreWhitespace) {
101+ this.ignoreWhitespace = ignoreWhitespace;
102+ };
103+ Diff.prototype = {
104+ diff: function(oldString, newString) {
105+ // Handle the identity case (this is due to unrolling editLength == 0
106+ if (newString === oldString) {
107+ return [{ value: newString }];
108+ }
109+ if (!newString) {
110+ return [{ value: oldString, removed: true }];
111+ }
112+ if (!oldString) {
113+ return [{ value: newString, added: true }];
114+ }
115+
116+ newString = this.tokenize(newString);
117+ oldString = this.tokenize(oldString);
118+
119+ var newLen = newString.length, oldLen = oldString.length;
120+ var maxEditLength = newLen + oldLen;
121+ var bestPath = [{ newPos: -1, components: [] }];
122+
123+ // Seed editLength = 0
124+ var oldPos = this.extractCommon(bestPath[0], newString, oldString, 0);
125+ if (bestPath[0].newPos+1 >= newLen && oldPos+1 >= oldLen) {
126+ return bestPath[0].components;
127+ }
128+
129+ for (var editLength = 1; editLength <= maxEditLength; editLength++) {
130+ for (var diagonalPath = -1*editLength; diagonalPath <= editLength; diagonalPath+=2) {
131+ var basePath;
132+ var addPath = bestPath[diagonalPath-1],
133+ removePath = bestPath[diagonalPath+1];
134+ oldPos = (removePath ? removePath.newPos : 0) - diagonalPath;
135+ if (addPath) {
136+ // No one else is going to attempt to use this value, clear it
137+ bestPath[diagonalPath-1] = undefined;
138+ }
139+
140+ var canAdd = addPath && addPath.newPos+1 < newLen;
141+ var canRemove = removePath && 0 <= oldPos && oldPos < oldLen;
142+ if (!canAdd && !canRemove) {
143+ bestPath[diagonalPath] = undefined;
144+ continue;
145+ }
146+
147+ // Select the diagonal that we want to branch from. We select the prior
148+ // path whose position in the new string is the farthest from the origin
149+ // and does not pass the bounds of the diff graph
150+ if (!canAdd || (canRemove && addPath.newPos < removePath.newPos)) {
151+ basePath = clonePath(removePath);
152+ this.pushComponent(basePath.components, oldString[oldPos], undefined, true);
153+ } else {
154+ basePath = clonePath(addPath);
155+ basePath.newPos++;
156+ this.pushComponent(basePath.components, newString[basePath.newPos], true, undefined);
157+ }
158+
159+ var oldPos = this.extractCommon(basePath, newString, oldString, diagonalPath);
160+
161+ if (basePath.newPos+1 >= newLen && oldPos+1 >= oldLen) {
162+ return basePath.components;
163+ } else {
164+ bestPath[diagonalPath] = basePath;
165+ }
166+ }
167+ }
168+ },
169+
170+ pushComponent: function(components, value, added, removed) {
171+ var last = components[components.length-1];
172+ if (last && last.added === added && last.removed === removed) {
173+ // We need to clone here as the component clone operation is just
174+ // as shallow array clone
175+ components[components.length-1] =
176+ {value: this.join(last.value, value), added: added, removed: removed };
177+ } else {
178+ components.push({value: value, added: added, removed: removed });
179+ }
180+ },
181+ extractCommon: function(basePath, newString, oldString, diagonalPath) {
182+ var newLen = newString.length,
183+ oldLen = oldString.length,
184+ newPos = basePath.newPos,
185+ oldPos = newPos - diagonalPath;
186+ while (newPos+1 < newLen && oldPos+1 < oldLen && this.equals(newString[newPos+1], oldString[oldPos+1])) {
187+ newPos++;
188+ oldPos++;
189+
190+ this.pushComponent(basePath.components, newString[newPos], undefined, undefined);
191+ }
192+ basePath.newPos = newPos;
193+ return oldPos;
194+ },
195+
196+ equals: function(left, right) {
197+ var reWhitespace = /\S/;
198+ if (this.ignoreWhitespace && !reWhitespace.test(left) && !reWhitespace.test(right)) {
199+ return true;
200+ } else {
201+ return left === right;
202+ }
203+ },
204+ join: function(left, right) {
205+ return left + right;
206+ },
207+ tokenize: function(value) {
208+ return value;
209+ }
210+ };
211+
212+ var CharDiff = new Diff();
213+
214+ var WordDiff = new Diff(true);
215+ var WordWithSpaceDiff = new Diff();
216+ WordDiff.tokenize = WordWithSpaceDiff.tokenize = function(value) {
217+ return removeEmpty(value.split(/(\s+|\b)/));
218+ };
219+
220+ var CssDiff = new Diff(true);
221+ CssDiff.tokenize = function(value) {
222+ return removeEmpty(value.split(/([{}:;,]|\s+)/));
223+ };
224+
225+ var LineDiff = new Diff();
226+ LineDiff.tokenize = function(value) {
227+ return value.split(/^/m);
228+ };
229+
230+ return {
231+ Diff: Diff,
232+
233+ diffChars: function(oldStr, newStr) { return CharDiff.diff(oldStr, newStr); },
234+ diffWords: function(oldStr, newStr) { return WordDiff.diff(oldStr, newStr); },
235+ diffWordsWithSpace: function(oldStr, newStr) { return WordWithSpaceDiff.diff(oldStr, newStr); },
236+ diffLines: function(oldStr, newStr) { return LineDiff.diff(oldStr, newStr); },
237+
238+ diffCss: function(oldStr, newStr) { return CssDiff.diff(oldStr, newStr); },
239+
240+ createPatch: function(fileName, oldStr, newStr, oldHeader, newHeader) {
241+ var ret = [];
242+
243+ ret.push('Index: ' + fileName);
244+ ret.push('===================================================================');
245+ ret.push('--- ' + fileName + (typeof oldHeader === 'undefined' ? '' : '\t' + oldHeader));
246+ ret.push('+++ ' + fileName + (typeof newHeader === 'undefined' ? '' : '\t' + newHeader));
247+
248+ var diff = LineDiff.diff(oldStr, newStr);
249+ if (!diff[diff.length-1].value) {
250+ diff.pop(); // Remove trailing newline add
251+ }
252+ diff.push({value: '', lines: []}); // Append an empty value to make cleanup easier
253+
254+ function contextLines(lines) {
255+ return lines.map(function(entry) { return ' ' + entry; });
256+ }
257+ function eofNL(curRange, i, current) {
258+ var last = diff[diff.length-2],
259+ isLast = i === diff.length-2,
260+ isLastOfType = i === diff.length-3 && (current.added !== last.added || current.removed !== last.removed);
261+
262+ // Figure out if this is the last line for the given file and missing NL
263+ if (!/\n$/.test(current.value) && (isLast || isLastOfType)) {
264+ curRange.push('\\ No newline at end of file');
265+ }
266+ }
267+
268+ var oldRangeStart = 0, newRangeStart = 0, curRange = [],
269+ oldLine = 1, newLine = 1;
270+ for (var i = 0; i < diff.length; i++) {
271+ var current = diff[i],
272+ lines = current.lines || current.value.replace(/\n$/, '').split('\n');
273+ current.lines = lines;
274+
275+ if (current.added || current.removed) {
276+ if (!oldRangeStart) {
277+ var prev = diff[i-1];
278+ oldRangeStart = oldLine;
279+ newRangeStart = newLine;
280+
281+ if (prev) {
282+ curRange = contextLines(prev.lines.slice(-4));
283+ oldRangeStart -= curRange.length;
284+ newRangeStart -= curRange.length;
285+ }
286+ }
287+ curRange.push.apply(curRange, lines.map(function(entry) { return (current.added?'+':'-') + entry; }));
288+ eofNL(curRange, i, current);
289+
290+ if (current.added) {
291+ newLine += lines.length;
292+ } else {
293+ oldLine += lines.length;
294+ }
295+ } else {
296+ if (oldRangeStart) {
297+ // Close out any changes that have been output (or join overlapping)
298+ if (lines.length <= 8 && i < diff.length-2) {
299+ // Overlapping
300+ curRange.push.apply(curRange, contextLines(lines));
301+ } else {
302+ // end the range and output
303+ var contextSize = Math.min(lines.length, 4);
304+ ret.push(
305+ '@@ -' + oldRangeStart + ',' + (oldLine-oldRangeStart+contextSize)
306+ + ' +' + newRangeStart + ',' + (newLine-newRangeStart+contextSize)
307+ + ' @@');
308+ ret.push.apply(ret, curRange);
309+ ret.push.apply(ret, contextLines(lines.slice(0, contextSize)));
310+ if (lines.length <= 4) {
311+ eofNL(ret, i, current);
312+ }
313+
314+ oldRangeStart = 0; newRangeStart = 0; curRange = [];
315+ }
316+ }
317+ oldLine += lines.length;
318+ newLine += lines.length;
319+ }
320+ }
321+
322+ return ret.join('\n') + '\n';
323+ },
324+
325+ applyPatch: function(oldStr, uniDiff) {
326+ var diffstr = uniDiff.split('\n');
327+ var diff = [];
328+ var remEOFNL = false,
329+ addEOFNL = false;
330+
331+ for (var i = (diffstr[0][0]==='I'?4:0); i < diffstr.length; i++) {
332+ if(diffstr[i][0] === '@') {
333+ var meh = diffstr[i].split(/@@ -(\d+),(\d+) \+(\d+),(\d+) @@/);
334+ diff.unshift({
335+ start:meh[3],
336+ oldlength:meh[2],
337+ oldlines:[],
338+ newlength:meh[4],
339+ newlines:[]
340+ });
341+ } else if(diffstr[i][0] === '+') {
342+ diff[0].newlines.push(diffstr[i].substr(1));
343+ } else if(diffstr[i][0] === '-') {
344+ diff[0].oldlines.push(diffstr[i].substr(1));
345+ } else if(diffstr[i][0] === ' ') {
346+ diff[0].newlines.push(diffstr[i].substr(1));
347+ diff[0].oldlines.push(diffstr[i].substr(1));
348+ } else if(diffstr[i][0] === '\\') {
349+ if (diffstr[i-1][0] === '+') {
350+ remEOFNL = true;
351+ } else if(diffstr[i-1][0] === '-') {
352+ addEOFNL = true;
353+ }
354+ }
355+ }
356+
357+ var str = oldStr.split('\n');
358+ for (var i = diff.length - 1; i >= 0; i--) {
359+ var d = diff[i];
360+ for (var j = 0; j < d.oldlength; j++) {
361+ if(str[d.start-1+j] !== d.oldlines[j]) {
362+ return false;
363+ }
364+ }
365+ Array.prototype.splice.apply(str,[d.start-1,+d.oldlength].concat(d.newlines));
366+ }
367+
368+ if (remEOFNL) {
369+ while (!str[str.length-1]) {
370+ str.pop();
371+ }
372+ } else if (addEOFNL) {
373+ str.push('');
374+ }
375+ return str.join('\n');
376+ },
377+
378+ convertChangesToXML: function(changes){
379+ var ret = [];
380+ for ( var i = 0; i < changes.length; i++) {
381+ var change = changes[i];
382+ if (change.added) {
383+ ret.push('<ins>');
384+ } else if (change.removed) {
385+ ret.push('<del>');
386+ }
387+
388+ ret.push(escapeHTML(change.value));
389+
390+ if (change.added) {
391+ ret.push('</ins>');
392+ } else if (change.removed) {
393+ ret.push('</del>');
394+ }
395+ }
396+ return ret.join('');
397+ },
398+
399+ // See: http://code.google.com/p/google-diff-match-patch/wiki/API
400+ convertChangesToDMP: function(changes){
401+ var ret = [], change;
402+ for ( var i = 0; i < changes.length; i++) {
403+ change = changes[i];
404+ ret.push([(change.added ? 1 : change.removed ? -1 : 0), change.value]);
405+ }
406+ return ret;
407+ }
408+ };
409+})();
410+
411+if (typeof module !== 'undefined') {
412+ module.exports = JsDiff;
413+}
414+
415+}); // module: browser/diff.js
416+
417+require.register("browser/events.js", function(module, exports, require){
418+
419+/**
420+ * Module exports.
421+ */
422+
423+exports.EventEmitter = EventEmitter;
424+
425+/**
426+ * Check if `obj` is an array.
427+ */
428+
429+function isArray(obj) {
430+ return '[object Array]' == {}.toString.call(obj);
431+}
432+
433+/**
434+ * Event emitter constructor.
435+ *
436+ * @api public
437+ */
438+
439+function EventEmitter(){};
440+
441+/**
442+ * Adds a listener.
443+ *
444+ * @api public
445+ */
446+
447+EventEmitter.prototype.on = function (name, fn) {
448+ if (!this.$events) {
449+ this.$events = {};
450+ }
451+
452+ if (!this.$events[name]) {
453+ this.$events[name] = fn;
454+ } else if (isArray(this.$events[name])) {
455+ this.$events[name].push(fn);
456+ } else {
457+ this.$events[name] = [this.$events[name], fn];
458+ }
459+
460+ return this;
461+};
462+
463+EventEmitter.prototype.addListener = EventEmitter.prototype.on;
464+
465+/**
466+ * Adds a volatile listener.
467+ *
468+ * @api public
469+ */
470+
471+EventEmitter.prototype.once = function (name, fn) {
472+ var self = this;
473+
474+ function on () {
475+ self.removeListener(name, on);
476+ fn.apply(this, arguments);
477+ };
478+
479+ on.listener = fn;
480+ this.on(name, on);
481+
482+ return this;
483+};
484+
485+/**
486+ * Removes a listener.
487+ *
488+ * @api public
489+ */
490+
491+EventEmitter.prototype.removeListener = function (name, fn) {
492+ if (this.$events && this.$events[name]) {
493+ var list = this.$events[name];
494+
495+ if (isArray(list)) {
496+ var pos = -1;
497+
498+ for (var i = 0, l = list.length; i < l; i++) {
499+ if (list[i] === fn || (list[i].listener && list[i].listener === fn)) {
500+ pos = i;
501+ break;
502+ }
503+ }
504+
505+ if (pos < 0) {
506+ return this;
507+ }
508+
509+ list.splice(pos, 1);
510+
511+ if (!list.length) {
512+ delete this.$events[name];
513+ }
514+ } else if (list === fn || (list.listener && list.listener === fn)) {
515+ delete this.$events[name];
516+ }
517+ }
518+
519+ return this;
520+};
521+
522+/**
523+ * Removes all listeners for an event.
524+ *
525+ * @api public
526+ */
527+
528+EventEmitter.prototype.removeAllListeners = function (name) {
529+ if (name === undefined) {
530+ this.$events = {};
531+ return this;
532+ }
533+
534+ if (this.$events && this.$events[name]) {
535+ this.$events[name] = null;
536+ }
537+
538+ return this;
539+};
540+
541+/**
542+ * Gets all listeners for a certain event.
543+ *
544+ * @api public
545+ */
546+
547+EventEmitter.prototype.listeners = function (name) {
548+ if (!this.$events) {
549+ this.$events = {};
550+ }
551+
552+ if (!this.$events[name]) {
553+ this.$events[name] = [];
554+ }
555+
556+ if (!isArray(this.$events[name])) {
557+ this.$events[name] = [this.$events[name]];
558+ }
559+
560+ return this.$events[name];
561+};
562+
563+/**
564+ * Emits an event.
565+ *
566+ * @api public
567+ */
568+
569+EventEmitter.prototype.emit = function (name) {
570+ if (!this.$events) {
571+ return false;
572+ }
573+
574+ var handler = this.$events[name];
575+
576+ if (!handler) {
577+ return false;
578+ }
579+
580+ var args = [].slice.call(arguments, 1);
581+
582+ if ('function' == typeof handler) {
583+ handler.apply(this, args);
584+ } else if (isArray(handler)) {
585+ var listeners = handler.slice();
586+
587+ for (var i = 0, l = listeners.length; i < l; i++) {
588+ listeners[i].apply(this, args);
589+ }
590+ } else {
591+ return false;
592+ }
593+
594+ return true;
595+};
596+}); // module: browser/events.js
597+
598+require.register("browser/fs.js", function(module, exports, require){
599+
600+}); // module: browser/fs.js
601+
602+require.register("browser/path.js", function(module, exports, require){
603+
604+}); // module: browser/path.js
605+
606+require.register("browser/progress.js", function(module, exports, require){
607+
608+/**
609+ * Expose `Progress`.
610+ */
611+
612+module.exports = Progress;
613+
614+/**
615+ * Initialize a new `Progress` indicator.
616+ */
617+
618+function Progress() {
619+ this.percent = 0;
620+ this.size(0);
621+ this.fontSize(11);
622+ this.font('helvetica, arial, sans-serif');
623+}
624+
625+/**
626+ * Set progress size to `n`.
627+ *
628+ * @param {Number} n
629+ * @return {Progress} for chaining
630+ * @api public
631+ */
632+
633+Progress.prototype.size = function(n){
634+ this._size = n;
635+ return this;
636+};
637+
638+/**
639+ * Set text to `str`.
640+ *
641+ * @param {String} str
642+ * @return {Progress} for chaining
643+ * @api public
644+ */
645+
646+Progress.prototype.text = function(str){
647+ this._text = str;
648+ return this;
649+};
650+
651+/**
652+ * Set font size to `n`.
653+ *
654+ * @param {Number} n
655+ * @return {Progress} for chaining
656+ * @api public
657+ */
658+
659+Progress.prototype.fontSize = function(n){
660+ this._fontSize = n;
661+ return this;
662+};
663+
664+/**
665+ * Set font `family`.
666+ *
667+ * @param {String} family
668+ * @return {Progress} for chaining
669+ */
670+
671+Progress.prototype.font = function(family){
672+ this._font = family;
673+ return this;
674+};
675+
676+/**
677+ * Update percentage to `n`.
678+ *
679+ * @param {Number} n
680+ * @return {Progress} for chaining
681+ */
682+
683+Progress.prototype.update = function(n){
684+ this.percent = n;
685+ return this;
686+};
687+
688+/**
689+ * Draw on `ctx`.
690+ *
691+ * @param {CanvasRenderingContext2d} ctx
692+ * @return {Progress} for chaining
693+ */
694+
695+Progress.prototype.draw = function(ctx){
696+ var percent = Math.min(this.percent, 100)
697+ , size = this._size
698+ , half = size / 2
699+ , x = half
700+ , y = half
701+ , rad = half - 1
702+ , fontSize = this._fontSize;
703+
704+ ctx.font = fontSize + 'px ' + this._font;
705+
706+ var angle = Math.PI * 2 * (percent / 100);
707+ ctx.clearRect(0, 0, size, size);
708+
709+ // outer circle
710+ ctx.strokeStyle = '#9f9f9f';
711+ ctx.beginPath();
712+ ctx.arc(x, y, rad, 0, angle, false);
713+ ctx.stroke();
714+
715+ // inner circle
716+ ctx.strokeStyle = '#eee';
717+ ctx.beginPath();
718+ ctx.arc(x, y, rad - 1, 0, angle, true);
719+ ctx.stroke();
720+
721+ // text
722+ var text = this._text || (percent | 0) + '%'
723+ , w = ctx.measureText(text).width;
724+
725+ ctx.fillText(
726+ text
727+ , x - w / 2 + 1
728+ , y + fontSize / 2 - 1);
729+
730+ return this;
731+};
732+
733+}); // module: browser/progress.js
734+
735+require.register("browser/tty.js", function(module, exports, require){
736+
737+exports.isatty = function(){
738+ return true;
739+};
740+
741+exports.getWindowSize = function(){
742+ if ('innerHeight' in global) {
743+ return [global.innerHeight, global.innerWidth];
744+ } else {
745+ // In a Web Worker, the DOM Window is not available.
746+ return [640, 480];
747+ }
748+};
749+
750+}); // module: browser/tty.js
751+
752+require.register("context.js", function(module, exports, require){
753+
754+/**
755+ * Expose `Context`.
756+ */
757+
758+module.exports = Context;
759+
760+/**
761+ * Initialize a new `Context`.
762+ *
763+ * @api private
764+ */
765+
766+function Context(){}
767+
768+/**
769+ * Set or get the context `Runnable` to `runnable`.
770+ *
771+ * @param {Runnable} runnable
772+ * @return {Context}
773+ * @api private
774+ */
775+
776+Context.prototype.runnable = function(runnable){
777+ if (0 == arguments.length) return this._runnable;
778+ this.test = this._runnable = runnable;
779+ return this;
780+};
781+
782+/**
783+ * Set test timeout `ms`.
784+ *
785+ * @param {Number} ms
786+ * @return {Context} self
787+ * @api private
788+ */
789+
790+Context.prototype.timeout = function(ms){
791+ this.runnable().timeout(ms);
792+ return this;
793+};
794+
795+/**
796+ * Set test slowness threshold `ms`.
797+ *
798+ * @param {Number} ms
799+ * @return {Context} self
800+ * @api private
801+ */
802+
803+Context.prototype.slow = function(ms){
804+ this.runnable().slow(ms);
805+ return this;
806+};
807+
808+/**
809+ * Inspect the context void of `._runnable`.
810+ *
811+ * @return {String}
812+ * @api private
813+ */
814+
815+Context.prototype.inspect = function(){
816+ return JSON.stringify(this, function(key, val){
817+ if ('_runnable' == key) return;
818+ if ('test' == key) return;
819+ return val;
820+ }, 2);
821+};
822+
823+}); // module: context.js
824+
825+require.register("hook.js", function(module, exports, require){
826+
827+/**
828+ * Module dependencies.
829+ */
830+
831+var Runnable = require('./runnable');
832+
833+/**
834+ * Expose `Hook`.
835+ */
836+
837+module.exports = Hook;
838+
839+/**
840+ * Initialize a new `Hook` with the given `title` and callback `fn`.
841+ *
842+ * @param {String} title
843+ * @param {Function} fn
844+ * @api private
845+ */
846+
847+function Hook(title, fn) {
848+ Runnable.call(this, title, fn);
849+ this.type = 'hook';
850+}
851+
852+/**
853+ * Inherit from `Runnable.prototype`.
854+ */
855+
856+function F(){};
857+F.prototype = Runnable.prototype;
858+Hook.prototype = new F;
859+Hook.prototype.constructor = Hook;
860+
861+
862+/**
863+ * Get or set the test `err`.
864+ *
865+ * @param {Error} err
866+ * @return {Error}
867+ * @api public
868+ */
869+
870+Hook.prototype.error = function(err){
871+ if (0 == arguments.length) {
872+ var err = this._error;
873+ this._error = null;
874+ return err;
875+ }
876+
877+ this._error = err;
878+};
879+
880+}); // module: hook.js
881+
882+require.register("interfaces/bdd.js", function(module, exports, require){
883+
884+/**
885+ * Module dependencies.
886+ */
887+
888+var Suite = require('../suite')
889+ , Test = require('../test')
890+ , utils = require('../utils');
891+
892+/**
893+ * BDD-style interface:
894+ *
895+ * describe('Array', function(){
896+ * describe('#indexOf()', function(){
897+ * it('should return -1 when not present', function(){
898+ *
899+ * });
900+ *
901+ * it('should return the index when present', function(){
902+ *
903+ * });
904+ * });
905+ * });
906+ *
907+ */
908