mirror of
https://github.com/zhigang1992/reactfire.git
synced 2026-03-29 17:18:39 +08:00
Switched test suite to Mocha and added linting
This commit is contained in:
152
.eslintrc
Normal file
152
.eslintrc
Normal file
@@ -0,0 +1,152 @@
|
||||
{
|
||||
"env": {
|
||||
"node": true,
|
||||
"browser": true
|
||||
},
|
||||
"globals": {
|
||||
"define" : false
|
||||
},
|
||||
"rules": {
|
||||
/**
|
||||
* Strict mode
|
||||
*/
|
||||
"strict": [2, "global"], // http://eslint.org/docs/rules/strict
|
||||
|
||||
/**
|
||||
* Variables
|
||||
*/
|
||||
"no-shadow": 2, // http://eslint.org/docs/rules/no-shadow
|
||||
"no-shadow-restricted-names": 2, // http://eslint.org/docs/rules/no-shadow-restricted-names
|
||||
"no-unused-vars": [2, { // http://eslint.org/docs/rules/no-unused-vars
|
||||
"vars": "local",
|
||||
"args": "after-used"
|
||||
}],
|
||||
"no-use-before-define": 2, // http://eslint.org/docs/rules/no-use-before-define
|
||||
|
||||
/**
|
||||
* Node.js
|
||||
*/
|
||||
"no-process-exit": 0, // http://eslint.org/docs/rules/no-process-exit
|
||||
"no-sync": 2, // http://eslint.org/docs/rules/no-sync
|
||||
|
||||
/**
|
||||
* Possible errors
|
||||
*/
|
||||
"comma-dangle": [2, "never"], // http://eslint.org/docs/rules/comma-dangle
|
||||
"no-cond-assign": [2, "always"], // http://eslint.org/docs/rules/no-cond-assign
|
||||
"no-console": 1, // http://eslint.org/docs/rules/no-console
|
||||
"no-debugger": 1, // http://eslint.org/docs/rules/no-debugger
|
||||
"no-alert": 1, // http://eslint.org/docs/rules/no-alert
|
||||
"no-constant-condition": 1, // http://eslint.org/docs/rules/no-constant-condition
|
||||
"no-dupe-keys": 2, // http://eslint.org/docs/rules/no-dupe-keys
|
||||
"no-duplicate-case": 2, // http://eslint.org/docs/rules/no-duplicate-case
|
||||
"no-empty": 2, // http://eslint.org/docs/rules/no-empty
|
||||
"no-ex-assign": 2, // http://eslint.org/docs/rules/no-ex-assign
|
||||
"no-extra-boolean-cast": 0, // http://eslint.org/docs/rules/no-extra-boolean-cast
|
||||
"no-extra-semi": 2, // http://eslint.org/docs/rules/no-extra-semi
|
||||
"no-func-assign": 2, // http://eslint.org/docs/rules/no-func-assign
|
||||
"no-inner-declarations": 2, // http://eslint.org/docs/rules/no-inner-declarations
|
||||
"no-invalid-regexp": 2, // http://eslint.org/docs/rules/no-invalid-regexp
|
||||
"no-irregular-whitespace": 2, // http://eslint.org/docs/rules/no-irregular-whitespace
|
||||
"no-obj-calls": 2, // http://eslint.org/docs/rules/no-obj-calls
|
||||
"no-reserved-keys": 2, // http://eslint.org/docs/rules/no-reserved-keys
|
||||
"no-sparse-arrays": 2, // http://eslint.org/docs/rules/no-sparse-arrays
|
||||
"no-unreachable": 2, // http://eslint.org/docs/rules/no-unreachable
|
||||
"use-isnan": 2, // http://eslint.org/docs/rules/use-isnan
|
||||
"block-scoped-var": 2, // http://eslint.org/docs/rules/block-scoped-var
|
||||
|
||||
/**
|
||||
* Best practices
|
||||
*/
|
||||
"consistent-return": 2, // http://eslint.org/docs/rules/consistent-return
|
||||
"curly": [2, "all"], // http://eslint.org/docs/rules/curly
|
||||
"default-case": 2, // http://eslint.org/docs/rules/default-case
|
||||
"dot-notation": [2, { // http://eslint.org/docs/rules/dot-notation
|
||||
"allowKeywords": true
|
||||
}],
|
||||
"eqeqeq": 2, // http://eslint.org/docs/rules/eqeqeq
|
||||
"guard-for-in": 2, // http://eslint.org/docs/rules/guard-for-in
|
||||
"no-caller": 2, // http://eslint.org/docs/rules/no-caller
|
||||
"no-else-return": 2, // http://eslint.org/docs/rules/no-else-return
|
||||
"no-eq-null": 2, // http://eslint.org/docs/rules/no-eq-null
|
||||
"no-eval": 2, // http://eslint.org/docs/rules/no-eval
|
||||
"no-extend-native": 2, // http://eslint.org/docs/rules/no-extend-native
|
||||
"no-extra-bind": 2, // http://eslint.org/docs/rules/no-extra-bind
|
||||
"no-fallthrough": 2, // http://eslint.org/docs/rules/no-fallthrough
|
||||
"no-floating-decimal": 2, // http://eslint.org/docs/rules/no-floating-decimal
|
||||
"no-implied-eval": 2, // http://eslint.org/docs/rules/no-implied-eval
|
||||
"no-lone-blocks": 2, // http://eslint.org/docs/rules/no-lone-blocks
|
||||
"no-loop-func": 2, // http://eslint.org/docs/rules/no-loop-func
|
||||
"no-multi-str": 2, // http://eslint.org/docs/rules/no-multi-str
|
||||
"no-native-reassign": 2, // http://eslint.org/docs/rules/no-native-reassign
|
||||
"no-new": 2, // http://eslint.org/docs/rules/no-new
|
||||
"no-new-func": 2, // http://eslint.org/docs/rules/no-new-func
|
||||
"no-new-wrappers": 2, // http://eslint.org/docs/rules/no-new-wrappers
|
||||
"no-octal": 2, // http://eslint.org/docs/rules/no-octal
|
||||
"no-octal-escape": 2, // http://eslint.org/docs/rules/no-octal-escape
|
||||
//"no-param-reassign": 2, // http://eslint.org/docs/rules/no-param-reassign
|
||||
"no-proto": 2, // http://eslint.org/docs/rules/no-proto
|
||||
"no-redeclare": 2, // http://eslint.org/docs/rules/no-redeclare
|
||||
"no-return-assign": 2, // http://eslint.org/docs/rules/no-return-assign
|
||||
"no-script-url": 2, // http://eslint.org/docs/rules/no-script-url
|
||||
"no-self-compare": 2, // http://eslint.org/docs/rules/no-self-compare
|
||||
"no-sequences": 2, // http://eslint.org/docs/rules/no-sequences
|
||||
"no-throw-literal": 2, // http://eslint.org/docs/rules/no-throw-literal
|
||||
"no-with": 2, // http://eslint.org/docs/rules/no-with
|
||||
"radix": 2, // http://eslint.org/docs/rules/radix
|
||||
//"vars-on-top": 2, // http://eslint.org/docs/rules/vars-on-top
|
||||
"wrap-iife": [2, "any"], // http://eslint.org/docs/rules/wrap-iife
|
||||
"yoda": 2, // http://eslint.org/docs/rules/yoda
|
||||
|
||||
/**
|
||||
* Style
|
||||
*/
|
||||
"indent": [2, 2], // http://eslint.org/docs/rules/indent
|
||||
"brace-style": [2, // http://eslint.org/docs/rules/brace-style
|
||||
"1tbs", {
|
||||
"allowSingleLine": true
|
||||
}],
|
||||
"quotes": [
|
||||
2, "single", "avoid-escape" // http://eslint.org/docs/rules/quotes
|
||||
],
|
||||
"camelcase": [2, { // http://eslint.org/docs/rules/camelcase
|
||||
"properties": "never"
|
||||
}],
|
||||
"comma-spacing": [2, { // http://eslint.org/docs/rules/comma-spacing
|
||||
"before": false,
|
||||
"after": true
|
||||
}],
|
||||
"comma-style": [2, "last"], // http://eslint.org/docs/rules/comma-style
|
||||
"eol-last": 2, // http://eslint.org/docs/rules/eol-last
|
||||
//"func-names": 1, // http://eslint.org/docs/rules/func-names
|
||||
"key-spacing": [2, { // http://eslint.org/docs/rules/key-spacing
|
||||
"beforeColon": false,
|
||||
"afterColon": true
|
||||
}],
|
||||
"new-cap": [2, { // http://eslint.org/docs/rules/new-cap
|
||||
"newIsCap": true
|
||||
}],
|
||||
"no-multiple-empty-lines": [2, { // http://eslint.org/docs/rules/no-multiple-empty-lines
|
||||
"max": 2
|
||||
}],
|
||||
"no-nested-ternary": 2, // http://eslint.org/docs/rules/no-nested-ternary
|
||||
"no-new-object": 2, // http://eslint.org/docs/rules/no-new-object
|
||||
"no-spaced-func": 2, // http://eslint.org/docs/rules/no-spaced-func
|
||||
"no-trailing-spaces": 2, // http://eslint.org/docs/rules/no-trailing-spaces
|
||||
"no-wrap-func": 2, // http://eslint.org/docs/rules/no-wrap-func
|
||||
"no-underscore-dangle": 0, // http://eslint.org/docs/rules/no-underscore-dangle
|
||||
"one-var": [2, "never"], // http://eslint.org/docs/rules/one-var
|
||||
"padded-blocks": [2, "never"], // http://eslint.org/docs/rules/padded-blocks
|
||||
"semi": [2, "always"], // http://eslint.org/docs/rules/semi
|
||||
"semi-spacing": [2, { // http://eslint.org/docs/rules/semi-spacing
|
||||
"before": false,
|
||||
"after": true
|
||||
}],
|
||||
"space-after-keywords": 2, // http://eslint.org/docs/rules/space-after-keywords
|
||||
"space-before-blocks": 2, // http://eslint.org/docs/rules/space-before-blocks
|
||||
"space-before-function-paren": [2, "never"], // http://eslint.org/docs/rules/space-before-function-paren
|
||||
"space-infix-ops": 2, // http://eslint.org/docs/rules/space-infix-ops
|
||||
"space-return-throw-case": 2, // http://eslint.org/docs/rules/space-return-throw-case
|
||||
"spaced-line-comment": 2, // http://eslint.org/docs/rules/spaced-line-comment
|
||||
}
|
||||
}
|
||||
6
.gitignore
vendored
6
.gitignore
vendored
@@ -1,4 +1,4 @@
|
||||
/dist/
|
||||
dist/
|
||||
coverage/
|
||||
node_modules/
|
||||
/bower_components/
|
||||
tests/coverage
|
||||
bower_components/
|
||||
|
||||
19
.jshintrc
19
.jshintrc
@@ -1,19 +0,0 @@
|
||||
{
|
||||
"predef": [
|
||||
"define",
|
||||
"module",
|
||||
"Firebase"
|
||||
],
|
||||
"bitwise": true,
|
||||
"curly": true,
|
||||
"eqeqeq": true,
|
||||
"forin": true,
|
||||
"freeze": true,
|
||||
"indent": 2,
|
||||
"latedef": true,
|
||||
"quotmark": "double",
|
||||
"strict": true,
|
||||
"trailing": true,
|
||||
"undef": true,
|
||||
"unused": true
|
||||
}
|
||||
@@ -2,9 +2,7 @@ language: node_js
|
||||
node_js:
|
||||
- '0.10'
|
||||
install:
|
||||
- npm install -g bower
|
||||
- npm install
|
||||
- bower install
|
||||
before_script:
|
||||
- export DISPLAY=:99.0
|
||||
- sh -e /etc/init.d/xvfb start
|
||||
|
||||
@@ -32,10 +32,7 @@
|
||||
"changelog.txt"
|
||||
],
|
||||
"dependencies": {
|
||||
"react": "0.12.x",
|
||||
"firebase": "2.0.x"
|
||||
},
|
||||
"devDependencies": {
|
||||
"jasmine": "~2.0.0"
|
||||
"react": "0.13.x",
|
||||
"firebase": "2.2.x"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,2 +0,0 @@
|
||||
return ReactFireMixin;
|
||||
}));
|
||||
26
build/header
26
build/header
@@ -1,26 +0,0 @@
|
||||
/*!
|
||||
* ReactFire is an open-source JavaScript library that allows you to add a
|
||||
* realtime data source to your React apps by providing and easy way to let
|
||||
* Firebase populate the state of React components.
|
||||
*
|
||||
* ReactFire 0.0.0
|
||||
* https://github.com/firebase/reactfire/
|
||||
* License: MIT
|
||||
*/
|
||||
|
||||
;(function (root, factory) {
|
||||
"use strict";
|
||||
if (typeof define === "function" && define.amd) {
|
||||
// AMD
|
||||
define([], function() {
|
||||
return (root.ReactFireMixin = factory());
|
||||
});
|
||||
} else if (typeof exports === "object") {
|
||||
// CommonJS
|
||||
module.exports = factory();
|
||||
} else {
|
||||
// Global variables
|
||||
root.ReactFireMixin = factory();
|
||||
}
|
||||
}(this, function() {
|
||||
"use strict";
|
||||
141
gulpfile.js
141
gulpfile.js
@@ -1,123 +1,94 @@
|
||||
'use strict';
|
||||
|
||||
/**************/
|
||||
/* REQUIRES */
|
||||
/**************/
|
||||
var gulp = require("gulp");
|
||||
var gulp = require('gulp');
|
||||
var runSequence = require('run-sequence');
|
||||
|
||||
// File IO
|
||||
var streamqueue = require("streamqueue");
|
||||
var concat = require("gulp-concat");
|
||||
var jshint = require("gulp-jshint");
|
||||
var uglify = require("gulp-uglify");
|
||||
var exit = require('gulp-exit');
|
||||
var eslint = require('gulp-eslint');
|
||||
var uglify = require('gulp-uglify');
|
||||
var extReplace = require('gulp-ext-replace');
|
||||
|
||||
// Testing
|
||||
var karma = require("gulp-karma");
|
||||
|
||||
// Determine if this is being run in Travis
|
||||
var travis = false;
|
||||
var mocha = require('gulp-mocha');
|
||||
var istanbul = require('gulp-istanbul');
|
||||
|
||||
|
||||
/****************/
|
||||
/* FILE PATHS */
|
||||
/****************/
|
||||
var paths = {
|
||||
destDir: "dist",
|
||||
destDir: 'dist',
|
||||
|
||||
scripts: {
|
||||
src: {
|
||||
dir: "src",
|
||||
files: [
|
||||
"src/*.js"
|
||||
]
|
||||
},
|
||||
dest: {
|
||||
dir: "dist",
|
||||
files: {
|
||||
unminified: "reactfire.js",
|
||||
minified: "reactfire.min.js"
|
||||
}
|
||||
}
|
||||
},
|
||||
srcFiles: [
|
||||
'src/reactfire.js'
|
||||
],
|
||||
|
||||
tests: {
|
||||
config: "tests/karma.conf.js",
|
||||
files: [
|
||||
"bower_components/firebase/firebase.js",
|
||||
"tests/phantomjs-es5-shim.js",
|
||||
"bower_components/react/react-with-addons.js",
|
||||
"src/*.js",
|
||||
"tests/specs/*.spec.js"
|
||||
]
|
||||
}
|
||||
testFiles: [
|
||||
'tests/helpers.js',
|
||||
'tests/reactfire.spec.js'
|
||||
]
|
||||
};
|
||||
|
||||
|
||||
/***********/
|
||||
/* TASKS */
|
||||
/***********/
|
||||
/* Lints, minifies, and concatenates the script files */
|
||||
gulp.task("scripts", function() {
|
||||
// Concatenate all src files together
|
||||
var stream = streamqueue({ objectMode: true });
|
||||
stream.queue(gulp.src("build/header"));
|
||||
stream.queue(gulp.src(paths.scripts.src.files));
|
||||
stream.queue(gulp.src("build/footer"));
|
||||
// Lints the JavaScript files
|
||||
gulp.task('lint', function() {
|
||||
var filesToLint = paths.srcFiles.concat(paths.testFiles).concat(['gulpfile.js']);
|
||||
return gulp.src(filesToLint)
|
||||
.pipe(eslint())
|
||||
.pipe(eslint.format())
|
||||
.pipe(eslint.failAfterError());
|
||||
});
|
||||
|
||||
// Output the final concatenated script file
|
||||
return stream.done()
|
||||
// Rename file
|
||||
.pipe(concat(paths.scripts.dest.files.unminified))
|
||||
|
||||
// Lint
|
||||
.pipe(jshint())
|
||||
.pipe(jshint.reporter("jshint-stylish"))
|
||||
.pipe(jshint.reporter("fail"))
|
||||
.on("error", function(error) {
|
||||
if (travis) {
|
||||
throw error;
|
||||
}
|
||||
})
|
||||
|
||||
/* Builds the distribution files */
|
||||
gulp.task('build', function() {
|
||||
return gulp.src(paths.srcFiles)
|
||||
// Write un-minified version
|
||||
.pipe(gulp.dest(paths.scripts.dest.dir))
|
||||
.pipe(gulp.dest(paths.destDir))
|
||||
|
||||
// Minify
|
||||
.pipe(uglify({
|
||||
preserveComments: "some"
|
||||
preserveComments: 'some'
|
||||
}))
|
||||
|
||||
// Rename file
|
||||
.pipe(concat(paths.scripts.dest.files.minified))
|
||||
// Change the file extension
|
||||
.pipe(extReplace('.min.js'))
|
||||
|
||||
// Write minified version to the distribution directory
|
||||
.pipe(gulp.dest(paths.scripts.dest.dir));
|
||||
// Write minified version
|
||||
.pipe(gulp.dest(paths.destDir));
|
||||
});
|
||||
|
||||
/* Uses the Karma test runner to run the Jasmine tests */
|
||||
gulp.task("test", function() {
|
||||
return gulp.src(paths.tests.files)
|
||||
.pipe(karma({
|
||||
configFile: paths.tests.config,
|
||||
browsers: travis ? ["Firefox"] : ["Chrome"],
|
||||
action: "run"
|
||||
}))
|
||||
.on("error", function(error) {
|
||||
throw error;
|
||||
// Runs the Mocha test suite
|
||||
gulp.task('test', function() {
|
||||
return gulp.src(paths.srcFiles)
|
||||
.pipe(istanbul())
|
||||
.pipe(istanbul.hookRequire())
|
||||
.on('finish', function() {
|
||||
gulp.src(paths.testFiles)
|
||||
.pipe(mocha({
|
||||
reporter: 'spec',
|
||||
timeout: 5000
|
||||
}))
|
||||
.pipe(istanbul.writeReports())
|
||||
.pipe(exit());
|
||||
});
|
||||
});
|
||||
|
||||
/* Re-runs the "scripts" task every time a script file changes */
|
||||
gulp.task("watch", function() {
|
||||
gulp.watch(["build/*", paths.scripts.src.dir + "/**/*"], ["scripts"]);
|
||||
// Re-lints and re-builds every time a source file changes
|
||||
gulp.task('watch', function() {
|
||||
gulp.watch([paths.srcFiles], ['lint', 'build']);
|
||||
});
|
||||
|
||||
/* Builds the distribution files */
|
||||
gulp.task("build", ["scripts"]);
|
||||
|
||||
/* Tasks to be run within Travis CI */
|
||||
gulp.task("travis", function() {
|
||||
travis = true;
|
||||
gulp.start("build", "test");
|
||||
// Default task
|
||||
gulp.task('default', function(done) {
|
||||
runSequence('lint', 'build', 'test', function(error) {
|
||||
done(error && error.err);
|
||||
});
|
||||
});
|
||||
|
||||
/* Runs the "scripts" and "test" tasks by default */
|
||||
gulp.task("default", ["build", "test"]);
|
||||
|
||||
32
package.json
32
package.json
@@ -32,28 +32,24 @@
|
||||
"package.json"
|
||||
],
|
||||
"dependencies": {
|
||||
"firebase": "2.0.x",
|
||||
"react": "0.12.x"
|
||||
"firebase": "2.2.x",
|
||||
"react": "0.13.x"
|
||||
},
|
||||
"devDependencies": {
|
||||
"coveralls": "^2.11.1",
|
||||
"gulp": "^3.8.7",
|
||||
"gulp-concat": "^2.2.0",
|
||||
"gulp-jshint": "^1.5.1",
|
||||
"gulp-karma": "0.0.4",
|
||||
"gulp-uglify": "^0.2.1",
|
||||
"jshint-stylish": "^0.2.0",
|
||||
"karma": "^0.12.16",
|
||||
"karma-chrome-launcher": "^0.1.5",
|
||||
"karma-coverage": "^0.2.4",
|
||||
"karma-failed-reporter": "0.0.2",
|
||||
"karma-firefox-launcher": "^0.1.3",
|
||||
"karma-jasmine": "~0.2.0",
|
||||
"karma-spec-reporter": "0.0.13",
|
||||
"streamqueue": "^0.1.1"
|
||||
"chai": "^3.0.0",
|
||||
"coveralls": "^2.11.2",
|
||||
"gulp": "^3.9.0",
|
||||
"gulp-eslint": "^0.15.0",
|
||||
"gulp-exit": "0.0.2",
|
||||
"gulp-ext-replace": "^0.2.0",
|
||||
"gulp-istanbul": "^0.10.0",
|
||||
"gulp-mocha": "^2.1.2",
|
||||
"gulp-uglify": "^1.2.0",
|
||||
"jsdom": "3.x.x",
|
||||
"run-sequence": "^1.1.1"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "gulp test",
|
||||
"travis": "gulp travis"
|
||||
"travis": "gulp"
|
||||
}
|
||||
}
|
||||
|
||||
307
src/reactfire.js
307
src/reactfire.js
@@ -1,146 +1,165 @@
|
||||
var ReactFireMixin = {
|
||||
/********************/
|
||||
/* MIXIN LIFETIME */
|
||||
/********************/
|
||||
/* Initializes the Firebase binding refs array */
|
||||
componentWillMount: function() {
|
||||
this.firebaseRefs = {};
|
||||
this.firebaseListeners = {};
|
||||
},
|
||||
/*!
|
||||
* ReactFire is an open-source JavaScript library that allows you to add a
|
||||
* realtime data source to your React apps by providing and easy way to let
|
||||
* Firebase populate the state of React components.
|
||||
*
|
||||
* ReactFire 0.0.0
|
||||
* https://github.com/firebase/reactfire/
|
||||
* License: MIT
|
||||
*/
|
||||
/* eslint "strict": [2, "function"] */
|
||||
(function(root, factory) {
|
||||
'use strict';
|
||||
|
||||
/* Removes any remaining Firebase bindings */
|
||||
componentWillUnmount: function() {
|
||||
for (var key in this.firebaseRefs) {
|
||||
if (this.firebaseRefs.hasOwnProperty(key)) {
|
||||
this.unbind(key);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
/*************/
|
||||
/* BINDING */
|
||||
/*************/
|
||||
/* Creates a binding between Firebase and the inputted bind variable as an array */
|
||||
bindAsArray: function(firebaseRef, bindVar, cancelCallback) {
|
||||
this._bind(firebaseRef, bindVar, cancelCallback, true);
|
||||
},
|
||||
|
||||
/* Creates a binding between Firebase and the inputted bind variable as an object */
|
||||
bindAsObject: function(firebaseRef, bindVar, cancelCallback) {
|
||||
this._bind(firebaseRef, bindVar, cancelCallback, false);
|
||||
},
|
||||
|
||||
/* Creates a binding between Firebase and the inputted bind variable as either an array or object */
|
||||
_bind: function(firebaseRef, bindVar, cancelCallback, bindAsArray) {
|
||||
this._validateBindVar(bindVar);
|
||||
|
||||
var errorMessage, errorCode;
|
||||
if (Object.prototype.toString.call(firebaseRef) !== "[object Object]") {
|
||||
errorMessage = "firebaseRef must be an instance of Firebase";
|
||||
errorCode = "INVALID_FIREBASE_REF";
|
||||
}
|
||||
else if (typeof bindAsArray !== "boolean") {
|
||||
errorMessage = "bindAsArray must be a boolean. Got: " + bindAsArray;
|
||||
errorCode = "INVALID_BIND_AS_ARRAY";
|
||||
}
|
||||
|
||||
if (typeof errorMessage !== "undefined") {
|
||||
var error = new Error("ReactFire: " + errorMessage);
|
||||
error.code = errorCode;
|
||||
throw error;
|
||||
}
|
||||
|
||||
this.firebaseRefs[bindVar] = firebaseRef.ref();
|
||||
this.firebaseListeners[bindVar] = firebaseRef.on("value", function(dataSnapshot) {
|
||||
var newState = {};
|
||||
if (bindAsArray) {
|
||||
newState[bindVar] = this._toArray(dataSnapshot.val());
|
||||
}
|
||||
else {
|
||||
newState[bindVar] = dataSnapshot.val();
|
||||
}
|
||||
this.setState(newState);
|
||||
}.bind(this), cancelCallback);
|
||||
},
|
||||
|
||||
/* Removes the binding between Firebase and the inputted bind variable */
|
||||
unbind: function(bindVar) {
|
||||
this._validateBindVar(bindVar);
|
||||
|
||||
if (typeof this.firebaseRefs[bindVar] === "undefined") {
|
||||
var error = new Error("ReactFire: unexpected value for bindVar. \"" + bindVar + "\" was either never bound or has already been unbound");
|
||||
error.code = "UNBOUND_BIND_VARIABLE";
|
||||
throw error;
|
||||
}
|
||||
|
||||
this.firebaseRefs[bindVar].off("value", this.firebaseListeners[bindVar]);
|
||||
delete this.firebaseRefs[bindVar];
|
||||
delete this.firebaseListeners[bindVar];
|
||||
},
|
||||
|
||||
|
||||
/*************/
|
||||
/* HELPERS */
|
||||
/*************/
|
||||
/* Validates the name of the variable which is being bound */
|
||||
_validateBindVar: function(bindVar) {
|
||||
var errorMessage;
|
||||
|
||||
if (typeof bindVar !== "string") {
|
||||
errorMessage = "bindVar must be a string. Got: " + bindVar;
|
||||
}
|
||||
else if (bindVar.length === 0) {
|
||||
errorMessage = "bindVar must be a non-empty string. Got: \"\"";
|
||||
}
|
||||
else if (bindVar.length > 768) {
|
||||
// Firebase can only stored child paths up to 768 characters
|
||||
errorMessage = "bindVar is too long to be stored in Firebase. Got: " + bindVar;
|
||||
}
|
||||
else if (/[\[\].#$\/\u0000-\u001F\u007F]/.test(bindVar)) {
|
||||
// Firebase does not allow node keys to contain the following characters
|
||||
errorMessage = "bindVar cannot contain any of the following characters: . # $ ] [ /. Got: " + bindVar;
|
||||
}
|
||||
|
||||
if (typeof errorMessage !== "undefined") {
|
||||
var error = new Error("ReactFire: " + errorMessage);
|
||||
error.code = "INVALID_BIND_VARIABLE";
|
||||
throw error;
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
/* Returns true if the inputted object is a JavaScript array */
|
||||
_isArray: function(obj) {
|
||||
return (Object.prototype.toString.call(obj) === "[object Array]");
|
||||
},
|
||||
|
||||
/* Converts a Firebase object to a JavaScript array */
|
||||
_toArray: function(obj) {
|
||||
var item;
|
||||
var out = [];
|
||||
if (obj) {
|
||||
if (this._isArray(obj)) {
|
||||
for (var i = 0, length = obj.length; i < length; i++) {
|
||||
item = obj[i];
|
||||
if (item !== undefined && item !== null) {
|
||||
out.push({ $key: i, $value: item });
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (typeof(obj) === "object") {
|
||||
for (var key in obj) {
|
||||
if (obj.hasOwnProperty(key)) {
|
||||
item = obj[key];
|
||||
if (typeof item !== "object") {
|
||||
item = { $value: item };
|
||||
}
|
||||
item.$key = key;
|
||||
out.push(item);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return out;
|
||||
/* istanbul ignore next */
|
||||
if (typeof define === 'function' && define.amd) {
|
||||
// AMD
|
||||
define([], function() {
|
||||
return (root.ReactFireMixin = factory());
|
||||
});
|
||||
} else if (typeof exports === 'object') {
|
||||
// CommonJS
|
||||
module.exports = factory();
|
||||
} else {
|
||||
// Global variables
|
||||
root.ReactFireMixin = factory();
|
||||
}
|
||||
};
|
||||
}(this, function() {
|
||||
'use strict';
|
||||
|
||||
var ReactFireMixin = {
|
||||
/********************/
|
||||
/* MIXIN LIFETIME */
|
||||
/********************/
|
||||
/* Initializes the Firebase binding refs array */
|
||||
componentWillMount: function() {
|
||||
this.firebaseRefs = {};
|
||||
this.firebaseListeners = {};
|
||||
},
|
||||
|
||||
/* Removes any remaining Firebase bindings */
|
||||
componentWillUnmount: function() {
|
||||
for (var key in this.firebaseRefs) {
|
||||
if (this.firebaseRefs.hasOwnProperty(key)) {
|
||||
this.unbind(key);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
/*************/
|
||||
/* BINDING */
|
||||
/*************/
|
||||
/* Creates a binding between Firebase and the inputted bind variable as an array */
|
||||
bindAsArray: function(firebaseRef, bindVar, cancelCallback) {
|
||||
this._bind(firebaseRef, bindVar, cancelCallback, true);
|
||||
},
|
||||
|
||||
/* Creates a binding between Firebase and the inputted bind variable as an object */
|
||||
bindAsObject: function(firebaseRef, bindVar, cancelCallback) {
|
||||
this._bind(firebaseRef, bindVar, cancelCallback, false);
|
||||
},
|
||||
|
||||
/* Throw a formatted error message */
|
||||
_throwError: function(message) {
|
||||
throw new Error('ReactFire: ' + message);
|
||||
},
|
||||
|
||||
/* Creates a binding between Firebase and the inputted bind variable as either an array or object */
|
||||
_bind: function(firebaseRef, bindVar, cancelCallback, bindAsArray) {
|
||||
this._validateBindVar(bindVar);
|
||||
|
||||
if (Object.prototype.toString.call(firebaseRef) !== '[object Object]') {
|
||||
this._throwError('firebaseRef must be an instance of Firebase');
|
||||
}
|
||||
|
||||
this.firebaseRefs[bindVar] = firebaseRef.ref();
|
||||
this.firebaseListeners[bindVar] = firebaseRef.on('value', function(dataSnapshot) {
|
||||
var newState = {};
|
||||
if (bindAsArray) {
|
||||
newState[bindVar] = this._toArray(dataSnapshot.val());
|
||||
} else {
|
||||
newState[bindVar] = dataSnapshot.val();
|
||||
}
|
||||
this.setState(newState);
|
||||
}.bind(this), cancelCallback);
|
||||
},
|
||||
|
||||
/* Removes the binding between Firebase and the inputted bind variable */
|
||||
unbind: function(bindVar, callback) {
|
||||
this._validateBindVar(bindVar);
|
||||
|
||||
if (typeof this.firebaseRefs[bindVar] === 'undefined') {
|
||||
this._throwError('unexpected value for bindVar. "' + bindVar + '" was either never bound or has already been unbound');
|
||||
}
|
||||
|
||||
this.firebaseRefs[bindVar].off('value', this.firebaseListeners[bindVar]);
|
||||
delete this.firebaseRefs[bindVar];
|
||||
delete this.firebaseListeners[bindVar];
|
||||
|
||||
var newState = {};
|
||||
newState[bindVar] = undefined;
|
||||
this.setState(newState, callback);
|
||||
},
|
||||
|
||||
|
||||
/*************/
|
||||
/* HELPERS */
|
||||
/*************/
|
||||
/* Validates the name of the variable which is being bound */
|
||||
_validateBindVar: function(bindVar) {
|
||||
var errorMessage;
|
||||
|
||||
if (typeof bindVar !== 'string') {
|
||||
errorMessage = 'bindVar must be a string. Got: ' + bindVar;
|
||||
} else if (bindVar.length === 0) {
|
||||
errorMessage = 'bindVar must be a non-empty string. Got: ""';
|
||||
} else if (bindVar.length > 768) {
|
||||
// Firebase can only stored child paths up to 768 characters
|
||||
errorMessage = 'bindVar is too long to be stored in Firebase. Got: ' + bindVar;
|
||||
} else if (/[\[\].#$\/\u0000-\u001F\u007F]/.test(bindVar)) {
|
||||
// Firebase does not allow node keys to contain the following characters
|
||||
errorMessage = 'bindVar cannot contain any of the following characters: . # $ ] [ /. Got: ' + bindVar;
|
||||
}
|
||||
|
||||
if (typeof errorMessage !== 'undefined') {
|
||||
this._throwError(errorMessage);
|
||||
}
|
||||
},
|
||||
|
||||
/* Returns true if the inputted object is a JavaScript array */
|
||||
_isArray: function(obj) {
|
||||
return (Object.prototype.toString.call(obj) === '[object Array]');
|
||||
},
|
||||
|
||||
/* Converts a Firebase object to a JavaScript array */
|
||||
_toArray: function(obj) {
|
||||
var item;
|
||||
var out = [];
|
||||
if (obj) {
|
||||
if (this._isArray(obj)) {
|
||||
for (var i = 0, length = obj.length; i < length; i++) {
|
||||
item = obj[i];
|
||||
if (item !== undefined && item !== null) {
|
||||
out.push({ $key: i, $value: item });
|
||||
}
|
||||
}
|
||||
} else if (typeof obj === 'object') {
|
||||
for (var key in obj) {
|
||||
if (obj.hasOwnProperty(key)) {
|
||||
item = obj[key];
|
||||
if (typeof item !== 'object') {
|
||||
item = { $value: item };
|
||||
}
|
||||
item.$key = key;
|
||||
out.push(item);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return out;
|
||||
}
|
||||
};
|
||||
|
||||
return ReactFireMixin;
|
||||
}));
|
||||
|
||||
8
tests/.eslintrc
Normal file
8
tests/.eslintrc
Normal file
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"env": {
|
||||
"mocha": true
|
||||
},
|
||||
"rules": {
|
||||
"no-unused-expressions": 0
|
||||
}
|
||||
}
|
||||
19
tests/helpers.js
Normal file
19
tests/helpers.js
Normal file
@@ -0,0 +1,19 @@
|
||||
'use strict';
|
||||
|
||||
module.exports = {
|
||||
invalidFirebaseRefs: [null, undefined, true, false, [], 0, 5, '', 'a', ['hi', 1]],
|
||||
invalidBindVars: ['', 1, true, false, [], {}, [1, 2], {a: 1}, null, undefined, 'te.st', 'te$st', 'te[st', 'te]st', 'te#st', 'te/st', 'a#i]$da[s', 'te/nst', 'te/rst', 'te/u0000st', 'te/u0015st', 'te/007Fst', Array(800).join('a')],
|
||||
|
||||
/* Returns a random alphabetic string of variable length */
|
||||
generateRandomString: function() {
|
||||
var possibleCharacters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
|
||||
var numPossibleCharacters = possibleCharacters.length;
|
||||
|
||||
var text = '';
|
||||
for (var i = 0; i < 10; i++) {
|
||||
text += possibleCharacters.charAt(Math.floor(Math.random() * numPossibleCharacters));
|
||||
}
|
||||
|
||||
return text;
|
||||
}
|
||||
};
|
||||
@@ -1,28 +0,0 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<title>ReactFire Test Suite</title>
|
||||
|
||||
<!-- Jasmine -->
|
||||
<script src="../bower_components/jasmine/lib/jasmine-core/jasmine.js"></script>
|
||||
<script src="../bower_components/jasmine/lib/jasmine-core/jasmine-html.js"></script>
|
||||
<script src="../bower_components/jasmine/lib/jasmine-core/boot.js"></script>
|
||||
<link rel="stylesheet" href="../bower_components/jasmine/lib/jasmine-core/jasmine.css">
|
||||
|
||||
<!-- React -->
|
||||
<script src="../bower_components/react/react-with-addons.js"></script>
|
||||
|
||||
<!-- Firebase -->
|
||||
<script src="../bower_components/firebase/firebase.js"></script>
|
||||
|
||||
<!-- ReactFire -->
|
||||
<script src="../src/reactfire.js"></script>
|
||||
|
||||
<!-- Jasmine specs -->
|
||||
<script src="specs/common.spec.js"></script>
|
||||
<script src="specs/reactfire.spec.js"></script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,25 +0,0 @@
|
||||
module.exports = function(config) {
|
||||
config.set({
|
||||
frameworks: ["jasmine"],
|
||||
autowatch: false,
|
||||
singleRun: true,
|
||||
|
||||
preprocessors: {
|
||||
"../src/*.js": "coverage"
|
||||
},
|
||||
|
||||
reporters: ["spec", "failed", "coverage"],
|
||||
coverageReporter: {
|
||||
reporters: [
|
||||
{
|
||||
type: "lcovonly",
|
||||
dir: "coverage",
|
||||
subdir: "."
|
||||
},
|
||||
{
|
||||
type: "text-summary"
|
||||
}
|
||||
]
|
||||
}
|
||||
});
|
||||
};
|
||||
File diff suppressed because it is too large
Load Diff
432
tests/reactfire.spec.js
Normal file
432
tests/reactfire.spec.js
Normal file
@@ -0,0 +1,432 @@
|
||||
'use strict';
|
||||
|
||||
// Mocha / Chai
|
||||
var chai = require('chai');
|
||||
var expect = chai.expect;
|
||||
|
||||
// React
|
||||
var React = require('react/addons');
|
||||
var ReactTestUtils = React.addons.TestUtils;
|
||||
|
||||
// ReactFire
|
||||
var Firebase = require('firebase');
|
||||
var ReactFireMixin = require('../src/reactfire.js');
|
||||
|
||||
// JSDom
|
||||
var jsdom = require('jsdom');
|
||||
global.document = jsdom.jsdom(); // Needed for ReactTestUtils shallow renderer
|
||||
document.createElement = null; // Needed for Firebase
|
||||
|
||||
// Test helpers
|
||||
var TH = require('./helpers.js');
|
||||
|
||||
// Get a reference to a random demo Firebase
|
||||
var demoFirebaseUrl = 'https://' + TH.generateRandomString() + '.firebaseio-demo.com';
|
||||
|
||||
|
||||
describe('ReactFire', function() {
|
||||
var firebaseRef;
|
||||
var shallowRenderer;
|
||||
|
||||
beforeEach(function(done) {
|
||||
shallowRenderer = ReactTestUtils.createRenderer();
|
||||
|
||||
firebaseRef = new Firebase(demoFirebaseUrl);
|
||||
firebaseRef.remove(function(error) {
|
||||
if (error) {
|
||||
done(error);
|
||||
} else {
|
||||
firebaseRef = firebaseRef.child(TH.generateRandomString());
|
||||
done();
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
describe('bindAsArray()', function() {
|
||||
it('throws error given invalid Firebase reference', function() {
|
||||
var TestComponent = React.createClass({
|
||||
mixins: [ReactFireMixin],
|
||||
|
||||
componentWillMount: function() {
|
||||
var _this = this;
|
||||
|
||||
TH.invalidFirebaseRefs.forEach(function(invalidFirebaseRef) {
|
||||
expect(function() {
|
||||
_this.bindAsArray(invalidFirebaseRef, 'items');
|
||||
}).to.throw('ReactFire: firebaseRef must be an instance of Firebase');
|
||||
});
|
||||
},
|
||||
|
||||
render: function() {
|
||||
return React.DOM.div(null);
|
||||
}
|
||||
});
|
||||
|
||||
shallowRenderer.render(React.createElement(TestComponent));
|
||||
});
|
||||
|
||||
it('throws error given invalid bind variable', function() {
|
||||
var TestComponent = React.createClass({
|
||||
mixins: [ReactFireMixin],
|
||||
|
||||
componentWillMount: function() {
|
||||
var _this = this;
|
||||
|
||||
TH.invalidBindVars.forEach(function(invalidBindVar) {
|
||||
expect(function() {
|
||||
_this.bindAsArray(firebaseRef, invalidBindVar);
|
||||
}).to.throw(/bindVar/);
|
||||
});
|
||||
},
|
||||
|
||||
render: function() {
|
||||
return React.DOM.div(null);
|
||||
}
|
||||
});
|
||||
|
||||
shallowRenderer.render(React.createElement(TestComponent));
|
||||
});
|
||||
|
||||
it('binds array items which are objects', function(done) {
|
||||
var TestComponent = React.createClass({
|
||||
mixins: [ReactFireMixin],
|
||||
|
||||
componentWillMount: function() {
|
||||
this.bindAsArray(firebaseRef, 'items');
|
||||
|
||||
firebaseRef.set({
|
||||
first: { index: 0 },
|
||||
second: { index: 1 },
|
||||
third: { index: 2 }
|
||||
}, function() {
|
||||
expect(this.state.items).to.deep.equal([
|
||||
{ '$key': 'first', index: 0 },
|
||||
{ '$key': 'second', index: 1 },
|
||||
{ '$key': 'third', index: 2 }
|
||||
]);
|
||||
|
||||
done();
|
||||
}.bind(this));
|
||||
},
|
||||
|
||||
render: function() {
|
||||
return React.DOM.div(null);
|
||||
}
|
||||
});
|
||||
|
||||
shallowRenderer.render(React.createElement(TestComponent));
|
||||
});
|
||||
|
||||
it('binds array items which are primitives', function(done) {
|
||||
var TestComponent = React.createClass({
|
||||
mixins: [ReactFireMixin],
|
||||
|
||||
componentWillMount: function() {
|
||||
this.bindAsArray(firebaseRef, 'items');
|
||||
|
||||
firebaseRef.set(['first', 'second', 'third'], function() {
|
||||
expect(this.state.items).to.deep.equal([
|
||||
{ '$key': 0, '$value': 'first' },
|
||||
{ '$key': 1, '$value': 'second' },
|
||||
{ '$key': 2, '$value': 'third' }
|
||||
]);
|
||||
|
||||
done();
|
||||
}.bind(this));
|
||||
},
|
||||
|
||||
render: function() {
|
||||
return React.DOM.div(null);
|
||||
}
|
||||
});
|
||||
|
||||
shallowRenderer.render(React.createElement(TestComponent));
|
||||
});
|
||||
|
||||
it('binds sparse arrays', function(done) {
|
||||
var TestComponent = React.createClass({
|
||||
mixins: [ReactFireMixin],
|
||||
|
||||
componentWillMount: function() {
|
||||
this.bindAsArray(firebaseRef, 'items');
|
||||
|
||||
firebaseRef.set({ 0: 'a', 2: 'b', 5: 'c' }, function() {
|
||||
expect(this.state).to.deep.equal({
|
||||
items: [
|
||||
{ $key: 0, $value: 'a' },
|
||||
{ $key: 2, $value: 'b' },
|
||||
{ $key: 5, $value: 'c' }
|
||||
]
|
||||
});
|
||||
|
||||
done();
|
||||
}.bind(this));
|
||||
},
|
||||
|
||||
render: function() {
|
||||
return React.DOM.div(null);
|
||||
}
|
||||
});
|
||||
|
||||
shallowRenderer.render(React.createElement(TestComponent));
|
||||
});
|
||||
|
||||
it('binds with limit queries', function(done) {
|
||||
var TestComponent = React.createClass({
|
||||
mixins: [ReactFireMixin],
|
||||
|
||||
componentWillMount: function() {
|
||||
this.bindAsArray(firebaseRef.limitToLast(2), 'items');
|
||||
|
||||
firebaseRef.set({ a: 1, b: 2, c: 3 }, function() {
|
||||
expect(this.state).to.deep.equal({
|
||||
items: [
|
||||
{ $key: 'b', $value: 2 },
|
||||
{ $key: 'c', $value: 3 }
|
||||
]
|
||||
});
|
||||
|
||||
done();
|
||||
}.bind(this));
|
||||
},
|
||||
|
||||
render: function() {
|
||||
return React.DOM.div(null);
|
||||
}
|
||||
});
|
||||
|
||||
shallowRenderer.render(React.createElement(TestComponent));
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
describe('bindAsObject()', function() {
|
||||
it('throws error given invalid Firebase reference', function() {
|
||||
var TestComponent = React.createClass({
|
||||
mixins: [ReactFireMixin],
|
||||
|
||||
componentWillMount: function() {
|
||||
var _this = this;
|
||||
|
||||
TH.invalidFirebaseRefs.forEach(function(invalidFirebaseRef) {
|
||||
expect(function() {
|
||||
_this.bindAsObject(invalidFirebaseRef, 'items');
|
||||
}).to.throw('ReactFire: firebaseRef must be an instance of Firebase');
|
||||
});
|
||||
},
|
||||
|
||||
render: function() {
|
||||
return React.DOM.div(null);
|
||||
}
|
||||
});
|
||||
|
||||
shallowRenderer.render(React.createElement(TestComponent));
|
||||
});
|
||||
|
||||
it('throws error given invalid bind variable', function() {
|
||||
var TestComponent = React.createClass({
|
||||
mixins: [ReactFireMixin],
|
||||
|
||||
componentWillMount: function() {
|
||||
var _this = this;
|
||||
|
||||
TH.invalidBindVars.forEach(function(invalidBindVar) {
|
||||
expect(function() {
|
||||
_this.bindAsObject(firebaseRef, invalidBindVar);
|
||||
}).to.throw(/bindVar/);
|
||||
});
|
||||
},
|
||||
|
||||
render: function() {
|
||||
return React.DOM.div(null);
|
||||
}
|
||||
});
|
||||
|
||||
shallowRenderer.render(React.createElement(TestComponent));
|
||||
});
|
||||
|
||||
it('binds objects', function(done) {
|
||||
var TestComponent = React.createClass({
|
||||
mixins: [ReactFireMixin],
|
||||
|
||||
componentWillMount: function() {
|
||||
this.bindAsObject(firebaseRef, 'items');
|
||||
|
||||
var obj = {
|
||||
first: { index: 0 },
|
||||
second: { index: 1 },
|
||||
third: { index: 2 }
|
||||
};
|
||||
|
||||
firebaseRef.set(obj, function() {
|
||||
expect(this.state.items).to.deep.equal(obj);
|
||||
|
||||
done();
|
||||
}.bind(this));
|
||||
},
|
||||
|
||||
render: function() {
|
||||
return React.DOM.div(null);
|
||||
}
|
||||
});
|
||||
|
||||
shallowRenderer.render(React.createElement(TestComponent));
|
||||
});
|
||||
|
||||
it('binds with limit queries', function(done) {
|
||||
var TestComponent = React.createClass({
|
||||
mixins: [ReactFireMixin],
|
||||
|
||||
componentWillMount: function() {
|
||||
this.bindAsObject(firebaseRef.limitToLast(2), 'items');
|
||||
|
||||
firebaseRef.set({
|
||||
first: { index: 0 },
|
||||
second: { index: 1 },
|
||||
third: { index: 2 }
|
||||
}, function() {
|
||||
expect(this.state.items).to.deep.equal({
|
||||
second: { index: 1 },
|
||||
third: { index: 2 }
|
||||
});
|
||||
|
||||
done();
|
||||
}.bind(this));
|
||||
},
|
||||
|
||||
render: function() {
|
||||
return React.DOM.div(null);
|
||||
}
|
||||
});
|
||||
|
||||
shallowRenderer.render(React.createElement(TestComponent));
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
describe('unbind()', function() {
|
||||
it('throws error given invalid bind variable', function() {
|
||||
var TestComponent = React.createClass({
|
||||
mixins: [ReactFireMixin],
|
||||
|
||||
componentWillMount: function() {
|
||||
var _this = this;
|
||||
|
||||
TH.invalidBindVars.forEach(function(invalidBindVar) {
|
||||
expect(function() {
|
||||
_this.unbind(invalidBindVar);
|
||||
}).to.throw(/bindVar/);
|
||||
});
|
||||
},
|
||||
|
||||
render: function() {
|
||||
return React.DOM.div(null);
|
||||
}
|
||||
});
|
||||
|
||||
shallowRenderer.render(React.createElement(TestComponent));
|
||||
});
|
||||
|
||||
it('throws error given unbound bind variable', function() {
|
||||
var TestComponent = React.createClass({
|
||||
mixins: [ReactFireMixin],
|
||||
|
||||
componentWillMount: function() {
|
||||
var _this = this;
|
||||
|
||||
expect(function() {
|
||||
_this.unbind('items');
|
||||
}).to.throw(/bindVar/);
|
||||
},
|
||||
|
||||
render: function() {
|
||||
return React.DOM.div(null);
|
||||
}
|
||||
});
|
||||
|
||||
shallowRenderer.render(React.createElement(TestComponent));
|
||||
});
|
||||
|
||||
it('unbinds the state bound to Firebase as an array', function(done) {
|
||||
var TestComponent = React.createClass({
|
||||
mixins: [ReactFireMixin],
|
||||
|
||||
componentWillMount: function() {
|
||||
this.bindAsArray(firebaseRef, 'items');
|
||||
|
||||
firebaseRef.set({
|
||||
first: { index: 0 },
|
||||
second: { index: 1 },
|
||||
third: { index: 2 }
|
||||
}, function() {
|
||||
this.unbind('items', function() {
|
||||
expect(this.state.items).to.be.undefined;
|
||||
done();
|
||||
});
|
||||
}.bind(this));
|
||||
},
|
||||
|
||||
render: function() {
|
||||
return React.DOM.div(null);
|
||||
}
|
||||
});
|
||||
|
||||
shallowRenderer.render(React.createElement(TestComponent));
|
||||
});
|
||||
|
||||
it('unbinds the state bound to Firebase as an object', function(done) {
|
||||
var TestComponent = React.createClass({
|
||||
mixins: [ReactFireMixin],
|
||||
|
||||
componentWillMount: function() {
|
||||
this.bindAsObject(firebaseRef, 'items');
|
||||
|
||||
firebaseRef.set({
|
||||
first: { index: 0 },
|
||||
second: { index: 1 },
|
||||
third: { index: 2 }
|
||||
}, function() {
|
||||
this.unbind('items', function() {
|
||||
expect(this.state.items).to.be.undefined;
|
||||
done();
|
||||
});
|
||||
}.bind(this));
|
||||
},
|
||||
|
||||
render: function() {
|
||||
return React.DOM.div(null);
|
||||
}
|
||||
});
|
||||
|
||||
shallowRenderer.render(React.createElement(TestComponent));
|
||||
});
|
||||
|
||||
it('unbinds the state bound to Firebase limit query', function(done) {
|
||||
var TestComponent = React.createClass({
|
||||
mixins: [ReactFireMixin],
|
||||
|
||||
componentWillMount: function() {
|
||||
this.bindAsObject(firebaseRef.limitToLast(2), 'items');
|
||||
|
||||
firebaseRef.set({
|
||||
first: { index: 0 },
|
||||
second: { index: 1 },
|
||||
third: { index: 2 }
|
||||
}, function() {
|
||||
this.unbind('items', function() {
|
||||
expect(this.state.items).to.be.undefined;
|
||||
done();
|
||||
});
|
||||
}.bind(this));
|
||||
},
|
||||
|
||||
render: function() {
|
||||
return React.DOM.div(null);
|
||||
}
|
||||
});
|
||||
|
||||
shallowRenderer.render(React.createElement(TestComponent));
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -1,61 +0,0 @@
|
||||
/*************/
|
||||
/* GLOBALS */
|
||||
/*************/
|
||||
// Override the default timeout interval for Jasmine
|
||||
jasmine.DEFAULT_TIMEOUT_INTERVAL = 5000;
|
||||
|
||||
// Get a reference to a random demo Firebase
|
||||
var demoFirebaseUrl = "https://" + generateRandomString() + ".firebaseio-demo.com";
|
||||
|
||||
// React test addon
|
||||
var ReactTestUtils = React.addons.TestUtils;
|
||||
|
||||
// Define examples of valid and invalid parameters
|
||||
var invalidFirebaseRefs = [null, undefined, true, false, [], 0, 5, "", "a", ["hi", 1]];
|
||||
var validBindVars = ["a", "testing", "(e@Xi:4t>*E2)hc<5oa:1s6{B0d?u", Array(743).join("a")];
|
||||
var invalidBindVars = ["", 1, true, false, [], {}, [1, 2], {a: 1}, null, undefined, "te.st", "te$st", "te[st", "te]st", "te#st", "te/st", "a#i]$da[s", "te/nst", "te/rst", "te/u0000st", "te/u0015st", "te/007Fst", Array(800).join("a")];
|
||||
|
||||
/**********************/
|
||||
/* HELPER FUNCTIONS */
|
||||
/**********************/
|
||||
/* Helper function which runs before each Jasmine test has started */
|
||||
function beforeEachHelper(done) {
|
||||
// Create a new firebase ref with a new context
|
||||
firebaseRef = new Firebase(demoFirebaseUrl, Firebase.Context());
|
||||
|
||||
// Reset the Firebase
|
||||
firebaseRef.remove(function() {
|
||||
// Create a new firebase ref at a random node
|
||||
firebaseRef = firebaseRef.child(generateRandomString());
|
||||
|
||||
done();
|
||||
});
|
||||
}
|
||||
|
||||
/* Helper function which runs after each Jasmine test has completed */
|
||||
function afterEachHelper(done) {
|
||||
React.unmountComponentAtNode(document.body);
|
||||
done();
|
||||
}
|
||||
|
||||
/* Returns a random alphabetic string of variable length */
|
||||
function generateRandomString() {
|
||||
var possibleCharacters = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
|
||||
var numPossibleCharacters = possibleCharacters.length;
|
||||
|
||||
var text = "";
|
||||
for (var i = 0; i < 10; i++) {
|
||||
text += possibleCharacters.charAt(Math.floor(Math.random() * numPossibleCharacters));
|
||||
}
|
||||
|
||||
return text;
|
||||
}
|
||||
|
||||
/* Returns the current data in the Firebase */
|
||||
function getFirebaseData() {
|
||||
return new RSVP.Promise(function(resolve, reject) {
|
||||
firebaseRef.once("value", function(dataSnapshot) {
|
||||
resolve(dataSnapshot.val());
|
||||
});
|
||||
});
|
||||
};
|
||||
@@ -1,568 +0,0 @@
|
||||
describe("ReactFireMixin Tests:", function() {
|
||||
beforeEach(function(done) {
|
||||
beforeEachHelper(done);
|
||||
});
|
||||
|
||||
afterEach(function(done) {
|
||||
afterEachHelper(done);
|
||||
});
|
||||
|
||||
describe("bindAsArray():", function() {
|
||||
it("bindAsArray() throws errors given invalid Firebase refs", function() {
|
||||
var TestComponent = React.createClass({
|
||||
mixins: [ReactFireMixin],
|
||||
|
||||
componentWillMount: function() {
|
||||
var _this = this;
|
||||
|
||||
invalidFirebaseRefs.forEach(function(invalidFirebaseRef) {
|
||||
try {
|
||||
_this.bindAsArray(invalidFirebaseRef, "items");
|
||||
expect("Function should throw error given parameter: " + invalidFirebaseRef).toBeFalsy();
|
||||
} catch (error) {
|
||||
expect(error.code).toEqual("INVALID_FIREBASE_REF");
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
render: function() {
|
||||
return React.DOM.div(null, "Testing");
|
||||
}
|
||||
});
|
||||
|
||||
React.render(new TestComponent(), document.body);
|
||||
});
|
||||
|
||||
it("bindAsArray() throws errors given invalid bind variables", function() {
|
||||
var TestComponent = React.createClass({
|
||||
mixins: [ReactFireMixin],
|
||||
|
||||
componentWillMount: function() {
|
||||
var _this = this;
|
||||
|
||||
invalidBindVars.forEach(function(invalidBindVar) {
|
||||
try {
|
||||
_this.bindAsArray(firebaseRef, invalidBindVar);
|
||||
expect("Function should throw error given parameter: " + invalidBindVar).toBeFalsy();
|
||||
} catch (error) {
|
||||
expect(error.code).toEqual("INVALID_BIND_VARIABLE");
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
render: function() {
|
||||
return React.DOM.div(null, "Testing");
|
||||
}
|
||||
});
|
||||
|
||||
React.render(new TestComponent(), document.body);
|
||||
});
|
||||
|
||||
it("bindAsArray() does not throw errors given valid inputs", function() {
|
||||
var TestComponent = React.createClass({
|
||||
mixins: [ReactFireMixin],
|
||||
|
||||
componentWillMount: function() {
|
||||
var _this = this;
|
||||
|
||||
validBindVars.forEach(function(validBindVar) {
|
||||
expect(function() { _this.bindAsArray(firebaseRef, validBindVar); }).not.toThrow();
|
||||
});
|
||||
},
|
||||
|
||||
render: function() {
|
||||
return React.DOM.div(null, "Testing");
|
||||
}
|
||||
});
|
||||
|
||||
React.render(new TestComponent(), document.body);
|
||||
});
|
||||
|
||||
it("bindAsArray() does not throw an error given a limit query", function() {
|
||||
var TestComponent = React.createClass({
|
||||
mixins: [ReactFireMixin],
|
||||
|
||||
componentWillMount: function() {
|
||||
var _this = this;
|
||||
|
||||
expect(function() { _this.bindAsArray(firebaseRef.limitToLast(10), "items"); }).not.toThrow();
|
||||
},
|
||||
|
||||
render: function() {
|
||||
return React.DOM.div(null, "Testing");
|
||||
}
|
||||
});
|
||||
|
||||
React.render(new TestComponent(), document.body);
|
||||
});
|
||||
|
||||
it("bindAsArray() binds to remote Firebase data as an array", function(done) {
|
||||
var TestComponent = React.createClass({
|
||||
mixins: [ReactFireMixin],
|
||||
|
||||
componentWillMount: function() {
|
||||
this.bindAsArray(firebaseRef, "items");
|
||||
},
|
||||
|
||||
componentDidMount: function() {
|
||||
firebaseRef.set({ a: 1, b: 2, c: 3 });
|
||||
},
|
||||
|
||||
componentDidUpdate: function(prevProps, prevState) {
|
||||
expect(this.state).toEqual({
|
||||
items: [
|
||||
{ $key: "a", $value: 1 },
|
||||
{ $key: "b", $value: 2 },
|
||||
{ $key: "c", $value: 3 }
|
||||
]
|
||||
});
|
||||
done();
|
||||
},
|
||||
|
||||
render: function() {
|
||||
return React.DOM.div(null, "Testing");
|
||||
}
|
||||
});
|
||||
|
||||
React.render(new TestComponent(), document.body);
|
||||
});
|
||||
|
||||
it("bindAsArray() binds to remote Firebase data as an array (limit query)", function(done) {
|
||||
var TestComponent = React.createClass({
|
||||
mixins: [ReactFireMixin],
|
||||
|
||||
componentWillMount: function() {
|
||||
this.bindAsArray(firebaseRef.limitToLast(2), "items");
|
||||
},
|
||||
|
||||
componentDidMount: function() {
|
||||
firebaseRef.set({ a: 1, b: 2, c: 3 });
|
||||
},
|
||||
|
||||
componentDidUpdate: function(prevProps, prevState) {
|
||||
expect(this.state).toEqual({
|
||||
items: [
|
||||
{ $key: "b", $value: 2 },
|
||||
{ $key: "c", $value: 3 }
|
||||
]
|
||||
});
|
||||
done();
|
||||
},
|
||||
|
||||
render: function() {
|
||||
return React.DOM.div(null, "Testing");
|
||||
}
|
||||
});
|
||||
|
||||
React.render(new TestComponent(), document.body);
|
||||
});
|
||||
|
||||
it("bindAsArray() makes $key available on array items when they are objects", function(done) {
|
||||
var TestComponent = React.createClass({
|
||||
mixins: [ReactFireMixin],
|
||||
componentWillMount: function() {
|
||||
this.bindAsArray(firebaseRef, "items");
|
||||
},
|
||||
componentDidMount: function() {
|
||||
firebaseRef.set({ first: { index: 1 }, second: { index: 2 }, third: { index: 3 } });
|
||||
},
|
||||
componentDidUpdate: function(prevProps, prevState) {
|
||||
expect(this.state.items.map(function(item) { return item.$key; })).toEqual(["first", "second", "third"]);
|
||||
done();
|
||||
},
|
||||
render: function() {
|
||||
return React.DOM.div(null, "Testing");
|
||||
}
|
||||
});
|
||||
React.render(new TestComponent(), document.body);
|
||||
});
|
||||
|
||||
it("bindAsArray() makes $key available on array items when they are primitives", function(done) {
|
||||
var TestComponent = React.createClass({
|
||||
mixins: [ReactFireMixin],
|
||||
componentWillMount: function() {
|
||||
this.bindAsArray(firebaseRef, "items");
|
||||
},
|
||||
componentDidMount: function() {
|
||||
firebaseRef.set(["first", "second", "third"]);
|
||||
},
|
||||
componentDidUpdate: function(prevProps, prevState) {
|
||||
expect(this.state.items.map(function(item) { return item.$key; })).toEqual([0, 1, 2]);
|
||||
expect(this.state.items.map(function(item) { return item.$value; })).toEqual(["first", "second", "third"]);
|
||||
done();
|
||||
},
|
||||
render: function() {
|
||||
return React.DOM.div(null, "Testing");
|
||||
}
|
||||
});
|
||||
React.render(new TestComponent(), document.body);
|
||||
});
|
||||
|
||||
it("bindAsArray() properly binds to sparse arrays", function(done) {
|
||||
var TestComponent = React.createClass({
|
||||
mixins: [ReactFireMixin],
|
||||
|
||||
componentWillMount: function() {
|
||||
this.bindAsArray(firebaseRef, "items");
|
||||
},
|
||||
|
||||
componentDidMount: function() {
|
||||
firebaseRef.set({ 0: 'a', 2: 'b', 5: 'c' });
|
||||
},
|
||||
|
||||
componentDidUpdate: function(prevProps, prevState) {
|
||||
expect(this.state).toEqual({
|
||||
items: [
|
||||
{ $key: 0, $value: 'a' },
|
||||
{ $key: 2, $value: 'b' },
|
||||
{ $key: 5, $value: 'c' }
|
||||
]
|
||||
});
|
||||
done();
|
||||
},
|
||||
|
||||
render: function() {
|
||||
return React.DOM.div(null, "Testing");
|
||||
}
|
||||
});
|
||||
|
||||
React.render(new TestComponent(), document.body);
|
||||
});
|
||||
});
|
||||
|
||||
describe("bindAsObject():", function() {
|
||||
it("bindAsObject() throws errors given invalid Firebase refs", function() {
|
||||
var TestComponent = React.createClass({
|
||||
mixins: [ReactFireMixin],
|
||||
|
||||
componentWillMount: function() {
|
||||
var _this = this;
|
||||
|
||||
invalidFirebaseRefs.forEach(function(invalidFirebaseRef) {
|
||||
try {
|
||||
_this.bindAsObject(invalidFirebaseRef, "items");
|
||||
expect("Function should throw error given parameter: " + invalidFirebaseRef).toBeFalsy();
|
||||
} catch (error) {
|
||||
expect(error.code).toEqual("INVALID_FIREBASE_REF");
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
render: function() {
|
||||
return React.DOM.div(null, "Testing");
|
||||
}
|
||||
});
|
||||
|
||||
React.render(new TestComponent(), document.body);
|
||||
});
|
||||
|
||||
it("bindAsObject() throws errors given invalid bind variables", function() {
|
||||
var TestComponent = React.createClass({
|
||||
mixins: [ReactFireMixin],
|
||||
|
||||
componentWillMount: function() {
|
||||
var _this = this;
|
||||
|
||||
invalidBindVars.forEach(function(invalidBindVar) {
|
||||
try {
|
||||
_this.bindAsObject(firebaseRef, invalidBindVar);
|
||||
expect("Function should throw error given parameter: " + invalidBindVar).toBeFalsy();
|
||||
} catch (error) {
|
||||
expect(error.code).toEqual("INVALID_BIND_VARIABLE");
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
render: function() {
|
||||
return React.DOM.div(null, "Testing");
|
||||
}
|
||||
});
|
||||
|
||||
React.render(new TestComponent(), document.body);
|
||||
});
|
||||
|
||||
it("bindAsObject() does not throw errors given valid inputs", function() {
|
||||
var TestComponent = React.createClass({
|
||||
mixins: [ReactFireMixin],
|
||||
|
||||
componentWillMount: function() {
|
||||
var _this = this;
|
||||
|
||||
validBindVars.forEach(function(validBindVar) {
|
||||
expect(function() { _this.bindAsObject(firebaseRef, validBindVar); }).not.toThrow();
|
||||
});
|
||||
},
|
||||
|
||||
render: function() {
|
||||
return React.DOM.div(null, "Testing");
|
||||
}
|
||||
});
|
||||
|
||||
React.render(new TestComponent(), document.body);
|
||||
});
|
||||
|
||||
it("bindAsObject() does not throw an error given a limit query", function() {
|
||||
var TestComponent = React.createClass({
|
||||
mixins: [ReactFireMixin],
|
||||
|
||||
componentWillMount: function() {
|
||||
var _this = this;
|
||||
|
||||
expect(function() { _this.bindAsObject(firebaseRef.limitToLast(10), "items"); }).not.toThrow();
|
||||
},
|
||||
|
||||
render: function() {
|
||||
return React.DOM.div(null, "Testing");
|
||||
}
|
||||
});
|
||||
|
||||
React.render(new TestComponent(), document.body);
|
||||
});
|
||||
|
||||
it("bindAsObject() binds to remote Firebase data as an object", function(done) {
|
||||
var TestComponent = React.createClass({
|
||||
mixins: [ReactFireMixin],
|
||||
|
||||
componentWillMount: function() {
|
||||
this.bindAsObject(firebaseRef, "items");
|
||||
},
|
||||
|
||||
componentDidMount: function() {
|
||||
firebaseRef.set({ a: 1, b: 2, c: 3 });
|
||||
},
|
||||
|
||||
componentDidUpdate: function(prevProps, prevState) {
|
||||
expect(this.state).toEqual({ items: { a: 1, b: 2, c: 3 } });
|
||||
done();
|
||||
},
|
||||
|
||||
render: function() {
|
||||
return React.DOM.div(null, "Testing");
|
||||
}
|
||||
});
|
||||
|
||||
React.render(new TestComponent(), document.body);
|
||||
});
|
||||
|
||||
it("bindAsObject() binds to remote Firebase data as an object (limit query)", function(done) {
|
||||
var TestComponent = React.createClass({
|
||||
mixins: [ReactFireMixin],
|
||||
|
||||
componentWillMount: function() {
|
||||
this.bindAsObject(firebaseRef.limitToLast(2), "items");
|
||||
},
|
||||
|
||||
componentDidMount: function() {
|
||||
firebaseRef.set({ a: 1, b: 2, c: 3 });
|
||||
},
|
||||
|
||||
componentDidUpdate: function(prevProps, prevState) {
|
||||
expect(this.state).toEqual({ items: { b: 2, c: 3 } });
|
||||
done();
|
||||
},
|
||||
|
||||
render: function() {
|
||||
return React.DOM.div(null, "Testing");
|
||||
}
|
||||
});
|
||||
|
||||
React.render(new TestComponent(), document.body);
|
||||
});
|
||||
});
|
||||
|
||||
describe("unbind():", function() {
|
||||
it("unbind() throws errors given invalid bind variables", function() {
|
||||
var TestComponent = React.createClass({
|
||||
mixins: [ReactFireMixin],
|
||||
|
||||
componentWillMount: function() {
|
||||
var _this = this;
|
||||
|
||||
invalidBindVars.forEach(function(invalidBindVar) {
|
||||
try {
|
||||
_this.unbind(invalidBindVar);
|
||||
expect("Function should throw error given parameter: " + invalidBindVar).toBeFalsy();
|
||||
} catch (error) {
|
||||
expect(error.code).toEqual("INVALID_BIND_VARIABLE");
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
render: function() {
|
||||
return React.DOM.div(null, "Testing");
|
||||
}
|
||||
});
|
||||
|
||||
React.render(new TestComponent(), document.body);
|
||||
});
|
||||
|
||||
it("unbind() throws errors given unbound bind variable", function() {
|
||||
var TestComponent = React.createClass({
|
||||
mixins: [ReactFireMixin],
|
||||
|
||||
componentWillMount: function() {
|
||||
var _this = this;
|
||||
|
||||
validBindVars.forEach(function(validBindVar) {
|
||||
try {
|
||||
_this.unbind(validBindVar);
|
||||
expect("Function should throw error given parameter: " + validBindVar).toBeFalsy();
|
||||
} catch (error) {
|
||||
expect(error.code).toEqual("UNBOUND_BIND_VARIABLE");
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
render: function() {
|
||||
return React.DOM.div(null, "Testing");
|
||||
}
|
||||
});
|
||||
|
||||
React.render(new TestComponent(), document.body);
|
||||
});
|
||||
|
||||
it("unbind() does not throw errors given valid bind variables", function() {
|
||||
var TestComponent = React.createClass({
|
||||
mixins: [ReactFireMixin],
|
||||
|
||||
componentWillMount: function() {
|
||||
var _this = this;
|
||||
|
||||
validBindVars.forEach(function(validBindVar) {
|
||||
_this.bindAsArray(firebaseRef, validBindVar);
|
||||
expect(function() { _this.unbind(validBindVar); }).not.toThrow();
|
||||
});
|
||||
},
|
||||
|
||||
render: function() {
|
||||
return React.DOM.div(null, "Testing");
|
||||
}
|
||||
});
|
||||
|
||||
React.render(new TestComponent(), document.body);
|
||||
});
|
||||
|
||||
it("unbind() does not throw an error given a limit query", function() {
|
||||
var TestComponent = React.createClass({
|
||||
mixins: [ReactFireMixin],
|
||||
|
||||
componentWillMount: function() {
|
||||
var _this = this;
|
||||
|
||||
validBindVars.forEach(function(validBindVar) {
|
||||
_this.bindAsArray(firebaseRef.limitToLast(10), validBindVar);
|
||||
expect(function() { _this.unbind(validBindVar); }).not.toThrow();
|
||||
});
|
||||
},
|
||||
|
||||
render: function() {
|
||||
return React.DOM.div(null, "Testing");
|
||||
}
|
||||
});
|
||||
|
||||
React.render(new TestComponent(), document.body);
|
||||
});
|
||||
|
||||
it("unbind() unbinds the state bound to Firebase as an array", function(done) {
|
||||
var TestComponent = React.createClass({
|
||||
mixins: [ReactFireMixin],
|
||||
|
||||
componentWillMount: function() {
|
||||
this.bindAsArray(firebaseRef, "items");
|
||||
this.unbind("items");
|
||||
},
|
||||
|
||||
componentDidMount: function() {
|
||||
firebaseRef.set({ a: 1, b: 2, c: 3 }, function() {
|
||||
this.setTimeout(done, 250);
|
||||
});
|
||||
},
|
||||
|
||||
componentDidUpdate: function(prevProps, prevState) {
|
||||
expect("Should not be here").toBeFalsy();
|
||||
},
|
||||
|
||||
render: function() {
|
||||
return React.DOM.div(null, "Testing");
|
||||
}
|
||||
});
|
||||
|
||||
React.render(new TestComponent(), document.body);
|
||||
});
|
||||
|
||||
it("unbind() unbinds the state bound to Firebase as an object", function(done) {
|
||||
var TestComponent = React.createClass({
|
||||
mixins: [ReactFireMixin],
|
||||
|
||||
componentWillMount: function() {
|
||||
this.bindAsObject(firebaseRef, "items");
|
||||
this.unbind("items");
|
||||
},
|
||||
|
||||
componentDidMount: function() {
|
||||
firebaseRef.set({ a: 1, b: 2, c: 3 }, function() {
|
||||
this.setTimeout(done, 250);
|
||||
});
|
||||
},
|
||||
|
||||
componentDidUpdate: function(prevProps, prevState) {
|
||||
expect("Should not be here").toBeFalsy();
|
||||
},
|
||||
|
||||
render: function() {
|
||||
return React.DOM.div(null, "Testing");
|
||||
}
|
||||
});
|
||||
|
||||
React.render(new TestComponent(), document.body);
|
||||
});
|
||||
});
|
||||
|
||||
describe("_bind():", function() {
|
||||
it("_bind() throws errors given invalid third input parameter", function() {
|
||||
var nonBooleanParams = [null, undefined, [], {}, 0, 5, "", "a", {a : 1}, ["hi", 1]];
|
||||
|
||||
var TestComponent = React.createClass({
|
||||
mixins: [ReactFireMixin],
|
||||
|
||||
componentWillMount: function() {
|
||||
var _this = this;
|
||||
|
||||
nonBooleanParams.forEach(function(nonBooleanParam) {
|
||||
try {
|
||||
_this._bind(firebaseRef, "items", nonBooleanParam);
|
||||
expect("Function should throw error given parameter: " + nonBooleanParam).toBeFalsy();
|
||||
} catch (error) {
|
||||
expect(error.code).toEqual("INVALID_BIND_AS_ARRAY");
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
render: function() {
|
||||
return React.DOM.div(null, "Testing");
|
||||
}
|
||||
});
|
||||
|
||||
React.render(new TestComponent(), document.body);
|
||||
});
|
||||
|
||||
it("_bind() does not throw error given valid inputs", function() {
|
||||
var TestComponent = React.createClass({
|
||||
mixins: [ReactFireMixin],
|
||||
|
||||
componentWillMount: function() {
|
||||
var _this = this;
|
||||
|
||||
expect(function() { _this._bind(firebaseRef, "items", function() {}, true); }).not.toThrow();
|
||||
expect(function() { _this._bind(firebaseRef, "items", function() {}, false); }).not.toThrow();
|
||||
},
|
||||
|
||||
render: function() {
|
||||
return React.DOM.div(null, "Testing");
|
||||
}
|
||||
});
|
||||
|
||||
React.render(new TestComponent(), document.body);
|
||||
});
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user