Permalink
Browse files

Created paged result class, with passing feature and specs

  • Loading branch information...
1 parent 3fdb117 commit c76690520076ef7da856bae9f673b6e40794abe0 @gingerhendrix committed Aug 2, 2009
View
3 TODO
@@ -1,7 +1,6 @@
@milestone Basic artist methods +done
@milestone Improve API, documentation and implement missing features
- @iteration Fluent Api
- Separate out the ugly xml mapping classes and provide a nice fluent interface based on an Artist object eg. anArtist.familiarity should return the familiarity as a number (transparently calling the webservice if required)
+ @iteration Fluent Api +done
@iteration Paging
Create a nice interface for paged results (urls, videos, blogs, audio etc).
@iteration Docs
@@ -4,8 +4,10 @@ Feature: Artist audio
Scenario: Artist audio
When I retrieve the audio for "music://id.echonest.com/~/AR/ARVVZQP11E2835DBCB"
- Then I should get some results
+ Then I should get some paged results
And a result should have a url
And a result should have a link
And a result should have a release
And a result should have a title
+ And a later result should have a url
+
@@ -16,6 +16,20 @@
@result.length.should_not == 0
end
+Then /^I should get some paged results$/ do
+ @result.should_not be_nil
+ @result.should be_kind_of(PagedResult)
+ @result.length.should_not == 0
+ @result.found.should_not == 0
+end
+
+Then /^a later result should have a ([^ ]*)$/ do |prop|
+ @later_result ||= @result[@result.length+1]
+ @later_result.send(prop.to_sym).should_not be_nil
+end
+
+
+
Then /^I should get a numeric result$/ do
@result.should_not be_nil
@result.should be_kind_of(Numeric)
View
@@ -2,6 +2,7 @@
require 'happymapper'
require 'open-uri'
require 'activesupport'
+require 'delegate'
module EchoNest
def self.api_key=(api_key)
@@ -15,6 +16,8 @@ def self.api_key
end
require "echonest/api_request.rb"
+require "echonest/paged_result.rb"
+
require "echonest/artist.rb"
require "echonest/xml/artist_doc.rb"
View
@@ -18,7 +18,11 @@ def self.service(name, options = {})
define_method name do
return instance_variable_get("@#{name.to_s}") if instance_variable_get("@#{name.to_s}")
result = self.send("get_#{name.to_s}")
- instance_variable_set("@#{name.to_s}", result.results.docs)
+ pager = Proc.new { |start, rows|
+ self.send("get_#{name.to_s}", :start => start, :rows => rows).results
+ }
+ page = PagedResult.new result.results, pager
+ instance_variable_set("@#{name.to_s}", page)
end
else
if !options[:provides]
@@ -1,14 +0,0 @@
-
-module EchoNest
- module Xml
- class ArtistSearchResult
- include HappyMapper
-
- tag :response
-
- # has_one :status, RequestStatus
- # has_one :query, RequestQuery
- has_many :artists, Xml::ArtistDoc
- end
- end
-end
@@ -0,0 +1,32 @@
+
+
+
+module EchoNest
+ class PagedResult < DelegateClass(Array)
+
+ def initialize(results, block)
+ @results = results
+ @update = block
+ @available = @results.docs
+ super(@available)
+ end
+
+ def found
+ @results.found
+ end
+
+ def next_page
+ results = @update.call @available.length, 15
+ @available += results.docs
+ self.__setobj__(@available)
+ end
+
+ def [](i)
+ return @available[i] if @available[i]
+ next_page
+ @available[i]
+ end
+
+
+ end
+end
@@ -0,0 +1,66 @@
+require File.dirname(__FILE__) + "/../spec_helper.rb"
+
+include EchoNest
+
+describe "PagedResult" do
+ before :each do
+ @docs = mock("docs", :length => 2)
+ @results = mock("results", :docs => @docs)
+ @block_body = mock("block body")
+ @block = Proc.new { |*args| @block_body.called(*args) }
+ @page = PagedResult.new @results, &@block
+
+ @docs2 = mock("docs2", :length => 2)
+ @page2 = mock("page2", :docs => @docs2)
+ @block_body.stub!(:called).and_return(@page2)
+
+ end
+
+ describe "each" do
+ it "should iterate over items in results" do
+ @docs.should_receive(:each)
+ @page.each
+ end
+ end
+
+ describe "[]" do
+ it "should return the nth doc" do
+ @docs.should_receive('[]').twice().with(1).and_return(:doc)
+ @page[1].should == :doc
+ end
+
+ it "should get the next page if index is out of range" do
+ @docs.should_receive('[]').at_least(1).and_return(nil)
+ @page.should_receive(:next_page)
+ @page[2]
+ end
+
+ end
+
+ describe "next_page" do
+
+ before(:each) do
+ @merged_docs = mock("Merged Docs", :length => 4)
+ @docs.stub!('+').and_return(@merged_docs)
+ end
+
+ it "should fetch the next page" do
+ @block_body.should_receive(:called).with(2, 15).and_return(@page2)
+ @page.next_page
+ end
+
+ it "should update the delegate" do
+ @docs.should_receive('+').with(@docs2).and_return(@merged_docs)
+ @page.next_page
+ @page.length.should == 4
+ end
+
+
+ end
+
+ describe "length" do
+
+ end
+
+
+end

0 comments on commit c766905

Please sign in to comment.