wcc-data 0.3.9 → 0.4.0.pre
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/.env.example +3 -0
- data/.gitignore +18 -0
- data/.rspec +2 -0
- data/Gemfile +6 -0
- data/Rakefile +36 -0
- data/bin/rspec +17 -0
- data/circle.yml +6 -0
- data/lib/wcc/data/faraday_client_app_token_auth.rb +63 -44
- data/lib/wcc/data/nucleus/campus.rb +3 -25
- data/lib/wcc/data/version.rb +1 -1
- data/spec/spec_helper.rb +24 -0
- data/spec/support/inheritable_class_attribute_examples.rb +16 -0
- data/spec/wcc/data/config_spec.rb +113 -0
- data/spec/wcc/data/enumerated_type_spec.rb +176 -0
- data/spec/wcc/data/faraday_client_app_token_auth_spec.rb +237 -0
- data/spec/wcc/data/mapper/attributes_spec.rb +94 -0
- data/spec/wcc/data/mapper/json_response_spec.rb +57 -0
- data/spec/wcc/data/mapper/rest_configuration_spec.rb +43 -0
- data/spec/wcc/data/mapper/rest_query_spec.rb +50 -0
- data/spec/wcc/data/model_spec.rb +33 -0
- data/spec/wcc/data/nucleus/campus_spec.rb +34 -0
- data/spec/wcc/data/rack_client_app_token_auth_spec.rb +219 -0
- data/spec/wcc/data/response_spec.rb +57 -0
- data/spec/wcc/data/rest_endpoint_spec.rb +71 -0
- data/spec/wcc/data/service_spec.rb +128 -0
- data/spec/wcc/data_spec.rb +25 -0
- data/wcc-data.gemspec +5 -3
- metadata +47 -7
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 82f9b734e798bdb01d28323037ba25ea1a87a831
|
4
|
+
data.tar.gz: 46b3020ff169cdfa6e687c9933b765a5f7ed26a6
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b527b25651b9e1e0930ba6c0f4c4b816e929b9efc664910d1b5dd7ce42936840f2b1ab46e1489654c05490a145426bf3121fb9efd236e4cf03d4d596f8f582d5
|
7
|
+
data.tar.gz: 4cf4c852f51a72b46ff553539a72903ef218e314eaafe70651b6945c587efececd064e0f222f2508ba75e6825884954eec81fbf5fc1b64f733ec3e82be292483
|
data/.env.example
ADDED
data/.gitignore
ADDED
data/.rspec
ADDED
data/Gemfile
ADDED
data/Rakefile
ADDED
@@ -0,0 +1,36 @@
|
|
1
|
+
require 'bundler/gem_tasks'
|
2
|
+
require 'dotenv/tasks'
|
3
|
+
|
4
|
+
PROJECT_PATH = File.dirname(__FILE__)
|
5
|
+
LIB_PATH = File.join(PROJECT_PATH, "lib")
|
6
|
+
|
7
|
+
task :default => :test
|
8
|
+
|
9
|
+
desc 'run test examples'
|
10
|
+
task :test do
|
11
|
+
exec 'rspec .'
|
12
|
+
end
|
13
|
+
|
14
|
+
task :environment => :dotenv do
|
15
|
+
$LOAD_PATH.unshift(LIB_PATH)
|
16
|
+
require 'wcc/data'
|
17
|
+
end
|
18
|
+
|
19
|
+
task :development => [:environment] do
|
20
|
+
WCC::Data.setup do |config|
|
21
|
+
conn = config.applications[:nucleus].connection
|
22
|
+
conn.use Faraday::Response::Logger
|
23
|
+
conn.basic_auth(ENV['NUCLEUS_CLIENT_ID'], ENV['NUCLEUS_CLIENT_SECRET'])
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
desc 'launch IRB shell with base environment loaded'
|
28
|
+
task :irb => :environment do
|
29
|
+
require 'irb'
|
30
|
+
ARGV.clear
|
31
|
+
IRB.start
|
32
|
+
end
|
33
|
+
|
34
|
+
desc 'launch IRB shell with development environment loaded'
|
35
|
+
task :console => [:development, :irb]
|
36
|
+
|
data/bin/rspec
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# frozen_string_literal: true
|
3
|
+
#
|
4
|
+
# This file was generated by Bundler.
|
5
|
+
#
|
6
|
+
# The application 'rspec' is installed as part of a gem, and
|
7
|
+
# this file is here to facilitate running it.
|
8
|
+
#
|
9
|
+
|
10
|
+
require "pathname"
|
11
|
+
ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile",
|
12
|
+
Pathname.new(__FILE__).realpath)
|
13
|
+
|
14
|
+
require "rubygems"
|
15
|
+
require "bundler/setup"
|
16
|
+
|
17
|
+
load Gem.bin_path("rspec-core", "rspec")
|
data/circle.yml
ADDED
@@ -1,64 +1,83 @@
|
|
1
|
+
|
2
|
+
begin
|
3
|
+
gem 'faraday'
|
4
|
+
require 'faraday'
|
5
|
+
rescue Gem::LoadError
|
6
|
+
# suppress
|
7
|
+
end
|
8
|
+
|
9
|
+
|
1
10
|
module WCC::Data
|
2
|
-
|
3
|
-
class
|
4
|
-
|
5
|
-
|
11
|
+
if defined?(Faraday)
|
12
|
+
class FaradayClientAppTokenAuth < Faraday::Middleware
|
13
|
+
class RedisCache
|
14
|
+
DEFAULT_CACHE_KEY = "org.watermark.data.client-app-token-cache-store"
|
15
|
+
attr_reader :connection, :cache_key
|
6
16
|
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
17
|
+
def initialize(connection, cache_key: DEFAULT_CACHE_KEY)
|
18
|
+
@connection = connection
|
19
|
+
@cache_key = cache_key
|
20
|
+
end
|
11
21
|
|
12
|
-
|
13
|
-
|
14
|
-
|
22
|
+
def [](hostname)
|
23
|
+
connection.call { |r| r.hget cache_key, hostname }
|
24
|
+
end
|
15
25
|
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
26
|
+
def []=(hostname, token)
|
27
|
+
if token
|
28
|
+
connection.call { |r| r.hset cache_key, hostname, token }
|
29
|
+
else
|
30
|
+
connection.call { |r| r.hdel cache_key, hostname }
|
31
|
+
end
|
21
32
|
end
|
22
33
|
end
|
23
|
-
end
|
24
34
|
|
25
|
-
|
35
|
+
attr_reader :cache, :token_factory
|
26
36
|
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
37
|
+
def initialize(app, cache: default_cache, token_factory: method(:default_token_factory))
|
38
|
+
super(app)
|
39
|
+
@cache = cache
|
40
|
+
@token_factory = token_factory
|
41
|
+
end
|
32
42
|
|
33
|
-
|
34
|
-
|
35
|
-
|
43
|
+
def token_for(host)
|
44
|
+
@cache[host] ||= token_factory.(host)
|
45
|
+
end
|
36
46
|
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
+
def call(env, retry_on_forbidden: true)
|
48
|
+
request_body = env[:body]
|
49
|
+
host = env[:url].host
|
50
|
+
env[:request_headers]["Authorization"] = "Bearer #{token_for(host)}"
|
51
|
+
@app.call(env).on_complete do |response_env|
|
52
|
+
response = Faraday::Response.new(response_env)
|
53
|
+
cache[host] = nil unless response.success?
|
54
|
+
if response.status == 403 && retry_on_forbidden
|
55
|
+
env[:body] = request_body
|
56
|
+
call(env, retry_on_forbidden: false)
|
57
|
+
end
|
47
58
|
end
|
48
59
|
end
|
49
|
-
end
|
50
60
|
|
51
|
-
|
61
|
+
private
|
52
62
|
|
53
|
-
|
54
|
-
|
55
|
-
|
63
|
+
def default_token_factory(host)
|
64
|
+
WCC::Data::Nucleus::ClientAppToken.create(hostname: host).token
|
65
|
+
end
|
56
66
|
|
57
|
-
|
58
|
-
|
67
|
+
def default_cache
|
68
|
+
RedisCache.new(Sidekiq.method(:redis))
|
69
|
+
end
|
70
|
+
end
|
71
|
+
else
|
72
|
+
class FaradayClientAppTokenAuth
|
73
|
+
def initialize(app, cache: default_cache, token_factory: method(:default_token_factory))
|
74
|
+
raise NotSupportedError, 'Please include the "faraday" gem to use this authentication method'
|
75
|
+
end
|
59
76
|
end
|
60
77
|
end
|
61
78
|
end
|
62
79
|
|
63
|
-
Faraday
|
80
|
+
if defined?(Faraday)
|
81
|
+
Faraday::Middleware.register_middleware :client_app_token => lambda { WCC::Data::FaradayClientAppTokenAuth }
|
82
|
+
end
|
64
83
|
|
@@ -27,11 +27,11 @@ module WCC::Data::Nucleus
|
|
27
27
|
code: 'FTW',
|
28
28
|
name: 'Fort Worth',
|
29
29
|
key: :ft_worth,
|
30
|
-
street: '
|
30
|
+
street: '3345 Winthrop Avenue',
|
31
31
|
city: 'Fort Worth',
|
32
32
|
state: 'TX',
|
33
|
-
zip: '
|
34
|
-
geo: [32.
|
33
|
+
zip: '76116',
|
34
|
+
geo: [32.7280064, -97.4146727]
|
35
35
|
},
|
36
36
|
{
|
37
37
|
id: 3,
|
@@ -54,28 +54,6 @@ module WCC::Data::Nucleus
|
|
54
54
|
state: 'TX',
|
55
55
|
zip: '75034',
|
56
56
|
geo: [33.130761, -96.822322]
|
57
|
-
},
|
58
|
-
{
|
59
|
-
id: 5,
|
60
|
-
code: 'SDL',
|
61
|
-
name: 'South Dallas',
|
62
|
-
key: :south_dallas,
|
63
|
-
street: '3400 Garden Ln',
|
64
|
-
city: 'Dallas',
|
65
|
-
state: 'TX',
|
66
|
-
zip: '75215',
|
67
|
-
geo: [32.758418, -96.743966]
|
68
|
-
},
|
69
|
-
{
|
70
|
-
id: 6,
|
71
|
-
code: 'ROC',
|
72
|
-
name: 'Rockwall',
|
73
|
-
key: :rockwall,
|
74
|
-
street: '1565 Airport Rd',
|
75
|
-
city: 'Rockwall',
|
76
|
-
state: 'TX',
|
77
|
-
zip: '75087',
|
78
|
-
geo: [32.926936, -96.439255]
|
79
57
|
}
|
80
58
|
]
|
81
59
|
end
|
data/lib/wcc/data/version.rb
CHANGED
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
SPEC_DIR = File.dirname(__FILE__)
|
2
|
+
FIXTURES_DIR = File.join(SPEC_DIR, "fixtures")
|
3
|
+
|
4
|
+
$LOAD_PATH.unshift File.join(SPEC_DIR, "..", "lib")
|
5
|
+
$LOAD_PATH.unshift SPEC_DIR
|
6
|
+
|
7
|
+
require 'dotenv'
|
8
|
+
Dotenv.load
|
9
|
+
|
10
|
+
require 'wcc/data'
|
11
|
+
require 'sidekiq'
|
12
|
+
|
13
|
+
Dir[File.join(SPEC_DIR, "support", "*.rb")].each do |support_file|
|
14
|
+
require "support/#{File.basename(support_file, ".rb")}"
|
15
|
+
end
|
16
|
+
|
17
|
+
RSpec.configure do |config|
|
18
|
+
config.run_all_when_everything_filtered = true
|
19
|
+
config.filter_run :focus
|
20
|
+
|
21
|
+
config.order = 'random'
|
22
|
+
|
23
|
+
ENV['NUCLEUS_URL'] ||= 'http://login.wcc'
|
24
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
shared_examples_for :inheritable_class_attributes do |name|
|
2
|
+
let(:subclass) { Class.new(subject) }
|
3
|
+
|
4
|
+
it "inherited value is the same as parent class" do
|
5
|
+
subject.send(:instance_variable_set, :"@#{name}", foo: :bar)
|
6
|
+
expect(subject.send(name)).to eq(foo: :bar)
|
7
|
+
expect(subclass.send(name)).to eq(foo: :bar)
|
8
|
+
end
|
9
|
+
|
10
|
+
it "inherited reference is unique from the parent class" do
|
11
|
+
subject.send(:instance_variable_set, :"@#{name}", foo: :bar)
|
12
|
+
subclass.send(name)[:bar] = :baz
|
13
|
+
expect(subject.send(name)).to eq(foo: :bar)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
@@ -0,0 +1,113 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe WCC::Data::Config::Application do
|
4
|
+
let(:unit) { WCC::Data::Config::Application }
|
5
|
+
subject { unit.new(:name) }
|
6
|
+
|
7
|
+
describe "#initialize" do
|
8
|
+
it "takes a single name symbol and stores in @name" do
|
9
|
+
obj = unit.new(:name)
|
10
|
+
expect(obj.name).to eq(:name)
|
11
|
+
end
|
12
|
+
|
13
|
+
it "takes a connection option and stores it in @connection" do
|
14
|
+
obj = unit.new(:name, connection: "foo")
|
15
|
+
expect(obj.connection).to eq("foo")
|
16
|
+
end
|
17
|
+
|
18
|
+
it "sets to a blank Faraday::Connection" do
|
19
|
+
obj = unit.new(:name)
|
20
|
+
expect(obj.connection).to be_a(Faraday::Connection)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
describe "#uri=" do
|
25
|
+
it "converts a string to a URI and stores in @uri" do
|
26
|
+
subject.uri = "http://test"
|
27
|
+
expect(subject.uri).to be_a(URI)
|
28
|
+
expect(subject.uri.scheme).to eq("http")
|
29
|
+
end
|
30
|
+
|
31
|
+
it "uses the URI object if set with a URI" do
|
32
|
+
subject.uri = test_value = URI("http://test")
|
33
|
+
expect(subject.uri).to eq(test_value)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
describe "#service" do
|
38
|
+
before(:each) do
|
39
|
+
subject.uri = "http://test.com/"
|
40
|
+
end
|
41
|
+
|
42
|
+
it "returns a service object based on the URI" do
|
43
|
+
obj = subject.service
|
44
|
+
expect(obj).to be_a(WCC::Data::Service)
|
45
|
+
expect(obj.uri).to eq(subject.uri)
|
46
|
+
end
|
47
|
+
|
48
|
+
it "passes the application connection through to the service" do
|
49
|
+
obj = subject.service
|
50
|
+
expect(obj.connection).to eq(subject.connection)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
describe "@connection" do
|
55
|
+
it "gets and sets" do
|
56
|
+
subject.connection = "foo"
|
57
|
+
expect(subject.connection).to eq("foo")
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
describe WCC::Data::Config do
|
63
|
+
let(:unit) { WCC::Data::Config }
|
64
|
+
subject { unit.new }
|
65
|
+
|
66
|
+
|
67
|
+
describe "#applications" do
|
68
|
+
it "returns a hash" do
|
69
|
+
expect(subject.applications).to be_a(Hash)
|
70
|
+
end
|
71
|
+
|
72
|
+
it "defaults empty keys to an application" do
|
73
|
+
expect(subject.applications[:foo]).to be_a(WCC::Data::Config::Application)
|
74
|
+
end
|
75
|
+
|
76
|
+
it "contains a default entry for :nucleus" do
|
77
|
+
expect(subject.applications[:nucleus].uri).to eq(
|
78
|
+
URI(ENV['NUCLEUS_URL'])
|
79
|
+
)
|
80
|
+
end
|
81
|
+
|
82
|
+
context "with APP_CLIENT_ID and APP_CLIENT_SECRET ENV vars set" do
|
83
|
+
after do
|
84
|
+
ENV['APP_CLIENT_ID'] = ENV['APP_CLIENT_SECRET'] = nil
|
85
|
+
end
|
86
|
+
|
87
|
+
it "sets the connection's basic auth for nucleus" do
|
88
|
+
ENV['APP_CLIENT_ID'] = "test"
|
89
|
+
ENV['APP_CLIENT_SECRET'] = "value"
|
90
|
+
|
91
|
+
header = subject.applications[:nucleus].connection.headers["Authorization"]
|
92
|
+
|
93
|
+
expect(header)
|
94
|
+
.to eq(Faraday::Request::BasicAuthentication.header("test", "value"))
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
context "with APP_CLIENT_ID and APP_CLIENT_SECRET not both set" do
|
99
|
+
it "does not set the basic auth for nucleus" do
|
100
|
+
header = subject.applications[:nucleus].connection.headers["Authorization"]
|
101
|
+
|
102
|
+
expect(header).to be_nil
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
describe "#apps alias" do
|
108
|
+
it "aliases to #applications" do
|
109
|
+
expect(subject.apps).to eq(subject.applications)
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
end
|
@@ -0,0 +1,176 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe WCC::Data::EnumeratedType do
|
4
|
+
|
5
|
+
context "with configured attributes" do
|
6
|
+
let(:type) {
|
7
|
+
Class.new(described_class) do
|
8
|
+
attributes :test1, :test2
|
9
|
+
end
|
10
|
+
}
|
11
|
+
let(:object) { type.new(data) }
|
12
|
+
let(:data) {
|
13
|
+
{
|
14
|
+
test1: "test data 1",
|
15
|
+
test2: "test data 2",
|
16
|
+
ignored: "",
|
17
|
+
}
|
18
|
+
}
|
19
|
+
|
20
|
+
it "adds a method for all arguments passed" do
|
21
|
+
expect(object).to respond_to(:test1)
|
22
|
+
expect(object).to respond_to(:test2)
|
23
|
+
end
|
24
|
+
|
25
|
+
it "sets values from initialize hash" do
|
26
|
+
expect(object.test1).to eq("test data 1")
|
27
|
+
expect(object.test2).to eq("test data 2")
|
28
|
+
end
|
29
|
+
|
30
|
+
describe "::defined_attributes" do
|
31
|
+
it "should return attributes" do
|
32
|
+
expect(type.defined_attributes).to eq([:test1, :test2])
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
context "with child classes" do
|
38
|
+
let(:parent) {
|
39
|
+
Class.new(described_class) do
|
40
|
+
attributes :attr1
|
41
|
+
attributes :attr2
|
42
|
+
end
|
43
|
+
}
|
44
|
+
let(:child) {
|
45
|
+
Class.new(parent) do
|
46
|
+
attributes :attr3, :attr4
|
47
|
+
end
|
48
|
+
}
|
49
|
+
let(:parent_object) { parent.new(data) }
|
50
|
+
let(:child_object) { child.new(data) }
|
51
|
+
let(:data) {
|
52
|
+
{
|
53
|
+
attr1: "data1",
|
54
|
+
attr2: "data2",
|
55
|
+
attr3: "data3",
|
56
|
+
attr4: "data4",
|
57
|
+
}
|
58
|
+
}
|
59
|
+
|
60
|
+
describe "parent class" do
|
61
|
+
it "does not include child attributes" do
|
62
|
+
expect(parent_object).to_not respond_to(:attr3)
|
63
|
+
expect(parent_object).to_not respond_to(:attr4)
|
64
|
+
end
|
65
|
+
|
66
|
+
it "includes both attributes" do
|
67
|
+
expect(parent_object).to respond_to(:attr1)
|
68
|
+
expect(parent_object).to respond_to(:attr2)
|
69
|
+
end
|
70
|
+
|
71
|
+
it "sets both attributes on initialize" do
|
72
|
+
expect(parent_object.attr1).to eq("data1")
|
73
|
+
expect(parent_object.attr2).to eq("data2")
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
describe "child class" do
|
78
|
+
it "includes all defined_attributes" do
|
79
|
+
expect(child.defined_attributes).to eq([:attr1, :attr2, :attr3, :attr4])
|
80
|
+
end
|
81
|
+
|
82
|
+
it "includes parent attributes and child attributes readers" do
|
83
|
+
expect(child_object.attr1).to eq("data1")
|
84
|
+
expect(child_object.attr2).to eq("data2")
|
85
|
+
expect(child_object.attr3).to eq("data3")
|
86
|
+
expect(child_object.attr4).to eq("data4")
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
end
|
91
|
+
|
92
|
+
context "with db, matches?, and attributes configured" do
|
93
|
+
let(:type) {
|
94
|
+
Class.new(described_class) do
|
95
|
+
attributes :id, :name, :key
|
96
|
+
|
97
|
+
def matches?(value)
|
98
|
+
[id, key].include?(value)
|
99
|
+
end
|
100
|
+
|
101
|
+
def self.db
|
102
|
+
[
|
103
|
+
{ id: 1, name: "One", key: :one },
|
104
|
+
{ id: 2, name: "Two", key: :two },
|
105
|
+
{ id: 3, name: "Three", key: :three },
|
106
|
+
{ id: 4, name: "Four", key: :three },
|
107
|
+
]
|
108
|
+
end
|
109
|
+
end
|
110
|
+
}
|
111
|
+
|
112
|
+
describe "::[]" do
|
113
|
+
it "returns an instance of type if match found" do
|
114
|
+
expect(type[1]).to be_a(type)
|
115
|
+
end
|
116
|
+
|
117
|
+
it "returns nil if no match found" do
|
118
|
+
expect(type[:nil]).to be_nil
|
119
|
+
end
|
120
|
+
|
121
|
+
it "returns first match when multiple matches present" do
|
122
|
+
expect(type[:three]).to eq(type.all[2])
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
describe "::all" do
|
127
|
+
it "returns instances of EnumeratedType for each item in db" do
|
128
|
+
expect(type.all.size).to eq(4)
|
129
|
+
expect(type.all[0]).to be_a(type)
|
130
|
+
expect(type.all[1]).to be_a(type)
|
131
|
+
expect(type.all[2]).to be_a(type)
|
132
|
+
expect(type.all[3]).to be_a(type)
|
133
|
+
end
|
134
|
+
|
135
|
+
it "sets attributes for each record properly" do
|
136
|
+
expect(type.all[0].id).to eq(1)
|
137
|
+
expect(type.all[0].name).to eq("One")
|
138
|
+
expect(type.all[0].key).to eq(:one)
|
139
|
+
expect(type.all[1].key).to eq(:two)
|
140
|
+
expect(type.all[2].key).to eq(:three)
|
141
|
+
end
|
142
|
+
|
143
|
+
it "caches the results" do
|
144
|
+
expect(type.all[0].object_id).to eq(type.all[0].object_id)
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|
148
|
+
describe "::reset" do
|
149
|
+
it "clears out all and forces new object creation" do
|
150
|
+
first_id = type.all[0].object_id
|
151
|
+
type.reset
|
152
|
+
expect(type.all[0].object_id).to_not eq(first_id)
|
153
|
+
end
|
154
|
+
end
|
155
|
+
end
|
156
|
+
|
157
|
+
describe "#initialize" do
|
158
|
+
it "allows passing no argument" do
|
159
|
+
expect { described_class.new }.to_not raise_error
|
160
|
+
end
|
161
|
+
end
|
162
|
+
|
163
|
+
describe "::db" do
|
164
|
+
it "raises NotImplementedError with instructions" do
|
165
|
+
expect { described_class.db }.to raise_error(NotImplementedError, /subclass/i)
|
166
|
+
end
|
167
|
+
end
|
168
|
+
|
169
|
+
describe "#matches?" do
|
170
|
+
it "raises NotImplementedError with instructions" do
|
171
|
+
object = described_class.new({})
|
172
|
+
expect { object.matches?(:val) }.to raise_error(NotImplementedError, /subclass/i)
|
173
|
+
end
|
174
|
+
end
|
175
|
+
|
176
|
+
end
|