typekit-client 0.0.4 → 0.0.5

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.
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'