diff --git a/spec/entities.spec.js b/spec/entities.spec.js
index 3d6a120..70cf1c5 100644
--- a/spec/entities.spec.js
+++ b/spec/entities.spec.js
@@ -1,4 +1,5 @@
var entities = require( '../src/entities' ),
+ iconv = require( 'iconv-lite' ),
nock = require( 'nock' );
describe( 'BooksList', function() {
@@ -11,6 +12,67 @@ describe( 'BooksList', function() {
});
+ it( 'should have a .fetchAll method', function( done ) {
+
+ var bl = new entities.BooksList(),
+ book = new entities.Book( 'foo' ),
+ body = '
Foo
'
+ + 'Bar
';
+
+ expect( typeof bl.fetchAll ).toEqual( 'function' );
+
+ bl.push( book );
+
+ nock( 'http://www.eyrolles.com' )
+ .get( '/foo' ).reply( 200, iconv.encode( body, 'latin1' ) );
+
+ bl.fetchAll({
+ callback: function( books ) {
+
+ expect( books ).toBeDefined();
+ expect( books ).not.toBeNull();
+ expect( books.length ).toEqual( 1 );
+
+ expect( books[0].title ).toEqual( 'Foo' );
+ expect( books[0].short_desc ).toEqual( 'Bar' );
+ expect( books[0].exists ).toBeTruthy();
+
+ done();
+
+ }
+ });
+
+ });
+
+ it( 'should behave like an array', function( done ) {
+
+ var bl = new entities.BooksList( 'Accueil/Recherche/?q=foo' );
+
+ expect( entities.BooksList.prototype ).toEqual( [] );
+ expect( bl.length ).toEqual( 0 );
+
+ nock( 'http://www.eyrolles.com' )
+ .get( '/Accueil/Recherche/?ajax=on&q=foo&page=1' )
+ .replyWithFile( 200,
+ __dirname + '/mocks/search-for-foo-p1.html' );
+
+ bl.fetch({
+
+ limit: 5,
+
+ callback: function() {
+
+ expect( bl.length ).toEqual( 5 );
+ expect( bl[0] instanceof entities.Book ).toBeTruthy();
+
+ done();
+
+ }
+
+ });
+
+ });
+
it( 'should use pagination to fetch large results', function( done ) {
var _n = nock( 'http://www.eyrolles.com' ), p;
@@ -31,8 +93,7 @@ describe( 'BooksList', function() {
callback: function() {
- expect( bl.books ).toBeDefined();
- expect( bl.books.length ).toEqual( 91 );
+ expect( bl.length ).toEqual( 91 );
done();
@@ -61,8 +122,7 @@ describe( 'BooksList', function() {
callback: function() {
- expect( bl.books ).toBeDefined();
- expect( bl.books.length ).toEqual( 30 );
+ expect( bl.length ).toEqual( 30 );
done();
@@ -92,8 +152,7 @@ describe( 'BooksList', function() {
callback: function() {
- expect( bl.books ).toBeDefined();
- expect( bl.books.length ).toEqual( 25 );
+ expect( bl.length ).toEqual( 25 );
done();
@@ -155,5 +214,27 @@ describe( 'Book object', function() {
});
+ it( 'should not fail '
+ + 'if the website doesn’t have all informations', function( done ) {
+
+ var body = 'Foo
',
+ book = new entities.Book( 'foo' );
+
+ nock( 'http://www.eyrolles.com' )
+ .get( '/foo' )
+ .reply( 200, iconv.encode( body, 'latin1' ) );
+
+ book.fetch({ callback: function( b ) {
+
+ expect( b ).not.toBeNull();
+ expect( b.title ).toEqual( 'Foo' );
+ expect( b.exists ).toBeTruthy();
+
+ done();
+
+ }});
+
+ });
+
});
diff --git a/spec/utils.spec.js b/spec/utils.spec.js
index dc2c33a..5eea0f4 100644
--- a/spec/utils.spec.js
+++ b/spec/utils.spec.js
@@ -133,3 +133,20 @@ describe( 'isArray function', function() {
});
});
+
+describe( 'noop function', function() {
+
+ it( 'should exist', function() {
+
+ expect( typeof utils.noop ).toEqual( 'function' );
+
+ });
+
+ it( 'should do nothing', function() {
+
+ expect( utils.noop.length ).toEqual( 0 );
+ expect( utils.noop() ).toBeUndefined();
+
+ });
+
+});
diff --git a/src/entities.js b/src/entities.js
index dfb766b..210eb2d 100644
--- a/src/entities.js
+++ b/src/entities.js
@@ -137,15 +137,22 @@ var Book = createEntity( '', function( book, $ ) {
.map(function( _, e ) {
return $( e ).text().split( colon_re ); }),
- i, len,
+ i, len, last_minis_children,
d_website_label, d_label, d_value, d_fn;
book.img = no_img_re.test( img_src ) ? null : img_src;
book.title = desc.find( 'h1' ).text();
book.short_desc = desc.find( 'h2' ).first().text();
- book.pages_count = parseInt( minis.last().children()
- .first().text().split( ':' )[1] );
- book.date = minis.last().children()[1].children[1].data.trim();
+
+ if ( minis.length > 0 ) {
+
+ last_minis_children = minis.last().children();
+
+ book.pages_count = parseInt( last_minis_children
+ .first().text().split( ':' )[1] );
+ book.date = last_minis_children[1].children[1].data.trim()
+
+ }
book.publisher = new Publisher( publisher.attr( 'href' ) );
@@ -198,42 +205,94 @@ var BooksList = function BL( path, attrs ) {
return new arguments.callee( path );
}
+ that.length = 0;
+
that.fetch = function( opts ) {
if ( opts === undefined ) {
- opts = {};
+ opts = {};
- } else if ( typeof opts === 'function' ) {
+ } else if ( typeof opts === 'function' ) {
- opts = { callback: opts };
+ opts = { callback: opts };
- }
+ }
+
+ requests.paginate( path, {
+
+ limit: opts.limit,
+ offset: opts.offset,
+ parser: parseBooksList,
+ callback: function( books ) {
+
+ var i = 0,
+ len = books.length;
+
+ for (; i < len; i++ ) {
- requests.paginate( path, {
+ that[ i ] = books[ i ];
- limit: opts.limit,
- offset: opts.offset,
- parser: parseBooksList,
- callback: function( books ) {
+ }
- that.books = books;
+ that.length = len;
- if ( typeof opts.callback === 'function' ) {
+ if ( typeof opts.callback === 'function' ) {
- opts.callback( that );
+ opts.callback( that );
+
+ }
+
+ },
+ error: opts.error
+
+ });
+
+ };
+
+ that.fetchAll = function( opts ) {
+
+ if ( !opts ) {
+ opts = {};
+ }
+
+ var count = that.length,
+
+ check_count = function() {
+
+ if ( --count <= 0
+ && typeof opts.callback === 'function' ) {
+
+ opts.callback( that );
}
},
- error: opts.error
+
+ fetch_args = {
+
+ callback: check_count
+
+ };
+
+ if ( typeof opts.error === 'function' ) {
+
+ fetch_args.error = opts.error;
+
+ }
+
+ that.forEach(function( b ) {
+
+ b.fetch(fetch_args);
});
- }
+ };
}
+BooksList.prototype = new Array();
+
var Publisher = createEntity( '', function( publisher, $ ) {
diff --git a/src/requests.js b/src/requests.js
index b9500c8..197b7eb 100644
--- a/src/requests.js
+++ b/src/requests.js
@@ -5,9 +5,7 @@ var cheerio = require( 'cheerio' ),
utils = require( './utils' ),
re_http = /^https?:\/\//,
- re_list_len = /: \d+ . \d+ sur (\d+) livres/,
-
- noop = function(){};
+ re_list_len = /: \d+ . \d+ sur (\d+) livres/;
function makeParams( params, url ) {
@@ -86,7 +84,7 @@ function parseBody( url, callback, error_callback ) {
if ( '' + url !== url ) {
- return (error_callback || noop)( 'No URL given.' );
+ return (error_callback || utils.noop)( 'No URL given.' );
}
@@ -102,10 +100,10 @@ function parseBody( url, callback, error_callback ) {
if ( error || code !== 200 ) {
- return ( error_callback || noop )( error || code );
+ return ( error_callback || utils.noop )( error || code );
}
- return ( callback || noop )( cheerio.load( page ) );
+ return ( callback || utils.noop )( cheerio.load( page ) );
});
@@ -121,7 +119,7 @@ function parseBodies( urls, parser, callback, error_callback ) {
results = [];
if ( urls_count === 0 ) {
- return ( callback || noop )( results );
+ return ( callback || utils.noop )( results );
}
urls.forEach( function( url, i ) {
@@ -132,7 +130,7 @@ function parseBodies( urls, parser, callback, error_callback ) {
urls_count--;
if ( urls_count === 0 ) {
- ( callback || noop )( results );
+ ( callback || utils.noop )( results );
}
}, function( err ) {
@@ -140,10 +138,10 @@ function parseBodies( urls, parser, callback, error_callback ) {
results[ i ] = null;
urls_count--;
- ( error_callback || noop )( err );
+ ( error_callback || utils.noop )( err );
if ( urls_count === 0 ) {
- ( callback || noop )( results );
+ ( callback || utils.noop )( results );
}
});
@@ -180,8 +178,8 @@ function paginate( url, opts ) {
var params = getParams( url ),
parser = opts.parser,
- final_cb = opts.callback || noop,
- error_cb = opts.error || noop,
+ final_cb = opts.callback || utils.noop,
+ error_cb = opts.error || utils.noop,
limit,
offset = opts.offset > 0 ? opts.offset : 0,
bpp = opts.bpp > 0 ? opts.bpp : null;
diff --git a/src/utils.js b/src/utils.js
index 1f0eaa8..8d83bb9 100644
--- a/src/utils.js
+++ b/src/utils.js
@@ -62,3 +62,4 @@ exports.clone = clone;
exports.copy = copy;
exports.extends = _extends;
exports.isArray = isArray;
+exports.noop = function(){};