typekit-client 0.0.4 → 0.0.5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (47) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +6 -0
  3. data/Guardfile +18 -4
  4. data/README.md +62 -39
  5. data/bin/{typekit → typekit-client} +14 -1
  6. data/bin/typekit-publisher +89 -0
  7. data/lib/typekit/client.rb +6 -10
  8. data/lib/typekit/collection.rb +15 -0
  9. data/lib/typekit/core.rb +3 -3
  10. data/lib/typekit/helper.rb +4 -0
  11. data/lib/typekit/processing/converter/boolean.rb +3 -0
  12. data/lib/typekit/processing/converter/collection.rb +18 -0
  13. data/lib/typekit/processing/converter/datetime.rb +3 -0
  14. data/lib/typekit/processing/converter/errors.rb +3 -1
  15. data/lib/typekit/processing/converter/record.rb +2 -1
  16. data/lib/typekit/processing/converter.rb +8 -13
  17. data/lib/typekit/record/base.rb +30 -8
  18. data/lib/typekit/record/family.rb +2 -1
  19. data/lib/typekit/record/kit.rb +1 -1
  20. data/lib/typekit/record/library.rb +1 -1
  21. data/lib/typekit/record/variation.rb +2 -2
  22. data/lib/typekit/record.rb +18 -18
  23. data/lib/typekit/version.rb +1 -1
  24. data/lib/typekit.rb +2 -0
  25. data/spec/cassettes/{show_families_calluna_found.yml → show_families_xxx_found.yml} +1 -1
  26. data/spec/cassettes/show_families_xxx_ok.yml +31 -0
  27. data/spec/cassettes/show_families_xxx_yyy_ok.yml +20 -0
  28. data/spec/cassettes/show_kits_xxx_families_yyy_ok.yml +16 -0
  29. data/spec/cassettes/show_kits_xxx_ok.yml +17 -0
  30. data/spec/cassettes/show_libraries_xxx_ok.yml +31 -0
  31. data/spec/features/client/delete_kit_spec.rb +13 -0
  32. data/spec/features/client/index_kits_spec.rb +25 -0
  33. data/spec/features/client/show_family_spec.rb +47 -0
  34. data/spec/features/client/show_kit_spec.rb +18 -0
  35. data/spec/features/client/show_library_spec.rb +18 -0
  36. data/spec/features/client/show_variation_spec.rb +22 -0
  37. data/spec/spec_helper.rb +3 -5
  38. data/spec/support/resource_helper.rb +34 -0
  39. data/spec/typekit/helper_spec.rb +12 -5
  40. data/spec/typekit/processing/converter_spec.rb +1 -1
  41. data/spec/typekit/record/base_spec.rb +56 -3
  42. data/spec/typekit/record_spec.rb +57 -24
  43. data/typekit-client.gemspec +1 -1
  44. metadata +36 -13
  45. data/lib/typekit/processing/converter/records.rb +0 -18
  46. data/spec/support/rest_helper.rb +0 -22
  47. data/spec/typekit/client_spec.rb +0 -42
@@ -6,30 +6,30 @@ require_relative 'record/library'
6
6
 
7
7
  module Typekit
8
8
  module Record
9
- def self.classes
10
- @classes ||= ObjectSpace.each_object(Class).select do |klass|
11
- klass < Base
12
- end
13
- end
14
-
15
- def self.collections
16
- @collections ||= members.map(&:to_s).map do |name|
17
- Helper.pluralize(name.to_s)
18
- end.map(&:to_sym)
9
+ def self.mapping
10
+ @mapping ||= Hash[
11
+ ObjectSpace.each_object(Class).select do |klass|
12
+ klass < Base && klass.name
13
+ end.map do |klass|
14
+ [ klass.name.downcase.sub(/^.*::/, '').to_sym, klass ]
15
+ end
16
+ ]
19
17
  end
20
18
 
21
- def self.members
22
- @members ||= classes.map(&:to_s).map(&:downcase).map do |name|
23
- name.sub(/^.*::/, '')
24
- end.map(&:to_sym)
19
+ def self.classify(name)
20
+ mapping[Helper.singularize(name.to_s).to_sym]
25
21
  end
26
22
 
27
- def self.collection?(name)
28
- collections.include?(name.to_s.to_sym)
23
+ def self.identify(name)
24
+ if mapping.include?(name.to_s.to_sym)
25
+ :record
26
+ elsif mapping.include?(Helper.singularize(name.to_s).to_sym)
27
+ :collection
28
+ end
29
29
  end
30
30
 
31
- def self.member?(name)
32
- members.include?(name.to_s.to_sym)
31
+ def self.build(name, *arguments)
32
+ classify(name).new(*arguments)
33
33
  end
34
34
  end
35
35
  end
@@ -1,3 +1,3 @@
1
1
  module Typekit
2
- VERSION = '0.0.4'
2
+ VERSION = '0.0.5'
3
3
  end
data/lib/typekit.rb CHANGED
@@ -1,3 +1,4 @@
1
+ require 'forwardable'
1
2
  require 'apitizer'
2
3
 
3
4
  require_relative 'typekit/core'
@@ -5,6 +6,7 @@ require_relative 'typekit/helper'
5
6
 
6
7
  require_relative 'typekit/processing'
7
8
 
9
+ require_relative 'typekit/collection'
8
10
  require_relative 'typekit/record'
9
11
  require_relative 'typekit/client'
10
12
 
@@ -2,7 +2,7 @@
2
2
  http_interactions:
3
3
  - request:
4
4
  method: get
5
- uri: https://typekit.com/api/v1/json/families/calluna
5
+ uri: https://typekit.com/api/v1/json/families/xxx
6
6
  response:
7
7
  status:
8
8
  code: 302
@@ -0,0 +1,31 @@
1
+ ---
2
+ http_interactions:
3
+ - request:
4
+ method: get
5
+ uri: https://typekit.com/api/v1/json/families/xxx
6
+ response:
7
+ status:
8
+ code: 200
9
+ message: OK
10
+ headers:
11
+ Status:
12
+ - 200 OK
13
+ body:
14
+ encoding: UTF-8
15
+ string: '{"family":{"id":"vybr","name":"Calluna","slug":"calluna","web_link":"http://typekit.com/fonts/calluna","browse_info":{"capitals":["uppercase-lowercase"],"classification":["serif"],"contrast":["regular"],"language":["ca","cs","de","en","es","fr","it","mt","nl","pl","pt","sl","sv"],"number_style":["lowercase"],"recommended_for":["paragraphs"],"weight":["heavy","regular"],"width":["regular"],"x_height":["regular"]},"css_stack":"serif","description":"Calluna
16
+ is a robust, clean and contemporary face with interesting details and a forward
17
+ flow. Calluna makes for comfortable reading even at very small text sizes;
18
+ its striking details ensure that it can also be used as a display font with
19
+ personality.\r\n","foundry":{"name":"exljbris Font Foundry","slug":"exljbris-font-foundry"},"libraries":[{"id":"trial","link":"/api/v1/json/libraries/trial","name":"Trial
20
+ Library"},{"id":"personal","link":"/api/v1/json/libraries/personal","name":"Personal
21
+ Library"},{"id":"full","link":"/api/v1/json/libraries/full","name":"Full Library"},{"id":"enterprise","link":"/api/v1/json/libraries/enterprise","name":"Enterprise
22
+ Library"}],"variations":[{"id":"vybr:n3","link":"/api/v1/json/families/vybr/n3","name":"Calluna
23
+ Light","fvd":"n3"},{"id":"vybr:n4","link":"/api/v1/json/families/vybr/n4","name":"Calluna
24
+ Regular","fvd":"n4"},{"id":"vybr:i4","link":"/api/v1/json/families/vybr/i4","name":"Calluna
25
+ Italic","fvd":"i4"},{"id":"vybr:n6","link":"/api/v1/json/families/vybr/n6","name":"Calluna
26
+ Semi Bold ","fvd":"n6"},{"id":"vybr:i6","link":"/api/v1/json/families/vybr/i6","name":"Calluna
27
+ Semi Bold Italic","fvd":"i6"},{"id":"vybr:n7","link":"/api/v1/json/families/vybr/n7","name":"Calluna
28
+ Bold","fvd":"n7"},{"id":"vybr:i7","link":"/api/v1/json/families/vybr/i7","name":"Calluna
29
+ Bold Italic","fvd":"i7"},{"id":"vybr:n9","link":"/api/v1/json/families/vybr/n9","name":"Calluna
30
+ Black","fvd":"n9"}]}}'
31
+ recorded_at: Fri, 06 Jun 2014 00:00:00 GMT
@@ -0,0 +1,20 @@
1
+ ---
2
+ http_interactions:
3
+ - request:
4
+ method: get
5
+ uri: https://typekit.com/api/v1/json/families/xxx/yyy
6
+ response:
7
+ status:
8
+ code: 200
9
+ message: OK
10
+ headers:
11
+ Status:
12
+ - 200 OK
13
+ body:
14
+ encoding: UTF-8
15
+ string: '{"variation":{"id":"vcsm:i9","name":"Proxima Nova Black Italic","family":{"id":"vcsm","link":"/api/v1/json/families/vcsm","name":"Proxima
16
+ Nova"},"font_style":"italic","font_variant":"normal","font_weight":"900","foundry":{"name":"Mark
17
+ Simonson Studio","slug":"mark-simonson-studio"},"libraries":[{"id":"full","link":"/api/v1/json/libraries/full","name":"Full
18
+ Library"},{"id":"enterprise","link":"/api/v1/json/libraries/enterprise","name":"Enterprise
19
+ Library"}],"postscript_name":"ProximaNova-BlackIt"}}'
20
+ recorded_at: Fri, 06 Jun 2014 00:00:00 GMT
@@ -0,0 +1,16 @@
1
+ ---
2
+ http_interactions:
3
+ - request:
4
+ method: get
5
+ uri: https://typekit.com/api/v1/json/kits/xxx/families/yyy
6
+ response:
7
+ status:
8
+ code: 200
9
+ message: OK
10
+ headers:
11
+ Status:
12
+ - 200 OK
13
+ body:
14
+ encoding: UTF-8
15
+ string: '{"family":{"id":"vcsm","name":"Proxima Nova","slug":"proxima-nova","css_names":["proxima-nova"],"css_stack":"\"proxima-nova\",sans-serif","subset":"default","variations":["n1","n3","n4"]}}'
16
+ recorded_at: Fri, 06 Jun 2014 00:00:00 GMT
@@ -0,0 +1,17 @@
1
+ ---
2
+ http_interactions:
3
+ - request:
4
+ method: get
5
+ uri: https://typekit.com/api/v1/json/kits/xxx
6
+ response:
7
+ status:
8
+ code: 200
9
+ message: OK
10
+ headers:
11
+ Status:
12
+ - 200 OK
13
+ body:
14
+ encoding: UTF-8
15
+ string: '{"kit":{"id":"bas4cfe","name":"Ivan Ukhov at LiU","analytics":false,"badge":false,"domains":["localhost","10.0.2.2","www.ida.liu.se/~ivauk83"],"families":[{"id":"vcsm","name":"Proxima
16
+ Nova","slug":"proxima-nova","css_names":["proxima-nova"],"css_stack":"\"proxima-nova\",sans-serif","subset":"default","variations":["n1","n3","n4"]},{"id":"vybr","name":"Calluna","slug":"calluna","css_names":["calluna"],"css_stack":"\"calluna\",serif","subset":"default","variations":["n4","i4"]}]}}'
17
+ recorded_at: Thu, 05 Jun 2014 00:00:00 GMT
@@ -0,0 +1,31 @@
1
+ ---
2
+ http_interactions:
3
+ - request:
4
+ method: get
5
+ uri: https://typekit.com/api/v1/json/libraries/xxx
6
+ response:
7
+ status:
8
+ code: 200
9
+ message: OK
10
+ headers:
11
+ Status:
12
+ - 200 OK
13
+ body:
14
+ encoding: UTF-8
15
+ string: '{"library":{"id":"trial","link":"/api/v1/json/libraries/trial","name":"Trial
16
+ Library","families":[{"id":"lgrs","link":"/api/v1/json/families/lgrs","name":"Abril
17
+ Fatface"},{"id":"jtgy","link":"/api/v1/json/families/jtgy","name":"Acta Display"},{"id":"spmb","link":"/api/v1/json/families/spmb","name":"Acta
18
+ Poster"},{"id":"drlt","link":"/api/v1/json/families/drlt","name":"Acta Poster
19
+ Swashes"},{"id":"zcmv","link":"/api/v1/json/families/zcmv","name":"Acuta"},{"id":"gmsj","link":"/api/v1/json/families/gmsj","name":"Adelle"},{"id":"hmqz","link":"/api/v1/json/families/hmqz","name":"Adobe
20
+ Caslon Pro"},{"id":"tmmf","link":"/api/v1/json/families/tmmf","name":"Adobe
21
+ Garamond Pro"},{"id":"ydjd","link":"/api/v1/json/families/ydjd","name":"Adrianna
22
+ Extended Demibold"},{"id":"dqrj","link":"/api/v1/json/families/dqrj","name":"Alber
23
+ New Web"},{"id":"bjtl","link":"/api/v1/json/families/bjtl","name":"Alegreya"},{"id":"xrsc","link":"/api/v1/json/families/xrsc","name":"Alegreya
24
+ SC"},{"id":"nztd","link":"/api/v1/json/families/nztd","name":"Alexa Std"},{"id":"kvxq","link":"/api/v1/json/families/kvxq","name":"Alpha
25
+ Echo"},{"id":"byws","link":"/api/v1/json/families/byws","name":"Alwyn New
26
+ Rounded Web"},{"id":"ymqr","link":"/api/v1/json/families/ymqr","name":"Alwyn
27
+ New Web"},{"id":"gxdg","link":"/api/v1/json/families/gxdg","name":"Angie STD
28
+ Sans"},{"id":"nrky","link":"/api/v1/json/families/nrky","name":"Anisette STD
29
+ Petite"},{"id":"bfnx","link":"/api/v1/json/families/bfnx","name":"Anisette
30
+ STD Petite SC"},{"id":"rnhy","link":"/api/v1/json/families/rnhy","name":"Anivers"}],"pagination":{"count":261,"on":"families","page":1,"page_count":14,"per_page":20}}}'
31
+ recorded_at: Fri, 06 Jun 2014 00:00:00 GMT
@@ -0,0 +1,13 @@
1
+ require 'spec_helper'
2
+
3
+ RSpec.describe 'Client#delete a kit' do
4
+ let(:subject) { Typekit::Client.new(token: 'arbitrary') }
5
+
6
+ options = { vcr: { cassette_name: 'delete_kits_xxx_ok' } }
7
+
8
+ let(:result) { subject.delete(:kits, 'xxx') }
9
+
10
+ it 'returns true', options do
11
+ expect(result).to be true
12
+ end
13
+ end
@@ -0,0 +1,25 @@
1
+ require 'spec_helper'
2
+
3
+ RSpec.describe 'Client#index kits' do
4
+ let(:subject) { Typekit::Client.new(token: 'arbitrary') }
5
+
6
+ context 'when successful' do
7
+ options = { vcr: { cassette_name: 'index_kits_ok' } }
8
+
9
+ let(:result) { subject.index(:kits) }
10
+
11
+ it 'returns Records', options do
12
+ expect(result.map(&:class).uniq).to \
13
+ contain_exactly(Typekit::Record::Kit)
14
+ end
15
+ end
16
+
17
+ context 'when unauthorized' do
18
+ options = { vcr: { cassette_name: 'index_kits_unauthorized' } }
19
+
20
+ it 'raises exceptions', options do
21
+ expect { subject.index(:kits) }.to \
22
+ raise_error(Typekit::Processing::Error, /Not authorized/i)
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,47 @@
1
+ require 'spec_helper'
2
+
3
+ RSpec.describe 'Client#show a family' do
4
+ let(:subject) { Typekit::Client.new(token: 'arbitrary') }
5
+
6
+ shared_examples 'an adequate reader' do |options|
7
+ it 'returns a Family', options do
8
+ expect(result).to be_kind_of(Typekit::Record::Family)
9
+ end
10
+
11
+ it 'returns a Family with Variations', options do
12
+ expect(result.variations.map(&:class).uniq).to \
13
+ contain_exactly(Typekit::Record::Variation)
14
+ end
15
+ end
16
+
17
+ context 'when looking up directly' do
18
+ options = { vcr: { cassette_name: 'show_families_xxx_ok' } }
19
+
20
+ let(:result) { subject.show(:families, 'xxx') }
21
+
22
+ it_behaves_like 'an adequate reader', options
23
+
24
+ it 'returns a Family with Libraries', options do
25
+ expect(result.libraries.map(&:class).uniq).to \
26
+ contain_exactly(Typekit::Record::Library)
27
+ end
28
+ end
29
+
30
+ context 'when looking up through a kit' do
31
+ options = { vcr: { cassette_name: 'show_kits_xxx_families_yyy_ok' } }
32
+
33
+ let(:result) { subject.show(:kits, 'xxx', :families, 'yyy') }
34
+
35
+ it_behaves_like 'an adequate reader', options
36
+ end
37
+
38
+ context 'when looking up directly via slugs' do
39
+ options = { vcr: { cassette_name: 'show_families_xxx_found' } }
40
+
41
+ let(:result) { subject.show(:families, 'xxx') }
42
+
43
+ it 'returns a Family', options do
44
+ expect(result).to be_kind_of(Typekit::Record::Family)
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,18 @@
1
+ require 'spec_helper'
2
+
3
+ RSpec.describe 'Client#show a kit' do
4
+ let(:subject) { Typekit::Client.new(token: 'arbitrary') }
5
+
6
+ options = { vcr: { cassette_name: 'show_kits_xxx_ok' } }
7
+
8
+ let(:result) { subject.show(:kits, 'xxx') }
9
+
10
+ it 'returns a Kit', options do
11
+ expect(result).to be_kind_of(Typekit::Record::Kit)
12
+ end
13
+
14
+ it 'returns a Kit with Families', options do
15
+ expect(result.families.map(&:class).uniq).to \
16
+ contain_exactly(Typekit::Record::Family)
17
+ end
18
+ end
@@ -0,0 +1,18 @@
1
+ require 'spec_helper'
2
+
3
+ RSpec.describe 'Client#show a library' do
4
+ let(:subject) { Typekit::Client.new(token: 'arbitrary') }
5
+
6
+ options = { vcr: { cassette_name: 'show_libraries_xxx_ok' } }
7
+
8
+ let(:result) { subject.show(:libraries, 'xxx') }
9
+
10
+ it 'returns a Library', options do
11
+ expect(result).to be_kind_of(Typekit::Record::Library)
12
+ end
13
+
14
+ it 'returns a Library with Families', options do
15
+ expect(result.families.map(&:class).uniq).to \
16
+ contain_exactly(Typekit::Record::Family)
17
+ end
18
+ end
@@ -0,0 +1,22 @@
1
+ require 'spec_helper'
2
+
3
+ RSpec.describe 'Client#show a variation' do
4
+ let(:subject) { Typekit::Client.new(token: 'arbitrary') }
5
+
6
+ options = { vcr: { cassette_name: 'show_families_xxx_yyy_ok' } }
7
+
8
+ let(:result) { subject.show(:families, 'xxx', 'yyy') }
9
+
10
+ it 'returns a Variation', options do
11
+ expect(result).to be_kind_of(Typekit::Record::Variation)
12
+ end
13
+
14
+ it 'returns a Variation with Libraries', options do
15
+ expect(result.libraries.map(&:class).uniq).to \
16
+ contain_exactly(Typekit::Record::Library)
17
+ end
18
+
19
+ it 'returns a Variation with a Family', options do
20
+ expect(result.family).to be_kind_of(Typekit::Record::Family)
21
+ end
22
+ end
data/spec/spec_helper.rb CHANGED
@@ -1,13 +1,11 @@
1
- require_relative 'support/rest_helper'
2
1
  require 'webmock/rspec'
3
2
  require 'vcr'
4
3
  require 'typekit'
5
4
 
5
+ require_relative 'support/resource_helper'
6
+
6
7
  RSpec.configure do |config|
7
- config.treat_symbols_as_metadata_keys_with_true_values = true
8
- config.run_all_when_everything_filtered = true
9
- config.filter_run :focus
10
- config.order = 'random'
8
+ config.disable_monkey_patching!
11
9
  end
12
10
 
13
11
  VCR.configure do |config|
@@ -0,0 +1,34 @@
1
+ module ResourceHelper
2
+ RECORD_NAMES = %w{family kit library variation}
3
+ COLLECTION_NAMES = %w{families kits libraries variations}
4
+
5
+ def record_names
6
+ RECORD_CLASS_NAMES
7
+ end
8
+
9
+ def record_symbols
10
+ @record_symbols ||= RECORD_NAMES.map(&:to_sym)
11
+ end
12
+
13
+ def record_classes
14
+ @record_classes ||= RECORD_NAMES.map do |name|
15
+ Typekit::Record.const_get(name.capitalize)
16
+ end
17
+ end
18
+
19
+ def collection_names
20
+ COLLECTION_NAMES
21
+ end
22
+
23
+ def collection_symbols
24
+ @collection_symbols ||= COLLECTION_NAMES.map(&:to_sym)
25
+ end
26
+
27
+ def record_mapping
28
+ @record_mapping ||= Hash[record_symbols.clone.zip(record_classes)]
29
+ end
30
+
31
+ def collection_mapping
32
+ @collection_mapping ||= Hash[collection_symbols.clone.zip(record_classes)]
33
+ end
34
+ end
@@ -1,6 +1,6 @@
1
1
  require 'spec_helper'
2
2
 
3
- describe Typekit::Helper do
3
+ RSpec.describe Typekit::Helper do
4
4
  let(:subject_module) { Typekit::Helper }
5
5
 
6
6
  describe '.pluralize' do
@@ -11,8 +11,8 @@ describe Typekit::Helper do
11
11
  'families' => 'families',
12
12
  'library' => 'libraries',
13
13
  'libraries' => 'libraries',
14
- 'variant' => 'variants',
15
- 'variants' => 'variants'
14
+ 'variation' => 'variations',
15
+ 'variations' => 'variations'
16
16
  }.each do |k, v|
17
17
  it "returns #{ v } for #{ k }" do
18
18
  expect(subject_module.pluralize(k)).to eq(v)
@@ -28,12 +28,19 @@ describe Typekit::Helper do
28
28
  'families' => 'family',
29
29
  'library' => 'library',
30
30
  'libraries' => 'library',
31
- 'variant' => 'variant',
32
- 'variants' => 'variant'
31
+ 'variation' => 'variation',
32
+ 'variations' => 'variation'
33
33
  }.each do |k, v|
34
34
  it "returns #{ v } for #{ k }" do
35
35
  expect(subject_module.singularize(k)).to eq(v)
36
36
  end
37
37
  end
38
38
  end
39
+
40
+ describe '.symbolize_keys' do
41
+ it 'does what it says' do
42
+ expect(subject_module.symbolize_keys('a' => { 'b' => 1 }, 'd' => 2)).to \
43
+ eq(a: { 'b' => 1 }, d: 2)
44
+ end
45
+ end
39
46
  end
@@ -1,6 +1,6 @@
1
1
  require 'spec_helper'
2
2
 
3
- describe Typekit::Processing::Converter do
3
+ RSpec.describe Typekit::Processing::Converter do
4
4
  def create(name)
5
5
  Typekit::Processing::Converter.build(name)
6
6
  end
@@ -1,10 +1,28 @@
1
1
  require 'spec_helper'
2
2
 
3
- describe Typekit::Record::Base do
4
- let(:subject_class) { Typekit::Record::Base }
3
+ RSpec.describe Typekit::Record::Base do
4
+ let(:subject_module) { Typekit::Record }
5
+
6
+ def create_class
7
+ Class.new(subject_module::Base)
8
+ end
9
+
10
+ let(:subject_class) { create_class }
11
+
12
+ describe '.has_many' do
13
+ it 'declares one-to-many relations between Records' do
14
+ expect { subject_class.has_many(:sections) }.not_to raise_error
15
+ end
16
+ end
17
+
18
+ describe '.belongs_to' do
19
+ it 'declares one-to-one relations between Records' do
20
+ expect { subject_class.belongs_to(:article) }.not_to raise_error
21
+ end
22
+ end
5
23
 
6
24
  describe '#new' do
7
- it 'treats each option as an attribute to keep track of' do
25
+ it 'treats each option as an attribute' do
8
26
  subject = subject_class.new(name: 'Awesome')
9
27
  expect { subject.name = 'Superb' }.to \
10
28
  change { subject.name }.from('Awesome').to('Superb')
@@ -17,6 +35,41 @@ describe Typekit::Record::Base do
17
35
  end
18
36
  end
19
37
 
38
+ context 'when there are one-to-many relations defined' do
39
+ let(:another_class) { create_class }
40
+
41
+ before(:example) do
42
+ allow(subject_module).to receive(:classify).and_return(another_class)
43
+ subject_class.has_many(:sections)
44
+ end
45
+
46
+ describe '#new' do
47
+ context 'when the attributes of the relations are given' do
48
+ subject do
49
+ subject_class.new(sections: [ { title: 'First' },
50
+ { title: 'Second' } ])
51
+ end
52
+
53
+ it 'initializes relations as Collections' do
54
+ expect(subject.sections).to be_kind_of(Typekit::Collection)
55
+ end
56
+
57
+ it 'initializes Collections based on the attributes' do
58
+ expect(subject.sections.map(&:title)).to \
59
+ contain_exactly('First', 'Second')
60
+ end
61
+ end
62
+
63
+ context 'when the attributes of the relations are missing' do
64
+ subject { subject_class.new }
65
+
66
+ it 'does not initialize Collections' do
67
+ expect { subject.sections }.to raise_error(NoMethodError)
68
+ end
69
+ end
70
+ end
71
+ end
72
+
20
73
  describe '#attributes' do
21
74
  it 'returns all attributes' do
22
75
  subject = subject_class.new(id: 1, name: 'Awesome')
@@ -1,47 +1,80 @@
1
1
  require 'spec_helper'
2
2
 
3
- describe Typekit::Record do
3
+ RSpec.describe Typekit::Record do
4
+ include ResourceHelper
5
+ extend ResourceHelper
6
+
4
7
  let(:subject_module) { Typekit::Record }
5
8
 
6
- describe '.collections' do
7
- it 'knows the major collections' do
8
- expect(subject_module.collections).to \
9
- match_array(%i{families kits libraries variations})
9
+ describe '.mapping' do
10
+ it 'returns a hash whose keys are the names of the resources' do
11
+ expect(subject_module.mapping.keys).to \
12
+ contain_exactly(*record_symbols)
10
13
  end
11
- end
12
14
 
13
- describe '.members' do
14
- it 'knows the major members' do
15
- expect(subject_module.members).to \
16
- match_array(%i{family kit library variation})
15
+ it 'returns a hash whose values are the classes of the resources' do
16
+ expect(subject_module.mapping.values).to \
17
+ contain_exactly(*record_classes)
17
18
  end
18
19
  end
19
20
 
20
- describe '.collection?' do
21
- %w{family kit library variation kitten kittens}.each do |name|
22
- it "returns false for #{ name }" do
23
- expect(subject_module.collection?(name)).to be_false
21
+ describe '.classify' do
22
+ record_mapping.each do |name, klass|
23
+ it "converts :#{ name } into the corresponding Record class" do
24
+ expect(subject_module.classify(name)).to eq(klass)
25
+ end
26
+
27
+ it "converts '#{ name }' into the corresponding Record class" do
28
+ expect(subject_module.classify(name.to_s)).to eq(klass)
24
29
  end
25
30
  end
26
31
 
27
- %w{families kits libraries variations}.each do |name|
28
- it "returns true for #{ name }" do
29
- expect(subject_module.collection?(name)).to be_true
32
+ collection_mapping.each do |name, klass|
33
+ it "converts :#{ name } into the corresponding Record class" do
34
+ expect(subject_module.classify(name)).to eq(klass)
30
35
  end
36
+
37
+ it "converts '#{ name }' into the corresponding Record class" do
38
+ expect(subject_module.classify(name.to_s)).to eq(klass)
39
+ end
40
+ end
41
+
42
+ it 'returns nil for unknown names' do
43
+ expect(subject_module.classify('smile')).to be nil
44
+ end
45
+
46
+ it 'returns nil for nil' do
47
+ expect(subject_module.classify(nil)).to be nil
31
48
  end
32
49
  end
33
50
 
34
- describe '.member?' do
35
- %w{family kit library variation}.each do |name|
36
- it "returns true for #{ name }" do
37
- expect(subject_module.member?(name)).to be_true
51
+ describe '.identify' do
52
+ record_mapping.each do |name, klass|
53
+ it "converts :#{ name } into :record" do
54
+ expect(subject_module.identify(name)).to eq(:record)
55
+ end
56
+
57
+ it "converts '#{ name }' into :record" do
58
+ expect(subject_module.identify(name.to_s)).to eq(:record)
38
59
  end
39
60
  end
40
61
 
41
- %w{families kits libraries variations kitten kittens}.each do |name|
42
- it "returns false for #{ name }" do
43
- expect(subject_module.member?(name)).to be_false
62
+ collection_mapping.each do |name, klass|
63
+ it "converts :#{ name } into :collection" do
64
+ expect(subject_module.identify(name)).to eq(:collection)
65
+ end
66
+
67
+ it "converts '#{ name }' into :collection" do
68
+ expect(subject_module.identify(name.to_s)).to eq(:collection)
44
69
  end
45
70
  end
71
+
72
+ it 'returns nil for unknown names' do
73
+ expect(subject_module.identify('smile')).to be nil
74
+ end
75
+
76
+ it 'returns nil for nil' do
77
+ expect(subject_module.identify(nil)).to be nil
78
+ end
46
79
  end
47
80
  end
@@ -27,7 +27,7 @@ Gem::Specification.new do |spec|
27
27
 
28
28
  spec.add_development_dependency 'bundler', '~> 1.6'
29
29
  spec.add_development_dependency 'rake'
30
- spec.add_development_dependency 'rspec', '~> 2.14'
30
+ spec.add_development_dependency 'rspec', '~> 3.0'
31
31
  spec.add_development_dependency 'guard-rspec', '~> 4.2'
32
32
  spec.add_development_dependency 'webmock', '~> 1.18'
33
33
  spec.add_development_dependency 'vcr', '~> 2.9'