data-provider 0.1.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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 38f6f8ba1418886f65eb5bed06cfba596744dfb8
4
+ data.tar.gz: 33d309c91f3cbb341159b20f99129d0ea387a10e
5
+ SHA512:
6
+ metadata.gz: f73b0708c03917f4a58a14bffddbd1357336154b917f0ff610511c0572fb743f12f2824647b36d7bd30972967cc41d6a887de8ae696b6318acd69236a847ec51
7
+ data.tar.gz: a19b6508e5c30fe4ad94ee42c0f205f8a539cc9f1311b9828feb407daf66ab99d2651f8268b418ffaf91c922c93006cfc9a03535a7ee14af676b7382ecc76c13
data/.gitignore ADDED
@@ -0,0 +1,35 @@
1
+ *.gem
2
+ *.rbc
3
+ /.config
4
+ /coverage/
5
+ /InstalledFiles
6
+ /pkg/
7
+ /spec/reports/
8
+ /test/tmp/
9
+ /test/version_tmp/
10
+ /tmp/
11
+
12
+ ## Specific to RubyMotion:
13
+ .dat*
14
+ .repl_history
15
+ build/
16
+
17
+ ## Documentation cache and generated files:
18
+ /.yardoc/
19
+ /_yardoc/
20
+ /doc/
21
+ /rdoc/
22
+
23
+ ## Environment normalisation:
24
+ /.bundle/
25
+ /vendor/bundle
26
+ /lib/bundler/man/
27
+
28
+ # for a library or gem, you might want to ignore these files since the code is
29
+ # intended to run in multiple environments; otherwise, check them in:
30
+ # Gemfile.lock
31
+ .ruby-version
32
+ .ruby-gemset
33
+
34
+ # unless supporting rvm < 1.11.0 or doing something fancy, ignore this:
35
+ .rvmrc
data/Gemfile ADDED
@@ -0,0 +1,7 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gemspec
4
+
5
+ group :test do
6
+ gem 'byebug'
7
+ end
data/Gemfile.lock ADDED
@@ -0,0 +1,36 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ data-provider (0.0.1)
5
+
6
+ GEM
7
+ remote: https://rubygems.org/
8
+ specs:
9
+ byebug (5.0.0)
10
+ columnize (= 0.9.0)
11
+ columnize (0.9.0)
12
+ diff-lcs (1.2.5)
13
+ rspec (3.3.0)
14
+ rspec-core (~> 3.3.0)
15
+ rspec-expectations (~> 3.3.0)
16
+ rspec-mocks (~> 3.3.0)
17
+ rspec-core (3.3.1)
18
+ rspec-support (~> 3.3.0)
19
+ rspec-expectations (3.3.0)
20
+ diff-lcs (>= 1.2.0, < 2.0)
21
+ rspec-support (~> 3.3.0)
22
+ rspec-mocks (3.3.1)
23
+ diff-lcs (>= 1.2.0, < 2.0)
24
+ rspec-support (~> 3.3.0)
25
+ rspec-support (3.3.0)
26
+
27
+ PLATFORMS
28
+ ruby
29
+
30
+ DEPENDENCIES
31
+ byebug
32
+ data-provider!
33
+ rspec
34
+
35
+ BUNDLED WITH
36
+ 1.10.5
data/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2015 Mark
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
22
+
data/README.md ADDED
@@ -0,0 +1,154 @@
1
+ # data-provider
2
+ Ruby gem that provides a set of classes to build consistent data interfaces
3
+
4
+ ## Installation
5
+
6
+ Rubygems:
7
+ ```
8
+ gem install data-provider
9
+ ```
10
+
11
+ Bundler:
12
+ ```ruby
13
+ gem 'data-provider'
14
+ ```
15
+
16
+ ## Examples
17
+
18
+ Define a provider class with some providers
19
+ ```ruby
20
+
21
+ require 'data_provider'
22
+
23
+ class BookProvider
24
+ include DataProvider::Base
25
+
26
+ # quick syntax for 'simple' providers
27
+ provides({
28
+ title: 'The Monkey Wrench Gang',
29
+ author: 'Edward Abbey'
30
+ })
31
+
32
+ # longer syntax for more complicated providers
33
+ provider :display_title do
34
+ "#{take(:author)} - #{take(:title)}"
35
+ end
36
+
37
+ provider :price do
38
+ 9.99
39
+ end
40
+ end
41
+ ```
42
+
43
+ Using a provider class
44
+ ```ruby
45
+ book_provider = BookProvider.new()
46
+ book_provider.take(:title) # => 'The Monkey Wrench Gang'
47
+ book_provider.take(:author) # => 'Edward Abbey'
48
+ book_provider.take(:display_title) # => 'Edward Abbey - The Monkey Wrench Gang'
49
+ book_provider.take(:price) # => 9.99
50
+ ```
51
+
52
+ Data providers can be given data to customize their output
53
+ ```ruby
54
+ require 'data_provider'
55
+
56
+ class ProductProvider
57
+ include DataProvider::Base
58
+
59
+ provider :normal_price do
60
+ 17.99
61
+ end
62
+
63
+ provider :discount_price do
64
+ take(:normal_price) - get_data(:discount)
65
+ end
66
+ end
67
+
68
+ product_provider = ProductProvider.new
69
+ product_provider.take(:normal_price) # => 17.99
70
+ product_provider.take(:discount_price) # => TypeError (discount data not given,): nil can't be coerced into Float
71
+ discounted_provider = product_provider.add_data(discount: 3.0) # returns a new instance of the same provider class
72
+ discounted_provider.take(:discount_price) # => 14.99
73
+ product_provider.take(:discount_price) # => TypeError (this instance didn't get the new data)
74
+ product_provider.add_date!(discount: 2) # => Updates this instance instead of creating a new one
75
+ product_provider.take(:discount_price) # => 15.99
76
+ product_provider.add_date!(discount: 4).take(:discount_price) #=> 13.99
77
+ ```
78
+
79
+ Providers can be defined in a module and added to a provider class using the add class-method (not using include!)
80
+ ```ruby
81
+ require 'data-provider'
82
+
83
+ module BandInfo
84
+ include DataProvider::Base
85
+
86
+ provider :band do
87
+ 'D4'
88
+ end
89
+
90
+ provider :bassPlayer do
91
+ 'Paddy'
92
+ end
93
+ end
94
+
95
+ class Band
96
+ include DataProvider::Base
97
+
98
+ provider :band do
99
+ 'Dillinger Four'
100
+ end
101
+
102
+ provider :drummer do
103
+ 'Lane Pederson'
104
+ end
105
+
106
+ add BandInfo # note: add, not include!
107
+ end
108
+
109
+ band = Band.new
110
+ band.take(:band) # => 'D4', class provider was overwritten when the module got added
111
+ band.take(:bassPlayer) # => 'Paddy'
112
+ band.take(:drummer) #=> 'Lane Pederson'
113
+ ```
114
+
115
+ Provider identifiers don't have to be symbols, they can be anything. Specifically array identifiers are suitable for creating data providers for hierarchical systems
116
+ ```ruby
117
+ require 'data_provider'
118
+
119
+ module AlbumProvider
120
+ include DataProvider::Base
121
+
122
+ provides({
123
+ title: 'Reinventing Axle Rose',
124
+ band: 'Against Me!'
125
+ [:band, :hometown] => 'Gainesville, FL'
126
+ })
127
+ end
128
+
129
+ class Catalog
130
+ include DataProvider::Base
131
+
132
+ provider [:music, :album, :bandname] do
133
+ # scoped_take is a method only available inside provider blocks,
134
+ # it lets a provider access other providers in the same 'scope',
135
+ # which means provider whose array-identifiers start with the same values,
136
+ # in this case the scope is [:music, :album]
137
+ scoped_take(:band).upcase
138
+ end
139
+
140
+ # by using `add_scoped` all providers of the added module, will be
141
+ # turned into array and prefixed with the given scope
142
+ add_scoped AlbumProvider, :scope => [:music, :album]
143
+ end
144
+
145
+ catalog = Catalog.new
146
+ catalog.take(:title) # => DataProvider::ProviderMissingException
147
+ catalog.take([:music, :album, :title]) # => 'Reinventing Axle Rose'
148
+ catalog.take([:music, :album, :band, :hometown]) # => 'Gainesville, FL'
149
+ catalog.take([:music, :album, :bandname]) # => 'AGAINST ME!"
150
+ ```
151
+
152
+
153
+
154
+
data/Rakefile ADDED
@@ -0,0 +1,20 @@
1
+ # rxsd project Rakefile
2
+ #
3
+ # Copyright (C) 2010 Mohammed Morsi <movitto@yahoo.com>
4
+ # Licensed under the LGPLv3+ http://www.gnu.org/licenses/lgpl.txt
5
+
6
+ require 'rdoc/task'
7
+ require "rspec/core/rake_task"
8
+
9
+ task :default => :rspec do; end
10
+
11
+ desc "Run all specs"
12
+ RSpec::Core::RakeTask.new('rspec') do |t|
13
+ t.pattern = 'spec/**/*_spec.rb'
14
+ end
15
+
16
+ Rake::RDocTask.new do |rd|
17
+ rd.main = "README.rdoc"
18
+ rd.rdoc_dir = "doc/site/api"
19
+ rd.rdoc_files.include("README.rdoc", "lib/**/*.rb")
20
+ end
@@ -0,0 +1,19 @@
1
+ GEM_NAME="data-provider"
2
+ PKG_VERSION='0.1.0'
3
+
4
+ Gem::Specification.new do |s|
5
+ s.name = GEM_NAME
6
+ s.version = PKG_VERSION
7
+ s.files = `git ls-files`.split($/)
8
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
9
+
10
+ s.add_development_dependency 'rspec'
11
+
12
+ s.author = "Mark van de Korput"
13
+ s.email = "dr.theman@gmail.com"
14
+ s.date = '2015-07-14'
15
+ s.description = %q{A library of Ruby classes to help create consistent data interfaces}
16
+ s.summary = %q{A library of Ruby classes to help create consistent data interfaces}
17
+ s.homepage = %q{https://github.com/markkorput/data-provider}
18
+ s.license = "MIT"
19
+ end
@@ -0,0 +1,227 @@
1
+ require 'logger'
2
+
3
+ module DataProvider
4
+
5
+ class ProviderMissingException < Exception
6
+ end
7
+
8
+ module Base
9
+
10
+ def self.included(base)
11
+ base.class_eval do
12
+ include InstanceMethods
13
+ extend ClassMethods
14
+ end
15
+ end
16
+
17
+ module ClassMethods
18
+ # provides, when called with a hash param, will define 'simple providers' (providers
19
+ # with a simple, static value). When called without a param (or nil) it returns
20
+ # the current cumulative 'simple providers' hash
21
+ def provides simple_provides = nil
22
+ if simple_provides
23
+ @data_provider ||= {}
24
+ @data_provider[:provides] ||= {}
25
+ @data_provider[:provides].merge!(simple_provides)
26
+ return self
27
+ end
28
+ # no data given? just return existing hash
29
+ (@data_provider || {})[:provides] || {}
30
+ end
31
+
32
+ # returns the requested provider as a Provider object
33
+ def get_provider(id)
34
+ args = data_provider_definitions.find{|args| args.first == id}
35
+ return args.nil? ? nil : Provider.new(*args)
36
+ end
37
+
38
+ def provider_identifiers
39
+ (provides.keys + data_provider_definitions.map(&:first)).compact.uniq
40
+ end
41
+
42
+ # adds a new provider to the class
43
+ def provider identifier, opts = {}, &block
44
+ add_provider(identifier, opts, block_given? ? block : nil)
45
+ end
46
+
47
+ # reader method for the raw data of the currently defined providers
48
+ def data_provider_definitions
49
+ ((@data_provider || {})[:provider_args] || [])
50
+ end
51
+
52
+ # returns wether a provider with the given identifier is available
53
+ def has_provider?(identifier)
54
+ (provides[identifier] || get_provider(identifier)) != nil
55
+ end
56
+
57
+ def has_providers_with_scope?(args)
58
+ scope = args.is_a?(Array) ? args : [args]
59
+ provider_identifiers.find{|id| id.is_a?(Array) && id.length > scope.length && id[0..(scope.length-1)] == scope} != nil
60
+ end
61
+
62
+ def fallback_provider?
63
+ !fallback_provider.nil?
64
+ end
65
+
66
+ # adds all the providers defined in the given module to this class
67
+ def add(providers_module)
68
+ data = providers_module.instance_variable_get('@data_provider') || {}
69
+
70
+ (data[:provider_args] || []).each do |definition|
71
+ add_provider(*definition)
72
+ end
73
+
74
+ self.provides(data[:provides] || {})
75
+ end
76
+
77
+ # adds all the providers defined in the given module to this class,
78
+ # but turns their identifiers into array and prefixes the array with the :scope option
79
+ def add_scoped(providers_module, _options = {})
80
+ data = providers_module.instance_variable_get('@data_provider') || {}
81
+
82
+ (data[:provider_args] || []).each do |definition|
83
+ definition[0] = [definition[0]].flatten
84
+ definition[0] = [_options[:scope]].flatten.compact + definition[0] if _options[:scope]
85
+ add_provider(*definition)
86
+ end
87
+
88
+ (data[:provides] || {}).each_pair do |key, value|
89
+ provides(([_options[:scope]].flatten.compact + [key].flatten.compact) => value)
90
+ end
91
+ end
92
+
93
+ def provider_missing &block
94
+ raise "DataProvider::Base#provider_missing expects a block as an argument" if !block_given?
95
+ @data_provider ||= {}
96
+ @data_provider[:provider_missing] = block
97
+ end
98
+
99
+ def fallback_provider
100
+ block = (@data_provider || {})[:provider_missing]
101
+ block.nil? ? nil : Provider.new(nil, nil, block)
102
+ end
103
+
104
+ private
105
+
106
+ def add_provider(identifier, opts = {}, block = nil)
107
+ @data_provider ||= {}
108
+ @data_provider[:provider_args] ||= []
109
+ @data_provider[:provider_args].unshift [identifier, opts, block]
110
+ end
111
+ end # module ClassMethods
112
+
113
+
114
+ module InstanceMethods
115
+
116
+ attr_reader :data
117
+ attr_reader :options
118
+
119
+ def initialize(opts = {})
120
+ @options = opts.is_a?(Hash) ? opts : {}
121
+ @data = options[:data].is_a?(Hash) ? options[:data] : {}
122
+ end
123
+
124
+ def logger
125
+ @logger ||= options[:logger] || Logger.new(STDOUT)
126
+ end
127
+
128
+ def has_provider?(id)
129
+ self.class.has_provider?(id)
130
+ end
131
+
132
+ def has_providers_with_scope?(scope)
133
+ self.class.has_providers_with_scope?(scope)
134
+ end
135
+
136
+ def fallback_provider?
137
+ self.class.fallback_provider?
138
+ end
139
+
140
+ def take(id)
141
+ # first try the simple providers
142
+ if self.class.provides.has_key?(id)
143
+ provider = self.class.provides[id]
144
+ return provider.is_a?(Proc) ? provider.call : provider
145
+ end
146
+ # try to get a provider object
147
+ provider = self.class.get_provider(id)
148
+ if provider
149
+ @scope ||= []
150
+ @scope << (id.is_a?(Array) ? id[0..-2] : [])
151
+ result = instance_eval(&provider.block)
152
+ @scope.pop
153
+ # execute provider object's block within the scope of self
154
+ return result
155
+ end
156
+
157
+ # couldn't find requested provider, let's see if there's a fallback
158
+ if provider = self.class.fallback_provider
159
+ # temporarily set the @missing_provider instance variable, so the
160
+ # fallback provider can use it through the missing_provider private method
161
+ @missing_provider = id
162
+ @scope ||= []
163
+ @scope << (id.is_a?(Array) ? id[0..-2] : [])
164
+ result = instance_eval(&provider.block) # provider.block.call # with the block.call method the provider can't access private methods like missing_provider
165
+ @scope = nil
166
+ return result
167
+ end
168
+ # no fallback either? Time for an error
169
+ raise ProviderMissingException.new(:message=>"Tried to take data from missing provider.", :provider_id => id)
170
+ end
171
+
172
+ def try_take(id, opts = {})
173
+ return take(id) if self.has_provider?(id) || self.fallback_provider?
174
+ if opts[:fallback] == true
175
+
176
+ logger.debug "Try for missing provider: #{id.inspect}"
177
+ return nil
178
+ end
179
+ end
180
+
181
+ private
182
+
183
+ def scoped_take(id)
184
+ take(((@scope || []).last || []) + [id].flatten)
185
+ end
186
+
187
+ public
188
+
189
+ def given(param_name)
190
+ return data[param_name] if data.has_key?(param_name)
191
+ logger.error "Data provider expected missing data with identifier: #{param_name.inspect}"
192
+ # TODO: raise?
193
+ return nil
194
+ end
195
+
196
+ alias :get_data :given
197
+
198
+ def give(_data = {})
199
+ return self.class.new(options.merge(:data => data.merge(_data)))
200
+ end
201
+
202
+ alias :add_scope :give
203
+ alias :add_data :give
204
+
205
+ def give!(_data = {})
206
+ @data = data.merge(_data)
207
+ return self
208
+ end
209
+
210
+ alias :add_scope! :give!
211
+ alias :add_data! :give!
212
+
213
+ private
214
+
215
+ def missing_provider
216
+ # byebug
217
+ @missing_provider
218
+ end
219
+
220
+ def scope
221
+ @scope || []
222
+ end
223
+ end # module InstanceMethods
224
+
225
+ end # module Base
226
+
227
+ end # module DataProvider
@@ -0,0 +1,20 @@
1
+ module DataProvider
2
+ class Provider
3
+ attr_reader :options
4
+ attr_reader :identifier
5
+ attr_reader :block
6
+
7
+ def initialize(identifier, opts = {}, block = nil)
8
+ @identifier = identifier
9
+ @options = opts.is_a?(Hash) ? opts : {}
10
+ @block = block || Proc.new
11
+ end
12
+
13
+ alias_method :id, :identifier
14
+
15
+ def requirements
16
+ [options[:requires]].flatten.compact
17
+ end
18
+
19
+ end # module Provider
20
+ end # module DataProvider
@@ -0,0 +1,2 @@
1
+ require 'data_provider/provider'
2
+ require 'data_provider/base'
@@ -0,0 +1,420 @@
1
+ require File.dirname(__FILE__) + '/spec_helper'
2
+
3
+ describe DataProvider::Base do
4
+ # Example implementation of DataProvider::Base
5
+ class ProviderClass
6
+ include DataProvider::Base
7
+
8
+ provider :sum, :requires => [:array] do
9
+ sum = 0
10
+
11
+ given(:array).each do |number|
12
+ sum += number.to_i
13
+ end
14
+
15
+ sum
16
+ end
17
+
18
+ provider :static do
19
+ 'StaticValue'
20
+ end
21
+
22
+ provider :billy do
23
+ take([:identification, :fullname])
24
+ end
25
+
26
+ provider [:identification, :firstname] do
27
+ 'Billy'
28
+ end
29
+
30
+ provider [:identification, :lastname] do
31
+ 'Bragg'
32
+ end
33
+
34
+ provider [:identification, :fullname] do
35
+ "#{scoped_take(:firstname)} #{scoped_take(:lastname)}"
36
+ end
37
+ end
38
+
39
+ let(:provider){
40
+ ProviderClass.new(:data => {:array => [1,2,4]})
41
+ }
42
+
43
+ describe "#has_provider?" do
44
+ it 'provides the has_provider? instance method' do
45
+ expect(provider.has_provider?(:sum)).to be true
46
+ expect(provider.has_provider?(:static)).to be true
47
+ expect(provider.has_provider?(:modulus)).to be false
48
+ end
49
+
50
+ it 'provides the has_provider? class method' do
51
+ expect(ProviderClass.respond_to?(:has_provider?)).to eq true
52
+ expect(ProviderClass.has_provider?(:sum)).to eq true
53
+ expect(ProviderClass.has_provider?(:divid)).to eq false
54
+ end
55
+ end
56
+
57
+ describe "#has_providers_with_scope?" do
58
+ let(:klass){
59
+ Class.new Object do
60
+ include DataProvider::Base
61
+ provider [:a, :b ,:c]
62
+ provider :unscoped
63
+ end
64
+ }
65
+
66
+ it "return true if there are providers defined with an array identifier that start with the given prefix" do
67
+ expect(klass.new.has_providers_with_scope?(:unscoped)).to eq false
68
+ # byebug
69
+ expect(klass.has_providers_with_scope?(:a)).to eq true
70
+ expect(klass.new.has_providers_with_scope?([:a, :b])).to eq true
71
+ # scope means prefix, identfier may not be exactly the given array
72
+ expect(klass.new.has_providers_with_scope?([:a, :b, :c])).to eq false
73
+ end
74
+ end
75
+
76
+ describe "#take" do
77
+ it 'lets you take data from it' do
78
+ expect(provider.take(:sum)).to eq 7
79
+ expect(provider.take(:static)).to eq 'StaticValue'
80
+ end
81
+
82
+ it 'raise a ProviderMissingException when attempting to take from unknown provider' do
83
+ expect{provider.take(:unknown)}.to raise_error(DataProvider::ProviderMissingException)
84
+ end
85
+
86
+
87
+ it 'works from within a provider block' do
88
+ expect(provider.take(:billy)).to eq 'Billy Bragg'
89
+ end
90
+ end
91
+
92
+ describe "#try_take" do
93
+ it "acts like #take when the specified provider is present" do
94
+ expect(provider.try_take(:sum)).to eq 7
95
+ end
96
+
97
+ it "returns nil when the specified provider is not found" do
98
+ expect(provider.try_take(:square_root)).to eq nil
99
+ end
100
+ end
101
+
102
+ describe "#scoped_take" do
103
+ it 'lets a provider call providers within its own scope' do
104
+ expect(provider.take([:identification, :fullname])).to eq 'Billy Bragg'
105
+ end
106
+ end
107
+
108
+ describe "#give" do
109
+ it "lets you give data, creating a new data provider instance" do
110
+ updated_provider = provider.give :array => [1,80]
111
+ expect(provider.take(:sum)).to eq 7
112
+ expect(updated_provider.take(:sum)).to eq 81
113
+ end
114
+
115
+ it "allows for linked notation" do
116
+ expect(provider.give(:array => [7, -3]).take(:sum)).to eq 4
117
+ end
118
+
119
+ it "has an add_scope alias" do
120
+ expect(provider.add_scope(:array => [400, 20]).take(:sum)).to eq 420
121
+ end
122
+
123
+ it "has an add_data alias" do
124
+ expect(provider.add_data(:array => [400, 20]).take(:sum)).to eq 420
125
+ end
126
+ end
127
+
128
+ describe "#give!" do
129
+ it "lets you update the current provider with additional data" do
130
+ prov = ProviderClass.new(:data => {:array => [1,1,90]})
131
+ expect(prov.take(:sum)).to eq 92
132
+ prov.give!(:array => [3,90])
133
+ expect(prov.take(:sum)).to eq 93
134
+ end
135
+
136
+ it "allows for linked notation" do
137
+ expect(provider.give.give!(:array => [-1, -4]).take(:sum)).to eq -5
138
+ end
139
+
140
+ it "has an add_scope! alias" do
141
+ newprovider = provider.add_scope
142
+ newprovider.add_scope!(:array => [-1, -4])
143
+ expect(newprovider.given(:array)).to eq [-1,-4]
144
+ expect(newprovider.take(:sum)).to eq -5
145
+ end
146
+
147
+ it "has an add_data! alias" do
148
+ scoped_provider = provider.add_data(:array => []).add_data!(:array => [5, 5])
149
+ expect(scoped_provider.get_data(:array)).to eq [5,5]
150
+ expect(scoped_provider.take(:sum)).to eq 10
151
+ end
152
+ end
153
+
154
+ describe "#given" do
155
+ it "has a given method to get given data" do
156
+ expect(provider.given(:array)).to eq [1,2,4]
157
+ expect(provider.give(:array => 'array').given(:array)).to eq 'array'
158
+ end
159
+
160
+ it "has a get_data alias" do
161
+ expect(provider.get_data(:array)).to eq provider.given(:array)
162
+ end
163
+ end
164
+
165
+ describe "#provides" do
166
+ class SimpleProviders
167
+ include DataProvider::Base
168
+ provides({
169
+ :name => 'Paddy',
170
+ 'instrument' => :bass,
171
+ })
172
+ end
173
+
174
+ it "lets you request all currently available simple providers when called without a parameter" do
175
+ expect(SimpleProviders.provides).to eq({
176
+ :name => 'Paddy',
177
+ 'instrument' => :bass
178
+ })
179
+ end
180
+
181
+ it "lets you define simple providers" do
182
+ expect(SimpleProviders.new.take(:name)).to eq 'Paddy'
183
+ expect(SimpleProviders.new.take('instrument')).to eq :bass
184
+ end
185
+
186
+ it "works with has_provider?" do
187
+ expect(SimpleProviders.has_provider?(:name)).to eq true
188
+ expect(SimpleProviders.new.has_provider?('name')).to eq false
189
+ expect(SimpleProviders.has_provider?('instrument')).to eq true
190
+ expect(SimpleProviders.new.has_provider?(:instrument)).to eq false
191
+ end
192
+
193
+ it "lets you overwrite existing simple providers" do
194
+ SimpleProviders.provides({:name => 'Erik'})
195
+ expect(SimpleProviders.new.take(:name)).to eq 'Erik'
196
+ end
197
+
198
+ it "lets you write linked notation" do
199
+ expect(SimpleProviders.provides({:name => 'Lane'}).new.take(:name)).to eq 'Lane'
200
+ end
201
+
202
+ it "works with lambdas" do
203
+ expect(SimpleProviders.provides(:name => lambda{ 'Patrick' }).new.take(:name)).to eq 'Patrick'
204
+ end
205
+
206
+ it "works with Procs" do
207
+ expect(SimpleProviders.provides(:name => Proc.new{ 'St. Patrick' }).new.take(:name)).to eq 'St. Patrick'
208
+ end
209
+ end
210
+
211
+ describe "#add" do
212
+ module OddProviders
213
+ include DataProvider::Base
214
+ provides({1 => 'one'})
215
+ provider :three do 3 end
216
+ end
217
+
218
+ module OddOverwriteProviders
219
+ include DataProvider::Base
220
+ provides({1 => 'Uno', :five => 555})
221
+ provider :three do :tres end
222
+ end
223
+
224
+ class BasicProviders
225
+ include DataProvider::Base
226
+ provides({2 => '1'})
227
+ provider :four do '4' end
228
+ add OddProviders
229
+ end
230
+
231
+ it "lets you add providers from another module" do
232
+ expect(BasicProviders.has_provider?(1)).to eq true
233
+ expect(BasicProviders.has_provider?(2)).to eq true
234
+ expect(BasicProviders.has_provider?(:three)).to eq true
235
+ expect(BasicProviders.has_provider?(:four)).to eq true
236
+ # expect(BasicProviders.new.take(1)).to eq 'one'
237
+ expect(BasicProviders.new.take(:three)).to eq 3
238
+ end
239
+
240
+ it "lets you add providers from another module at runtime" do
241
+ expect(BasicProviders.has_provider?(:five)).to eq false
242
+ BasicProviders.add(OddOverwriteProviders)
243
+ expect(BasicProviders.has_provider?(:five)).to eq true
244
+ end
245
+
246
+ # for the following test the providers of OddOverwriteProviders
247
+ # have already been added (by the previous test)
248
+ it "lets overwrite providers" do
249
+ expect(BasicProviders.new.take(1)).to eq 'Uno'
250
+ expect(BasicProviders.new.take(:three)).to eq :tres
251
+ end
252
+ end
253
+
254
+ describe "#add_scoped" do
255
+ module ChildProviders
256
+ include DataProvider::Base
257
+ provider :name do "child" end
258
+ end
259
+
260
+ module GrandchildProviders
261
+ include DataProvider::Base
262
+ provider :name do "grandchild" end
263
+ provider [:age] do 1 end
264
+ provides({
265
+ :mommy => 'Wilma',
266
+ :daddy => 'Fret'
267
+ })
268
+ end
269
+
270
+ class ProviderKlass
271
+ include DataProvider::Base
272
+ provider :parent do 'parent' end
273
+ add_scoped ChildProviders, :scope => :child
274
+ add_scoped GrandchildProviders, :scope => [:child, :child]
275
+ end
276
+
277
+ it 'let you array-prefix the providers of an included module' do
278
+ expect(ProviderKlass.has_provider?(:parent)).to eq true
279
+ expect(ProviderKlass.has_provider?(:name)).to eq false
280
+ expect(ProviderKlass.has_provider?([:child, :name])).to eq true
281
+ expect(ProviderKlass.has_provider?([:child, :age])).to eq false
282
+ expect(ProviderKlass.has_provider?([:child, :child, :name])).to eq true
283
+ expect(ProviderKlass.has_provider?([:child, :child, :age])).to eq true
284
+ expect(ProviderKlass.has_provider?([:child, :child, :mommy])).to eq true
285
+ expect(ProviderKlass.has_provider?([:child, :child, :daddy])).to eq true
286
+ expect(ProviderKlass.new.take([:child, :name])).to eq 'child'
287
+ expect(ProviderKlass.new.take([:child, :child, :name])).to eq 'grandchild'
288
+ expect(ProviderKlass.new.take([:child, :child, :age])).to eq 1
289
+ expect(ProviderKlass.new.take([:child, :child, :mommy])).to eq 'Wilma'
290
+ expect(ProviderKlass.new.take([:child, :child, :daddy])).to eq 'Fret'
291
+ end
292
+ end
293
+
294
+ describe "provider_missing" do
295
+ it "lets you define a default fallback provider" do
296
+ klass = Class.new Object do
297
+ include DataProvider::Base
298
+ provider_missing do
299
+ "This provider don't exist!"
300
+ end
301
+ end
302
+
303
+ expect(klass.has_provider?(:message)).to eq false
304
+ expect(klass.new.take(:message)).to eq "This provider don't exist!"
305
+ end
306
+
307
+ it "provides the missing provider id through the private missing_provider method" do
308
+ klass = Class.new Object do
309
+ include DataProvider::Base
310
+ provider_missing do
311
+ "Missing #{missing_provider}"
312
+ end
313
+ end
314
+
315
+ expect(klass.new.take(:something)).to eq 'Missing something'
316
+ expect{klass.new.missing_provider}.to raise_error(NoMethodError)
317
+ end
318
+
319
+ it 'calls the fallback provider when using try_take with an unknown provider' do
320
+ klass = Class.new Object do
321
+ include DataProvider::Base
322
+ provider_missing do
323
+ "fallback_#{missing_provider}"
324
+ end
325
+ end
326
+
327
+ expect(klass.new.try_take(:cool)).to eq 'fallback_cool'
328
+ end
329
+ end
330
+
331
+ describe "fallback_provider?" do
332
+ it "lets you know if a fallback provider has been registered" do
333
+ klass = Class.new Object do
334
+ include DataProvider::Base
335
+ end
336
+
337
+ expect(klass.fallback_provider?).to eq false
338
+ expect(klass.new.fallback_provider?).to eq false
339
+
340
+ klass.provider_missing do
341
+ "New fallback!"
342
+ end
343
+
344
+ expect(klass.fallback_provider?).to eq true
345
+ expect(klass.new.fallback_provider?).to eq true
346
+ end
347
+ end
348
+ end
349
+
350
+ describe "Adding additional providers" do
351
+ module AdditionalProvider
352
+ include DataProvider::Base
353
+
354
+ provider 'provider2' do
355
+ '#2'
356
+ end
357
+ end
358
+
359
+ module OverwriteProvider
360
+ include DataProvider::Base
361
+
362
+ provider 'provider1' do
363
+ '#111'
364
+ end
365
+ end
366
+
367
+ class OriginalProvider
368
+ include DataProvider::Base
369
+
370
+ provider 'provider1' do
371
+ '#1'
372
+ end
373
+
374
+ add AdditionalProvider
375
+ add OverwriteProvider
376
+ end
377
+
378
+ it "lets you include modules with additional providers" do
379
+ expect(OriginalProvider.new.take('provider2')).to eq '#2'
380
+ end
381
+
382
+ it "lets you include modules with additional providers" do
383
+ expect(OriginalProvider.new.take('provider1')).to eq '#111'
384
+ end
385
+ end
386
+
387
+ describe "Array identifiers" do
388
+ module ArrayProviderModule
389
+ include DataProvider::Base
390
+
391
+ provider [:some, 'Stuff'] do
392
+ 'OtherStuff'
393
+ end
394
+ end
395
+
396
+ class ArrayProviderClass
397
+ include DataProvider::Base
398
+
399
+ provider [:some, 'Stuff'] do
400
+ 'SomeStuff'
401
+ end
402
+
403
+ # add ArrayProviderModule
404
+ end
405
+
406
+ let(:provider){
407
+ ArrayProviderClass.new
408
+ }
409
+
410
+ it "lets you use array as provider identifiers" do
411
+ expect(provider.take([:some, 'Stuff'])).to eq 'SomeStuff'
412
+ end
413
+
414
+ it "lets you overwrite existing providers with Array-based identifiers" do
415
+ expect(provider.take([:some, 'Stuff'])).to eq 'SomeStuff'
416
+
417
+ provider.class.add(ArrayProviderModule)
418
+ expect(provider.take([:some, 'Stuff'])).to eq 'OtherStuff'
419
+ end
420
+ end
@@ -0,0 +1,12 @@
1
+ # loads and runs all tests for the rxsd project
2
+ #
3
+ # Copyright (C) 2010 Mohammed Morsi <movitto@yahoo.com>
4
+ # Licensed under the AGPLv3+ http://www.gnu.org/licenses/agpl.txt
5
+
6
+ require 'rspec'
7
+
8
+ CURRENT_DIR=File.dirname(__FILE__)
9
+ $: << File.expand_path(CURRENT_DIR + "/../lib")
10
+
11
+ require 'data_provider'
12
+ require 'byebug'
metadata ADDED
@@ -0,0 +1,69 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: data-provider
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Mark van de Korput
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-07-14 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rspec
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ description: A library of Ruby classes to help create consistent data interfaces
28
+ email: dr.theman@gmail.com
29
+ executables: []
30
+ extensions: []
31
+ extra_rdoc_files: []
32
+ files:
33
+ - ".gitignore"
34
+ - Gemfile
35
+ - Gemfile.lock
36
+ - LICENSE
37
+ - README.md
38
+ - Rakefile
39
+ - data-provider.gemspec
40
+ - lib/data_provider.rb
41
+ - lib/data_provider/base.rb
42
+ - lib/data_provider/provider.rb
43
+ - spec/data_provider_spec.rb
44
+ - spec/spec_helper.rb
45
+ homepage: https://github.com/markkorput/data-provider
46
+ licenses:
47
+ - MIT
48
+ metadata: {}
49
+ post_install_message:
50
+ rdoc_options: []
51
+ require_paths:
52
+ - lib
53
+ required_ruby_version: !ruby/object:Gem::Requirement
54
+ requirements:
55
+ - - ">="
56
+ - !ruby/object:Gem::Version
57
+ version: '0'
58
+ required_rubygems_version: !ruby/object:Gem::Requirement
59
+ requirements:
60
+ - - ">="
61
+ - !ruby/object:Gem::Version
62
+ version: '0'
63
+ requirements: []
64
+ rubyforge_project:
65
+ rubygems_version: 2.2.2
66
+ signing_key:
67
+ specification_version: 4
68
+ summary: A library of Ruby classes to help create consistent data interfaces
69
+ test_files: []