claire_client 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
data/.document ADDED
@@ -0,0 +1,5 @@
1
+ README.rdoc
2
+ lib/**/*.rb
3
+ bin/*
4
+ features/**/*.feature
5
+ LICENSE
data/.gitignore ADDED
@@ -0,0 +1,21 @@
1
+ ## MAC OS
2
+ .DS_Store
3
+
4
+ ## TEXTMATE
5
+ *.tmproj
6
+ tmtags
7
+
8
+ ## EMACS
9
+ *~
10
+ \#*
11
+ .\#*
12
+
13
+ ## VIM
14
+ *.swp
15
+
16
+ ## PROJECT::GENERAL
17
+ coverage
18
+ rdoc
19
+ pkg
20
+
21
+ ## PROJECT::SPECIFIC
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2009 Matheus E. Muller
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.rdoc ADDED
@@ -0,0 +1,17 @@
1
+ = claire.client
2
+
3
+ Description goes here.
4
+
5
+ == Note on Patches/Pull Requests
6
+
7
+ * Fork the project.
8
+ * Make your feature addition or bug fix.
9
+ * Add tests for it. This is important so I don't break it in a
10
+ future version unintentionally.
11
+ * Commit, do not mess with rakefile, version, or history.
12
+ (if you want to have your own version, that is fine but bump version in a commit by itself I can ignore when I pull)
13
+ * Send me a pull request. Bonus points for topic branches.
14
+
15
+ == Copyright
16
+
17
+ Copyright (c) 2010 Matheus E. Muller. See LICENSE for details.
data/Rakefile ADDED
@@ -0,0 +1,47 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+
4
+ begin
5
+ require 'jeweler'
6
+ Jeweler::Tasks.new do |gem|
7
+ gem.name = "claire_client"
8
+ gem.summary = "A ruby client for St. Claire."
9
+ gem.description = "This gem is a Ruby client for the St. Claire Media Server, which power power Canção Nova's reach of video and streamming web services."
10
+ gem.email = "hello@memuller.com"
11
+ gem.homepage = "http://github.com/memuller/claire.client"
12
+ gem.authors = ["Matheus E. Muller"]
13
+ gem.add_dependency "activesupport", ">= 2.3.5"
14
+ gem.add_dependency "hashie", ">= 0.2.0"
15
+ gem.add_development_dependency "rspec", ">= 1.2.9"
16
+ # gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
17
+ end
18
+ Jeweler::GemcutterTasks.new
19
+ rescue LoadError
20
+ puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler"
21
+ end
22
+
23
+ require 'spec/rake/spectask'
24
+ Spec::Rake::SpecTask.new(:spec) do |spec|
25
+ spec.libs << 'lib' << 'spec'
26
+ spec.spec_files = FileList['spec/**/*_spec.rb']
27
+ end
28
+
29
+ Spec::Rake::SpecTask.new(:rcov) do |spec|
30
+ spec.libs << 'lib' << 'spec'
31
+ spec.pattern = 'spec/**/*_spec.rb'
32
+ spec.rcov = true
33
+ end
34
+
35
+ task :spec => :check_dependencies
36
+
37
+ task :default => :spec
38
+
39
+ require 'rake/rdoctask'
40
+ Rake::RDocTask.new do |rdoc|
41
+ version = File.exist?('VERSION') ? File.read('VERSION') : ""
42
+
43
+ rdoc.rdoc_dir = 'rdoc'
44
+ rdoc.title = "claire.client #{version}"
45
+ rdoc.rdoc_files.include('README*')
46
+ rdoc.rdoc_files.include('lib/**/*.rb')
47
+ end
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.0.2
@@ -0,0 +1,77 @@
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE DIRECTLY
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
4
+ # -*- encoding: utf-8 -*-
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = %q{claire_client}
8
+ s.version = "0.0.2"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = ["Matheus E. Muller"]
12
+ s.date = %q{2010-04-28}
13
+ s.description = %q{This gem is a Ruby client for the St. Claire Media Server, which power power Canção Nova's reach of video and streamming web services.}
14
+ s.email = %q{hello@memuller.com}
15
+ s.extra_rdoc_files = [
16
+ "LICENSE",
17
+ "README.rdoc"
18
+ ]
19
+ s.files = [
20
+ ".document",
21
+ ".gitignore",
22
+ "LICENSE",
23
+ "README.rdoc",
24
+ "Rakefile",
25
+ "VERSION",
26
+ "claire_client.gemspec",
27
+ "lib/claire_client.rb",
28
+ "lib/claire_client/category.rb",
29
+ "lib/claire_client/item.rb",
30
+ "lib/claire_client/list.rb",
31
+ "lib/claire_client/listable.rb",
32
+ "lib/claire_client/stream.rb",
33
+ "lib/claire_client/video.rb",
34
+ "spec/claire_client/item_spec.rb",
35
+ "spec/claire_client/list_spec.rb",
36
+ "spec/claire_client/listable_spec.rb",
37
+ "spec/claire_client_spec.rb",
38
+ "spec/fixtures/item.xml",
39
+ "spec/fixtures/item_direct.xml",
40
+ "spec/fixtures/item_with_channel.xml",
41
+ "spec/fixtures/list.xml",
42
+ "spec/spec.opts",
43
+ "spec/spec_helper.rb"
44
+ ]
45
+ s.homepage = %q{http://github.com/memuller/claire.client}
46
+ s.rdoc_options = ["--charset=UTF-8"]
47
+ s.require_paths = ["lib"]
48
+ s.rubygems_version = %q{1.3.6}
49
+ s.summary = %q{A ruby client for St. Claire.}
50
+ s.test_files = [
51
+ "spec/claire_client/item_spec.rb",
52
+ "spec/claire_client/list_spec.rb",
53
+ "spec/claire_client/listable_spec.rb",
54
+ "spec/claire_client_spec.rb",
55
+ "spec/spec_helper.rb"
56
+ ]
57
+
58
+ if s.respond_to? :specification_version then
59
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
60
+ s.specification_version = 3
61
+
62
+ if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
63
+ s.add_runtime_dependency(%q<activesupport>, [">= 2.3.5"])
64
+ s.add_runtime_dependency(%q<hashie>, [">= 0.2.0"])
65
+ s.add_development_dependency(%q<rspec>, [">= 1.2.9"])
66
+ else
67
+ s.add_dependency(%q<activesupport>, [">= 2.3.5"])
68
+ s.add_dependency(%q<hashie>, [">= 0.2.0"])
69
+ s.add_dependency(%q<rspec>, [">= 1.2.9"])
70
+ end
71
+ else
72
+ s.add_dependency(%q<activesupport>, [">= 2.3.5"])
73
+ s.add_dependency(%q<hashie>, [">= 0.2.0"])
74
+ s.add_dependency(%q<rspec>, [">= 1.2.9"])
75
+ end
76
+ end
77
+
@@ -0,0 +1,10 @@
1
+ module Claire
2
+ module Client
3
+ class Category
4
+ include Claire::Client::Item
5
+ include Claire::Client::Listable
6
+
7
+ end
8
+
9
+ end
10
+ end
@@ -0,0 +1,92 @@
1
+ module Claire
2
+ module Client
3
+ module Item
4
+
5
+ attr_writer :partial
6
+
7
+ def initialize arg
8
+ if arg.is_a? String
9
+ file = Claire::Client.get("#{self.class.base_url}/#{arg}")
10
+ if Claire::Client.format == 'xml'
11
+ hash = Hashie::Mash.new(Hashie::Mash.from_xml(file))
12
+ else
13
+ hash = Hashie::Mash.new(JSON.parse(file))
14
+ end
15
+ @partial = false
16
+ else
17
+ hash = Hashie::Mash.new(arg) and @partial = true
18
+ end
19
+
20
+ # fetches items from rss, channel, or directly?
21
+ if hash.rss
22
+ hash = hash.rss
23
+ hash = if hash.channel
24
+ then hash.channel
25
+ else hash.item
26
+ end
27
+ end
28
+
29
+ hash.each do |k,v|
30
+
31
+ # skips paging and sub-items.
32
+ next if %w(item next previous).include? k
33
+
34
+ # sets an element's label
35
+ v = v.label if v.respond_to?('merge') and not v.label.nil?
36
+
37
+ # properly fetches the items's link, in case there are more than one link
38
+ v = v.first if k == 'link' and v.respond_to? 'push'
39
+
40
+ class_eval "def #{k}; @#{k}; end"
41
+ instance_variable_set "@#{k}", v
42
+ end
43
+
44
+ # a link is always required.
45
+ raise Claire::Error, "a link is always required" if @link.nil? or @link.empty?
46
+
47
+ end
48
+
49
+ # comparison operator. Sorts by title.
50
+ def <=> arg
51
+ criteria = :title
52
+ return 1 if self.send(criteria) > arg.send(criteria)
53
+ return 0 if self.send(criteria) == arg.send(criteria)
54
+ return -1 if self.send(criteria) < arg.send(criteria)
55
+ end
56
+
57
+ # checks an item's partial status
58
+ def partial?
59
+ @partial
60
+ end
61
+
62
+ module ClassMethods
63
+
64
+ # Returns this class base URI on the server,
65
+ # or guesses it from this class name.
66
+ def base_url
67
+ if defined? @@base_url
68
+ return @@base_url unless @@base_url.nil?
69
+ end
70
+ self.to_s.downcase.pluralize.split('::').last
71
+ end
72
+
73
+ # Manually set this class base URI on the server.
74
+ def base_url= arg
75
+ @@base_url = arg
76
+ end
77
+ end
78
+
79
+ # Extends the class methods above.
80
+ def Item.included base
81
+ base.extend ClassMethods
82
+ (@@children ||= []) << base
83
+ end
84
+
85
+ # Lists all avaliable Claire::Items
86
+ def self.children
87
+ @@children ||= []
88
+ end
89
+
90
+ end
91
+ end
92
+ end
@@ -0,0 +1,53 @@
1
+ module Claire
2
+ module Client
3
+ class List
4
+ include Enumerable
5
+
6
+ attr_reader :body, :document
7
+
8
+ # gets, parses, and builds objects.
9
+ def initialize(arg)
10
+ #puts Claire::Client.respond_to? :get
11
+ @body = Claire::Client.get(arg)
12
+ @document = Hashie::Mash.new(Hashie::Mash.from_xml(@body))
13
+ @document = @document.rss if @document.rss
14
+ @document = @document.channel if @document.channel
15
+ if @document.item.nil?
16
+ @items = []
17
+ else
18
+ @items = @document.item
19
+ end
20
+ build_items
21
+ end
22
+
23
+ # Implements an iterator that either
24
+ # - returns an Array of items if no block is given
25
+ # - yields the given block once for each item
26
+ def each &block
27
+ return @objects unless block
28
+ @objects.each do |obj|
29
+ yield(obj)
30
+ end
31
+ end
32
+
33
+ private
34
+
35
+ # Builds an array of Claire media objects.
36
+ # guesses their classes based on their restfull URI.
37
+ def build_items
38
+ @items.each do |item|
39
+ link = if item.link.is_a? String
40
+ then item.link
41
+ else item.link.first
42
+ end
43
+ klass = ("Claire::Client::" + link.split('/')[-2].classify).constantize
44
+ obj = klass.new(item)
45
+ (@objects||=[]) << obj
46
+
47
+ end
48
+
49
+ end
50
+
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,37 @@
1
+ module Claire
2
+ module Client
3
+ module Listable
4
+
5
+ module ClassMethods
6
+
7
+ # Returns a Claire::List on its base_url.
8
+ # if passed a block, gets the list, them applies a local
9
+ # filter to the received items, returning an Array.
10
+ def all &block
11
+ list = List.new(self.base_url)
12
+ return list unless block
13
+ items = []
14
+ list.each do |item|
15
+ items << item if yield(item)
16
+ end
17
+ items
18
+
19
+ end
20
+
21
+ end
22
+
23
+ # Extends the class methods above.
24
+ def Listable.included base
25
+ raise Error, "only Claire::Client::Item s can be Listable" unless Item.children.include? base
26
+ base.extend ClassMethods
27
+ (@@children ||= []) << base
28
+ end
29
+
30
+ # Lists all avaliable Claire::Items
31
+ def self.children
32
+ @@children ||= []
33
+ end
34
+
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,10 @@
1
+ module Claire
2
+ module Client
3
+ class Stream
4
+ include Claire::Client::Item
5
+ include Claire::Client::Listable
6
+
7
+ end
8
+
9
+ end
10
+ end
@@ -0,0 +1,10 @@
1
+ module Claire
2
+ module Client
3
+ class Video
4
+ include Claire::Client::Item
5
+ include Claire::Client::Listable
6
+
7
+ end
8
+
9
+ end
10
+ end
@@ -0,0 +1,85 @@
1
+ #loads global dependencies
2
+ #%w(rubygems mongo mongo_mapper memcache yaml activesupport json).each{|lib| require lib}
3
+
4
+ #loads every ruby file inside those folders
5
+ full_dir = File.expand_path(File.join(File.dirname(__FILE__), 'claire_client'))
6
+ %w(item list listable category video stream).each do |lib|
7
+ load "#{full_dir}/#{lib}.rb"
8
+ end
9
+
10
+ #
11
+ # Dir.new(full_dir).entries.each do |file|
12
+ # load [full_dir, file]*'/' if file.include? '.rb'
13
+ # end
14
+
15
+ #main module here.
16
+ module Claire
17
+ module Client
18
+ %w(rubygems open-uri active_support hashie).each { |lib| require lib }
19
+ @@hostname = "localhost:3000"
20
+ @@api_key = "33c80d2e38e6b1753982500721f76eccaee0d111"
21
+ @@format = 'xml'
22
+
23
+ %w(api_key hostname format).each do |var|
24
+ class_eval <<-METHOD
25
+ def self.#{var}
26
+ @@#{var}
27
+ end
28
+
29
+ def self.#{var}= arg
30
+ @@#{var} = arg
31
+ end
32
+ METHOD
33
+ end
34
+
35
+ # receives all parameters necessary for request-making.
36
+ def self.config args={}
37
+ args.each do |k,v|
38
+ class_variable_set "@@#{k}", v
39
+ end
40
+ end
41
+
42
+ # assembles an URL from an string of params.
43
+ def self.assemble_url url="", params={}
44
+ url = "http://#{@@hostname}/#{url}"
45
+ url += ".#{@@format.downcase}" if @@format
46
+ uri = URI.parse url
47
+ (uri.query ||= "") << "api_key=#{@@api_key}"
48
+ params.each do |k,v|
49
+ uri.query << "&#{k}=#{v}"
50
+ end
51
+ uri
52
+
53
+ end
54
+
55
+ # gets an URL. Assembles it first.
56
+ def self.get url=''
57
+ url = assemble_url(url)
58
+ request = open(url)
59
+ return request.read if request.status.first.to_i == 200
60
+ nil
61
+ rescue Exception => e
62
+
63
+
64
+ raise
65
+ end
66
+
67
+
68
+ end
69
+
70
+
71
+ #here goes the errors.
72
+ class Error < StandardError; end
73
+ class ClientError < Error; end
74
+ class AuthError < Error; end
75
+ class NotFound < Error; end
76
+ class TimeoutError < Error; end
77
+
78
+ module Client
79
+ class Video
80
+ include Claire::Client::Item
81
+ end
82
+ end
83
+
84
+ end
85
+
@@ -0,0 +1,128 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
2
+
3
+ class Video
4
+ include Claire::Client::Item
5
+ end
6
+
7
+ describe Claire::Client::Item do
8
+ #@session.should_receive(:post).with("url", "data", "headers")
9
+ #@session = mock("session")
10
+ before do
11
+ Claire::Client.stub(:get).with('videos/id').and_return xml :item
12
+ @video = Video.new(hash_from_xml(:item))
13
+ end
14
+
15
+ describe "its initializer" do
16
+
17
+ describe "its base_url class attribute" do
18
+ it "should default to the class name, pluralized" do
19
+ Video.base_url.should == "videos"
20
+ end
21
+
22
+ it "should accept manual overwrite on the class" do
23
+ Video.base_url = "lists"
24
+ Video.base_url.should == "lists"
25
+ Video.base_url = nil
26
+ Video.base_url.should == "videos"
27
+ end
28
+
29
+ it "if the class is in a module, it should get the class name only" do
30
+ eval %(
31
+ module Testing
32
+ class Video
33
+ include Claire::Client::Item
34
+ end
35
+ end
36
+ )
37
+ Testing::Video.base_url.should == "videos"
38
+ end
39
+ end
40
+
41
+ context "upon receiving a Hash" do
42
+ before :each do
43
+ @video = Video.new(hash_from_xml(:item))
44
+ end
45
+
46
+ it "should set partial do true" do
47
+ @video.should be_partial
48
+ end
49
+
50
+ it "should skip the <rss> container if it is present" do
51
+ @video.title.should be_a_kind_of String
52
+ @video.should_not respond_to :rss
53
+ end
54
+
55
+ it "should skip the <channel> container if its present" do
56
+ video = Video.new(hash_from_xml(:item_with_channel))
57
+ video.title.should be_a_kind_of String
58
+ video.should_not respond_to :channel
59
+ end
60
+
61
+ it "should never set 'items' attributes " do
62
+ %w(item item_with_channel).each do |type|
63
+ video = Video.new(hash_from_xml(type))
64
+ video.should_not respond_to :item
65
+ video.title.should be_a_kind_of String
66
+
67
+ end
68
+ end
69
+
70
+ it "should set the link attribute properly (eg ignoring links to other objects/pages)" do
71
+ video = Video.new hash_from_xml :item_with_channel
72
+ video.link.should be_a_kind_of String
73
+ end
74
+
75
+ it "should set its key/values as properties of the element" do
76
+ %w(title link category keywords description).each do |item|
77
+ @video.send(item).should be_a_kind_of String
78
+ end
79
+ %w(thumbnail content).each{ |item| @video.send(item).should be_a_kind_of Array }
80
+ end
81
+ it "should fail if there is not a link attribute" do
82
+ lambda { Video.new( {:rss => {:item => {:name => 'bla'}}} ) }.should raise_error Claire::Error
83
+ end
84
+ end
85
+
86
+ context "upon receiving a String" do
87
+ before { @video = Video.new 'id' }
88
+ it "should open the given string" do
89
+ lambda { Video.new "" }.should raise_error
90
+ lambda { Video.new "id" }.should_not raise_error
91
+ end
92
+ it "should parse the result using the XML parsing rules" do
93
+ @video.title.should be_a_kind_of String
94
+ end
95
+ it "should set partial to false" do
96
+ @video.should_not be_partial
97
+ end
98
+
99
+ end
100
+
101
+ end
102
+
103
+ describe "its comparison (spaceship) operator" do
104
+ it "should be defined" do
105
+ @video.should respond_to '<=>'
106
+ end
107
+
108
+ it "should compare items by title" do
109
+ @video2 = @video.clone
110
+ (@video <=> @video2).should be 0
111
+ end
112
+
113
+ end
114
+
115
+ context "when an undefined method is called" do
116
+ it "it should raise error if partial is false"
117
+ context "if the item is partial" do
118
+ it "should request the full object from server, and replace itself"
119
+ it "should return the asked attribute"
120
+ end
121
+ end
122
+
123
+ it "should have a list of its children as the children class attribute" do
124
+ Claire::Client::Item.children.include?(Video).should be true
125
+ end
126
+
127
+
128
+ end
@@ -0,0 +1,61 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
2
+
3
+
4
+ describe Claire::Client::List do
5
+
6
+ before do
7
+ Claire::Client.stub(:get).with('categories').and_return(xml(:item_with_channel))
8
+ @list = Claire::Client::List.new('categories')
9
+ end
10
+
11
+ describe "its initializing methods & states" do
12
+ it "should require a String" do
13
+ lambda { Claire::Client::List.new }.should raise_error ArgumentError
14
+ lambda { Claire::Client::List.new('categories') }.should_not raise_error
15
+ end
16
+
17
+ it "should make the response accessible thru the body property" do
18
+ @list.body.should be_a_kind_of String
19
+ end
20
+
21
+
22
+ it "should have a parsed document accessible thru the document property" do
23
+ @list.document.should respond_to '[]'
24
+ end
25
+
26
+ end
27
+
28
+ describe "its each method" do
29
+
30
+ it "should return an array" do
31
+ @list.each.should respond_to :first
32
+ end
33
+
34
+ it "should accept a block, yielding once for each object" do
35
+ i = 0 and arr = []
36
+ @list.each do |item|
37
+ item.should_not be_nil
38
+ i += 1
39
+ end
40
+ i.should == 2
41
+ arr.each_slice(2){ |a| a.first.should_not == a.last }
42
+ end
43
+
44
+ it "should contain a list of Claire::Client:Itens-based objects" do
45
+ @list.each do |item|
46
+ Claire::Client::Item.children.include?(item.class).should be true
47
+ end
48
+ end
49
+
50
+ it "the returned objects should be set as partial" do
51
+ @list.each { |item| item.should be_partial }
52
+ end
53
+ end
54
+
55
+ describe "its size method" do
56
+ it "should return the nun_items field if its avaliable"
57
+ it "should count the items if otherwise"
58
+ end
59
+
60
+
61
+ end
@@ -0,0 +1,49 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
2
+
3
+ class Video
4
+ include Claire::Client::Item
5
+ include Claire::Client::Listable
6
+ end
7
+
8
+ describe Claire::Client::Listable do
9
+ before do
10
+ Claire::Client.stub(:get).with('videos').and_return xml(:item_with_channel)
11
+ Claire::Client.stub(:get).with('videos/id').and_return xml(:item)
12
+ end
13
+
14
+ describe "initialization" do
15
+ it "should work only on Claire::Items" do
16
+ lambda { eval("
17
+ class NotAVideo
18
+ include Claire::Client::Listable
19
+ end
20
+ ") }.should raise_error Claire::Error
21
+ lambda { Video.new('id')}.should_not raise_error
22
+ end
23
+ end
24
+
25
+ describe "its all method" do
26
+ it "should be defined" do
27
+ Video.should respond_to :all
28
+ end
29
+
30
+ it "should return a Claire::List on the item's base URL" do
31
+ Video.all.should be_a_kind_of Claire::Client::List
32
+ end
33
+ end
34
+
35
+ it "delegate a count property to its all method" # do
36
+ # Video.count.should == 2
37
+ # end
38
+
39
+ it "should have a list of its children" do
40
+ Claire::Client::Listable.children.include?(Video).should be_true
41
+ end
42
+
43
+ it "should accept a block filter" do
44
+ Video.all { |video| video.title }.should_not be_empty
45
+ Video.all { |video| video.title == ''}.should be_empty
46
+ end
47
+
48
+
49
+ end
@@ -0,0 +1,115 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
+ describe Claire::Client do
3
+ before { Claire::Client.stub(:get).with('categories').and_return(xml(:list)) }
4
+
5
+ it "should have a hostname property" do
6
+ %w(hostname hostname=).each{ |method| Claire::Client.should respond_to method }
7
+ end
8
+ it "should have an API key" do
9
+ %w(api_key api_key=).each{ |method| Claire::Client.should respond_to method }
10
+ end
11
+ it "should have a format property" do
12
+ %w(format format=).each{ |method| Claire::Client.should respond_to method }
13
+ end
14
+
15
+ context "its config method" do
16
+
17
+ it "should exist"do
18
+ Claire::Client.should respond_to "config"
19
+ end
20
+
21
+ it "should accept an hash of init options" do
22
+ lambda{ Claire::Client.config :api_key => "abc", :hostname => "localhost:3000"}.should_not raise_error
23
+ end
24
+
25
+ it "received options must be set" do
26
+ Claire::Client.config :api_key => "abc", :hostname => "localhost:3000"
27
+ Claire::Client.api_key.should == "abc"
28
+ Claire::Client.hostname.should == "localhost:3000"
29
+ end
30
+
31
+ end
32
+
33
+ it "standard errors should be defined" do
34
+ %w(Claire::Error Claire::ClientError Claire::AuthError Claire::NotFound Claire::TimeoutError).each do |err|
35
+ lambda{ eval("#{err}") }.should_not raise_error
36
+ end
37
+ end
38
+
39
+ describe "its assemble_url method" do
40
+
41
+ it "should exist" do
42
+ Claire::Client.should respond_to "assemble_url"
43
+ end
44
+
45
+ it "should receive a string" do
46
+ lambda{ Claire::Client.assemble_url("url") }.should_not raise_error
47
+ end
48
+
49
+ it "should receive an optional parameter hash" do
50
+ lambda{ Claire::Client.assemble_url("url",{:param => 'value'}) }.should_not raise_error
51
+ end
52
+
53
+ it "should return an URI object" do
54
+ Claire::Client.assemble_url.should be_a_kind_of URI
55
+ end
56
+
57
+ context "about the resulting URI" do
58
+ before do
59
+ @response = Claire::Client.assemble_url("categories")
60
+ end
61
+
62
+ it "should have the given hostname" do
63
+ lambda { Claire::Client.hostname.include?(@response.host) }.call.should be true
64
+ end
65
+
66
+ it "should use the API key" do
67
+ @response.query.include?("api_key=#{Claire::Client.api_key}").should be true
68
+ end
69
+
70
+ it "should have the desired format" do
71
+ lambda { @response.to_s.include?(".#{Claire::Client.format.downcase}") }.call.should be true
72
+ end
73
+
74
+ it "should have the desired path" do
75
+ lambda { @response.path.include? "categories" }.call.should be true
76
+ end
77
+
78
+ it "should have the given query" do
79
+ @response = Claire::Client.assemble_url("categories?stuff=true")
80
+ lambda { @response.query.include?("stuff=true") }.call.should be true
81
+ end
82
+
83
+ context "if a param hash was given" do
84
+ before :each do
85
+ @response = Claire::Client.assemble_url("categories", :page => 2, :limit => 10)
86
+ end
87
+
88
+ it "assembles the params in the URI" do
89
+ %w(limit=10 page=2).each do |i|
90
+ @response.query.include?(i).should be true
91
+ end
92
+ end
93
+ end
94
+
95
+ end
96
+
97
+ end
98
+
99
+ describe "its get method" do
100
+ it "should exist" do
101
+ Claire::Client.should respond_to "get"
102
+ end
103
+
104
+ it "should receive a String" do
105
+ lambda { Claire::Client.get "categories" }.should_not raise_error
106
+ end
107
+
108
+ it "should receive aditional params as an hash"
109
+
110
+ it "should make the request and return an body" do
111
+ lambda { Claire::Client.get "categories" }.call.should_not be_empty
112
+ end
113
+
114
+ end
115
+ end
@@ -0,0 +1,23 @@
1
+ <?xml version="1.0" encoding="utf-8" standalone="yes"?>
2
+
3
+ <rss version="2.0" xmlns:media="http://search.yahoo.com/mrss" xmlns:atom="http://www.w3.org/2005/Atom">
4
+ <item>
5
+ <title>new title</title>
6
+ <link>http://localhost:3000/videos/4bbced401637fd736a000004</link>
7
+ <media:content type="video/flv" url="/videos/4bbced401637fd736a000004/flv-h263.flv" duration=""/>
8
+ <media:content type="video/flv" url="/videos/4bbced401637fd736a000004/flv-h264.flv" duration=""/>
9
+ <media:thumbnail width="215" url="/videos/4bbced401637fd736a000004/thumb_thumb_medium.jpg" heigth="120"/>
10
+ <media:thumbnail width="50" url="/videos/4bbced401637fd736a000004/thumb_thumb_square.jpg" heigth="50"/>
11
+ <media:thumbnail width="500" url="/videos/4bbced401637fd736a000004/thumb_thumb_large.jpg" heigth="281"/>
12
+ <media:category label="test"/>
13
+ <media:keywords>many, keywords, here</media:keywords>
14
+ <media:description>asa</media:description>
15
+ <media:community>
16
+ <media:starRating average="0.0"/>
17
+ <media:statistics views="0"/>
18
+ </media:community>
19
+ <related>
20
+ <item title="new title" link="http://localhost:3000/videos/4bbced401637fd736a000004" thumbnail="/videos/4bbced401637fd736a000004/thumb_thumb_square.jpg"/>
21
+ </related>
22
+ </item>
23
+ </rss>
@@ -0,0 +1,19 @@
1
+ <item>
2
+ <title>new title</title>
3
+ <link>http://localhost:3000/videos/4bbced401637fd736a000004</link>
4
+ <media:content type="video/flv" url="/videos/4bbced401637fd736a000004/flv-h263.flv" duration=""/>
5
+ <media:content type="video/flv" url="/videos/4bbced401637fd736a000004/flv-h264.flv" duration=""/>
6
+ <media:thumbnail width="215" url="/videos/4bbced401637fd736a000004/thumb_thumb_medium.jpg" heigth="120"/>
7
+ <media:thumbnail width="50" url="/videos/4bbced401637fd736a000004/thumb_thumb_square.jpg" heigth="50"/>
8
+ <media:thumbnail width="500" url="/videos/4bbced401637fd736a000004/thumb_thumb_large.jpg" heigth="281"/>
9
+ <media:category label="test"/>
10
+ <media:keywords></media:keywords>
11
+ <media:description>asa</media:description>
12
+ <media:community>
13
+ <media:starRating average="0.0"/>
14
+ <media:statistics views="0"/>
15
+ </media:community>
16
+ <related>
17
+ <item title="new title" link="http://localhost:3000/videos/4bbced401637fd736a000004" thumbnail="/videos/4bbced401637fd736a000004/thumb_thumb_square.jpg"/>
18
+ </related>
19
+ </item>
@@ -0,0 +1,53 @@
1
+ <?xml version="1.0" encoding="utf-8" standalone="yes"?>
2
+
3
+ <rss version="2.0" xmlns:media="http://search.yahoo.com/mrss" xmlns:atom="http://www.w3.org/2005/Atom">
4
+
5
+ <channel>
6
+ <title>test</title>
7
+ <description></description>
8
+ <header>/public/categories/4bb48ef61637fd69c1000005/original.jpg</header>
9
+ <num_items>1</num_items>
10
+ <link>http://localhost:3000/categories/4bb48ef61637fd69c1000005</link>
11
+ <item>
12
+ <title>new title</title>
13
+ <link>http://localhost:3000/videos/4bbced401637fd736a000004</link>
14
+ <media:content type="video/flv" duration="" url="/videos/4bbced401637fd736a000004/flv-h263.flv"/>
15
+ <media:content type="video/flv" duration="" url="/videos/4bbced401637fd736a000004/flv-h264.flv"/>
16
+ <media:thumbnail heigth="50" width="50" url="/videos/4bbced401637fd736a000004/thumb_thumb_square.jpg"/>
17
+ <media:thumbnail heigth="120" width="215" url="/videos/4bbced401637fd736a000004/thumb_thumb_medium.jpg"/>
18
+ <media:thumbnail heigth="281" width="500" url="/videos/4bbced401637fd736a000004/thumb_thumb_large.jpg"/>
19
+ <media:category label="testting"/>
20
+ <media:keywords></media:keywords>
21
+ <media:description>asa</media:description>
22
+ <media:community>
23
+ <media:starRating average="0.0"/>
24
+ <media:statistics views="0"/>
25
+ </media:community>
26
+ <related>
27
+ <item thumbnail="/videos/4bbced401637fd736a000004/thumb_thumb_square.jpg" title="new title" link="http://localhost:3000/videos/4bbced401637fd736a000004"/>
28
+ </related>
29
+ </item>
30
+ <item>
31
+ <title>new title 2</title>
32
+ <link>http://localhost:3000/videos/4bbced401637fd736a000004</link>
33
+ <media:content type="video/flv" duration="" url="/videos/4bbced401637fd736a000004/flv-h263.flv"/>
34
+ <media:content type="video/flv" duration="" url="/videos/4bbced401637fd736a000004/flv-h264.flv"/>
35
+ <media:thumbnail heigth="50" width="50" url="/videos/4bbced401637fd736a000004/thumb_thumb_square.jpg"/>
36
+ <media:thumbnail heigth="120" width="215" url="/videos/4bbced401637fd736a000004/thumb_thumb_medium.jpg"/>
37
+ <media:thumbnail heigth="281" width="500" url="/videos/4bbced401637fd736a000004/thumb_thumb_large.jpg"/>
38
+ <media:category label="testting"/>
39
+ <media:keywords></media:keywords>
40
+ <media:description>asa</media:description>
41
+ <media:community>
42
+ <media:starRating average="0.0"/>
43
+ <media:statistics views="0"/>
44
+ </media:community>
45
+ <related>
46
+ <item thumbnail="/videos/4bbced401637fd736a000004/thumb_thumb_square.jpg" title="new title" link="http://localhost:3000/videos/4bbced401637fd736a000004"/>
47
+ </related>
48
+ </item>
49
+ <atom:link rel="next" href="http://localhost:3000/categories/4bb48ef61637fd69c1000005.xml?page=2"/>
50
+ </channel>
51
+
52
+
53
+ </rss>
@@ -0,0 +1,24 @@
1
+ <?xml version="1.0" encoding="utf-8" standalone="yes"?>
2
+
3
+ <rss version="2.0" xmlns:media="http://search.yahoo.com/mrss" xmlns:atom="http://www.w3.org/2005/Atom">
4
+
5
+ <item>
6
+ <title>test</title>
7
+ <link>http://localhost:3000/categories/4bb48ef61637fd69c1000005</link>
8
+ <num_videos>1</num_videos>
9
+ </item>
10
+ <item>
11
+ <title>none</title>
12
+ <link>http://localhost:3000/categories/4bb881681637fd0513000001</link>
13
+ <description>some</description>
14
+ <num_videos>0</num_videos>
15
+ </item>
16
+ <item>
17
+ <title>name</title>
18
+ <link>http://localhost:3000/categories/4bb882251637fd0513000002</link>
19
+ <description>namae</description>
20
+ <num_videos>0</num_videos>
21
+ </item>
22
+
23
+
24
+ </rss>
data/spec/spec.opts ADDED
@@ -0,0 +1 @@
1
+ --color
@@ -0,0 +1,20 @@
1
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
2
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
3
+
4
+ require 'claire_client'
5
+ require 'spec'
6
+ require 'spec/autorun'
7
+
8
+ $root = File.join(File.dirname(__FILE__), '..')
9
+
10
+ Spec::Runner.configure do |config|
11
+
12
+ end
13
+
14
+ def xml arg
15
+ File.open("#{$root}/spec/fixtures/#{arg}.xml", 'r').read
16
+ end
17
+
18
+ def hash_from_xml arg
19
+ Hashie::Mash.from_xml(xml(arg))
20
+ end
metadata ADDED
@@ -0,0 +1,131 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: claire_client
3
+ version: !ruby/object:Gem::Version
4
+ prerelease: false
5
+ segments:
6
+ - 0
7
+ - 0
8
+ - 2
9
+ version: 0.0.2
10
+ platform: ruby
11
+ authors:
12
+ - Matheus E. Muller
13
+ autorequire:
14
+ bindir: bin
15
+ cert_chain: []
16
+
17
+ date: 2010-04-28 00:00:00 -03:00
18
+ default_executable:
19
+ dependencies:
20
+ - !ruby/object:Gem::Dependency
21
+ name: activesupport
22
+ prerelease: false
23
+ requirement: &id001 !ruby/object:Gem::Requirement
24
+ requirements:
25
+ - - ">="
26
+ - !ruby/object:Gem::Version
27
+ segments:
28
+ - 2
29
+ - 3
30
+ - 5
31
+ version: 2.3.5
32
+ type: :runtime
33
+ version_requirements: *id001
34
+ - !ruby/object:Gem::Dependency
35
+ name: hashie
36
+ prerelease: false
37
+ requirement: &id002 !ruby/object:Gem::Requirement
38
+ requirements:
39
+ - - ">="
40
+ - !ruby/object:Gem::Version
41
+ segments:
42
+ - 0
43
+ - 2
44
+ - 0
45
+ version: 0.2.0
46
+ type: :runtime
47
+ version_requirements: *id002
48
+ - !ruby/object:Gem::Dependency
49
+ name: rspec
50
+ prerelease: false
51
+ requirement: &id003 !ruby/object:Gem::Requirement
52
+ requirements:
53
+ - - ">="
54
+ - !ruby/object:Gem::Version
55
+ segments:
56
+ - 1
57
+ - 2
58
+ - 9
59
+ version: 1.2.9
60
+ type: :development
61
+ version_requirements: *id003
62
+ description: "This gem is a Ruby client for the St. Claire Media Server, which power power Can\xC3\xA7\xC3\xA3o Nova's reach of video and streamming web services."
63
+ email: hello@memuller.com
64
+ executables: []
65
+
66
+ extensions: []
67
+
68
+ extra_rdoc_files:
69
+ - LICENSE
70
+ - README.rdoc
71
+ files:
72
+ - .document
73
+ - .gitignore
74
+ - LICENSE
75
+ - README.rdoc
76
+ - Rakefile
77
+ - VERSION
78
+ - claire_client.gemspec
79
+ - lib/claire_client.rb
80
+ - lib/claire_client/category.rb
81
+ - lib/claire_client/item.rb
82
+ - lib/claire_client/list.rb
83
+ - lib/claire_client/listable.rb
84
+ - lib/claire_client/stream.rb
85
+ - lib/claire_client/video.rb
86
+ - spec/claire_client/item_spec.rb
87
+ - spec/claire_client/list_spec.rb
88
+ - spec/claire_client/listable_spec.rb
89
+ - spec/claire_client_spec.rb
90
+ - spec/fixtures/item.xml
91
+ - spec/fixtures/item_direct.xml
92
+ - spec/fixtures/item_with_channel.xml
93
+ - spec/fixtures/list.xml
94
+ - spec/spec.opts
95
+ - spec/spec_helper.rb
96
+ has_rdoc: true
97
+ homepage: http://github.com/memuller/claire.client
98
+ licenses: []
99
+
100
+ post_install_message:
101
+ rdoc_options:
102
+ - --charset=UTF-8
103
+ require_paths:
104
+ - lib
105
+ required_ruby_version: !ruby/object:Gem::Requirement
106
+ requirements:
107
+ - - ">="
108
+ - !ruby/object:Gem::Version
109
+ segments:
110
+ - 0
111
+ version: "0"
112
+ required_rubygems_version: !ruby/object:Gem::Requirement
113
+ requirements:
114
+ - - ">="
115
+ - !ruby/object:Gem::Version
116
+ segments:
117
+ - 0
118
+ version: "0"
119
+ requirements: []
120
+
121
+ rubyforge_project:
122
+ rubygems_version: 1.3.6
123
+ signing_key:
124
+ specification_version: 3
125
+ summary: A ruby client for St. Claire.
126
+ test_files:
127
+ - spec/claire_client/item_spec.rb
128
+ - spec/claire_client/list_spec.rb
129
+ - spec/claire_client/listable_spec.rb
130
+ - spec/claire_client_spec.rb
131
+ - spec/spec_helper.rb