phantom_svg 1.0.0
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.
- checksums.yaml +7 -0
- data/.gitignore +42 -0
- data/.rspec +3 -0
- data/.rubocop.yml +11 -0
- data/.travis.yml +9 -0
- data/Gemfile +16 -0
- data/Guardfile +12 -0
- data/LICENSE +165 -0
- data/README.md +6 -0
- data/lib/phantom/frame.rb +71 -0
- data/lib/phantom/parser/abstract_animation_reader.rb +117 -0
- data/lib/phantom/parser/json_animation_reader.rb +42 -0
- data/lib/phantom/parser/raster.rb +115 -0
- data/lib/phantom/parser/svg_reader.rb +131 -0
- data/lib/phantom/parser/svg_writer.rb +163 -0
- data/lib/phantom/parser/xml_animation_reader.rb +32 -0
- data/lib/phantom/svg.rb +139 -0
- data/lib/phantom_svg.rb +1 -0
- data/phantom_svg.gemspec +25 -0
- data/spec/images/apngasm.png +0 -0
- data/spec/images/ninja.svg +63 -0
- data/spec/images/stuck_out_tongue/0.svg +103 -0
- data/spec/images/stuck_out_tongue/1.svg +103 -0
- data/spec/images/stuck_out_tongue/10.svg +103 -0
- data/spec/images/stuck_out_tongue/11.svg +103 -0
- data/spec/images/stuck_out_tongue/2.svg +103 -0
- data/spec/images/stuck_out_tongue/3.svg +103 -0
- data/spec/images/stuck_out_tongue/4.svg +103 -0
- data/spec/images/stuck_out_tongue/5.svg +103 -0
- data/spec/images/stuck_out_tongue/6.svg +103 -0
- data/spec/images/stuck_out_tongue/7.svg +103 -0
- data/spec/images/stuck_out_tongue/8.svg +103 -0
- data/spec/images/stuck_out_tongue/9.svg +103 -0
- data/spec/images/stuck_out_tongue/loops_test.json +9 -0
- data/spec/images/stuck_out_tongue/loops_test.xml +4 -0
- data/spec/images/stuck_out_tongue/skip_first_test.json +10 -0
- data/spec/images/stuck_out_tongue/skip_first_test.xml +5 -0
- data/spec/images/stuck_out_tongue/test1.json +20 -0
- data/spec/images/stuck_out_tongue/test1.xml +15 -0
- data/spec/images/stuck_out_tongue/test2.json +13 -0
- data/spec/images/stuck_out_tongue/test2.xml +4 -0
- data/spec/phantom/svg_spec.rb +421 -0
- data/spec/spec_helper.rb +81 -0
- metadata +170 -0
@@ -0,0 +1,15 @@
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
2
|
+
<animation name="myanimation" loops="0" skip_first="false" default_delay="100/1000">
|
3
|
+
<frame src="0" delay="1000" />
|
4
|
+
<frame src="1" />
|
5
|
+
<frame src="2" />
|
6
|
+
<frame src="3" />
|
7
|
+
<frame src="4" />
|
8
|
+
<frame src="5" />
|
9
|
+
<frame src="6" />
|
10
|
+
<frame src="7" />
|
11
|
+
<frame src="8" />
|
12
|
+
<frame src="9" />
|
13
|
+
<frame src="10" />
|
14
|
+
<frame src="11" delay="4/2" />
|
15
|
+
</animation>
|
@@ -0,0 +1,421 @@
|
|
1
|
+
require 'phantom/svg'
|
2
|
+
|
3
|
+
# Set Current directory.
|
4
|
+
Dir.chdir(SPEC_ROOT_DIR)
|
5
|
+
|
6
|
+
describe Phantom::SVG::Base do
|
7
|
+
|
8
|
+
describe 'loading a non-animated svg' do
|
9
|
+
before(:all) do
|
10
|
+
@image_name = 'ninja'
|
11
|
+
@source = "#{SPEC_SOURCE_DIR}/#{@image_name}.svg"
|
12
|
+
end
|
13
|
+
|
14
|
+
before do
|
15
|
+
@loader = Phantom::SVG::Base.new(@source)
|
16
|
+
end
|
17
|
+
|
18
|
+
it 'frames vector has a size of 1.' do
|
19
|
+
expect(@loader.frames.size).to eq(1)
|
20
|
+
end
|
21
|
+
|
22
|
+
it 'frame duration equals 0.1.' do
|
23
|
+
expect(@loader.frames[0].duration).to eq(0.1)
|
24
|
+
end
|
25
|
+
|
26
|
+
it 'frame surfaces is not nil.' do
|
27
|
+
expect(@loader.frames[0].surfaces).not_to be_nil
|
28
|
+
end
|
29
|
+
|
30
|
+
it 'frame surfaces is not empty.' do
|
31
|
+
expect(@loader.frames[0].surfaces).not_to be_empty
|
32
|
+
end
|
33
|
+
|
34
|
+
it 'frame width equal to \'64px\'.' do
|
35
|
+
expect(@loader.frames[0].width).to eq('64px')
|
36
|
+
end
|
37
|
+
|
38
|
+
it 'frame height equal to \'64px\'.' do
|
39
|
+
expect(@loader.frames[0].height).to eq('64px')
|
40
|
+
end
|
41
|
+
|
42
|
+
it 'frame namespaces is not empty.' do
|
43
|
+
expect(@loader.frames[0].namespaces).not_to be_empty
|
44
|
+
end
|
45
|
+
|
46
|
+
after do
|
47
|
+
# nop
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
describe 'creating an animated SVG' do
|
52
|
+
before(:all) do
|
53
|
+
@image_name = 'stuck_out_tongue'
|
54
|
+
@source = "#{SPEC_SOURCE_DIR}/#{@image_name}/*.svg"
|
55
|
+
@destination_dir = "#{SPEC_TEMP_DIR}/#{@image_name}"
|
56
|
+
@destination = "#{@destination_dir}/#{@image_name}.svg"
|
57
|
+
FileUtils.mkdir_p(@destination_dir)
|
58
|
+
end
|
59
|
+
|
60
|
+
before do
|
61
|
+
@loader = Phantom::SVG::Base.new
|
62
|
+
end
|
63
|
+
|
64
|
+
it 'saves a non-zero-byte file.' do
|
65
|
+
@loader.add_frame_from_file(@source)
|
66
|
+
write_size = @loader.save_svg(@destination)
|
67
|
+
expect(write_size).not_to eq(0)
|
68
|
+
end
|
69
|
+
|
70
|
+
it 'is an animation with a frame vector size of 12.' do
|
71
|
+
@loader.add_frame_from_file(@destination)
|
72
|
+
expect(@loader.frames.size).to eq(12)
|
73
|
+
end
|
74
|
+
|
75
|
+
it ' has a frame surfaces length not equal to 1.' do
|
76
|
+
@loader.add_frame_from_file(@destination)
|
77
|
+
|
78
|
+
range = 0..(@loader.frames.length - 1)
|
79
|
+
range.each do |i|
|
80
|
+
frame = @loader.frames[i]
|
81
|
+
expect(frame.surfaces.to_s.length).not_to eq(1)
|
82
|
+
|
83
|
+
@loader.save_svg_frame("#{@destination_dir}/#{i}.svg", frame)
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
after do
|
88
|
+
# nop
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
describe 'creating an animated SVG file from a JSON animation spec file' do
|
93
|
+
before(:all) do
|
94
|
+
@image_name = 'stuck_out_tongue'
|
95
|
+
@source_dir = "#{SPEC_SOURCE_DIR}/#{@image_name}"
|
96
|
+
@destination_dir = SPEC_TEMP_DIR
|
97
|
+
end
|
98
|
+
|
99
|
+
before do
|
100
|
+
@loader = Phantom::SVG::Base.new
|
101
|
+
end
|
102
|
+
|
103
|
+
it 'loads frames from "test1.json".' do
|
104
|
+
test_name = 'test1'
|
105
|
+
@loader.add_frame_from_file("#{@source_dir}/#{test_name}.json")
|
106
|
+
expect(@loader.frames.size).to eq(12)
|
107
|
+
@loader.frames.each do |frame|
|
108
|
+
expect(frame.duration.instance_of?(Float)).to eq(true)
|
109
|
+
expect(frame.width).to eq('64px')
|
110
|
+
expect(frame.height).to eq('64px')
|
111
|
+
expect(frame.surfaces).not_to be_nil
|
112
|
+
expect(frame.surfaces).not_to be_empty
|
113
|
+
expect(frame.surfaces.to_s.length).not_to eq(1)
|
114
|
+
expect(frame.namespaces).not_to be_empty
|
115
|
+
end
|
116
|
+
write_size = @loader.save_svg("#{@destination_dir}/json_#{test_name}.svg")
|
117
|
+
expect(write_size).not_to eq(0)
|
118
|
+
end
|
119
|
+
|
120
|
+
it 'loads frames from "test2.json".' do
|
121
|
+
test_name = 'test2'
|
122
|
+
@loader.add_frame_from_file("#{@source_dir}/#{test_name}.json")
|
123
|
+
expect(@loader.frames.size).to eq(12)
|
124
|
+
@loader.frames.each do |frame|
|
125
|
+
expect(frame.duration.instance_of?(Float)).to eq(true)
|
126
|
+
expect(frame.width).to eq('64px')
|
127
|
+
expect(frame.height).to eq('64px')
|
128
|
+
expect(frame.surfaces).not_to be_nil
|
129
|
+
expect(frame.surfaces).not_to be_empty
|
130
|
+
expect(frame.surfaces.to_s.length).not_to eq(1)
|
131
|
+
expect(frame.namespaces).not_to be_empty
|
132
|
+
end
|
133
|
+
write_size = @loader.save_svg("#{@destination_dir}/json_#{test_name}.svg")
|
134
|
+
expect(write_size).not_to eq(0)
|
135
|
+
end
|
136
|
+
end
|
137
|
+
|
138
|
+
describe 'creating an animated SVG from file from an XML animation spec' do
|
139
|
+
before(:all) do
|
140
|
+
@image_name = 'stuck_out_tongue'
|
141
|
+
@source_dir = "#{SPEC_SOURCE_DIR}/#{@image_name}"
|
142
|
+
@destination_dir = SPEC_TEMP_DIR
|
143
|
+
end
|
144
|
+
|
145
|
+
before do
|
146
|
+
@loader = Phantom::SVG::Base.new
|
147
|
+
end
|
148
|
+
|
149
|
+
it 'loads frames from "test1.xml".' do
|
150
|
+
test_name = 'test1'
|
151
|
+
@loader.add_frame_from_file("#{@source_dir}/#{test_name}.xml")
|
152
|
+
expect(@loader.frames.size).to eq(12)
|
153
|
+
@loader.frames.each do |frame|
|
154
|
+
expect(frame.duration.instance_of?(Float)).to eq(true)
|
155
|
+
expect(frame.width).to eq('64px')
|
156
|
+
expect(frame.height).to eq('64px')
|
157
|
+
expect(frame.surfaces).not_to be_nil
|
158
|
+
expect(frame.surfaces).not_to be_empty
|
159
|
+
expect(frame.surfaces.to_s.length).not_to eq(1)
|
160
|
+
expect(frame.namespaces).not_to be_empty
|
161
|
+
end
|
162
|
+
write_size = @loader.save_svg("#{@destination_dir}/xml_#{test_name}.svg")
|
163
|
+
expect(write_size).not_to eq(0)
|
164
|
+
end
|
165
|
+
|
166
|
+
it 'load frames from "test2.xml".' do
|
167
|
+
test_name = 'test2'
|
168
|
+
@loader.add_frame_from_file("#{@source_dir}/#{test_name}.xml")
|
169
|
+
expect(@loader.frames.size).to eq(12)
|
170
|
+
@loader.frames.each do |frame|
|
171
|
+
expect(frame.duration.instance_of?(Float)).to eq(true)
|
172
|
+
expect(frame.width).to eq('64px')
|
173
|
+
expect(frame.height).to eq('64px')
|
174
|
+
expect(frame.surfaces).not_to be_nil
|
175
|
+
expect(frame.surfaces).not_to be_empty
|
176
|
+
expect(frame.surfaces.to_s.length).not_to eq(1)
|
177
|
+
expect(frame.namespaces).not_to be_empty
|
178
|
+
end
|
179
|
+
write_size = @loader.save_svg("#{@destination_dir}/xml_#{test_name}.svg")
|
180
|
+
expect(write_size).not_to eq(0)
|
181
|
+
end
|
182
|
+
end
|
183
|
+
|
184
|
+
describe 'converting a keyframe animated SVG to APNG' do
|
185
|
+
before(:all) do
|
186
|
+
@image_name = 'stuck_out_tongue'
|
187
|
+
@source = "#{SPEC_SOURCE_DIR}/#{@image_name}/*.svg"
|
188
|
+
@destination = "#{SPEC_TEMP_DIR}/svg2apng.png"
|
189
|
+
end
|
190
|
+
|
191
|
+
before do
|
192
|
+
options = { duration: 0.5 }
|
193
|
+
@loader = Phantom::SVG::Base.new(@source, options)
|
194
|
+
end
|
195
|
+
|
196
|
+
it 'successfully converts.' do
|
197
|
+
expect(@loader.frames.size).to eq(12)
|
198
|
+
is_succeeded = @loader.save_apng(@destination)
|
199
|
+
expect(is_succeeded).to eq(true)
|
200
|
+
end
|
201
|
+
end
|
202
|
+
|
203
|
+
describe 'converting an APNG to a keyframe animated SVG' do
|
204
|
+
before(:all) do
|
205
|
+
@apng_name = 'apngasm'
|
206
|
+
@source = "#{SPEC_SOURCE_DIR}/#{@apng_name}.png"
|
207
|
+
@destination_dir = "#{SPEC_TEMP_DIR}/#{@apng_name}"
|
208
|
+
@destination = "#{@destination_dir}/#{@apng_name}.svg"
|
209
|
+
FileUtils.mkdir_p(@destination_dir)
|
210
|
+
end
|
211
|
+
|
212
|
+
before do
|
213
|
+
@loader = Phantom::SVG::Base.new
|
214
|
+
end
|
215
|
+
|
216
|
+
it 'loads an APNG and saves a keyframe animated SVG.' do
|
217
|
+
@loader.add_frame_from_file(@source)
|
218
|
+
expect(@loader.frames.size).to eq(34)
|
219
|
+
|
220
|
+
write_size = @loader.save_svg(@destination)
|
221
|
+
expect(write_size).not_to eq(0)
|
222
|
+
|
223
|
+
range = 0..(@loader.frames.length - 1)
|
224
|
+
range.each do |i|
|
225
|
+
frame = @loader.frames[i]
|
226
|
+
write_size = @loader.save_svg_frame("#{@destination_dir}/#{i}.svg", frame)
|
227
|
+
expect(write_size).not_to eq(0)
|
228
|
+
end
|
229
|
+
end
|
230
|
+
|
231
|
+
it 'adds frames.' do
|
232
|
+
@loader.add_frame_from_file(@destination)
|
233
|
+
expect(@loader.frames.size).to eq(34)
|
234
|
+
|
235
|
+
@loader.frames.each do |frame|
|
236
|
+
expect(frame.duration).to eq(0.1)
|
237
|
+
expect(frame.width).to eq('64px')
|
238
|
+
expect(frame.height).to eq('64px')
|
239
|
+
expect(frame.surfaces.to_s.length).not_to eq(0)
|
240
|
+
expect(frame.namespaces.length).not_to eq(0)
|
241
|
+
end
|
242
|
+
end
|
243
|
+
end
|
244
|
+
|
245
|
+
describe 'using a finite loop count' do
|
246
|
+
before(:all) do
|
247
|
+
@image_name = 'stuck_out_tongue'
|
248
|
+
@source_dir = "#{SPEC_SOURCE_DIR}/#{@image_name}"
|
249
|
+
@source = "#{@source_dir}/*.svg"
|
250
|
+
@destination_dir = SPEC_TEMP_DIR
|
251
|
+
@destination_svg = "#{@destination_dir}/loops_test.svg"
|
252
|
+
@destination_png = "#{@destination_dir}/loops_test.png"
|
253
|
+
end
|
254
|
+
|
255
|
+
before do
|
256
|
+
@loader = Phantom::SVG::Base.new
|
257
|
+
end
|
258
|
+
|
259
|
+
it 'saves a keyframe animated SVG.' do
|
260
|
+
@loader.add_frame_from_file(@source)
|
261
|
+
@loader.loops = 2
|
262
|
+
|
263
|
+
write_size = @loader.save_svg(@destination_svg)
|
264
|
+
expect(write_size).not_to eq(0)
|
265
|
+
end
|
266
|
+
|
267
|
+
it 'correctly saved the keyframe animated SVG.' do
|
268
|
+
@loader.add_frame_from_file(@destination_svg)
|
269
|
+
|
270
|
+
expect(@loader.frames.size).to eq(12)
|
271
|
+
expect(@loader.width).to eq('64px')
|
272
|
+
expect(@loader.height).to eq('64px')
|
273
|
+
expect(@loader.loops).to eq(2)
|
274
|
+
expect(@loader.skip_first).to eq(false)
|
275
|
+
end
|
276
|
+
|
277
|
+
it 'exports/saves to APNG.' do
|
278
|
+
@loader.add_frame_from_file(@source)
|
279
|
+
@loader.loops = 2
|
280
|
+
|
281
|
+
write_size = @loader.save_apng(@destination_png)
|
282
|
+
expect(write_size).not_to eq(0)
|
283
|
+
end
|
284
|
+
|
285
|
+
it 'correctly saved the APNG.' do
|
286
|
+
@loader.add_frame_from_file(@destination_png)
|
287
|
+
|
288
|
+
expect(@loader.frames.size).to eq(12)
|
289
|
+
expect(@loader.width).to eq('64px')
|
290
|
+
expect(@loader.height).to eq('64px')
|
291
|
+
expect(@loader.loops).to eq(2)
|
292
|
+
expect(@loader.skip_first).to eq(false)
|
293
|
+
end
|
294
|
+
|
295
|
+
it 'loads an animation spec from a JSON file.' do
|
296
|
+
test_name = 'loops_test'
|
297
|
+
source = "#{@source_dir}/#{test_name}.json"
|
298
|
+
destination = "#{@destination_dir}/#{test_name}_json.svg"
|
299
|
+
|
300
|
+
@loader.add_frame_from_file(source)
|
301
|
+
@loader.save_svg(destination)
|
302
|
+
@loader.reset
|
303
|
+
@loader.add_frame_from_file(destination)
|
304
|
+
|
305
|
+
expect(@loader.frames.size).to eq(12)
|
306
|
+
expect(@loader.width).to eq('64px')
|
307
|
+
expect(@loader.height).to eq('64px')
|
308
|
+
expect(@loader.loops).to eq(3)
|
309
|
+
expect(@loader.skip_first).to eq(false)
|
310
|
+
expect(@loader.frames[0].duration).to eq(0.05)
|
311
|
+
end
|
312
|
+
|
313
|
+
it 'loads an animation spec from an XML file.' do
|
314
|
+
test_name = 'loops_test'
|
315
|
+
source = "#{@source_dir}/#{test_name}.xml"
|
316
|
+
destination = "#{@destination_dir}/#{test_name}_xml.svg"
|
317
|
+
|
318
|
+
@loader.add_frame_from_file(source)
|
319
|
+
@loader.save_svg(destination)
|
320
|
+
@loader.reset
|
321
|
+
@loader.add_frame_from_file(destination)
|
322
|
+
|
323
|
+
expect(@loader.frames.size).to eq(12)
|
324
|
+
expect(@loader.width).to eq('64px')
|
325
|
+
expect(@loader.height).to eq('64px')
|
326
|
+
expect(@loader.loops).to eq(3)
|
327
|
+
expect(@loader.skip_first).to eq(false)
|
328
|
+
expect(@loader.frames[0].duration).to eq(0.05)
|
329
|
+
end
|
330
|
+
end
|
331
|
+
|
332
|
+
describe 'using the skip_first flag' do
|
333
|
+
before(:all) do
|
334
|
+
@image_name = 'stuck_out_tongue'
|
335
|
+
@source_dir = "#{SPEC_SOURCE_DIR}/#{@image_name}"
|
336
|
+
@source = "#{@source_dir}/*.svg"
|
337
|
+
@source_skip_frame = "#{SPEC_SOURCE_DIR}/ninja.svg"
|
338
|
+
@destination_dir = SPEC_TEMP_DIR
|
339
|
+
@destination_svg = "#{@destination_dir}/skip_first_test.svg"
|
340
|
+
@destination_png = "#{@destination_dir}/skip_first_test.png"
|
341
|
+
end
|
342
|
+
|
343
|
+
before do
|
344
|
+
@loader = Phantom::SVG::Base.new
|
345
|
+
end
|
346
|
+
|
347
|
+
it 'can save a keyframe animated SVG' do
|
348
|
+
@loader.add_frame_from_file(@source_skip_frame)
|
349
|
+
@loader.add_frame_from_file(@source)
|
350
|
+
@loader.skip_first = true
|
351
|
+
|
352
|
+
write_size = @loader.save_svg(@destination_svg)
|
353
|
+
expect(write_size).not_to eq(0)
|
354
|
+
end
|
355
|
+
|
356
|
+
it 'successfully saves a keyframe animated SVG.' do
|
357
|
+
@loader.add_frame_from_file(@destination_svg)
|
358
|
+
|
359
|
+
expect(@loader.frames.size).to eq(13)
|
360
|
+
expect(@loader.width).to eq('64px')
|
361
|
+
expect(@loader.height).to eq('64px')
|
362
|
+
expect(@loader.loops).to eq(0)
|
363
|
+
expect(@loader.skip_first).to eq(true)
|
364
|
+
end
|
365
|
+
|
366
|
+
it 'exports/saves to APNG' do
|
367
|
+
@loader.add_frame_from_file(@source_skip_frame)
|
368
|
+
@loader.add_frame_from_file(@source)
|
369
|
+
@loader.skip_first = true
|
370
|
+
|
371
|
+
write_size = @loader.save_apng(@destination_png)
|
372
|
+
expect(write_size).not_to eq(0)
|
373
|
+
end
|
374
|
+
|
375
|
+
it 'correctly saved an APNG.' do
|
376
|
+
@loader.add_frame_from_file(@destination_png)
|
377
|
+
|
378
|
+
expect(@loader.frames.size).to eq(13)
|
379
|
+
expect(@loader.width).to eq('64px')
|
380
|
+
expect(@loader.height).to eq('64px')
|
381
|
+
expect(@loader.loops).to eq(0)
|
382
|
+
expect(@loader.skip_first).to eq(true)
|
383
|
+
end
|
384
|
+
|
385
|
+
it 'loads an animation spec from a JSON.' do
|
386
|
+
test_name = 'skip_first_test'
|
387
|
+
source = "#{@source_dir}/#{test_name}.json"
|
388
|
+
destination = "#{@destination_dir}/#{test_name}_json.svg"
|
389
|
+
|
390
|
+
@loader.add_frame_from_file(source)
|
391
|
+
@loader.save_svg(destination)
|
392
|
+
@loader.reset
|
393
|
+
@loader.add_frame_from_file(destination)
|
394
|
+
|
395
|
+
expect(@loader.frames.size).to eq(13)
|
396
|
+
expect(@loader.width).to eq('64px')
|
397
|
+
expect(@loader.height).to eq('64px')
|
398
|
+
expect(@loader.loops).to eq(0)
|
399
|
+
expect(@loader.skip_first).to eq(true)
|
400
|
+
expect(@loader.frames[1].duration).to eq(0.05)
|
401
|
+
end
|
402
|
+
|
403
|
+
it 'loads an animation spec from an XML file.' do
|
404
|
+
test_name = 'skip_first_test'
|
405
|
+
source = "#{@source_dir}/#{test_name}.xml"
|
406
|
+
destination = "#{@destination_dir}/#{test_name}_xml.svg"
|
407
|
+
|
408
|
+
@loader.add_frame_from_file(source)
|
409
|
+
@loader.save_svg(destination)
|
410
|
+
@loader.reset
|
411
|
+
@loader.add_frame_from_file(destination)
|
412
|
+
|
413
|
+
expect(@loader.frames.size).to eq(13)
|
414
|
+
expect(@loader.width).to eq('64px')
|
415
|
+
expect(@loader.height).to eq('64px')
|
416
|
+
expect(@loader.loops).to eq(0)
|
417
|
+
expect(@loader.skip_first).to eq(true)
|
418
|
+
expect(@loader.frames[1].duration).to eq(0.05)
|
419
|
+
end
|
420
|
+
end
|
421
|
+
end
|