spigot 0.0.1

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.
@@ -0,0 +1,7 @@
1
+ module Spigot
2
+ module Mapping
3
+ def self.multiple_resources
4
+ User.basic.merge(Post.basic)
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,22 @@
1
+ module Spigot
2
+ module Mapping
3
+
4
+ class Post
5
+
6
+ def self.basic
7
+ {'post' => base}
8
+ end
9
+
10
+ def self.namespaced
11
+ {'wrapper/post' => base}
12
+ end
13
+
14
+ private
15
+
16
+ def self.base
17
+ {'title' => 'title', 'body' => 'description'}
18
+ end
19
+ end
20
+
21
+ end
22
+ end
@@ -0,0 +1,33 @@
1
+ module Spigot
2
+ module Mapping
3
+
4
+ class User
5
+ def self.basic
6
+ {'user' => base}
7
+ end
8
+
9
+ def self.with_options
10
+ {'user' => base.merge('spigot' => options)}
11
+ end
12
+
13
+ def self.with_conditions
14
+ {'user' => base.merge('spigot' => options.merge(conditions))}
15
+ end
16
+
17
+ private
18
+
19
+ def self.base
20
+ {'full_name' => 'name', 'login' => 'username'}
21
+ end
22
+
23
+ def self.options
24
+ {'primary_key' => 'username', 'foreign_key' => 'login'}
25
+ end
26
+
27
+ def self.conditions
28
+ {'conditions' => 'username, name'}
29
+ end
30
+ end
31
+
32
+ end
33
+ end
@@ -0,0 +1,40 @@
1
+ require 'rspec'
2
+ require 'spigot'
3
+ require 'hashie'
4
+ require 'active_record'
5
+ require "test/unit"
6
+ require "mocha/setup"
7
+
8
+ %w(fixtures support).each do |dir|
9
+ Dir[File.join(Spigot.root, "spec/#{dir}/**/*.rb")].each {|f| require f}
10
+ end
11
+
12
+ # Mocked Classes
13
+ User = Class.new(Hashie::Mash)
14
+
15
+ class ActiveUser < ActiveRecord::Base
16
+ include Spigot::Base
17
+ end
18
+
19
+ module Wrapper
20
+ Post = Class.new(Hashie::Mash)
21
+ end
22
+
23
+ def with_mapping(name, map)
24
+ before do
25
+ instance_variable_set("@prior_#{name}".to_sym, Spigot.config.translations)
26
+ Spigot.configure{|c| c.translations = map }
27
+ end
28
+
29
+ after do
30
+ map_cache = instance_variable_get("@prior_#{name}".to_sym)
31
+ Spigot.configure{|c| c.translations = map_cache }
32
+ end
33
+ end
34
+
35
+ RSpec.configure do |config|
36
+ config.after(:each) do
37
+ ActiveUser.delete_all
38
+ Spigot.config.reset
39
+ end
40
+ end
@@ -0,0 +1,95 @@
1
+ require 'spec_helper'
2
+
3
+ describe Spigot::ActiveRecord do
4
+ let(:subject){ActiveUser}
5
+ let(:service){:github}
6
+ let(:data){ Spigot::ApiData.user.merge(id: '987') }
7
+
8
+ context 'with invalid mapping' do
9
+ with_mapping(:basic_active_user, Spigot::Mapping::ActiveUser.with_invalid_options)
10
+
11
+ context '#find_by_api' do
12
+ it 'requires the primary key to be accurate' do
13
+ expect {
14
+ subject.find_by_api(service, {full_name: 'Dean Martin'}).should_not be_nil
15
+ }.to raise_error(Spigot::InvalidSchemaError)
16
+ end
17
+ end
18
+ end
19
+
20
+ context 'with valid mapping' do
21
+ with_mapping(:active_user_with_options, Spigot::Mapping::ActiveUser.with_options)
22
+ let(:user){ subject.create(name: 'Dean Martin', username: 'classyasfuck') }
23
+
24
+ context '#find_by_api' do
25
+ before{ user }
26
+
27
+ it 'queries by the specified primary_key' do
28
+ subject.find_by_api(service, data).should eq(user)
29
+ end
30
+ end
31
+
32
+ context '#find_all_by_api' do
33
+ with_mapping(:non_unique_key, Spigot::Mapping::ActiveUser.non_unique_key)
34
+ before do
35
+ user.update_attribute(:token, '123abc')
36
+ subject.create(name: 'Frank Sinatra', username: 'livetilidie', token: '123abc')
37
+ end
38
+
39
+ it 'returns all records matching primary key' do
40
+ subject.find_all_by_api(service, data).length.should eq(2)
41
+ end
42
+ end
43
+
44
+ context '#create_by_api' do
45
+ it 'creates a record' do
46
+ record = subject.create_by_api(service, data)
47
+ record.name.should eq('Dean Martin')
48
+ record.username.should eq('classyasfuck')
49
+ record.token.should be_nil
50
+ end
51
+ end
52
+
53
+ context '#update_by_api' do
54
+ before{ user }
55
+ it 'updates a record' do
56
+ record = subject.update_by_api(service, data.merge(full_name: 'Dino Baby'))
57
+ record.name.should eq('Dino Baby')
58
+ end
59
+ end
60
+
61
+ context '#find_or_create_by_api' do
62
+ before{ user }
63
+ it 'returns an existing record' do
64
+ record = subject.find_or_create_by_api(service, data)
65
+ record.id.should eq(user.id)
66
+ end
67
+
68
+ it 'creates a record when none exists' do
69
+ record = subject.find_or_create_by_api(service, Spigot::ApiData.updated_user)
70
+ record.id.should_not eq(user.id)
71
+ record.name.should eq('Frank Sinatra')
72
+ record.username.should eq('livetilidie')
73
+ end
74
+ end
75
+
76
+ context '#create_or_update_by_api' do
77
+ before{ user }
78
+
79
+ it 'updates an existing record' do
80
+ record = subject.create_or_update_by_api(service, data.merge(full_name: 'Dino Baby'))
81
+ record.id.should eq(user.id)
82
+ record.name.should eq('Dino Baby')
83
+ record.username.should eq('classyasfuck')
84
+ end
85
+
86
+ it 'creates a record when none exists' do
87
+ record = subject.create_or_update_by_api(service, Spigot::ApiData.updated_user)
88
+ record.id.should_not eq(user.id)
89
+ record.name.should eq('Frank Sinatra')
90
+ record.username.should eq('livetilidie')
91
+ end
92
+ end
93
+ end
94
+
95
+ end
@@ -0,0 +1,7 @@
1
+ require 'spec_helper'
2
+
3
+ describe Spigot::Base do
4
+
5
+
6
+
7
+ end
@@ -0,0 +1,60 @@
1
+ require 'spec_helper'
2
+
3
+ describe Spigot::Configuration do
4
+ before do
5
+ @prior_translations = Spigot.config.translations
6
+ end
7
+
8
+ after do
9
+ Spigot.configure{|c| c.translations = @prior_translations }
10
+ end
11
+
12
+ context 'defaults' do
13
+ it 'is a hash of default configuration' do
14
+ expect(Spigot::Configuration.defaults).to be_kind_of(Hash)
15
+ end
16
+ end
17
+
18
+ context 'access' do
19
+ before do
20
+ @previous_path = Spigot.config.path
21
+ end
22
+
23
+ after do
24
+ Spigot.configure{|config| config.path = @previous_path }
25
+ end
26
+
27
+ it "is callable from .configure" do
28
+ Spigot.configure do |c|
29
+ expect(c).to be_kind_of(Spigot::Configuration)
30
+ end
31
+ end
32
+
33
+ context 'options' do
34
+ let(:path){'/baller'}
35
+ let(:map){{'user' => {a: 1}}}
36
+ let(:options_key){'my_special_key'}
37
+
38
+ it "is able to set the path" do
39
+ Spigot.configure{|config| config.path = path }
40
+ expect(Spigot.config.path).to eq(path)
41
+ end
42
+
43
+ it "is able to set translations" do
44
+ Spigot.configure{|config| config.translations = map }
45
+ expect(Spigot.config.translations).to eq(map)
46
+ end
47
+
48
+ it "is able to set the options_key" do
49
+ Spigot.configure{|config| config.options_key = options_key }
50
+ expect(Spigot.config.options_key).to eq(options_key)
51
+ end
52
+
53
+ it "is able to set the logger" do
54
+ logger = Logger.new(STDOUT)
55
+ Spigot.configure{|config| config.logger = logger }
56
+ expect(Spigot.config.logger).to eq(logger)
57
+ end
58
+ end
59
+ end
60
+ end
@@ -0,0 +1,5 @@
1
+ require 'spec_helper'
2
+
3
+ describe Spigot::Record do
4
+
5
+ end
@@ -0,0 +1,165 @@
1
+ require 'spec_helper'
2
+
3
+ describe Spigot::Translator do
4
+
5
+ context '#initialize' do
6
+ it 'requires a service' do
7
+ expect{
8
+ Spigot::Translator.new(nil, Struct)
9
+ }.to raise_error(Spigot::InvalidServiceError)
10
+ end
11
+
12
+ it 'requires a resource' do
13
+ expect{
14
+ Spigot::Translator.new(:github, nil)
15
+ }.to raise_error(Spigot::InvalidResourceError)
16
+ end
17
+
18
+ it 'accepts an instance or class resource' do
19
+ by_class = Spigot::Translator.new(:github, User)
20
+ by_instance = Spigot::Translator.new(:github, User.new)
21
+ expect(by_class.resource).to eq(by_instance.resource)
22
+ end
23
+ end
24
+
25
+ context '#format' do
26
+ let(:subject){Spigot::Translator.new(:github, User.new, {a: '1'})}
27
+
28
+ context 'with a missing map' do
29
+ it 'raises error with a missing file' do
30
+ expect {
31
+ subject.format
32
+ }.to raise_error(Spigot::MissingServiceError)
33
+ end
34
+ end
35
+
36
+ context 'with a missing resource map' do
37
+ before do
38
+ subject.stubs(:translation_file).returns("missing:\n foo: 'bar'")
39
+ end
40
+
41
+ it 'raises error with a missing resource map' do
42
+ expect{
43
+ subject.format
44
+ }.to raise_error(Spigot::MissingResourceError)
45
+ end
46
+ end
47
+
48
+ context 'and a valid resource map' do
49
+ with_mapping(:basic_user, Spigot::Mapping::User.basic)
50
+
51
+ it 'returns empty hash from nil data' do
52
+ expect(subject.format).to eq({})
53
+ end
54
+ end
55
+
56
+ context 'with basic user data' do
57
+ let(:subject){Spigot::Translator.new(:github, User.new, Spigot::ApiData.basic_user)}
58
+
59
+ context 'with a basic mapping' do
60
+ with_mapping(:basic_user, Spigot::Mapping::User.basic)
61
+
62
+ it 'reads one layer' do
63
+ expect(subject.format).to eq({'name' => 'Dean Martin', 'username' => 'classyasfuck'})
64
+ end
65
+ end
66
+
67
+ context 'with a mapping containing several resources' do
68
+ with_mapping(:multiple_resources, Spigot::Mapping.multiple_resources)
69
+
70
+ it 'selects the user map' do
71
+ expect(subject.format).to eq({'name' => 'Dean Martin', 'username' => 'classyasfuck'})
72
+ end
73
+ end
74
+ end
75
+
76
+ context 'with a namedspaced resource' do
77
+ let(:subject){Spigot::Translator.new(:github, Wrapper::Post.new, Spigot::ApiData.post)}
78
+ with_mapping(:namespaced_post, Spigot::Mapping::Post.namespaced)
79
+
80
+ it 'accesses the wrapper/post key' do
81
+ expect(subject.format).to eq({'title' => 'Regular Article', 'description' => 'dolor sit amet'})
82
+ end
83
+ end
84
+ end
85
+
86
+ context '#lookup' do
87
+ let(:subject){Spigot::Translator.new(:github, User.new, {a: '1'})}
88
+
89
+ it 'returns the value at a given key' do
90
+ subject.lookup(:a).should eq('1')
91
+ end
92
+ end
93
+
94
+ context '#id' do
95
+ let(:subject){Spigot::Translator.new(:github, User.new, {id: '123'})}
96
+
97
+ it 'returns the value at the foreign_key' do
98
+ subject.stubs(:foreign_key).returns('id')
99
+ subject.id.should eq('123')
100
+ end
101
+ end
102
+
103
+ context '#conditions' do
104
+ let(:subject){Spigot::Translator.new(:github, User.new, Spigot::ApiData.user)}
105
+ with_mapping(:user_with_conditions, Spigot::Mapping::User.with_options)
106
+
107
+ it 'should return a hash' do
108
+ previous_translations = Spigot.config.translations
109
+ Spigot.configure{|c| c.translations = Spigot::Mapping::User.with_options }
110
+ subject.conditions.should eq({"username"=>"classyasfuck"})
111
+ Spigot.configure{|c| c.translations = previous_translations }
112
+ end
113
+
114
+ context 'with conditions specified' do
115
+ with_mapping(:user_with_conditions, Spigot::Mapping::User.with_conditions)
116
+
117
+ it 'can specify the keys used in the map options' do
118
+ subject.conditions.should eq({"username"=>"classyasfuck", "name"=>"Dean Martin"})
119
+ end
120
+
121
+ it 'can specify only one key' do
122
+ subject.conditions.should eq({"username"=>"classyasfuck", "name"=>"Dean Martin"})
123
+ end
124
+ end
125
+ end
126
+
127
+ context '#options' do
128
+ let(:subject){Spigot::Translator.new(:github, User.new, {remote_id: '987'})}
129
+
130
+ context 'without options provided' do
131
+ with_mapping(:basic_user, Spigot::Mapping::User.basic)
132
+
133
+ context 'defaults' do
134
+ it '#primary_key is the name of the service _id' do
135
+ subject.primary_key.should eq('github_id')
136
+ end
137
+
138
+ it '#foreign_key is id' do
139
+ subject.foreign_key.should eq('id')
140
+ end
141
+ end
142
+ end
143
+
144
+ context 'with options provided' do
145
+ with_mapping(:user_with_options, Spigot::Mapping::User.with_options)
146
+
147
+ it 'reads the options from the spigot key' do
148
+ subject.options.should eq(Spigot::Mapping::User.with_options['user']['spigot'])
149
+ end
150
+
151
+ context '#primary_key' do
152
+ it 'reads a primary key from the mapping' do
153
+ subject.primary_key.should eq('username')
154
+ end
155
+ end
156
+
157
+ context '#foreign_key' do
158
+ it 'reads a foreign key from the mapping' do
159
+ subject.foreign_key.should eq('login')
160
+ end
161
+ end
162
+ end
163
+ end
164
+
165
+ end
@@ -0,0 +1,15 @@
1
+ ActiveRecord::Base.establish_connection({
2
+ :adapter => "sqlite3",
3
+ :database => ':memory:'
4
+ })
5
+
6
+ ActiveRecord::Schema.define do
7
+ self.verbose = false
8
+
9
+ create_table :active_users, :force => true do |t|
10
+ t.string :name
11
+ t.integer :github_id
12
+ t.string :username
13
+ t.string :token
14
+ end
15
+ end