animoto 0.0.0.alpha0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (44) hide show
  1. data/README.md +39 -0
  2. data/lib/animoto/asset.rb +25 -0
  3. data/lib/animoto/client.rb +226 -0
  4. data/lib/animoto/content_type.rb +47 -0
  5. data/lib/animoto/directing_and_rendering_job.rb +19 -0
  6. data/lib/animoto/directing_and_rendering_manifest.rb +25 -0
  7. data/lib/animoto/directing_job.rb +18 -0
  8. data/lib/animoto/directing_manifest.rb +115 -0
  9. data/lib/animoto/errors.rb +3 -0
  10. data/lib/animoto/footage.rb +15 -0
  11. data/lib/animoto/image.rb +14 -0
  12. data/lib/animoto/job.rb +37 -0
  13. data/lib/animoto/manifest.rb +21 -0
  14. data/lib/animoto/rendering_job.rb +24 -0
  15. data/lib/animoto/rendering_manifest.rb +37 -0
  16. data/lib/animoto/resource.rb +153 -0
  17. data/lib/animoto/song.rb +16 -0
  18. data/lib/animoto/standard_envelope.rb +27 -0
  19. data/lib/animoto/storyboard.rb +22 -0
  20. data/lib/animoto/title_card.rb +26 -0
  21. data/lib/animoto/video.rb +29 -0
  22. data/lib/animoto/visual.rb +30 -0
  23. data/lib/animoto.rb +5 -0
  24. data/spec/animoto/asset_spec.rb +1 -0
  25. data/spec/animoto/client_spec.rb +119 -0
  26. data/spec/animoto/directing_and_rendering_job_spec.rb +45 -0
  27. data/spec/animoto/directing_and_rendering_manifest_spec.rb +143 -0
  28. data/spec/animoto/directing_job_spec.rb +48 -0
  29. data/spec/animoto/directing_manifest_spec.rb +186 -0
  30. data/spec/animoto/footage_spec.rb +56 -0
  31. data/spec/animoto/image_spec.rb +41 -0
  32. data/spec/animoto/job_spec.rb +128 -0
  33. data/spec/animoto/rendering_job_spec.rb +57 -0
  34. data/spec/animoto/rendering_manifest_spec.rb +115 -0
  35. data/spec/animoto/resource_spec.rb +55 -0
  36. data/spec/animoto/song_spec.rb +54 -0
  37. data/spec/animoto/standard_envelope_spec.rb +0 -0
  38. data/spec/animoto/storyboard_spec.rb +8 -0
  39. data/spec/animoto/title_card_spec.rb +42 -0
  40. data/spec/animoto/video_spec.rb +1 -0
  41. data/spec/animoto/visual_spec.rb +0 -0
  42. data/spec/animoto_spec.rb +5 -0
  43. data/spec/spec_helper.rb +10 -0
  44. metadata +127 -0
@@ -0,0 +1,186 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
2
+
3
+ describe Animoto::DirectingManifest do
4
+
5
+ def manifest options = {}
6
+ @manifest ||= Animoto::DirectingManifest.new(options)
7
+ end
8
+
9
+ describe "initializing" do
10
+ it "should specify the title of the manifest as the first argument" do
11
+ manifest(:title => "Funderful Wonderment").title.should == "Funderful Wonderment"
12
+ end
13
+
14
+ it "should default to 'default' pacing" do
15
+ manifest.pacing.should == 'default'
16
+ end
17
+
18
+ it "should be able to specify the pacing with a :pacing parameter" do
19
+ manifest(:pacing => 'double').pacing.should == 'double'
20
+ end
21
+
22
+ it "should default to 'original' style" do
23
+ manifest.style.should == 'original'
24
+ end
25
+
26
+ it "should default to no producer" do
27
+ manifest.producer.should be_nil
28
+ end
29
+
30
+ it "should be able to specify the producer with a :producer parameter" do
31
+ manifest(:producer => "Senor Spielbergo").producer.should == "Senor Spielbergo"
32
+ end
33
+
34
+ it "should default to having to visuals" do
35
+ manifest.visuals.should be_empty
36
+ end
37
+ end
38
+
39
+ describe "adding assets" do
40
+ describe "using the append operator" do
41
+ before do
42
+ @title_card = Animoto::TitleCard.new "woohoo!"
43
+ end
44
+
45
+ it "should add the asset to this manifest's visuals" do
46
+ manifest << @title_card
47
+ manifest.visuals.should include(@title_card)
48
+ end
49
+
50
+ it "should raise an error if the object being added isn't a visual" do
51
+ lambda { manifest << "beef hearts" }.should raise_error
52
+ end
53
+ end
54
+
55
+ describe "using a convenience method" do
56
+ it "should append the asset to this manifest's visuals" do
57
+ manifest.add_title_card("woohoo!")
58
+ vis = manifest.visuals.last
59
+ vis.should be_an_instance_of(Animoto::TitleCard)
60
+ vis.title.should == "woohoo!"
61
+ end
62
+
63
+ it "should send the parameters to the asset initializer" do
64
+ manifest.add_title_card("woohoo!", "everything is great!")
65
+ vis = manifest.visuals.last
66
+ vis.title.should == "woohoo!"
67
+ vis.subtitle.should == "everything is great!"
68
+ end
69
+ end
70
+ end
71
+
72
+ describe "adding a song" do
73
+ it "should use the append operator" do
74
+ song = Animoto::Song.new "http://song.org/song.mp3"
75
+ manifest << song
76
+ manifest.song.should == song
77
+ end
78
+
79
+ it "should use the add_song method" do
80
+ song = manifest.add_song("http://song.org/song.mp3")
81
+ manifest.song.should == song
82
+ end
83
+
84
+ it "should replace an existing song" do
85
+ song = Animoto::Song.new "http://song.org/song.mp3"
86
+ song2 = Animoto::Song.new "http://song.org/song2.mp3"
87
+ manifest << song
88
+ manifest << song2
89
+ manifest.song.should == song2
90
+ end
91
+ end
92
+
93
+ describe "generating a hash" do
94
+ before do
95
+ manifest(:title => 'Funderful Wonderment', :producer => 'Senor Spielbergo', :pacing => 'double')
96
+ @image = manifest.add_image 'http://website.com/image.png'
97
+ @title_card = manifest.add_title_card 'woohoo', 'this is awesome'
98
+ @footage = manifest.add_footage 'http://website.com/movie.mp4'
99
+ @song_obj = manifest.add_song 'http://website.com/song.mp3'
100
+ end
101
+
102
+ it "should have top-level 'directing_job' object" do
103
+ manifest.to_hash.should have_key('directing_job')
104
+ manifest.to_hash['directing_job'].should be_a(Hash)
105
+ end
106
+
107
+ it "should have a 'directing_manifest' object within the 'directing_job'" do
108
+ manifest.to_hash['directing_job'].should have_key('directing_manifest')
109
+ manifest.to_hash['directing_job']['directing_manifest'].should be_a(Hash)
110
+ end
111
+
112
+ it "should have a 'style' key in the manifest" do
113
+ manifest.to_hash['directing_job']['directing_manifest'].should have_key('style')
114
+ manifest.to_hash['directing_job']['directing_manifest']['style'].should == manifest.style
115
+ end
116
+
117
+ it "should have a 'pacing' key in the manifest" do
118
+ manifest.to_hash['directing_job']['directing_manifest'].should have_key('pacing')
119
+ manifest.to_hash['directing_job']['directing_manifest']['pacing'].should == manifest.pacing
120
+ end
121
+
122
+ it "should have a 'producer_name' key in the manifest" do
123
+ manifest.to_hash['directing_job']['directing_manifest'].should have_key('producer_name')
124
+ manifest.to_hash['directing_job']['directing_manifest']['producer_name'].should == manifest.producer
125
+ end
126
+
127
+ it "should have a 'visuals' key in the manifest" do
128
+ manifest.to_hash['directing_job']['directing_manifest'].should have_key('visuals')
129
+ end
130
+
131
+ it "should have a 'song' object in the manifest" do
132
+ manifest.to_hash['directing_job']['directing_manifest'].should have_key('song')
133
+ manifest.to_hash['directing_job']['directing_manifest']['song'].should be_a(Hash)
134
+ end
135
+
136
+ describe "when the callback url is set" do
137
+ before do
138
+ manifest.http_callback_url = 'http://website.com/callback'
139
+ end
140
+
141
+ describe "but the callback format isn't" do
142
+ it "should raise an error" do
143
+ lambda { manifest.to_hash }.should raise_error(ArgumentError)
144
+ end
145
+ end
146
+
147
+ describe "as well as the format" do
148
+ before do
149
+ manifest.http_callback_format = 'xml'
150
+ end
151
+
152
+ it "should have the HTTP callback URL in the job" do
153
+ manifest.to_hash['directing_job'].should have_key('http_callback')
154
+ manifest.to_hash['directing_job']['http_callback'].should == manifest.http_callback_url
155
+ end
156
+
157
+ it "should have the HTTP callback format in the job" do
158
+ manifest.to_hash['directing_job'].should have_key('http_callback_format')
159
+ manifest.to_hash['directing_job']['http_callback_format'].should == manifest.http_callback_format
160
+ end
161
+ end
162
+ end
163
+
164
+ describe "visuals array" do
165
+ before do
166
+ @visuals = manifest.to_hash['directing_job']['directing_manifest']['visuals']
167
+ end
168
+
169
+ it "should have the visuals in the order they were added" do
170
+ @visuals[0].should == @image.to_hash
171
+ @visuals[1].should == @title_card.to_hash
172
+ @visuals[2].should == @footage.to_hash
173
+ end
174
+ end
175
+
176
+ describe "song" do
177
+ before do
178
+ @song = manifest.to_hash['directing_job']['directing_manifest']['song']
179
+ end
180
+
181
+ it "should have info about the song" do
182
+ @song.should == @song_obj.to_hash
183
+ end
184
+ end
185
+ end
186
+ end
@@ -0,0 +1,56 @@
1
+ require File.expand_path(File.dirname(__FILE__) + "/../spec_helper")
2
+
3
+ describe Animoto::Footage do
4
+
5
+ it "should be a visual" do
6
+ Animoto::Footage.should include(Animoto::Visual)
7
+ end
8
+
9
+ describe "#to_hash" do
10
+ before do
11
+ @footage = Animoto::Footage.new 'http://website.com/movie.mp4'
12
+ end
13
+
14
+ it "should have a 'source_url' key with the url" do
15
+ @footage.to_hash.should have_key('source_url')
16
+ @footage.to_hash['source_url'].should == @footage.source_url
17
+ end
18
+
19
+ it "should not have a 'spotlit' key" do
20
+ @footage.to_hash.should_not have_key('spotlit')
21
+ end
22
+
23
+ describe "if audio mixing is turned on" do
24
+ before do
25
+ @footage.audio_mix = true
26
+ end
27
+
28
+ it "should have an 'audio_mix' key telling how to mix" do
29
+ @footage.to_hash.should have_key('audio_mix')
30
+ @footage.to_hash['audio_mix'].should == 'MIX'
31
+ end
32
+ end
33
+
34
+ describe "if using a different start time" do
35
+ before do
36
+ @footage.start_time = 10.5
37
+ end
38
+
39
+ it "should have a 'start_time' key with the starting time" do
40
+ @footage.to_hash.should have_key('start_time')
41
+ @footage.to_hash['start_time'].should == @footage.start_time
42
+ end
43
+ end
44
+
45
+ describe "if a duration was specified" do
46
+ before do
47
+ @footage.duration = 300
48
+ end
49
+
50
+ it "should have a 'duration' key with the duration" do
51
+ @footage.to_hash.should have_key('duration')
52
+ @footage.to_hash['duration'].should == @footage.duration
53
+ end
54
+ end
55
+ end
56
+ end
@@ -0,0 +1,41 @@
1
+ require File.expand_path(File.dirname(__FILE__) + "/../spec_helper")
2
+
3
+ describe Animoto::Image do
4
+
5
+ it "should be a visual" do
6
+ Animoto::Image.should include(Animoto::Visual)
7
+ end
8
+
9
+ describe "#to_hash" do
10
+ before do
11
+ @image = Animoto::Image.new 'http://website.com/image.png'
12
+ end
13
+
14
+ it "should have a 'source_url' key with the url" do
15
+ @image.to_hash.should have_key('source_url')
16
+ @image.to_hash['source_url'].should == @image.source_url
17
+ end
18
+
19
+ describe "if rotated" do
20
+ before do
21
+ @image.rotation = 2
22
+ end
23
+
24
+ it "should have a 'rotation' key with the EXIF rotation value" do
25
+ @image.to_hash.should have_key('rotation')
26
+ @image.to_hash['rotation'].should == @image.rotation
27
+ end
28
+ end
29
+
30
+ describe "if spotlit" do
31
+ before do
32
+ @image.spotlit = true
33
+ end
34
+
35
+ it "should have a 'spotlit' key telling whether or not this image is spotlit" do
36
+ @image.to_hash.should have_key('spotlit')
37
+ @image.to_hash['spotlit'].should == @image.spotlit?
38
+ end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,128 @@
1
+ require File.expand_path(File.dirname(__FILE__) + "/../spec_helper")
2
+
3
+ describe Animoto::Job do
4
+
5
+ describe "initialization" do
6
+ before do
7
+ @body = {
8
+ 'response' => {
9
+ 'status' => {
10
+ 'code' => 200
11
+ },
12
+ 'payload' => {
13
+ 'job' => {
14
+ 'state' => 'initial',
15
+ 'links' => {
16
+ 'self' => "http://animoto.com/jobs/1"
17
+ }
18
+ }
19
+ }
20
+ }
21
+ }
22
+ @job = Animoto::Job.load @body
23
+ end
24
+
25
+ it "should set its state from the job state given" do
26
+ @job.state.should == 'initial'
27
+ end
28
+
29
+ it "should set its url from the 'self' link given" do
30
+ @job.url.should == 'http://animoto.com/jobs/1'
31
+ end
32
+ end
33
+
34
+ describe "when there are errors" do
35
+ before do
36
+ @body = {
37
+ 'response' => {
38
+ 'status' => {
39
+ 'code' => 400,
40
+ 'errors' => [
41
+ {
42
+ 'code' => 'FORMAT',
43
+ 'description' => 'There is an item in the request that is incorrectly formatted'
44
+ }
45
+ ]
46
+ },
47
+ 'payload' => {
48
+ 'job' => {
49
+ 'state' => 'failed',
50
+ 'links' => {
51
+ 'self' => 'http://animoto.com/jobs/1'
52
+ }
53
+ }
54
+ }
55
+ }
56
+ }
57
+ @job = Animoto::Job.load @body
58
+ end
59
+
60
+ it "should have 'failed' state" do
61
+ @job.state.should == 'failed'
62
+ end
63
+
64
+ it "should have non-empty errors" do
65
+ @job.errors.should_not be_empty
66
+ end
67
+
68
+ it "should wrap the errors in error objects" do
69
+ @job.errors.first.should be_an_instance_of(Animoto::Error)
70
+ end
71
+ end
72
+
73
+ describe "returning state" do
74
+ before do
75
+ @job = Animoto::Job.load 'response'=>{'status'=>{'code'=>200},'payload'=>{'job'=>{'state'=>'initial','links'=>{'self'=>'http://animoto.com/jobs/1'}}}}
76
+ end
77
+
78
+ describe "when 'initial'" do
79
+ it "should not be failed" do
80
+ @job.should_not be_failed
81
+ end
82
+
83
+ it "should not be completed" do
84
+ @job.should_not be_completed
85
+ end
86
+
87
+ it "should be pending" do
88
+ @job.should be_pending
89
+ end
90
+ end
91
+
92
+ describe "when 'failed'" do
93
+ before do
94
+ @job.instance_variable_set :@state, 'failed'
95
+ end
96
+
97
+ it "should be failed" do
98
+ @job.should be_failed
99
+ end
100
+
101
+ it "should not be completed" do
102
+ @job.should_not be_completed
103
+ end
104
+
105
+ it "should not be pending" do
106
+ @job.should_not be_pending
107
+ end
108
+ end
109
+
110
+ describe "when 'completed'" do
111
+ before do
112
+ @job.instance_variable_set :@state, 'completed'
113
+ end
114
+
115
+ it "should not be failed" do
116
+ @job.should_not be_failed
117
+ end
118
+
119
+ it "should be completed" do
120
+ @job.should be_completed
121
+ end
122
+
123
+ it "should not be pending" do
124
+ @job.should_not be_pending
125
+ end
126
+ end
127
+ end
128
+ end
@@ -0,0 +1,57 @@
1
+ require File.expand_path(File.dirname(__FILE__) + "/../spec_helper")
2
+
3
+ describe Animoto::RenderingJob do
4
+
5
+ it "should have endpoint /jobs/rendering" do
6
+ Animoto::RenderingJob.endpoint.should == '/jobs/rendering'
7
+ end
8
+
9
+ it "should have content type 'application/vnd.animoto.rendering_job'" do
10
+ Animoto::RenderingJob.content_type.should == 'rendering_job'
11
+ end
12
+
13
+ it "should have payload key 'rendering_job'" do
14
+ Animoto::RenderingJob.payload_key.should == 'rendering_job'
15
+ end
16
+
17
+ describe "loading from a response body" do
18
+ before do
19
+ @body = {
20
+ 'response' => {
21
+ 'status' => {
22
+ 'code' => 200
23
+ },
24
+ 'payload' => {
25
+ 'rendering_job' => {
26
+ 'state' => 'completed',
27
+ 'links' => {
28
+ 'self' => 'http://animoto.com/jobs/rendering/1',
29
+ 'storyboard' => 'http://animoto.com/storyboards/1',
30
+ 'video' => 'http://animoto.com/videos/1'
31
+ }
32
+ }
33
+ }
34
+ }
35
+ }
36
+ @job = Animoto::RenderingJob.load @body
37
+ end
38
+
39
+ it "should set the storyboard url from the body" do
40
+ @job.storyboard_url.should == "http://animoto.com/storyboards/1"
41
+ end
42
+
43
+ it "should set the video url from the body" do
44
+ @job.video_url.should == "http://animoto.com/videos/1"
45
+ end
46
+
47
+ it "should create a storyboard from the storyboard url" do
48
+ @job.storyboard.should be_an_instance_of(Animoto::Storyboard)
49
+ @job.storyboard.url.should == @job.storyboard_url
50
+ end
51
+
52
+ it "should create a video from the video url" do
53
+ @job.video.should be_an_instance_of(Animoto::Video)
54
+ @job.video.url.should == @job.video_url
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,115 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
2
+
3
+ describe Animoto::RenderingManifest do
4
+
5
+ def manifest *args
6
+ @manifest ||= begin
7
+ options = args.last.is_a?(Hash) ? args.pop : {}
8
+ @storyboard = args[0] || Animoto::Storyboard.new
9
+ Animoto::RenderingManifest.new @storyboard, options
10
+ end
11
+ end
12
+
13
+ describe "initialization" do
14
+ before do
15
+ @storyboard = Animoto::Storyboard.new
16
+ end
17
+
18
+ it "should take a storyboard as the first argument" do
19
+ Animoto::RenderingManifest.new(@storyboard).storyboard = @storyboard
20
+ end
21
+
22
+ it "should take a :resolution parameter to set the resolution" do
23
+ manifest(:resolution => "720p").resolution.should == "720p"
24
+ end
25
+
26
+ it "should take a :framerate parameter to set the framerate" do
27
+ manifest(:framerate => 24).framerate.should == 24
28
+ end
29
+
30
+ it "should take a :format parameter to set the format" do
31
+ manifest(:format => 'flv').format.should == 'flv'
32
+ end
33
+
34
+ it "should take :http_callback_url and :http_callback_format parameters to set the callback" do
35
+ manifest(:http_callback_url => "http://website.com/callback", :http_callback_format => 'xml')
36
+ manifest.http_callback_url.should == "http://website.com/callback"
37
+ manifest.http_callback_format.should == 'xml'
38
+ end
39
+ end
40
+
41
+ describe "generating a hash" do
42
+ before do
43
+ @storyboard = Animoto::Storyboard.new
44
+ @url = "http://animoto.com/storyboards/1"
45
+ @storyboard.instance_variable_set(:@url, @url)
46
+ manifest(@storyboard, :resolution => "720p", :framerate => 24, :format => 'flv')
47
+ end
48
+
49
+ it "should have a top-level 'rendering_job' object" do
50
+ manifest.to_hash.should have_key('rendering_job')
51
+ manifest.to_hash['rendering_job'].should be_a(Hash)
52
+ end
53
+
54
+ it "should have a 'rendering_manifest' object in the 'rendering_job'" do
55
+ manifest.to_hash['rendering_job'].should have_key('rendering_manifest')
56
+ manifest.to_hash['rendering_job']['rendering_manifest'].should be_a(Hash)
57
+ end
58
+
59
+ it "should have a 'storyboard_url' key in the manifest" do
60
+ manifest.to_hash['rendering_job']['rendering_manifest'].should have_key('storyboard_url')
61
+ manifest.to_hash['rendering_job']['rendering_manifest']['storyboard_url'].should == @storyboard.url
62
+ end
63
+
64
+ it "should have a 'rendering_profile' object in the manifest" do
65
+ manifest.to_hash['rendering_job']['rendering_manifest'].should have_key('rendering_profile')
66
+ manifest.to_hash['rendering_job']['rendering_manifest']['rendering_profile'].should be_a(Hash)
67
+ end
68
+
69
+ describe "rendering profile" do
70
+ before do
71
+ @profile = manifest.to_hash['rendering_job']['rendering_manifest']['rendering_profile']
72
+ end
73
+
74
+ it "should have a 'vertical_resolution' key" do
75
+ @profile['vertical_resolution'].should == manifest.resolution
76
+ end
77
+
78
+ it "should have a 'framerate' key" do
79
+ @profile['framerate'].should == manifest.framerate
80
+ end
81
+
82
+ it "should have a 'format' key" do
83
+ @profile['format'].should == manifest.format
84
+ end
85
+ end
86
+
87
+ describe "when an HTTP callback is set" do
88
+ before do
89
+ manifest.http_callback_url = "http://website.com/callback"
90
+ end
91
+
92
+ describe "but a format isn't" do
93
+ it "should raise an error" do
94
+ lambda { manifest.to_hash }.should raise_error(ArgumentError)
95
+ end
96
+ end
97
+
98
+ describe "as well as the format" do
99
+ before do
100
+ manifest.http_callback_format = 'xml'
101
+ end
102
+
103
+ it "should have the HTTP callback URL in the job" do
104
+ manifest.to_hash['rendering_job'].should have_key('http_callback')
105
+ manifest.to_hash['rendering_job']['http_callback'].should == manifest.http_callback_url
106
+ end
107
+
108
+ it "should have the HTTP callback format in the job" do
109
+ manifest.to_hash['rendering_job'].should have_key('http_callback_format')
110
+ manifest.to_hash['rendering_job']['http_callback_format'].should == manifest.http_callback_format
111
+ end
112
+ end
113
+ end
114
+ end
115
+ end
@@ -0,0 +1,55 @@
1
+ require File.expand_path(File.dirname(__FILE__) + "/../spec_helper")
2
+
3
+ describe Animoto::Resource do
4
+
5
+ def define_thing options = {}
6
+ Object.__send__ :remove_const, :Thing if defined?(Thing)
7
+ Object.__send__ :const_set, :Thing, Class.new(Animoto::Resource)
8
+ options.each { |k,v| Thing.__send__(k, v) }
9
+ end
10
+
11
+ describe "inferring the content type" do
12
+ it "should be the underscored, lowercase version of the base class name" do
13
+ class Animoto::ThisIsALongAndStupidName < Animoto::Resource; end
14
+ Animoto::ThisIsALongAndStupidName.content_type.should == 'this_is_a_long_and_stupid_name'
15
+ end
16
+ end
17
+
18
+ describe "identity mapping" do
19
+ before do
20
+ @url = "https://api.animoto.com/videos/1"
21
+ @video = Animoto::Video.new :url => @url
22
+ @body = {
23
+ 'response' => {
24
+ 'status' => { 'code' => 200 },
25
+ 'payload' => {
26
+ 'video' => {
27
+ 'links' => {
28
+ 'download' => "http://animoto.com/videos/1",
29
+ 'storyboard' => "https://api.animoto.com/storyboards/1",
30
+ 'self' => @url
31
+ },
32
+ 'metadata' => {
33
+ 'duration' => 300,
34
+ 'format' => 'h264',
35
+ 'framerate' => 30,
36
+ 'vertical_resolution' => "720p"
37
+ }
38
+ }
39
+ }
40
+ }
41
+ }
42
+ end
43
+
44
+ it "should ensure that two instances instantiated with the same unique identifier will both be the same object" do
45
+ @video.should equal(Animoto::Video.load(@body))
46
+ end
47
+
48
+ it "should update the original instance with the initialization parameters of the new one" do
49
+ @video.duration.should be_nil
50
+ video = Animoto::Video.load(@body)
51
+ video.duration.should == 300
52
+ @video.duration.should == 300
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,54 @@
1
+ require File.expand_path(File.dirname(__FILE__) + "/../spec_helper")
2
+
3
+ describe Animoto::Song do
4
+
5
+ describe "#to_hash" do
6
+ before do
7
+ @song = Animoto::Song.new 'http://website.com/song.mp3'
8
+ end
9
+
10
+ it "should have a 'source_url' key with the url" do
11
+ @song.to_hash.should have_key('source_url')
12
+ @song.to_hash['source_url'].should == @song.source_url
13
+ end
14
+
15
+ describe "if a start time was specified" do
16
+ before do
17
+ @song.start_time = 30.2
18
+ end
19
+
20
+ it "should have a 'start_time' key with the start time" do
21
+ @song.to_hash.should have_key('start_time')
22
+ @song.to_hash['start_time'].should == @song.start_time
23
+ end
24
+ end
25
+
26
+ describe "if a duration was specified" do
27
+ before do
28
+ @song.duration = 300
29
+ end
30
+
31
+ it "should have a 'duration' key with the duration" do
32
+ @song.to_hash.should have_key('duration')
33
+ @song.to_hash['duration'].should == @song.duration
34
+ end
35
+ end
36
+
37
+ describe "if a title and/or artist was specified" do
38
+ before do
39
+ @song.title = "Antarctican Drinking Song"
40
+ @song.artist = "Gwar"
41
+ end
42
+
43
+ it "should have an 'artist' key with the artist" do
44
+ @song.to_hash.should have_key('artist')
45
+ @song.to_hash['artist'].should == @song.artist
46
+ end
47
+
48
+ it "should have a 'title' key with the title" do
49
+ @song.to_hash.should have_key('title')
50
+ @song.to_hash['title'].should == @song.title
51
+ end
52
+ end
53
+ end
54
+ end