wax_iiif 0.0.2 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (52) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -0
  3. data/.rubocop.yml +25 -0
  4. data/.travis.yml +2 -2
  5. data/Gemfile +3 -2
  6. data/README.md +4 -4
  7. data/lib/wax_iiif.rb +34 -44
  8. data/lib/wax_iiif/base_properties.rb +90 -0
  9. data/lib/wax_iiif/builder.rb +252 -0
  10. data/lib/wax_iiif/collection.rb +58 -0
  11. data/lib/{iiif_s3 → wax_iiif}/config.rb +46 -60
  12. data/lib/{iiif_s3 → wax_iiif}/errors.rb +6 -12
  13. data/lib/{iiif_s3 → wax_iiif}/full_image.rb +3 -8
  14. data/lib/wax_iiif/image_info.rb +89 -0
  15. data/lib/{iiif_s3 → wax_iiif}/image_record.rb +48 -63
  16. data/lib/{iiif_s3 → wax_iiif}/image_tile.rb +8 -14
  17. data/lib/{iiif_s3 → wax_iiif}/image_variant.rb +20 -38
  18. data/lib/wax_iiif/manifest.rb +151 -0
  19. data/lib/{iiif_s3 → wax_iiif}/thumbnail.rb +5 -9
  20. data/lib/{iiif_s3 → wax_iiif}/utilities.rb +5 -5
  21. data/lib/{iiif_s3 → wax_iiif}/utilities/helpers.rb +18 -48
  22. data/lib/{iiif_s3 → wax_iiif}/utilities/pdf_splitter.rb +20 -23
  23. data/spec/base_properties_spec.rb +8 -12
  24. data/spec/shared_contexts.rb +28 -92
  25. data/spec/spec_helper.rb +3 -3
  26. data/spec/wax_iiif/builder_spec.rb +143 -0
  27. data/spec/wax_iiif/collection_spec.rb +53 -0
  28. data/spec/wax_iiif/config_spec.rb +15 -0
  29. data/spec/wax_iiif/image_info_spec.rb +57 -0
  30. data/spec/wax_iiif/image_record_spec.rb +82 -0
  31. data/spec/wax_iiif/image_variant_spec.rb +66 -0
  32. data/spec/wax_iiif/manifest_spec.rb +97 -0
  33. data/spec/wax_iiif/utilities/pdf_splitter_spec.rb +14 -0
  34. data/wax_iiif.gemspec +15 -19
  35. metadata +52 -97
  36. data/Guardfile +0 -10
  37. data/Rakefile +0 -24
  38. data/lib/iiif_s3/base_properties.rb +0 -95
  39. data/lib/iiif_s3/builder.rb +0 -241
  40. data/lib/iiif_s3/collection.rb +0 -61
  41. data/lib/iiif_s3/image_info.rb +0 -96
  42. data/lib/iiif_s3/manifest.rb +0 -151
  43. data/lib/iiif_s3/version.rb +0 -5
  44. data/spec/iiif_s3/builder_spec.rb +0 -152
  45. data/spec/iiif_s3/collection_spec.rb +0 -68
  46. data/spec/iiif_s3/config_spec.rb +0 -15
  47. data/spec/iiif_s3/image_info_spec.rb +0 -57
  48. data/spec/iiif_s3/image_record_spec.rb +0 -96
  49. data/spec/iiif_s3/image_variant_spec.rb +0 -68
  50. data/spec/iiif_s3/manifest_spec.rb +0 -97
  51. data/spec/iiif_s3/utilities/pdf_splitter_spec.rb +0 -17
  52. data/test.rb +0 -77
@@ -1,9 +1,7 @@
1
- require "mini_magick"
1
+ require 'mini_magick'
2
2
 
3
- module IiifS3
3
+ module WaxIiif
4
4
  module Utilities
5
-
6
- #
7
5
  # Class PdfSplitter is a utility function designed to convert a PDF into a stack of images.
8
6
  #
9
7
  # @author David Newbury <david.newbury@gmail.com>
@@ -15,36 +13,35 @@ module IiifS3
15
13
  # @param [Hash] options The configuration hash
16
14
  #
17
15
  # @return [Array<String>] The paths to the generated files
18
- #
19
- def self.split(path, options={})
20
-
21
- output_dir = options.fetch(:output_dir, ".")
22
- verbose = options.fetch(:verbose, false)
23
- puts "processing #{path}" if verbose
24
- name = File.basename(path, File.extname(path))
16
+ def self.split(path, options = {})
17
+ puts "processing #{path}" if options.fetch(:verbose, false)
25
18
 
26
- pages = []
27
-
28
- pdf = MiniMagick::Image.open(path)
19
+ name = File.basename(path, File.extname(path))
20
+ output_dir = "#{options.fetch(:output_dir, '.')}/#{name}"
21
+ pages = []
22
+ pdf = MiniMagick::Image.open(path)
23
+ max_digits = pdf.pages.length.digits.length
29
24
 
30
25
  pdf.pages.each_with_index do |page, index|
31
- page_file_name = "#{output_dir}/#{name}_#{index+1}.jpg"
32
-
26
+ FileUtils.mkdir_p output_dir
27
+ page_file_name = "#{output_dir}/#{index.to_s.rjust(max_digits, '0')}.jpg"
28
+
33
29
  MiniMagick::Tool::Convert.new do |convert|
34
- convert.density("300")
35
- convert.units("PixelsPerInch")
36
- convert << page.path
37
- convert.quality("80")
38
- convert.colorspace("sRGB")
39
- convert.interlace("none")
30
+ convert.density('300')
31
+ convert.units('PixelsPerInch')
32
+ convert << page.path
33
+ convert.quality('80')
34
+ convert.colorspace('sRGB')
35
+ convert.interlace('none')
40
36
  convert.flatten
41
37
  convert << page_file_name
42
38
  end
43
39
  pages.push(page_file_name)
44
40
  end
45
41
  GC.start
42
+
46
43
  pages
47
44
  end
48
45
  end
49
46
  end
50
- end
47
+ end
@@ -1,22 +1,18 @@
1
1
  require 'spec_helper'
2
2
 
3
- shared_examples "base properties" do
4
- it "has a description" do
5
- test_string = "test description"
3
+ shared_examples 'base properties' do
4
+ it 'has a description' do
5
+ test_string = 'test description'
6
6
  @object.description = test_string
7
7
  expect(@object.description).to eq test_string
8
8
  end
9
- it "has an @id" do
9
+ it 'has an @id' do
10
10
  expect(@object.id).not_to be_nil
11
11
  end
12
- it "has a valid @id" do
13
- expect(@object.id).to include IiifS3::Config::DEFAULT_URL
12
+ it 'has a valid @id' do
13
+ expect(@object.id).to include WaxIiif::Config::DEFAULT_URL
14
14
  end
15
- it "encodes @ids when set" do
16
- @object.id = "http://www.example.com/a space"
17
- expect(@object.id).to include "%20"
18
- end
19
- it "reveals the type" do
15
+ it 'reveals the type' do
20
16
  expect(@object.type).to eq described_class::TYPE
21
17
  end
22
- end
18
+ end
@@ -4,112 +4,48 @@ RSpec.shared_context "fake variants" do
4
4
  "full" => OpenStruct.new(:id => "http://www.example.com/images/1", :width => 1000, :height => 1200),
5
5
  "thumbnail" => OpenStruct.new(:id => "http://www.example.com/images/1", :width => 100, :height => 120)
6
6
  }
7
- @fake_image_info = '{
8
- "@context": "http://iiif.io/api/image/2/context.json",
9
- "@id": "http://www.example.com/test/1",
10
- "protocol": "http://iiif.io/api/image",
11
- "width": 1000,
12
- "height": 1200,
13
- "sizes": [
14
- {
15
- "width": 1000,
16
- "height": 1200
17
- },
18
- {
19
- "width": 100,
20
- "height": 120
21
- }
22
- ],
23
- "profile": [
24
- "http://iiif.io/api/image/2/level0.json",
25
- {
26
- "supports": [
27
- "cors",
28
- "sizeByWhListed",
29
- "baseUriRedirect"
30
- ]
31
- }
32
- ]
33
- }'
7
+ @fake_image_info = '{"@context":"http://iiif.io/api/image/2/context.json","@id":"http://www.example.com/test/1","protocol":"http://iiif.io/api/image","width":1000,"height":1200,"sizes":[{"width":1000,"height":1200},{"width":100,"height":120}],"profile":["http://iiif.io/api/image/2/level0.json",{"supports":["cors","sizeByWhListed","baseUriRedirect"]}]}'
34
8
  end
35
9
  end
36
10
 
37
11
  RSpec.shared_context "fake data" do
38
12
  include_context("fake variants")
39
13
  before(:example) do
40
-
41
- @fake_collection = '{
42
- "@context": "http://iiif.io/api/presentation/2/context.json",
43
- "@id": "http://0.0.0.0/collection/name.json",
44
- "@type": "sc:Collection",
45
- "label": "Test Data",
46
- "manifests": [
47
- {
48
- "@id": "http://0.0.0.0/1/manifest.json",
49
- "@type": "sc:Manifest",
50
- "label": "test label"
51
- }
52
- ]
53
- }'
54
14
 
55
- @fake_data = ImageRecord.new({
15
+ @fake_collection = '{"@context":"http://iiif.io/api/presentation/2/context.json","@id":"http://0.0.0.0/collection/test.json","@type":"sc:Collection","label":"test","manifests":[{"@id":"http://0.0.0.0/1/manifest.json","@type":"sc:Manifest","label":"testlabel"}]}'
16
+
17
+ @fake_data = [ WaxIiif::ImageRecord.new({
18
+ "manifest_id" => 1,
56
19
  "id" => 1,
57
- "page_number" => "1",
58
20
  "image_path" => "./spec/data/test.jpg",
59
21
  "is_primary" => true,
60
22
  "variants" => @fake_variants,
61
23
  "label" => "test label",
62
24
  "attribution" => "All rights reserved",
63
25
  "logo" => "http://www.example.com/logo.jpg"
64
- })
65
- @fake_manifest = '{
66
- "@context": "http://iiif.io/api/presentation/2/context.json",
67
- "@id": "http://0.0.0.0/1/manifest.json",
68
- "@type": "sc:Manifest",
69
- "label": "test label",
70
- "attribution": "All rights reserved",
71
- "logo": "http://www.example.com/logo.jpg",
72
- "thumbnail": "http://www.example.com/images/1/full/100,/0/default.jpg",
73
- "viewingDirection": "left-to-right",
74
- "viewingHint": "individuals",
75
- "sequences": [
76
- {
77
- "@id": "http://0.0.0.0/1/sequence/default.json",
78
- "@type": "sc:Sequence",
79
- "canvases": [
80
- {
81
- "@type": "sc:Canvas",
82
- "@id": "http://0.0.0.0/1/canvas/front.json",
83
- "label": "front",
84
- "width": 2000,
85
- "height": 2400,
86
- "thumbnail": "http://www.example.com/images/1/full/100,/0/default.jpg",
87
- "images": [
88
- {
89
- "@type": "oa:Annotation",
90
- "@id": "http://0.0.0.0/1/annotation/front.json",
91
- "motivation": "sc:painting",
92
- "resource": {
93
- "@id": "http://www.example.com/images/1/full/full/0/default.jpg",
94
- "@type": "dcterms:Image",
95
- "format": "image/jpeg",
96
- "service": {
97
- "@context": "http://iiif.io/api/image/2/context.json",
98
- "@id": "http://www.example.com/images/1",
99
- "profile": "http://iiif.io/api/image/2/level0.json"
100
- },
101
- "width": 1000,
102
- "height": 1200
103
- },
104
- "on": "http://0.0.0.0/1/canvas/front.json"
105
- }
106
- ]
107
- }
108
- ]
109
- }
110
- ]
111
- }'
26
+ }),
27
+ WaxIiif::ImageRecord.new({
28
+ "manifest_id" => 1,
29
+ "id" => 2,
30
+ "image_path" => "./spec/data/test.jpg",
31
+ "is_primary" => false,
32
+ "variants" => @fake_variants,
33
+ "label" => "test label",
34
+ "attribution" => "All rights reserved",
35
+ "logo" => "http://www.example.com/logo.jpg"
36
+ }),
37
+ WaxIiif::ImageRecord.new({
38
+ "id" => 3,
39
+ "image_path" => "./spec/data/test.jpg",
40
+ "is_primary" => true,
41
+ "variants" => @fake_variants,
42
+ "label" => "test label",
43
+ "attribution" => "All rights reserved",
44
+ "logo" => "http://www.example.com/logo.jpg"
45
+ })]
112
46
 
47
+ @fake_manifest_1 = '{"@context":"http://iiif.io/api/presentation/2/context.json","@id":"http://0.0.0.0/1/manifest.json","@type":"sc:Manifest","label":"testlabel","attribution":"Allrightsreserved","logo":"http://www.example.com/logo.jpg","thumbnail":"http://www.example.com/images/1/full/100,/0/default.jpg","viewingDirection":"left-to-right","viewingHint":"individuals","sequences":[{"@id":"http://0.0.0.0/sequence/1.json","@type":"sc:Sequence","canvases":[{"@type":"sc:Canvas","@id":"http://0.0.0.0/canvas/1.json","label":"front","width":2000,"height":2400,"thumbnail":"http://www.example.com/images/1/full/100,/0/default.jpg","images":[{"@type":"oa:Annotation","@id":"http://0.0.0.0/annotation/1.json","motivation":"sc:painting","resource":{"@id":"http://www.example.com/images/1/full/full/0/default.jpg","@type":"dcterms:Image","format":"image/jpeg","service":{"@context":"http://iiif.io/api/image/2/context.json","@id":"http://www.example.com/images/1","profile":"http://iiif.io/api/image/2/level0.json"},"width":1000,"height":1200},"on":"http://0.0.0.0/canvas/1.json"}]},{"@type":"sc:Canvas","@id":"http://0.0.0.0/canvas/2.json","label":"front","width":2000,"height":2400,"thumbnail":"http://www.example.com/images/1/full/100,/0/default.jpg","images":[{"@type":"oa:Annotation","@id":"http://0.0.0.0/annotation/2.json","motivation":"sc:painting","resource":{"@id":"http://www.example.com/images/1/full/full/0/default.jpg","@type":"dcterms:Image","format":"image/jpeg","service":{"@context":"http://iiif.io/api/image/2/context.json","@id":"http://www.example.com/images/1","profile":"http://iiif.io/api/image/2/level0.json"},"width":1000,"height":1200},"on":"http://0.0.0.0/canvas/2.json"}]}]}]}'
113
48
 
49
+ @fake_manifest_3 = '{"@context":"http://iiif.io/api/presentation/2/context.json","@id":"http://0.0.0.0/3/manifest.json","@type":"sc:Manifest","label":"testlabel","attribution":"Allrightsreserved","logo":"http://www.example.com/logo.jpg","thumbnail":"http://www.example.com/images/1/full/100,/0/default.jpg","viewingDirection":"left-to-right","viewingHint":"individuals","sequences":[{"@id":"http://0.0.0.0/sequence/3.json","@type":"sc:Sequence","canvases":[{"@type":"sc:Canvas","@id":"http://0.0.0.0/canvas/3.json","label":"front","width":2000,"height":2400,"thumbnail":"http://www.example.com/images/1/full/100,/0/default.jpg","images":[{"@type":"oa:Annotation","@id":"http://0.0.0.0/annotation/3.json","motivation":"sc:painting","resource":{"@id":"http://www.example.com/images/1/full/full/0/default.jpg","@type":"dcterms:Image","format":"image/jpeg","service":{"@context":"http://iiif.io/api/image/2/context.json","@id":"http://www.example.com/images/1","profile":"http://iiif.io/api/image/2/level0.json"},"width":1000,"height":1200},"on":"http://0.0.0.0/canvas/3.json"}]}]}]}'
114
50
  end
115
- end
51
+ end
@@ -5,8 +5,8 @@ Dotenv.load
5
5
  require 'simplecov'
6
6
  SimpleCov.start
7
7
 
8
- require "shared_contexts"
8
+ require 'shared_contexts'
9
9
  require 'wax_iiif'
10
10
 
11
- ENV["TEST_INTERNET_CONNECTIVITY"] ||= nil
12
- ENV["SKIP_EXPENSIVE_TESTS"] ||= nil
11
+ ENV['TEST_INTERNET_CONNECTIVITY'] ||= nil
12
+ ENV['SKIP_EXPENSIVE_TESTS'] ||= nil
@@ -0,0 +1,143 @@
1
+ require 'spec_helper'
2
+ require 'ostruct'
3
+ require 'fileutils'
4
+
5
+ describe WaxIiif::Builder do
6
+ let (:iiif) { WaxIiif::Builder.new() }
7
+ let (:test_object_0) { WaxIiif::ImageRecord.new({'id' => 'img1' }) }
8
+ let (:test_object_1) { WaxIiif::ImageRecord.new({'id' => 'img2', 'manifest_id' => 'm1'}) }
9
+ let (:test_object_2) { WaxIiif::ImageRecord.new({'id' => 'img3', 'manifest_id' => 'm1' }) }
10
+ let (:test_object_2) { WaxIiif::ImageRecord.new({'id' => 'img4', 'manifest_id' => 'm2' }) }
11
+ let (:data) {[test_object_0, test_object_1,test_object_2]}
12
+
13
+ context 'When initializing' do
14
+ it 'generates manifests' do
15
+ expect(iiif.manifests).to eq(Array.new)
16
+ end
17
+ it 'uses the default config' do
18
+ expect(iiif.config).to eq(WaxIiif::Config.new)
19
+ end
20
+ it 'will accept a configuration hash' do
21
+ opts = {tile_width: 99}
22
+ iiif2 = WaxIiif::Builder.new(opts)
23
+ expect(iiif2.config.tile_width).to eq(99)
24
+ end
25
+ end
26
+
27
+ context 'loading data' do
28
+ it 'will accept an array of objects' do
29
+ iiif.load(data)
30
+ expect(iiif.data).to eq(data)
31
+ end
32
+ it 'will accept a single object' do
33
+ iiif.load(test_object_1)
34
+ expect(iiif.data).to eq([test_object_1])
35
+ end
36
+
37
+ it 'will error if the data is bad' do
38
+ expect{iiif.load({random: 'hash'})}.to raise_error(WaxIiif::Error::InvalidImageData)
39
+ expect{iiif.load([{random: 'hash'}])}.to raise_error(WaxIiif::Error::InvalidImageData)
40
+ end
41
+ end
42
+
43
+ context 'when processing data' do
44
+ include_context('fake variants')
45
+ include_context('fake data')
46
+
47
+ before(:example) do
48
+ @iiif = WaxIiif::Builder.new({base_url: 'http://0.0.0.0', verbose: true, thumbnail_size: 120})
49
+ @iiif.load(@fake_data)
50
+ allow(@iiif).to receive(:generate_tiles) {nil}
51
+ allow(@iiif).to receive(:generate_variants) {@fake_variants}
52
+ end
53
+ it 'does not fail with no data' do
54
+ expect {iiif.process_data}.not_to raise_error
55
+ end
56
+
57
+ it 'does not fail with real data' do
58
+ expect {@iiif.process_data}.not_to raise_error
59
+ end
60
+
61
+ it ' passes the Temporary Manifest Check' do
62
+ @iiif.process_data
63
+ expect(@iiif.manifests.count).to eq 2
64
+ expect(@iiif.manifests.first.to_json.delete(" \t\r\n")).to eq @fake_manifest_1
65
+ expect(@iiif.manifests.last.to_json.delete(" \t\r\n")).to eq @fake_manifest_3
66
+ end
67
+ end
68
+
69
+
70
+ context 'when dealing with already loaded data' do
71
+ include_context('fake data')
72
+ include_context('fake variants')
73
+
74
+ before(:example) do
75
+ @dir = Dir.mktmpdir
76
+ @iiif = WaxIiif::Builder.new({output_dir: @dir, base_url: 'http://0.0.0.0', verbose: true, thumbnail_size: 120})
77
+ @iiif.load(@fake_data)
78
+ @info_json = "#{@dir}/images/1/info.json"
79
+ allow(@iiif).to receive(:generate_tiles) {nil}
80
+ allow(@iiif).to receive(:generate_variants) {@fake_variants}
81
+ @iiif.process_data
82
+ end
83
+
84
+ after(:example) do
85
+ FileUtils.remove_entry @dir
86
+ end
87
+
88
+ it 'has the temporary file' do
89
+ expect(File.exist?(@info_json)).to eq true
90
+ end
91
+
92
+ it 'does try to generate images if that file is missing' do
93
+ File.delete(@info_json)
94
+ @iiif.process_data
95
+ expect(@iiif).to have_received(:generate_tiles).exactly(4).times
96
+ expect(@iiif).to have_received(:generate_variants).exactly(4).times
97
+ end
98
+
99
+ it 'does not try to generate images if that file is present' do
100
+ @iiif.process_data
101
+ expect(@iiif).to have_received(:generate_tiles).exactly(3).times
102
+ expect(@iiif).to have_received(:generate_variants).exactly(3).times
103
+ end
104
+
105
+ it 'generates the correct manifest anyway' do
106
+ @iiif.process_data
107
+ expect(@iiif.manifests.count).to eq 2
108
+ expect(@iiif.manifests.first.to_json.delete(" \t\r\n")).to eq @fake_manifest_1
109
+ end
110
+
111
+ end
112
+
113
+ context 'When load_csving CSV files' do
114
+ it 'accepts a path' do
115
+ expect{iiif.load_csv('./spec/data/test.csv')}.not_to raise_error()
116
+ end
117
+ it 'fails on blank CSV files' do
118
+ expect{iiif.load_csv('./spec/data/blank.csv')}.to raise_error(WaxIiif::Error::BlankCSV)
119
+ end
120
+ it 'fails on invalid CSV files' do
121
+ expect{iiif.load_csv('./spec/data/invalid.csv')}.to raise_error(WaxIiif::Error::InvalidCSV)
122
+ end
123
+ it 'fails on missing CSV files' do
124
+ expect{iiif.load_csv('./spec/data/i_dont_exist.csv')}.to raise_error(WaxIiif::Error::InvalidCSV)
125
+ end
126
+ end
127
+
128
+ context 'When loading a CSV file' do
129
+ it 'saves the data into the @data param' do
130
+ expect(iiif.data).to be_nil
131
+ iiif.load_csv('./spec/data/test.csv')
132
+ expect(iiif.data).not_to be_nil
133
+ end
134
+ it 'removes headers' do
135
+ iiif.load_csv('./spec/data/test.csv')
136
+ expect(iiif.data[0]['image_path']).to eq('spec/data/test.jpg')
137
+ end
138
+ it "doesn't remove headers if not present" do
139
+ iiif.load_csv('./spec/data/no_header.csv')
140
+ expect(iiif.data[0]['image_path']).to eq('spec/data/test.jpg')
141
+ end
142
+ end
143
+ end
@@ -0,0 +1,53 @@
1
+ require 'spec_helper'
2
+ require 'base_properties_spec'
3
+
4
+ describe WaxIiif::Collection do
5
+ let (:labeled_config) { WaxIiif::Config.new(collection_label: 'test') }
6
+ let (:config) { WaxIiif::Config.new }
7
+ context 'base' do
8
+ before(:each) do
9
+ @object = WaxIiif::Collection.new(labeled_config)
10
+ @labeled_object = WaxIiif::Collection.new(config)
11
+ end
12
+ it_behaves_like 'base properties'
13
+ end
14
+
15
+ context 'initialization' do
16
+ it 'initializes without issues when given a label' do
17
+ collection = nil
18
+ expect{ collection = WaxIiif::Collection.new(labeled_config) }.not_to raise_error
19
+ expect(collection.id).to eq('http://0.0.0.0/collection/test.json')
20
+ end
21
+ it 'initializes with default label when none is specified' do
22
+ collection = WaxIiif::Collection.new(config)
23
+ expect(collection.id).to include 'top.json'
24
+ end
25
+ end
26
+ context 'data init' do
27
+ include_context('fake data')
28
+ let(:collection) { WaxIiif::Collection.new(labeled_config) }
29
+ let(:manifest) { WaxIiif::Manifest.new(@fake_data[0,2], config) }
30
+ it 'has a label' do
31
+ expect(collection.label).to eq 'test'
32
+ end
33
+ it 'has an id' do
34
+ expect(collection.id).to eq 'http://0.0.0.0/collection/test.json'
35
+ end
36
+
37
+ it 'allows you to add a collection' do
38
+ newCollection = collection.clone
39
+ expect{ collection.add_collection(newCollection) }.not_to raise_error
40
+ end
41
+
42
+ it 'fails if you add something else to a collection' do
43
+ newCollection = {}
44
+ expect{ collection.add_collection(newCollection) }.to raise_error(WaxIiif::Error::NotACollection)
45
+ end
46
+
47
+
48
+ it 'generates correct JSON' do
49
+ collection.add_manifest(manifest)
50
+ expect(collection.to_json.delete(" \t\r\n")).to eq @fake_collection
51
+ end
52
+ end
53
+ end