Permalink
Browse files

updating to the jQuery 1.8 api; v0.2.0 release

	* gave Callbacks tests their own file
	* updated _type implementation to conform to jQuery's
  • Loading branch information...
Sam Breed
Sam Breed committed Aug 17, 2012
1 parent bac02fb commit fbee957859a9385fe3bc11dd6beaae2e44fcc0c9
Showing with 575 additions and 459 deletions.
  1. +1 −1 grunt.js
  2. +16 −8 readme.md
  3. +262 −0 test/callbacks.js
  4. +72 −229 test/deferred.js
  5. +1 −0 test/index.html
  6. +223 −221 underscore.deferred.js
View
@@ -12,7 +12,7 @@ module.exports = function(grunt) {
},
concat: {
dist: {
- src: ['<banner:meta.banner>', '<file_strip_banner:lib/<%= pkg.name %>.js>'],
+ src: ['<banner:meta.banner>', '<file_strip_banner:<%= pkg.name %>.js>'],
dest: 'dist/<%= pkg.name %>.js'
}
},
View
@@ -2,17 +2,18 @@
[![Build Status](https://secure.travis-ci.org/wookiehangover/underscore.deferred.png?branch=master)](http://travis-ci.org/wookiehangover/underscore.deferred)
-v0.1.5
+v0.2.0 (jQuery 1.8.0)
+
+This is a port of jQuery.Deferred as an Underscore mixin, but it can be
+used without any depencencies. It currently matches the Deferred specifications
+and implementation from jQuery 1.8.0, with all the associated helpers.
**Please note that as of 0.1.4 underscore.deferred will be ALL LOWERCASE on
npm.** The camelcasing was a mistake from the outset, please update your
`package.json` appropriately.
-This is a port of jQuery.Deferred as an Underscore mixin, but it can be
-used without any depencencies. It currently matches the Deferred specifications
-and implementation from jQuery 1.7.2, with all the associated helpers.
-## Deferred's are great, let's take them everywhere
+## Deferreds are great, let's take them everywhere
jQuery offers a robust, consistent and well documented API; this project aims
to make it portable. jQuery added a handful of helper methods to their
@@ -29,13 +30,20 @@ API. Here are some of the method implemented:
* [notifyWith](http://api.jquery.com/deferred.notifywith/)
* [pipe](http://api.jquery.com/deferred.pipe/)
* [promise](http://api.jquery.com/deferred.promise/)
-* [resolve](http://api.jquery.com/deferred.resolve/)
* [reject](http://api.jquery.com/deferred.reject/)
+* [rejectWith](http://api.jquery.com/deferred.rejectWith/)
+* [resolve](http://api.jquery.com/deferred.resolve/)
+* [resolveWith](http://api.jquery.com/deferred.resolve/)
* [state](http://api.jquery.com/deferred.notifywith/)
* [then](http://api.jquery.com/deferred.then/)
+* [when](http://api.jquery.com/jQuery.when/)
For the complete API documentation, look to the [jQuery Docs][jquery-docs].
+This project wouldn't exist if not for the the hard work and effort put
+into jQuery by its core team and contributors--thanks for making this
+possible!
+
## Usage
underscore.deferred works on the server and in the browser.
@@ -68,13 +76,13 @@ $ npm install
To build with [grunt](https://github.com/cowboy/grunt)
```
-$ node build
+$ grunt
```
To run headless Qunit tests (must have phantomjs in your path)
```
-$ node build qunit
+$ grunt qunit
```
## Contributors
View
@@ -0,0 +1,262 @@
+module("callbacks");
+
+(function() {
+
+var output,
+ addToOutput = function( string ) {
+ return function() {
+ output += string;
+ };
+ },
+ outputA = addToOutput( "A" ),
+ outputB = addToOutput( "B" ),
+ outputC = addToOutput( "C" ),
+ tests = {
+ "": "XABC X XABCABCC X XBB X XABA X",
+ "once": "XABC X X X X X XABA X",
+ "memory": "XABC XABC XABCABCCC XA XBB XB XABA XC",
+ "unique": "XABC X XABCA X XBB X XAB X",
+ "stopOnFalse": "XABC X XABCABCC X XBB X XA X",
+ "once memory": "XABC XABC X XA X XA XABA XC",
+ "once unique": "XABC X X X X X XAB X",
+ "once stopOnFalse": "XABC X X X X X XA X",
+ "memory unique": "XABC XA XABCA XA XBB XB XAB XC",
+ "memory stopOnFalse": "XABC XABC XABCABCCC XA XBB XB XA X",
+ "unique stopOnFalse": "XABC X XABCA X XBB X XA X"
+ },
+ filters = {
+ "no filter": undefined,
+ "filter": function( fn ) {
+ return function() {
+ return fn.apply( this, arguments );
+ };
+ }
+ };
+
+ function showFlags( flags ) {
+ if ( typeof flags === "string" ) {
+ return '"' + flags + '"';
+ }
+ var output = [], key;
+ for ( key in flags ) {
+ output.push( '"' + key + '": ' + flags[ key ] );
+ }
+ return "{ " + output.join( ", " ) + " }";
+ }
+
+_.each( tests, function( resultString, strFlags ) {
+
+ var objectFlags = {};
+
+ _.each( strFlags.split( " " ), function( str ) {
+ if ( str.length ) {
+ objectFlags[ str ] = true;
+ }
+ });
+
+ _.each( filters, function( filter, filterLabel ) {
+
+ _.each( { "string": strFlags, "object": objectFlags }, function( flags, flagsTypes ) {
+
+ test( "_.Callbacks( " + showFlags( flags ) + " ) - " + filterLabel, function() {
+
+ expect( 20 );
+
+ // Give qunit a little breathing room
+ stop();
+ setTimeout( start, 0 );
+
+ var cblist,
+ results = resultString.split( /\s+/ );
+
+ // Basic binding and firing
+ output = "X";
+ cblist = _.Callbacks( flags );
+ cblist.add(function( str ) {
+ output += str;
+ });
+ cblist.fire( "A" );
+ strictEqual( output, "XA", "Basic binding and firing" );
+ strictEqual( cblist.fired(), true, ".fired() detects firing" );
+ output = "X";
+ cblist.disable();
+ cblist.add(function( str ) {
+ output += str;
+ });
+ strictEqual( output, "X", "Adding a callback after disabling" );
+ cblist.fire( "A" );
+ strictEqual( output, "X", "Firing after disabling" );
+
+ // Basic binding and firing (context, arguments)
+ output = "X";
+ cblist = _.Callbacks( flags );
+ cblist.add(function() {
+ equal( this, window, "Basic binding and firing (context)" );
+ output += Array.prototype.join.call( arguments, "" );
+ });
+ cblist.fireWith( window, [ "A", "B" ] );
+ strictEqual( output, "XAB", "Basic binding and firing (arguments)" );
+
+ // fireWith with no arguments
+ output = "";
+ cblist = _.Callbacks( flags );
+ cblist.add(function() {
+ equal( this, window, "fireWith with no arguments (context is window)" );
+ strictEqual( arguments.length, 0, "fireWith with no arguments (no arguments)" );
+ });
+ cblist.fireWith();
+
+ // Basic binding, removing and firing
+ output = "X";
+ cblist = _.Callbacks( flags );
+ cblist.add( outputA, outputB, outputC );
+ cblist.remove( outputB, outputC );
+ cblist.fire();
+ strictEqual( output, "XA", "Basic binding, removing and firing" );
+
+ // Empty
+ output = "X";
+ cblist = _.Callbacks( flags );
+ cblist.add( outputA );
+ cblist.add( outputB );
+ cblist.add( outputC );
+ cblist.empty();
+ cblist.fire();
+ strictEqual( output, "X", "Empty" );
+
+ // Locking
+ output = "X";
+ cblist = _.Callbacks( flags );
+ cblist.add( function( str ) {
+ output += str;
+ });
+ cblist.lock();
+ cblist.add( function( str ) {
+ output += str;
+ });
+ cblist.fire( "A" );
+ cblist.add( function( str ) {
+ output += str;
+ });
+ strictEqual( output, "X", "Lock early" );
+
+ // Ordering
+ output = "X";
+ cblist = _.Callbacks( flags );
+ cblist.add( function() {
+ cblist.add( outputC );
+ outputA();
+ }, outputB );
+ cblist.fire();
+ strictEqual( output, results.shift(), "Proper ordering" );
+
+ // Add and fire again
+ output = "X";
+ cblist.add( function() {
+ cblist.add( outputC );
+ outputA();
+ }, outputB );
+ strictEqual( output, results.shift(), "Add after fire" );
+
+ output = "X";
+ cblist.fire();
+ strictEqual( output, results.shift(), "Fire again" );
+
+ // Multiple fire
+ output = "X";
+ cblist = _.Callbacks( flags );
+ cblist.add( function( str ) {
+ output += str;
+ } );
+ cblist.fire( "A" );
+ strictEqual( output, "XA", "Multiple fire (first fire)" );
+ output = "X";
+ cblist.add( function( str ) {
+ output += str;
+ } );
+ strictEqual( output, results.shift(), "Multiple fire (first new callback)" );
+ output = "X";
+ cblist.fire( "B" );
+ strictEqual( output, results.shift(), "Multiple fire (second fire)" );
+ output = "X";
+ cblist.add( function( str ) {
+ output += str;
+ } );
+ strictEqual( output, results.shift(), "Multiple fire (second new callback)" );
+
+ // Return false
+ output = "X";
+ cblist = _.Callbacks( flags );
+ cblist.add( outputA, function() { return false; }, outputB );
+ cblist.add( outputA );
+ cblist.fire();
+ strictEqual( output, results.shift(), "Callback returning false" );
+
+ // Add another callback (to control lists with memory do not fire anymore)
+ output = "X";
+ cblist.add( outputC );
+ strictEqual( output, results.shift(), "Adding a callback after one returned false" );
+
+ });
+ });
+ });
+});
+
+})();
+
+test( "_.Callbacks( options ) - options are copied", function() {
+
+ expect( 1 );
+
+ var options = {
+ "unique": true
+ },
+ cb = _.Callbacks( options ),
+ count = 0,
+ fn = function() {
+ ok( !( count++ ), "called once" );
+ };
+ options["unique"] = false;
+ cb.add( fn, fn );
+ cb.fire();
+});
+
+test( "jQuery.Callbacks.fireWith - arguments are copied", function() {
+
+ expect( 1 );
+
+ var cb = _.Callbacks( "memory" ),
+ args = [ "hello" ];
+
+ cb.fireWith( null, args );
+ args[ 0 ] = "world";
+
+ cb.add(function( hello ) {
+ strictEqual( hello, "hello", "arguments are copied internally" );
+ });
+});
+
+test( "jQuery.Callbacks.remove - should remove all instances", function() {
+
+ expect( 1 );
+
+ var cb = _.Callbacks();
+
+ function fn() {
+ ok( false, "function wasn't removed" );
+ }
+
+ cb.add( fn, fn, function() {
+ ok( true, "end of test" );
+ }).remove( fn ).fire();
+});
+
+test( "_.Callbacks() - adding a string doesn't cause a stack overflow", function() {
+
+ expect( 1 );
+
+ _.Callbacks().add( "hello world" );
+
+ ok( true, "no stack overflow" );
+});
+
Oops, something went wrong.

0 comments on commit fbee957

Please sign in to comment.