spigot 0.1.0 → 0.2.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 +1 -0
- data/README.md +25 -32
- data/Rakefile +6 -0
- data/examples/active_record.rb +18 -15
- data/examples/model.rb +38 -7
- data/lib/spigot.rb +18 -6
- data/lib/spigot/configuration.rb +4 -5
- data/lib/spigot/map/base.rb +44 -0
- data/lib/spigot/map/definition.rb +69 -0
- data/lib/spigot/map/option.rb +27 -0
- data/lib/spigot/map/resource.rb +37 -0
- data/lib/spigot/map/service.rb +43 -0
- data/lib/spigot/patch.rb +1 -1
- data/lib/spigot/proxy.rb +3 -2
- data/lib/spigot/translator.rb +22 -71
- data/lib/spigot/version.rb +1 -1
- data/script/console.rb +26 -20
- data/spec/fixtures/data/active_user.rb +17 -0
- data/spec/fixtures/data/post.rb +15 -0
- data/spec/fixtures/data/user.rb +41 -0
- data/spec/fixtures/mappings/active_user_map.rb +58 -22
- data/spec/fixtures/mappings/post_map.rb +10 -10
- data/spec/fixtures/mappings/user_map.rb +73 -29
- data/spec/spec_helper.rb +3 -12
- data/spec/spigot/active_record_spec.rb +34 -26
- data/spec/spigot/base_spec.rb +32 -1
- data/spec/spigot/configuration_spec.rb +0 -27
- data/spec/spigot/map/base_spec.rb +70 -0
- data/spec/spigot/map/definition_spec.rb +45 -0
- data/spec/spigot/map/resource_spec.rb +57 -0
- data/spec/spigot/map/service_spec.rb +88 -0
- data/spec/spigot/translator_spec.rb +110 -113
- data/spigot.gemspec +3 -2
- metadata +43 -20
- data/examples/.DS_Store +0 -0
- data/lib/.DS_Store +0 -0
- data/lib/spigot/config/.DS_Store +0 -0
- data/spec/.DS_Store +0 -0
- data/spec/fixtures/.DS_Store +0 -0
- data/spec/fixtures/api_data.rb +0 -46
- data/spec/spigot/factory_spec.rb +0 -5
@@ -0,0 +1,43 @@
|
|
1
|
+
module Spigot
|
2
|
+
module Map
|
3
|
+
class Service
|
4
|
+
|
5
|
+
attr_reader :name
|
6
|
+
attr_accessor :resources
|
7
|
+
|
8
|
+
def initialize(name)
|
9
|
+
@name = name.to_s.underscore.to_sym
|
10
|
+
@resources = []
|
11
|
+
end
|
12
|
+
|
13
|
+
def self.service(name, &block)
|
14
|
+
service = find(name) || Spigot::Map::Service.new(name)
|
15
|
+
service.instance_eval(&block) if block_given?
|
16
|
+
current_map.update(name, service)
|
17
|
+
end
|
18
|
+
|
19
|
+
def self.find(name)
|
20
|
+
current_map.service(name)
|
21
|
+
end
|
22
|
+
|
23
|
+
def resource(name, &block)
|
24
|
+
resources << Spigot::Map::Resource.new(name, &block)
|
25
|
+
end
|
26
|
+
|
27
|
+
def reset
|
28
|
+
@resources = []
|
29
|
+
end
|
30
|
+
|
31
|
+
def [](name)
|
32
|
+
resources.detect{|r| r.instance_variable_get(:@name).to_sym == name.to_sym}
|
33
|
+
end
|
34
|
+
|
35
|
+
private
|
36
|
+
|
37
|
+
def self.current_map
|
38
|
+
Spigot.config.map
|
39
|
+
end
|
40
|
+
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
data/lib/spigot/patch.rb
CHANGED
data/lib/spigot/proxy.rb
CHANGED
@@ -14,6 +14,7 @@ module Spigot
|
|
14
14
|
# @param service [String] This is the service that dictates the proxy.
|
15
15
|
# @param resource [Object] This is the class implementing the proxy.
|
16
16
|
def initialize(service, resource)
|
17
|
+
raise MissingServiceError, "No service definition found for #{service}" if Spigot.config.map.service(service).nil?
|
17
18
|
@service = service
|
18
19
|
@resource = resource
|
19
20
|
end
|
@@ -27,13 +28,13 @@ module Spigot
|
|
27
28
|
## #map
|
28
29
|
# Return a hash of the data map the current translator is using
|
29
30
|
def map
|
30
|
-
translator.
|
31
|
+
translator.resource_map
|
31
32
|
end
|
32
33
|
|
33
34
|
## #options
|
34
35
|
# Return a hash of any service specific options for this translator. `Spigot.config` not included
|
35
36
|
def options
|
36
|
-
translator.
|
37
|
+
translator.options || {}
|
37
38
|
end
|
38
39
|
|
39
40
|
end
|
data/lib/spigot/translator.rb
CHANGED
@@ -12,9 +12,7 @@ module Spigot
|
|
12
12
|
# in the yaml file for that resource.
|
13
13
|
#
|
14
14
|
# Relevant Configuration:
|
15
|
-
# config.options_key => The key which the Translator uses to configure a
|
16
|
-
# config.path => The path which the Translator will look in to find the mappings.
|
17
|
-
# config.translations => A hash that overrides any mappings found in the `path` directory.
|
15
|
+
# config.options_key => The key which the Translator uses to configure a resource_map.
|
18
16
|
|
19
17
|
attr_reader :service, :resource
|
20
18
|
attr_accessor :data
|
@@ -35,20 +33,10 @@ module Spigot
|
|
35
33
|
@data = data || {}
|
36
34
|
end
|
37
35
|
|
38
|
-
## #format
|
36
|
+
## #format
|
39
37
|
# Formats the hash of data passed in to the format specified in the yaml file.
|
40
|
-
|
41
|
-
|
42
|
-
# @param custom_data [Hash] Optional data that you can prefer to use over the @data currently on the object.
|
43
|
-
def format(custom_map=nil, custom_data=nil)
|
44
|
-
map = Hashie::Mash.new(custom_map || mapping)
|
45
|
-
dataset = custom_data || data
|
46
|
-
|
47
|
-
if dataset.is_a?(Array)
|
48
|
-
dataset.map{|n| translate(map, n) }
|
49
|
-
elsif dataset.is_a?(Hash)
|
50
|
-
translate(map, dataset)
|
51
|
-
end
|
38
|
+
def format
|
39
|
+
@format ||= data.is_a?(Array) ? data.map{|el| parse(el) } : parse(data)
|
52
40
|
end
|
53
41
|
|
54
42
|
## #id
|
@@ -78,81 +66,44 @@ module Spigot
|
|
78
66
|
# Default: nil
|
79
67
|
# Array of attributes included in the database query, these are names of columns in your database.
|
80
68
|
def options
|
81
|
-
@options ||=
|
69
|
+
@options ||= resource_map.instance_variable_get(:@options)
|
82
70
|
end
|
83
71
|
|
84
72
|
def primary_key
|
85
|
-
options
|
73
|
+
options.primary_key || "#{service}_id"
|
86
74
|
end
|
87
75
|
|
88
76
|
def foreign_key
|
89
|
-
options
|
77
|
+
options.foreign_key || 'id'
|
90
78
|
end
|
91
79
|
|
92
80
|
def conditions
|
93
|
-
|
94
|
-
keys = mapping.select{|k, v| p_keys.include?(v.to_s) }
|
95
|
-
format(keys)
|
81
|
+
{primary_key => format[primary_key]}
|
96
82
|
end
|
97
83
|
|
98
|
-
## #
|
99
|
-
# Return
|
100
|
-
def
|
101
|
-
return @
|
102
|
-
|
103
|
-
|
104
|
-
@
|
84
|
+
## #resource_map
|
85
|
+
# Return the mapped resource object for the current service and resource
|
86
|
+
def resource_map
|
87
|
+
return @resource_map if defined?(@resource_map)
|
88
|
+
resource_key = resource.to_s.underscore
|
89
|
+
@resource_map = service_map[resource_key]
|
90
|
+
raise MissingResourceError, "There is no #{resource_key} resource_map for #{service}" if @resource_map.nil?
|
91
|
+
@resource_map
|
105
92
|
end
|
106
93
|
|
107
94
|
private
|
108
95
|
|
109
|
-
def
|
96
|
+
def parse(dataset)
|
110
97
|
formatted = {}
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
else
|
115
|
-
dataset.each_pair do |key, val|
|
116
|
-
next if key == Spigot.config.options_key
|
117
|
-
attribute = map[key]
|
118
|
-
next if attribute.nil?
|
119
|
-
|
120
|
-
result = attribute.is_a?(Hash) ? translate(attribute, val) : val
|
121
|
-
formatted.merge! mergeable_content(key, result, map)
|
122
|
-
end
|
98
|
+
resource_map.definitions.each do |rule|
|
99
|
+
result = rule.parse(dataset)
|
100
|
+
formatted.merge!(result)
|
123
101
|
end
|
124
|
-
|
125
102
|
formatted
|
126
103
|
end
|
127
104
|
|
128
|
-
def
|
129
|
-
|
130
|
-
{key.to_s => value}
|
131
|
-
elsif value.is_a?(Hash)
|
132
|
-
value
|
133
|
-
else
|
134
|
-
{map[key] => value}
|
135
|
-
end
|
136
|
-
end
|
137
|
-
|
138
|
-
def condition_keys
|
139
|
-
options['conditions'].to_s.split(',').map(&:strip)
|
140
|
-
end
|
141
|
-
|
142
|
-
def resource_key
|
143
|
-
resource.to_s.underscore
|
144
|
-
end
|
145
|
-
|
146
|
-
def translations
|
147
|
-
@translations ||= Hashie::Mash.new(Spigot.config.translations || YAML.load(translation_file))
|
148
|
-
end
|
149
|
-
|
150
|
-
def translation_file
|
151
|
-
begin
|
152
|
-
@translation_file ||= File.read(File.join(Spigot.config.path, "#{service.to_s}.yml"))
|
153
|
-
rescue Errno::ENOENT => e
|
154
|
-
raise MissingServiceError, "There is no service map for #{service} defined"
|
155
|
-
end
|
105
|
+
def service_map
|
106
|
+
Spigot.config.map ? Spigot.config.map.service(service) : {}
|
156
107
|
end
|
157
108
|
|
158
109
|
end
|
data/lib/spigot/version.rb
CHANGED
data/script/console.rb
CHANGED
@@ -1,6 +1,32 @@
|
|
1
1
|
require 'active_record'
|
2
2
|
require 'spigot'
|
3
3
|
|
4
|
+
Spigot.define do
|
5
|
+
service :github do
|
6
|
+
resource :active_user do
|
7
|
+
id :github_id
|
8
|
+
full_name :name
|
9
|
+
login :username
|
10
|
+
contact do
|
11
|
+
address :address
|
12
|
+
telephone do
|
13
|
+
work :work_phone
|
14
|
+
home :home_phone
|
15
|
+
end
|
16
|
+
url :homepage do |value|
|
17
|
+
"https://github.com/#{value}"
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
resource :pull_request do
|
23
|
+
id :id
|
24
|
+
title :title
|
25
|
+
body :body
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
4
30
|
ActiveRecord::Base.logger = Spigot.logger
|
5
31
|
require File.join(Spigot.root, 'spec', 'support', 'active_record')
|
6
32
|
|
@@ -8,24 +34,4 @@ class ActiveUser < ActiveRecord::Base
|
|
8
34
|
include Spigot::Base
|
9
35
|
end
|
10
36
|
|
11
|
-
map = {'activeuser' => {
|
12
|
-
'name' => 'name',
|
13
|
-
'username' => 'login',
|
14
|
-
'spigot' => {
|
15
|
-
'primary_key' => 'username'
|
16
|
-
}
|
17
|
-
}}
|
18
|
-
|
19
|
-
conditions = {'activeuser' => {
|
20
|
-
'name' => 'name',
|
21
|
-
'login' => 'username',
|
22
|
-
'spigot' => {
|
23
|
-
'primary_key' => 'username'
|
24
|
-
}
|
25
|
-
}}
|
26
|
-
|
27
|
-
Spigot.configure do |config|
|
28
|
-
config.translations = conditions
|
29
|
-
end
|
30
|
-
|
31
37
|
user = ActiveUser.create(name: 'Matt', username: 'mttwrnr', token: 'abc123')
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module Spigot
|
2
|
+
module Data
|
3
|
+
class ActiveUser
|
4
|
+
class << self
|
5
|
+
|
6
|
+
def basic
|
7
|
+
{full_name: 'Dean Martin', login: 'classyasfuck', auth_token: '123abc'}
|
8
|
+
end
|
9
|
+
|
10
|
+
def alt
|
11
|
+
{full_name: 'Frank Sinatra', login: 'livetilidie', auth_token: '987zyx'}
|
12
|
+
end
|
13
|
+
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module Spigot
|
2
|
+
module Data
|
3
|
+
class Post
|
4
|
+
class << self
|
5
|
+
def basic
|
6
|
+
{'title' => 'Brief Article', 'body' => 'lorem ipsum'}
|
7
|
+
end
|
8
|
+
|
9
|
+
def alt
|
10
|
+
{'title' => 'Regular Article', 'body' => 'dolor sit amet', 'author' => 'Dean Martin'}
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
module Spigot
|
2
|
+
module Data
|
3
|
+
class User
|
4
|
+
class << self
|
5
|
+
def basic
|
6
|
+
{'id' => '123', 'full_name' => 'Dean Martin', 'login' => 'classyasfuck'}
|
7
|
+
end
|
8
|
+
|
9
|
+
def alt
|
10
|
+
{'full_name' => 'Frank Sinatra', 'login' => 'livetilidie', 'auth_token' => '456bcd'}
|
11
|
+
end
|
12
|
+
|
13
|
+
def full
|
14
|
+
basic.merge('auth_token' => '123abc')
|
15
|
+
end
|
16
|
+
|
17
|
+
def array
|
18
|
+
[full, alt]
|
19
|
+
end
|
20
|
+
|
21
|
+
def nested_array
|
22
|
+
{'account' => 'Rockafella', 'users' => array, 'count' => 2}
|
23
|
+
end
|
24
|
+
|
25
|
+
def nested
|
26
|
+
full.merge('login' => login_info)
|
27
|
+
end
|
28
|
+
|
29
|
+
def double_nested
|
30
|
+
full.merge('login' => {'contact' => login_info, 'last_seen_ip' => '127.0.0.1'})
|
31
|
+
end
|
32
|
+
|
33
|
+
private
|
34
|
+
|
35
|
+
def login_info
|
36
|
+
{'email' => 'dino@amore.io', 'user_name' => 'classyasfuck'}
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -1,42 +1,78 @@
|
|
1
1
|
module Spigot
|
2
2
|
module Mapping
|
3
|
-
|
4
3
|
class ActiveUser
|
5
4
|
|
6
|
-
def self.
|
7
|
-
|
5
|
+
def self.stub
|
6
|
+
template do
|
7
|
+
login :username
|
8
|
+
full_name :name
|
9
|
+
end
|
8
10
|
end
|
9
11
|
|
10
12
|
def self.with_options
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
13
|
+
template do
|
14
|
+
login :username
|
15
|
+
full_name :name
|
16
|
+
options do
|
17
|
+
primary_key :username
|
18
|
+
foreign_key :login
|
19
|
+
end
|
20
|
+
end
|
16
21
|
end
|
17
22
|
|
18
|
-
def self.
|
19
|
-
|
23
|
+
def self.non_unique_keys
|
24
|
+
template do
|
25
|
+
login :username
|
26
|
+
full_name :name
|
27
|
+
auth_token :token
|
28
|
+
options do
|
29
|
+
primary_key :token
|
30
|
+
foreign_key :auth_token
|
31
|
+
end
|
32
|
+
end
|
20
33
|
end
|
21
34
|
|
22
35
|
private
|
23
36
|
|
24
|
-
def self.
|
25
|
-
|
37
|
+
def self.template(&block)
|
38
|
+
Spigot.define do
|
39
|
+
service :github do
|
40
|
+
resource :active_user do
|
41
|
+
self.instance_eval(&block)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
26
45
|
end
|
27
46
|
|
28
|
-
def self.
|
29
|
-
|
30
|
-
end
|
47
|
+
# def self.basic
|
48
|
+
# {'active_user' => base}
|
49
|
+
# end
|
31
50
|
|
32
|
-
def self.
|
33
|
-
|
34
|
-
end
|
51
|
+
# def self.non_unique_key
|
52
|
+
# {'active_user' => base.merge('auth_token' => 'token', 'spigot' => non_unique)}
|
53
|
+
# end
|
35
54
|
|
36
|
-
def self.
|
37
|
-
|
38
|
-
end
|
39
|
-
|
55
|
+
# def self.with_invalid_options
|
56
|
+
# {'active_user' => base.merge('spigot' => invalid_options)}
|
57
|
+
# end
|
58
|
+
|
59
|
+
# private
|
60
|
+
|
61
|
+
# def self.base
|
62
|
+
# {'full_name' => 'name', 'login' => 'username'}
|
63
|
+
# end
|
40
64
|
|
65
|
+
# def self.options
|
66
|
+
# {'primary_key' => 'username', 'foreign_key' => 'login'}
|
67
|
+
# end
|
68
|
+
|
69
|
+
# def self.non_unique
|
70
|
+
# {'primary_key' => 'token', 'foreign_key' => 'auth_token'}
|
71
|
+
# end
|
72
|
+
|
73
|
+
# def self.invalid_options
|
74
|
+
# {'primary_key' => 'nosuchcolumn', 'foreign_key' => 'nosuchkey'}
|
75
|
+
# end
|
76
|
+
end
|
41
77
|
end
|
42
78
|
end
|