metal_archives 0.8.0 → 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 +4 -4
- data/.gitignore +59 -7
- data/.rspec +1 -0
- data/.rubocop.yml +14 -0
- data/.travis.yml +11 -0
- data/Gemfile +2 -0
- data/{LICENSE → LICENSE.md} +0 -0
- data/README.md +77 -9
- data/Rakefile +5 -3
- data/lib/metal_archives.rb +8 -0
- data/lib/metal_archives/configuration.rb +28 -7
- data/lib/metal_archives/error.rb +37 -30
- data/lib/metal_archives/http_client.rb +21 -42
- data/lib/metal_archives/middleware/headers.rb +38 -0
- data/lib/metal_archives/middleware/rewrite_endpoint.rb +38 -0
- data/lib/metal_archives/models/artist.rb +51 -65
- data/lib/metal_archives/models/band.rb +41 -39
- data/lib/metal_archives/models/base_model.rb +88 -59
- data/lib/metal_archives/models/label.rb +7 -6
- data/lib/metal_archives/parsers/artist.rb +110 -99
- data/lib/metal_archives/parsers/band.rb +168 -156
- data/lib/metal_archives/parsers/label.rb +54 -52
- data/lib/metal_archives/parsers/parser.rb +73 -71
- data/lib/metal_archives/utils/collection.rb +7 -1
- data/lib/metal_archives/utils/lru_cache.rb +11 -4
- data/lib/metal_archives/utils/nil_date.rb +54 -0
- data/lib/metal_archives/utils/range.rb +16 -8
- data/lib/metal_archives/version.rb +3 -1
- data/metal_archives.gemspec +21 -11
- data/spec/configuration_spec.rb +101 -0
- data/spec/factories/artist_factory.rb +37 -0
- data/spec/factories/band_factory.rb +60 -0
- data/spec/factories/nil_date_factory.rb +9 -0
- data/spec/factories/range_factory.rb +8 -0
- data/spec/models/artist_spec.rb +142 -0
- data/spec/models/band_spec.rb +179 -0
- data/spec/models/base_model_spec.rb +217 -0
- data/spec/parser_spec.rb +19 -0
- data/spec/spec_helper.rb +111 -0
- data/spec/support/factory_girl.rb +5 -0
- data/spec/support/metal_archives.rb +26 -0
- data/spec/utils/collection_spec.rb +72 -0
- data/spec/utils/lru_cache_spec.rb +53 -0
- data/spec/utils/nil_date_spec.rb +98 -0
- data/spec/utils/range_spec.rb +62 -0
- metadata +142 -57
- data/test/base_model_test.rb +0 -111
- data/test/configuration_test.rb +0 -57
- data/test/parser_test.rb +0 -37
- data/test/property/artist_property_test.rb +0 -43
- data/test/property/band_property_test.rb +0 -94
- data/test/query/artist_query_test.rb +0 -109
- data/test/query/band_query_test.rb +0 -152
- data/test/test_helper.rb +0 -25
- data/test/utils/collection_test.rb +0 -51
- data/test/utils/lru_cache_test.rb +0 -22
- data/test/utils/range_test.rb +0 -42
@@ -0,0 +1,37 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
FactoryGirl.define do
|
4
|
+
factory :artist, :class => MetalArchives::Artist do
|
5
|
+
id { Faker::Number.number [1, 2, 3, 4].sample }
|
6
|
+
name { Faker::Name.name }
|
7
|
+
gender { %i[male female].sample }
|
8
|
+
biography { Faker::Lorem.words(200).join ' ' }
|
9
|
+
trivia { Faker::Lorem.words(200).join ' ' }
|
10
|
+
|
11
|
+
country { ISO3166::Country[Faker::Address.country_code] }
|
12
|
+
location { Faker::Address.city }
|
13
|
+
|
14
|
+
date_of_birth { Faker::Date.birthday 18, 65 }
|
15
|
+
|
16
|
+
links do
|
17
|
+
3.times.collect do
|
18
|
+
{
|
19
|
+
:url => Faker::Internet.url,
|
20
|
+
:type => %i[official unofficial unlisted_bands].sample,
|
21
|
+
:title => Faker::Lorem.words(4).join(' ')
|
22
|
+
}
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
trait :has_died do
|
27
|
+
date_of_death { Faker::Date.between date_of_birth, Date.today }
|
28
|
+
cause_of_death { %w(Suicide N/A Accident Cancer Illness Murder).sample }
|
29
|
+
end
|
30
|
+
|
31
|
+
trait :with_aliases do
|
32
|
+
aliases do
|
33
|
+
3.times.collect { Faker::Name.name }
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
FactoryGirl.define do
|
4
|
+
factory :band, :class => MetalArchives::Band do
|
5
|
+
id { Faker::Number.number [1, 2, 3, 4].sample }
|
6
|
+
name { Faker::Name.name }
|
7
|
+
status { %i[active split_up on_hold unknown changed_name disputed].sample }
|
8
|
+
|
9
|
+
comment { Faker::Lorem.words(200).join ' ' }
|
10
|
+
|
11
|
+
country { ISO3166::Country[Faker::Address.country_code] }
|
12
|
+
location { Faker::Address.city }
|
13
|
+
|
14
|
+
date_formed { Faker::Date.birthday 0, 50 }
|
15
|
+
date_active { build_list :range }
|
16
|
+
|
17
|
+
label { [build(:label), nil].sample }
|
18
|
+
independent { label.nil? }
|
19
|
+
|
20
|
+
logo { Faker::Internet.url }
|
21
|
+
photo { Faker::Internet.url }
|
22
|
+
|
23
|
+
genres do
|
24
|
+
3.times.collect do
|
25
|
+
"#{%w(Black Death Doom Power Progressive Speed Thrash).sample} Metal"
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
lyrical_themes do
|
30
|
+
3.times.collect do
|
31
|
+
['Fantasy', 'Epic battles', 'Tales', 'Myths', 'Legends', 'Feelings', 'Life', 'Eden', 'Glory', 'the Four Elements', 'Metal'].sample
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
similar do
|
36
|
+
4.times.collect do
|
37
|
+
{
|
38
|
+
:band => build(:band),
|
39
|
+
:score => Faker::Number.between(1, 100)
|
40
|
+
}
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
links do
|
45
|
+
3.times.collect do
|
46
|
+
{
|
47
|
+
:url => Faker::Internet.url,
|
48
|
+
:type => %i[official unofficial unlisted_bands].sample,
|
49
|
+
:title => Faker::Lorem.words(4).join(' ')
|
50
|
+
}
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
trait :with_aliases do
|
55
|
+
aliases do
|
56
|
+
3.times.collect { Faker::Name.name }
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
@@ -0,0 +1,142 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
RSpec.describe MetalArchives::Artist do
|
4
|
+
describe 'properties' do
|
5
|
+
it 'Alberto Rionda has properties' do
|
6
|
+
artist = MetalArchives::Artist.find 60908
|
7
|
+
|
8
|
+
expect(artist).to be_instance_of MetalArchives::Artist
|
9
|
+
expect(artist.id).to eq 60908
|
10
|
+
expect(artist.name).to eq 'Alberto Rionda'
|
11
|
+
expect(artist.aliases).to be_empty
|
12
|
+
expect(artist.country).to eq ISO3166::Country['ES']
|
13
|
+
expect(artist.location).to eq 'Oviedo, Asturias'
|
14
|
+
expect(artist.date_of_birth).to eq Date.new(1972, 9, 2)
|
15
|
+
expect(artist.gender).to eq :male
|
16
|
+
expect(artist.biography).to match 'Avalanch'
|
17
|
+
expect(artist.trivia).to match 'Sanctuarium Estudios'
|
18
|
+
expect(artist.photo).to be_instance_of URI::HTTPS
|
19
|
+
expect(artist.photo.path).to eq '/images/6/0/9/0/60908_artist.jpg'
|
20
|
+
end
|
21
|
+
|
22
|
+
it 'Lemmy Kilmister has properties' do
|
23
|
+
artist = MetalArchives::Artist.find 260
|
24
|
+
|
25
|
+
expect(artist).to be_instance_of MetalArchives::Artist
|
26
|
+
expect(artist.name).to eq 'Ian Fraser Kilmister'
|
27
|
+
expect(artist.aliases).to include 'Lemmy Kilmister'
|
28
|
+
expect(artist.date_of_death).to eq Date.new(2015, 12, 28)
|
29
|
+
expect(artist.links.length).to eq 5
|
30
|
+
expect(artist.links.count { |l| l[:type] == :official }).to eq 1
|
31
|
+
expect(artist.links.count { |l| l[:type] == :unofficial }).to eq 2
|
32
|
+
expect(artist.links.count { |l| l[:type] == :unlisted_bands }).to eq 2
|
33
|
+
expect(artist.links.select { |l| l[:type] == :official }.first[:url]).to eq 'https://www.facebook.com/OfficialLemmy'
|
34
|
+
expect(artist.links.select { |l| l[:type] == :official }.first[:title]).to eq 'Facebook'
|
35
|
+
end
|
36
|
+
|
37
|
+
it 'maps query parameters' do
|
38
|
+
expect(MetalArchives::Parsers::Artist.map_params(:name => 'name')[:query]).to eq 'name'
|
39
|
+
end
|
40
|
+
|
41
|
+
it 'rewrites URIs' do
|
42
|
+
old_endpoint = MetalArchives.config.endpoint
|
43
|
+
MetalArchives.config.endpoint = 'https://foo.bar/'
|
44
|
+
|
45
|
+
artist = MetalArchives::Artist.find! 60908
|
46
|
+
|
47
|
+
expect(artist.photo.scheme).to eq 'https'
|
48
|
+
expect(artist.photo.host).to eq 'foo.bar'
|
49
|
+
|
50
|
+
MetalArchives.config.endpoint = old_endpoint
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
describe 'methods' do
|
55
|
+
describe 'find' do
|
56
|
+
it 'finds an artist' do
|
57
|
+
artist = MetalArchives::Artist.find 60908
|
58
|
+
|
59
|
+
expect(artist).to be_instance_of MetalArchives::Artist
|
60
|
+
expect(artist.name).to eq 'Alberto Rionda'
|
61
|
+
end
|
62
|
+
|
63
|
+
it 'lazily loads' do
|
64
|
+
artist = MetalArchives::Artist.find -1
|
65
|
+
|
66
|
+
expect(artist).to be_instance_of MetalArchives::Artist
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
describe 'find!' do
|
71
|
+
it 'finds an artist' do
|
72
|
+
artist = MetalArchives::Artist.find! 60908
|
73
|
+
|
74
|
+
expect(artist).to be_instance_of MetalArchives::Artist
|
75
|
+
expect(artist.name).to eq 'Alberto Rionda'
|
76
|
+
end
|
77
|
+
|
78
|
+
it 'raises on invalid id' do
|
79
|
+
expect(-> { MetalArchives::Artist.find! -1 }).to raise_error MetalArchives::Errors::APIError
|
80
|
+
expect(-> { MetalArchives::Artist.find! 0 }).to raise_error MetalArchives::Errors::InvalidIDError
|
81
|
+
expect(-> { MetalArchives::Artist.find! nil }).to raise_error MetalArchives::Errors::InvalidIDError
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
describe 'find_by' do
|
86
|
+
it 'finds an artist' do
|
87
|
+
artist = MetalArchives::Artist.find_by :name => 'Alberto Rionda'
|
88
|
+
|
89
|
+
expect(artist).to be_instance_of MetalArchives::Artist
|
90
|
+
expect(artist.id).to eq 60908
|
91
|
+
end
|
92
|
+
|
93
|
+
it 'returns nil on invalid id' do
|
94
|
+
artist = MetalArchives::Artist.find_by :name => 'SomeNonExistantName'
|
95
|
+
|
96
|
+
expect(artist).to be_nil
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
describe 'find_by!' do
|
101
|
+
it 'finds an artist' do
|
102
|
+
artist = MetalArchives::Artist.find_by! :name => 'Alberto Rionda'
|
103
|
+
|
104
|
+
expect(artist).to be_instance_of MetalArchives::Artist
|
105
|
+
expect(artist.id).to eq 60908
|
106
|
+
end
|
107
|
+
|
108
|
+
it 'returns nil on invalid id' do
|
109
|
+
artist = MetalArchives::Artist.find_by! :name => 'SomeNonExistantName'
|
110
|
+
|
111
|
+
expect(artist).to be_nil
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
describe 'search' do
|
116
|
+
it 'returns a collection' do
|
117
|
+
collection = MetalArchives::Artist.search 'Alberto Rionda'
|
118
|
+
|
119
|
+
expect(collection).to be_instance_of MetalArchives::Collection
|
120
|
+
expect(collection.first).to be_instance_of MetalArchives::Artist
|
121
|
+
end
|
122
|
+
|
123
|
+
it 'returns a collection' do
|
124
|
+
expect(MetalArchives::Artist.search('Alberto Rionda').count).to eq 1
|
125
|
+
expect(MetalArchives::Artist.search('Name').count).to eq 10
|
126
|
+
expect(MetalArchives::Artist.search('SomeNonExistantName').count).to eq 0
|
127
|
+
expect(MetalArchives::Artist.search 'SomeNonExistantName').to be_empty
|
128
|
+
expect(MetalArchives::Artist.search('Filip').count).to be > 200
|
129
|
+
end
|
130
|
+
|
131
|
+
it 'returns an empty collection' do
|
132
|
+
expect(MetalArchives::Artist.search 'SomeNoneExistantName').to be_empty
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
136
|
+
describe 'all' do
|
137
|
+
it 'returns a collection' do
|
138
|
+
expect(MetalArchives::Artist.all).to be_instance_of MetalArchives::Collection
|
139
|
+
end
|
140
|
+
end
|
141
|
+
end
|
142
|
+
end
|
@@ -0,0 +1,179 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
RSpec.describe MetalArchives::Band do
|
4
|
+
describe 'properties' do
|
5
|
+
it 'Pathfinder has properties' do
|
6
|
+
band = MetalArchives::Band.find 122302
|
7
|
+
|
8
|
+
expect(band).to be_instance_of MetalArchives::Band
|
9
|
+
expect(band.name).to eq 'Pathfinder'
|
10
|
+
expect(band.aliases).to be_empty
|
11
|
+
expect(band.country).to eq ISO3166::Country['PL']
|
12
|
+
expect(band.location).to eq 'Poznań'
|
13
|
+
expect(band.date_formed).to eq Date.new(2006)
|
14
|
+
expect(band.date_active).to eq [MetalArchives::Range.new(Date.new(2006), nil)]
|
15
|
+
expect(band.status).to eq :active
|
16
|
+
expect(band.genres).to eq ['Symphonic Power']
|
17
|
+
expect(band.lyrical_themes.sort).to eq ['Fantasy', 'Battles', 'Glory', 'The Four Elements', 'Metal'].sort
|
18
|
+
expect(band.comment).to match 'Pathfinder was founded by'
|
19
|
+
expect(band.logo).to be_instance_of URI::HTTPS
|
20
|
+
expect(band.logo.path).to eq '/images/1/2/2/3/122302_logo.jpg'
|
21
|
+
expect(band.photo).to be_instance_of URI::HTTPS
|
22
|
+
expect(band.photo.path).to eq '/images/1/2/2/3/122302_photo.jpg'
|
23
|
+
expect(band.independent).not_to be true
|
24
|
+
expect(band.similar.length).to eq 19
|
25
|
+
expect(band.links.length).to eq 15
|
26
|
+
expect(band.links.count { |l| l[:type] == :official }).to eq 12
|
27
|
+
expect(band.links.count { |l| l[:type] == :merchandise }).to eq 3
|
28
|
+
expect(band.links.select { |l| l[:type] == :merchandise }.first[:url]).to eq 'http://www.amazon.com/Fifth-Element-Pathfinder/dp/B007MNNCVW'
|
29
|
+
expect(band.links.select { |l| l[:type] == :merchandise }.first[:title]).to eq 'Amazon'
|
30
|
+
end
|
31
|
+
|
32
|
+
it 'Lemmy Kilmister has properties' do
|
33
|
+
band = MetalArchives::Band.find 32
|
34
|
+
|
35
|
+
expect(band).to be_instance_of MetalArchives::Band
|
36
|
+
expect(band.name).to eq 'Rhapsody of Fire'
|
37
|
+
expect(band.aliases).to match %w(Thundercross Rhapsody)
|
38
|
+
end
|
39
|
+
|
40
|
+
it 'maps status' do
|
41
|
+
expect(MetalArchives::Parsers::Band.send(:map_status, nil)).to eq ''
|
42
|
+
expect(MetalArchives::Parsers::Band.send(:map_status, :active)).to eq 'Active'
|
43
|
+
expect(MetalArchives::Parsers::Band.send(:map_status, :split_up)).to eq 'Split-up'
|
44
|
+
expect(MetalArchives::Parsers::Band.send(:map_status, :on_hold)).to eq 'On hold'
|
45
|
+
expect(MetalArchives::Parsers::Band.send(:map_status, :unknown)).to eq 'Unknown'
|
46
|
+
expect(MetalArchives::Parsers::Band.send(:map_status, :changed_name)).to eq 'Changed name'
|
47
|
+
expect(MetalArchives::Parsers::Band.send(:map_status, :disputed)).to eq 'Disputed'
|
48
|
+
|
49
|
+
expect(-> { MetalArchives::Parsers::Band.send(:map_status, :invalid_status) }).to raise_error MetalArchives::Errors::ParserError
|
50
|
+
end
|
51
|
+
|
52
|
+
it 'rewrites URIs' do
|
53
|
+
old_endpoint = MetalArchives.config.endpoint
|
54
|
+
MetalArchives.config.endpoint = 'https://foo.bar/'
|
55
|
+
|
56
|
+
band = MetalArchives::Band.find! 122302
|
57
|
+
|
58
|
+
expect(band.logo.scheme).to eq 'https'
|
59
|
+
expect(band.logo.host).to eq 'foo.bar'
|
60
|
+
|
61
|
+
expect(band.logo.scheme).to eq 'https'
|
62
|
+
expect(band.photo.host).to eq 'foo.bar'
|
63
|
+
|
64
|
+
MetalArchives.config.endpoint = old_endpoint
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
describe 'methods' do
|
69
|
+
describe 'find' do
|
70
|
+
it 'finds a band' do
|
71
|
+
band = MetalArchives::Band.find 3540361100
|
72
|
+
|
73
|
+
expect(band).not_to be_nil
|
74
|
+
expect(band).to be_instance_of MetalArchives::Band
|
75
|
+
expect(band.id).to eq 3540361100
|
76
|
+
expect(band.name).to eq 'Alquimia'
|
77
|
+
expect(band.country).to eq ISO3166::Country['ES']
|
78
|
+
|
79
|
+
expect(band.logo).to be_instance_of URI::HTTPS
|
80
|
+
expect(band.logo.path).to eq '/images/3/5/4/0/3540361100_logo.gif'
|
81
|
+
|
82
|
+
expect(band.photo).to be_instance_of URI::HTTPS
|
83
|
+
expect(band.photo.path).to eq '/images/3/5/4/0/3540361100_photo.jpg'
|
84
|
+
end
|
85
|
+
|
86
|
+
it 'lazily loads' do
|
87
|
+
band = MetalArchives::Band.find -1
|
88
|
+
|
89
|
+
expect(band).to be_instance_of MetalArchives::Band
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
describe 'find!' do
|
94
|
+
it 'finds a band' do
|
95
|
+
band = MetalArchives::Band.find! 3540361100
|
96
|
+
|
97
|
+
expect(band).to be_instance_of MetalArchives::Band
|
98
|
+
expect(band.name).to eq 'Alquimia'
|
99
|
+
end
|
100
|
+
|
101
|
+
it 'raises on invalid id' do
|
102
|
+
expect(-> { MetalArchives::Band.find! -1 }).to raise_error MetalArchives::Errors::APIError
|
103
|
+
expect(-> { MetalArchives::Band.find! 0 }).to raise_error MetalArchives::Errors::InvalidIDError
|
104
|
+
expect(-> { MetalArchives::Band.find! nil }).to raise_error MetalArchives::Errors::InvalidIDError
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
describe 'find_by' do
|
109
|
+
it 'finds a band' do
|
110
|
+
band = MetalArchives::Band.find_by :name => 'Falconer'
|
111
|
+
|
112
|
+
expect(band).to be_instance_of MetalArchives::Band
|
113
|
+
expect(band.id).to eq 74
|
114
|
+
end
|
115
|
+
|
116
|
+
it 'returns nil on invalid id' do
|
117
|
+
band = MetalArchives::Band.find_by :name => 'SomeNonExistantName'
|
118
|
+
|
119
|
+
expect(band).to be_nil
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
describe 'find_by!' do
|
124
|
+
it 'finds a band' do
|
125
|
+
band = MetalArchives::Band.find_by! :name => 'Falconer'
|
126
|
+
|
127
|
+
expect(band).to be_instance_of MetalArchives::Band
|
128
|
+
expect(band.id).to eq 74
|
129
|
+
end
|
130
|
+
|
131
|
+
it 'returns nil on invalid id' do
|
132
|
+
band = MetalArchives::Band.find_by! :name => 'SomeNonExistantName'
|
133
|
+
|
134
|
+
expect(band).to be_nil
|
135
|
+
end
|
136
|
+
end
|
137
|
+
|
138
|
+
describe 'search' do
|
139
|
+
it 'returns a collection' do
|
140
|
+
collection = MetalArchives::Band.search 'Alquimia'
|
141
|
+
|
142
|
+
expect(collection).to be_instance_of MetalArchives::Collection
|
143
|
+
expect(collection.first).to be_instance_of MetalArchives::Band
|
144
|
+
end
|
145
|
+
|
146
|
+
it 'returns an empty collection' do
|
147
|
+
expect(MetalArchives::Band.search 'SomeNoneExistantName').to be_empty
|
148
|
+
end
|
149
|
+
|
150
|
+
it 'searches by name' do
|
151
|
+
expect(MetalArchives::Band.search_by(:name => 'Alquimia').count).to eq 5
|
152
|
+
expect(MetalArchives::Band.search_by(:name => 'Lost Horizon').count).to eq 3
|
153
|
+
expect(MetalArchives::Band.search_by(:name => 'Lost Horizon', :exact => true).count).to eq 2
|
154
|
+
expect(MetalArchives::Band.search_by(:name => 'Alquimia', :genre => 'Melodic Power').count).to eq 2
|
155
|
+
end
|
156
|
+
|
157
|
+
it 'searches by year' do
|
158
|
+
expect(MetalArchives::Band.search_by(:name => 'Alquimia', :year => MetalArchives::Range.new(nil, nil)).count).to eq 5
|
159
|
+
expect(MetalArchives::Band.search_by(:name => 'Alquimia', :year => MetalArchives::Range.new(Date.new(2013), nil)).count).to eq 1
|
160
|
+
expect(MetalArchives::Band.search_by(:name => 'Alquimia', :year => MetalArchives::Range.new(Date.new(2008), Date.new(2008))).count).to eq 1
|
161
|
+
expect(MetalArchives::Band.search_by(:name => 'Alquimia', :year => MetalArchives::Range.new(Date.new(2008), Date.new(2013))).count).to eq 2
|
162
|
+
expect(MetalArchives::Band.search_by(:name => 'Alquimia', :year => MetalArchives::Range.new(nil, Date.new(2013))).count).to eq 5
|
163
|
+
end
|
164
|
+
|
165
|
+
it 'searches by country' do
|
166
|
+
expect(MetalArchives::Band.search_by(:name => 'Alquimia', :country => ISO3166::Country['ES']).count).to eq 1
|
167
|
+
expect(MetalArchives::Band.search_by(:name => 'Alquimia', :country => ISO3166::Country['AR']).count).to eq 3
|
168
|
+
expect(MetalArchives::Band.search_by(:name => 'Alquimia', :country => ISO3166::Country['AR']).count).to eq 3
|
169
|
+
expect(MetalArchives::Band.search_by(:name => 'Alquimia', :label => 'Mutus Liber').count).to eq 1
|
170
|
+
end
|
171
|
+
end
|
172
|
+
|
173
|
+
describe 'all' do
|
174
|
+
it 'returns a collection' do
|
175
|
+
expect(MetalArchives::Band.all).to be_instance_of MetalArchives::Collection
|
176
|
+
end
|
177
|
+
end
|
178
|
+
end
|
179
|
+
end
|
@@ -0,0 +1,217 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
|
4
|
+
##
|
5
|
+
# Sample model without :id property or :assemble method
|
6
|
+
#
|
7
|
+
class ModelOne < MetalArchives::BaseModel
|
8
|
+
property :property_one
|
9
|
+
end
|
10
|
+
|
11
|
+
##
|
12
|
+
# Sample model without :assemble method
|
13
|
+
#
|
14
|
+
class ModelTwo < MetalArchives::BaseModel
|
15
|
+
property :id
|
16
|
+
property :property_one
|
17
|
+
end
|
18
|
+
|
19
|
+
##
|
20
|
+
# Sample complete model
|
21
|
+
#
|
22
|
+
class ModelThree < MetalArchives::BaseModel
|
23
|
+
property :id
|
24
|
+
property :property_one
|
25
|
+
|
26
|
+
def assemble
|
27
|
+
{ :property_one => 'Property One' }
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
##
|
32
|
+
# Sample complete model
|
33
|
+
#
|
34
|
+
class ModelFour < MetalArchives::BaseModel
|
35
|
+
property :id
|
36
|
+
property :property_one
|
37
|
+
|
38
|
+
def assemble
|
39
|
+
{ :property_one => 'Property One' }
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
##
|
44
|
+
# Sample invalid model
|
45
|
+
#
|
46
|
+
class ModelFive < MetalArchives::BaseModel
|
47
|
+
property :id
|
48
|
+
property :property_one
|
49
|
+
|
50
|
+
def assemble
|
51
|
+
raise MetalArchives::Errors::APIError
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
RSpec.describe MetalArchives::BaseModel do
|
56
|
+
it 'requires an :id property' do
|
57
|
+
expect(-> { ModelOne.new(:property_one => 'foo') }).to raise_error MetalArchives::Errors::NotImplementedError
|
58
|
+
end
|
59
|
+
|
60
|
+
it 'requires an :assemble method' do
|
61
|
+
expect(-> { ModelTwo.new(:id => 'foo').property_one }).to raise_error MetalArchives::Errors::NotImplementedError
|
62
|
+
end
|
63
|
+
|
64
|
+
it 'defines methods' do
|
65
|
+
model = ModelTwo.new :id => 'foo'
|
66
|
+
|
67
|
+
expect(model).to respond_to :id
|
68
|
+
expect(model).to respond_to :id=
|
69
|
+
expect(model).to respond_to :id?
|
70
|
+
expect(model).to respond_to :property_one
|
71
|
+
expect(model).to respond_to :property_one=
|
72
|
+
expect(model).to respond_to :property_one?
|
73
|
+
expect(model).not_to respond_to :property_two
|
74
|
+
expect(model).not_to respond_to :property_two=
|
75
|
+
expect(model).not_to respond_to :property_two?
|
76
|
+
end
|
77
|
+
|
78
|
+
it 'returns properties' do
|
79
|
+
model = ModelThree.new :id => 'foo', :property_one => 'bar'
|
80
|
+
|
81
|
+
expect(model.id).to eq 'foo'
|
82
|
+
expect(model.property_one).to eq 'bar'
|
83
|
+
end
|
84
|
+
|
85
|
+
it 'sets properties' do
|
86
|
+
model = ModelThree.new :id => 'foo', :property_one => 'bar'
|
87
|
+
|
88
|
+
model.id = 'baz'
|
89
|
+
model.property_one = 'bat'
|
90
|
+
|
91
|
+
expect(model.id).to eq 'baz'
|
92
|
+
expect(model.property_one).to eq 'bat'
|
93
|
+
end
|
94
|
+
|
95
|
+
it 'checks properties' do
|
96
|
+
model = ModelThree.new :id => 'foo', :property_one => 'bar'
|
97
|
+
model2 = ModelThree.new :id => 'foo'
|
98
|
+
model2.load!
|
99
|
+
model2.property_one = nil
|
100
|
+
|
101
|
+
expect(model.id?).to be true
|
102
|
+
expect(model.property_one?).to be true
|
103
|
+
|
104
|
+
expect(model2.id?).to be true
|
105
|
+
expect(model2.property_one?).to be false
|
106
|
+
end
|
107
|
+
|
108
|
+
it 'calls assemble' do
|
109
|
+
model = ModelThree.new :id => 'foo'
|
110
|
+
|
111
|
+
expect(model.id).to eq 'foo'
|
112
|
+
expect(model.property_one).to eq 'Property One'
|
113
|
+
end
|
114
|
+
|
115
|
+
it 'lazily loads' do
|
116
|
+
model = ModelThree.new :id => 'foo'
|
117
|
+
|
118
|
+
expect(model).to be_instance_variable_defined '@id'
|
119
|
+
expect(model).not_to be_instance_variable_defined '@property_one'
|
120
|
+
|
121
|
+
model.property_one
|
122
|
+
|
123
|
+
expect(model).to be_instance_variable_defined '@id'
|
124
|
+
expect(model).to be_instance_variable_defined '@property_one'
|
125
|
+
expect(model.property_one).to eq 'Property One'
|
126
|
+
end
|
127
|
+
|
128
|
+
|
129
|
+
it 'implements the load! operation' do
|
130
|
+
model = ModelThree.new :id => 'foo'
|
131
|
+
|
132
|
+
expect(model).to be_instance_variable_defined '@id'
|
133
|
+
expect(model).not_to be_instance_variable_defined '@property_one'
|
134
|
+
|
135
|
+
model.load!
|
136
|
+
|
137
|
+
expect(model).to be_instance_variable_defined '@id'
|
138
|
+
expect(model).to be_instance_variable_defined '@property_one'
|
139
|
+
expect(model.property_one).to eq 'Property One'
|
140
|
+
end
|
141
|
+
|
142
|
+
it 'implements the equal operator' do
|
143
|
+
m1 = ModelThree.new :id => 'id_one'
|
144
|
+
m2 = ModelThree.new :id => 'id_one'
|
145
|
+
m3 = ModelThree.new :id => 'id_two'
|
146
|
+
m4 = ModelFour.new :id => 'id_one'
|
147
|
+
|
148
|
+
expect(m1).to eq m2
|
149
|
+
expect(m2).not_to eq m3
|
150
|
+
expect(m1).not_to eq m3
|
151
|
+
expect(m1).not_to eq m4
|
152
|
+
expect(m2).not_to eq m4
|
153
|
+
end
|
154
|
+
|
155
|
+
describe 'loaded?' do
|
156
|
+
it 'has a :loaded? method' do
|
157
|
+
expect(ModelThree.new).to respond_to :loaded?
|
158
|
+
end
|
159
|
+
|
160
|
+
it 'returns false on lazy load' do
|
161
|
+
m = ModelThree.new :id => 'id_one'
|
162
|
+
|
163
|
+
expect(m).not_to be_loaded
|
164
|
+
end
|
165
|
+
|
166
|
+
it 'returns true on load!' do
|
167
|
+
m = ModelThree.new :id => 'id_one'
|
168
|
+
m.load!
|
169
|
+
|
170
|
+
expect(m).to be_loaded
|
171
|
+
end
|
172
|
+
end
|
173
|
+
|
174
|
+
describe 'cached?' do
|
175
|
+
context 'valid model' do
|
176
|
+
it 'has a :cached? method' do
|
177
|
+
expect(ModelThree.new).to respond_to :cached?
|
178
|
+
end
|
179
|
+
|
180
|
+
it "doesn't cache lazily loaded objects" do
|
181
|
+
m = ModelThree.new :id => 'id_one'
|
182
|
+
|
183
|
+
expect(m).not_to be_loaded
|
184
|
+
expect(m).not_to be_cached
|
185
|
+
end
|
186
|
+
|
187
|
+
it 'caches loaded objects' do
|
188
|
+
m = ModelThree.new :id => 'id_one'
|
189
|
+
m.load!
|
190
|
+
|
191
|
+
expect(m).to be_loaded
|
192
|
+
expect(m).to be_cached
|
193
|
+
end
|
194
|
+
end
|
195
|
+
|
196
|
+
context 'invalid model' do
|
197
|
+
it 'has a :cached? method' do
|
198
|
+
expect(ModelFive.new).to respond_to :cached?
|
199
|
+
end
|
200
|
+
|
201
|
+
it "doesn't cache lazily loaded objects" do
|
202
|
+
m = ModelFive.new :id => 'id_one'
|
203
|
+
|
204
|
+
expect(m).not_to be_loaded
|
205
|
+
expect(m).not_to be_cached
|
206
|
+
end
|
207
|
+
|
208
|
+
it "doesn't cache loaded invalid objects" do
|
209
|
+
m = ModelFive.new :id => 'id_one'
|
210
|
+
expect(-> { m.load! }).to raise_error MetalArchives::Errors::APIError
|
211
|
+
|
212
|
+
expect(m).not_to be_loaded
|
213
|
+
expect(m).not_to be_cached
|
214
|
+
end
|
215
|
+
end
|
216
|
+
end
|
217
|
+
end
|