metal_archives 0.8.0 → 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|