horza 0.5.2 → 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +65 -14
- data/lib/horza/adapters/abstract_adapter.rb +0 -5
- data/lib/horza/adapters/active_record/active_record.rb +4 -7
- data/lib/horza/adapters/class_methods.rb +1 -19
- data/lib/horza/configuration.rb +12 -23
- data/lib/horza/core_extensions/string.rb +2 -8
- data/lib/horza/dependency_loading.rb +68 -0
- data/lib/horza/entities/collection.rb +2 -0
- data/lib/horza/entities/single.rb +1 -0
- data/lib/horza/errors.rb +1 -4
- data/lib/horza/shared_config.rb +19 -0
- data/lib/horza/version.rb +3 -0
- data/lib/horza.rb +22 -3
- data/spec/active_record_spec.rb +100 -154
- data/spec/configuration_spec.rb +26 -0
- data/spec/dependency_loading_spec.rb +94 -0
- data/spec/horza_spec.rb +0 -47
- data/spec/shared_config_spec.rb +16 -0
- data/spec/test_constants/test_employer.rb +4 -0
- metadata +36 -26
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 85e3c731e1151f920c9079e120808d32ebc1a2d2
|
4
|
+
data.tar.gz: 862ba540a13154564bbe845c89ee03d752db4ca6
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: dac65236a361da1124d08ee528c49410f3434da8f197038827b8c374d226f269ca1190d8558905128744e64acaf4585fcd8888c6894a37cd101e914dc9595048
|
7
|
+
data.tar.gz: cd2bd65854ef303f73743c6fd797d87b8acdfc2d10f44281efa8e4bab382083ac389bfbb78d52cdf4481f67d85f7ce311ca5f5a9108dbe6223c93f7d7baf013c
|
data/README.md
CHANGED
@@ -2,21 +2,9 @@
|
|
2
2
|
|
3
3
|
Horza is a library for decoupling your application from the ORM you have implemented.
|
4
4
|
|
5
|
-
|
6
|
-
|
7
|
-
Horza uses ORM-specific adapters to decouple Ruby apps from their ORMS.
|
8
|
-
|
9
|
-
**Configure Adapter**
|
5
|
+
**ActiveRecord Example**
|
10
6
|
```ruby
|
11
|
-
|
12
|
-
config.adapter = :active_record
|
13
|
-
end
|
14
|
-
```
|
15
|
-
|
16
|
-
**Get Adapter for your ORM Object**
|
17
|
-
```ruby
|
18
|
-
# ActiveRecord Example
|
19
|
-
# Don't worry, We don't actually call things horza_users in our codebase, this is just for emphasis
|
7
|
+
# Get Adapter for your ORM Object
|
20
8
|
horza_user = Horza.adapt(User)
|
21
9
|
|
22
10
|
# Examples
|
@@ -153,3 +141,66 @@ end
|
|
153
141
|
The returned entity for ActiveRecord adapter now include ActiveModel semantics. This type of
|
154
142
|
entity SingleWithActiveModel can work with rails form helper and the submitted params will be
|
155
143
|
grouped under params[:horza_entities_single_with_active_model].
|
144
|
+
|
145
|
+
|
146
|
+
## Config
|
147
|
+
|
148
|
+
Horza uses ORM-specific adapters to decouple Ruby apps from their ORMS.
|
149
|
+
Currently only the ActiveRecord adapter is supported.
|
150
|
+
|
151
|
+
**Configure Adapter**
|
152
|
+
```ruby
|
153
|
+
Horza.configure do |config|
|
154
|
+
config.adapter = :active_record
|
155
|
+
end
|
156
|
+
```
|
157
|
+
|
158
|
+
**Constant paths**
|
159
|
+
Some of the operations in Horza involve resolving constants from the given options.
|
160
|
+
Consider the following snippet from above:
|
161
|
+
```ruby
|
162
|
+
user.create_as_child(id: parent_id, klass: :employer, options)
|
163
|
+
```
|
164
|
+
Horza by default will return the <tt>Employer</tt> class if it has already been loaded.
|
165
|
+
In environments where constants are lazy-loaded - such as in Rails - you would need to explicitly configure paths that Horza should look up when trying to resolve constants.
|
166
|
+
|
167
|
+
For instance in a Rails app your models are typically found in the ```app/models``` directory,
|
168
|
+
so you would need to add it to the constant_paths.
|
169
|
+
|
170
|
+
```ruby
|
171
|
+
# config/initializers/horza.rb
|
172
|
+
Horza.configure do |config|
|
173
|
+
# config.adapter = :active_record
|
174
|
+
config.constant_paths += [Rails.root.join("app/models").to_s]
|
175
|
+
end
|
176
|
+
```
|
177
|
+
**Note** The file paths added to _constant_paths_ would also need to be added to your app's _autoload_paths_ for the constants to be loaded dynamically.
|
178
|
+
|
179
|
+
**Model Namespaces**
|
180
|
+
|
181
|
+
Horza will attempt to resolve namespaced constants where possibble provided the following caveats are met:
|
182
|
+
|
183
|
+
- The file names added to the constant_paths and the constants defined in them follow the Rails naming conventions.
|
184
|
+
- There aren't multiple files with the same base name in a given directory in the constant paths.
|
185
|
+
|
186
|
+
To illustrate the second point consider the following directory structure:
|
187
|
+
```ruby
|
188
|
+
# app/models/employer.rb
|
189
|
+
class Employer < ActiveRecord::Base
|
190
|
+
has_many :users
|
191
|
+
end
|
192
|
+
|
193
|
+
# app/models/my_namespace/employer.rb
|
194
|
+
module MyNamespace
|
195
|
+
class Employer < ActiveRecord::Base
|
196
|
+
has_many :users
|
197
|
+
end
|
198
|
+
end
|
199
|
+
|
200
|
+
# In this case Horza will load the top level <tt>Employer</tt> model.
|
201
|
+
```
|
202
|
+
|
203
|
+
**Resetting config** _(At runtime or on app boot)_
|
204
|
+
```ruby
|
205
|
+
Horza.reset
|
206
|
+
```
|
@@ -3,7 +3,6 @@ module Horza
|
|
3
3
|
class AbstractAdapter
|
4
4
|
extend ::Horza::Adapters::ClassMethods
|
5
5
|
include ::Horza::Adapters::InstanceMethods
|
6
|
-
extend ActiveSupport::DescendantsTracker
|
7
6
|
|
8
7
|
attr_reader :context
|
9
8
|
|
@@ -11,10 +10,6 @@ module Horza
|
|
11
10
|
def expected_errors_map
|
12
11
|
not_implemented_error
|
13
12
|
end
|
14
|
-
|
15
|
-
def entity_context_map
|
16
|
-
not_implemented_error
|
17
|
-
end
|
18
13
|
end
|
19
14
|
|
20
15
|
def get!(id)
|
@@ -1,3 +1,5 @@
|
|
1
|
+
require 'active_record'
|
2
|
+
|
1
3
|
module Horza
|
2
4
|
module Adapters
|
3
5
|
class ActiveRecord < AbstractAdapter
|
@@ -9,12 +11,6 @@ module Horza
|
|
9
11
|
::Horza::Entities::SingleWithActiveModel
|
10
12
|
end
|
11
13
|
|
12
|
-
def entity_context_map
|
13
|
-
# Rails doesn't preload classes in development mode, caching doesn't make sense
|
14
|
-
return ::Horza.descendants_map(CONTEXT_NAMESPACE) if ::Horza.configuration.development_mode
|
15
|
-
@map ||= ::Horza.descendants_map(CONTEXT_NAMESPACE)
|
16
|
-
end
|
17
|
-
|
18
14
|
def expected_errors_map
|
19
15
|
{
|
20
16
|
::ActiveRecord::RecordNotFound => Horza::Errors::RecordNotFound,
|
@@ -84,7 +80,7 @@ module Horza
|
|
84
80
|
base = base.find(options.id)
|
85
81
|
|
86
82
|
result = walk_family_tree(base, options)
|
87
|
-
return nil
|
83
|
+
return nil if result.nil?
|
88
84
|
|
89
85
|
options.target.to_s.plural? ? entity(query(options, result)) : entity(result.attributes)
|
90
86
|
end
|
@@ -117,6 +113,7 @@ module Horza
|
|
117
113
|
via = options.via || []
|
118
114
|
|
119
115
|
via.push(options.target).reduce(object) do |object, relation|
|
116
|
+
return nil if object.nil?
|
120
117
|
raise ::Horza::Errors::InvalidAncestry.new(INVALID_ANCESTRY_MSG) unless object.respond_to? relation
|
121
118
|
object.send(relation)
|
122
119
|
end
|
@@ -14,25 +14,7 @@ module Horza
|
|
14
14
|
end
|
15
15
|
|
16
16
|
def context_for_entity(entity)
|
17
|
-
|
18
|
-
return context if context
|
19
|
-
|
20
|
-
lazy_load_model(entity)
|
21
|
-
end
|
22
|
-
|
23
|
-
def lazy_load_model(entity)
|
24
|
-
#raise Horza::Errors::NoContextForEntity.new unless Horza.configuration.development_mode
|
25
|
-
lazy_const = entity.to_s.camelize
|
26
|
-
|
27
|
-
[Object].concat(Horza.configuration.namespaces).each do |namespace|
|
28
|
-
begin
|
29
|
-
return namespace.const_get(lazy_const) if (namespace.const_get(lazy_const) < Horza.adapter::CONTEXT_NAMESPACE)
|
30
|
-
rescue NameError
|
31
|
-
next
|
32
|
-
end
|
33
|
-
end
|
34
|
-
|
35
|
-
raise Horza::Errors::NoContextForEntity.new
|
17
|
+
DependencyLoading.resolve_dependency(entity.to_s)
|
36
18
|
end
|
37
19
|
|
38
20
|
def not_implemented_error
|
data/lib/horza/configuration.rb
CHANGED
@@ -1,35 +1,24 @@
|
|
1
1
|
module Horza
|
2
|
-
|
3
|
-
|
2
|
+
class Configuration
|
3
|
+
attr_accessor :constant_paths
|
4
4
|
|
5
|
-
def
|
6
|
-
@
|
5
|
+
def initialize
|
6
|
+
@constant_paths = []
|
7
7
|
end
|
8
8
|
|
9
|
-
def
|
10
|
-
|
11
|
-
@adapter, @adapter_map = nil, nil # Class-level cache clear
|
12
|
-
end
|
13
|
-
|
14
|
-
def configure
|
15
|
-
yield(configuration)
|
9
|
+
def clear_constant_paths
|
10
|
+
constant_paths.clear
|
16
11
|
end
|
17
12
|
|
18
13
|
def adapter
|
19
|
-
raise
|
20
|
-
@adapter ||= adapter_map[configuration.adapter]
|
21
|
-
end
|
22
|
-
|
23
|
-
def adapter_map
|
24
|
-
@adapter_map ||= ::Horza.descendants_map(::Horza::Adapters::AbstractAdapter)
|
14
|
+
@adapter || raise(::Horza::Errors::AdapterError.new("No adapter configured"))
|
25
15
|
end
|
26
|
-
end
|
27
|
-
|
28
|
-
class Config
|
29
|
-
attr_accessor :adapter, :development_mode, :namespaces
|
30
16
|
|
31
|
-
def
|
32
|
-
|
17
|
+
def adapter=(name)
|
18
|
+
@adapter = "Horza::Adapters::#{name.to_s.camelize}".constantize if name
|
19
|
+
rescue NameError
|
20
|
+
raise ::Horza::Errors::AdapterError.new("No adapter found for: #{name}")
|
21
|
+
@adapter = nil
|
33
22
|
end
|
34
23
|
end
|
35
24
|
end
|
@@ -12,14 +12,8 @@ module Horza
|
|
12
12
|
def symbolize
|
13
13
|
underscore.to_sym
|
14
14
|
end
|
15
|
-
|
16
|
-
def underscore
|
17
|
-
gsub(/::/, '/')
|
18
|
-
.gsub(/([A-Z]+)([A-Z][a-z])/, '\1_\2')
|
19
|
-
.gsub(/([a-z\d])([A-Z])/, '\1_\2')
|
20
|
-
.tr('-', '_')
|
21
|
-
.downcase
|
22
|
-
end
|
23
15
|
end
|
24
16
|
end
|
25
17
|
end
|
18
|
+
|
19
|
+
String.send(:include, ::Horza::CoreExtensions::String)
|
@@ -0,0 +1,68 @@
|
|
1
|
+
module Horza
|
2
|
+
module DependencyLoading
|
3
|
+
extend self
|
4
|
+
|
5
|
+
Error = Class.new(StandardError)
|
6
|
+
MissingFile = Class.new(Error)
|
7
|
+
|
8
|
+
def resolve_dependency(entity_name)
|
9
|
+
file_name = entity_name.to_s.underscore
|
10
|
+
# Return already loaded constant from memory if possible,
|
11
|
+
# otherwise search for a matching filename and try to load that.
|
12
|
+
constant = get_loaded_constant(file_name)
|
13
|
+
return constant if !constant.nil?
|
14
|
+
|
15
|
+
resolve_from_file_paths(file_name)
|
16
|
+
end
|
17
|
+
|
18
|
+
def resolve_from_file_paths(entity_name)
|
19
|
+
raise ArgumentError.new("No file paths configured to lookup constants") if Horza.constant_paths.empty?
|
20
|
+
|
21
|
+
file_path = search_for_file(entity_name)
|
22
|
+
|
23
|
+
resolved_name = constant_name_for_path(file_path).first
|
24
|
+
|
25
|
+
if resolved_name.nil?
|
26
|
+
Error.new("No constant found for: #{entity_name.inspect}")
|
27
|
+
else
|
28
|
+
ActiveSupport::Dependencies::Reference.safe_get(resolved_name)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
|
33
|
+
def constant_name_for_path(file_path)
|
34
|
+
ActiveSupport::Dependencies.loadable_constants_for_path(file_path, Horza.constant_paths).tap do |loadables|
|
35
|
+
if loadables.many?
|
36
|
+
raise "It seems that your registered constant file paths are not setup correctly " +
|
37
|
+
"and would cause Horza to try and load the following constants:\n\n #{loadables.map(&:inspect).join(', ')}"
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
# Search for a file matching the provided suffix.
|
43
|
+
# This recursively checks directories in the #Horza.constant_paths for matches.
|
44
|
+
def search_for_file(path_suffix)
|
45
|
+
path_suffix = path_suffix.sub(/(\.rb)?$/, ".rb")
|
46
|
+
|
47
|
+
Horza.constant_paths.each do |root|
|
48
|
+
Dir.glob(File.join(root, "**/")).each do |dir|
|
49
|
+
path = File.join(dir, path_suffix)
|
50
|
+
return path if File.file? path
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
raise MissingFile.new(
|
55
|
+
"No matching file found for: '#{path_suffix.sub(/(\.rb)?$/, "")}'\n" +
|
56
|
+
"Searched in: (#{Horza.constant_paths.map(&:inspect).join(', ')})"
|
57
|
+
)
|
58
|
+
end
|
59
|
+
|
60
|
+
def get_loaded_constant(entity_name)
|
61
|
+
constant_name = entity_name.camelize
|
62
|
+
if ActiveSupport::Dependencies.qualified_const_defined?(constant_name)
|
63
|
+
return ActiveSupport::Dependencies::Reference.get(constant_name)
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
end
|
68
|
+
end
|
data/lib/horza/errors.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
module Horza
|
2
2
|
module Errors
|
3
|
-
class
|
3
|
+
class AdapterError < StandardError
|
4
4
|
end
|
5
5
|
|
6
6
|
class MethodNotImplemented < StandardError
|
@@ -24,9 +24,6 @@ module Horza
|
|
24
24
|
class InvalidOption < StandardError
|
25
25
|
end
|
26
26
|
|
27
|
-
class NoContextForEntity < StandardError
|
28
|
-
end
|
29
|
-
|
30
27
|
class UnknownAttributeError < StandardError
|
31
28
|
end
|
32
29
|
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
# Helper module to allow other libraries to access the global
|
2
|
+
# Horza configuration instance and dispatch methods accordingly.
|
3
|
+
module Horza
|
4
|
+
module SharedConfig
|
5
|
+
DelegatedMethods = %w(
|
6
|
+
configuration configure reset constant_paths
|
7
|
+
clear_constant_paths adapter adapter=
|
8
|
+
)
|
9
|
+
|
10
|
+
DelegatedMethods.each do |_meth_|
|
11
|
+
module_eval <<-RUBY, __FILE__, __LINE__ + 1
|
12
|
+
def #{_meth_}(*args, &blk)
|
13
|
+
Horza.send(:'#{_meth_}', *args, &blk)
|
14
|
+
end
|
15
|
+
RUBY
|
16
|
+
end
|
17
|
+
|
18
|
+
end
|
19
|
+
end
|
data/lib/horza.rb
CHANGED
@@ -1,3 +1,8 @@
|
|
1
|
+
require 'active_support/inflections'
|
2
|
+
require 'active_support/descendants_tracker'
|
3
|
+
require 'active_support/core_ext/module/delegation'
|
4
|
+
require 'active_support/dependencies'
|
5
|
+
require 'horza/dependency_loading'
|
1
6
|
require 'horza/adapters/class_methods'
|
2
7
|
require 'horza/adapters/instance_methods'
|
3
8
|
require 'horza/adapters/options'
|
@@ -10,13 +15,27 @@ require 'horza/entities/collection'
|
|
10
15
|
require 'horza/entities/single_with_active_model'
|
11
16
|
require 'horza/entities'
|
12
17
|
require 'horza/configuration'
|
18
|
+
require 'horza/shared_config'
|
13
19
|
require 'horza/errors'
|
14
|
-
require '
|
20
|
+
require 'horza/version'
|
15
21
|
|
16
|
-
module Horza
|
17
|
-
extend Configuration
|
18
22
|
|
23
|
+
module Horza
|
19
24
|
class << self
|
25
|
+
delegate :constant_paths, :clear_constant_paths, :adapter, :adapter=, to: :configuration
|
26
|
+
|
27
|
+
def configuration
|
28
|
+
@configuration ||= Configuration.new
|
29
|
+
end
|
30
|
+
|
31
|
+
def reset
|
32
|
+
@configuration = nil
|
33
|
+
end
|
34
|
+
|
35
|
+
def configure
|
36
|
+
yield(configuration)
|
37
|
+
end
|
38
|
+
|
20
39
|
def descendants_map(klass)
|
21
40
|
klass.descendants.reduce({}) { |hash, (klass)| hash.merge(klass.name.split('::').last.underscore.to_sym => klass) }
|
22
41
|
end
|
data/spec/active_record_spec.rb
CHANGED
@@ -16,139 +16,78 @@ else
|
|
16
16
|
end
|
17
17
|
end
|
18
18
|
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
end
|
24
|
-
|
25
|
-
class User < ActiveRecord::Base
|
26
|
-
belongs_to :employer
|
27
|
-
end
|
19
|
+
class Employer < ActiveRecord::Base
|
20
|
+
has_many :users
|
21
|
+
has_many :sports_cars
|
22
|
+
end
|
28
23
|
|
29
|
-
|
30
|
-
|
31
|
-
|
24
|
+
class User < ActiveRecord::Base
|
25
|
+
belongs_to :employer
|
26
|
+
end
|
32
27
|
|
33
|
-
|
34
|
-
|
35
|
-
|
28
|
+
class Customer < ActiveRecord::Base
|
29
|
+
validates :last_name, presence: true
|
30
|
+
end
|
36
31
|
|
37
|
-
|
38
|
-
|
39
|
-
|
32
|
+
class SportsCar < ActiveRecord::Base
|
33
|
+
belongs_to :employer
|
34
|
+
end
|
40
35
|
|
41
|
-
|
42
|
-
|
43
|
-
end
|
36
|
+
class DummyModel < ActiveRecord::Base
|
37
|
+
belongs_to :employer
|
44
38
|
end
|
45
39
|
|
46
|
-
class
|
40
|
+
class OtherDummyModel < ActiveRecord::Base
|
41
|
+
belongs_to :employer
|
47
42
|
end
|
43
|
+
end
|
48
44
|
|
49
|
-
|
50
|
-
|
51
|
-
|
45
|
+
class SimpleRecord < ActiveRecord::Base
|
46
|
+
end
|
47
|
+
|
48
|
+
module Lazy
|
49
|
+
class LazyRecord < ActiveRecord::Base
|
52
50
|
end
|
53
51
|
end
|
54
52
|
|
55
53
|
describe Horza do
|
56
54
|
let(:last_name) { 'Turner' }
|
57
55
|
let(:adapter) { :active_record }
|
58
|
-
let(:user_adapter) { Horza.adapt(
|
59
|
-
let(:customer_adapter) { Horza.adapt(
|
60
|
-
let(:employer_adapter) { Horza.adapt(
|
61
|
-
let(:sports_car_adapter) { Horza.adapt(
|
56
|
+
let(:user_adapter) { Horza.adapt(User) }
|
57
|
+
let(:customer_adapter) { Horza.adapt(Customer) }
|
58
|
+
let(:employer_adapter) { Horza.adapt(Employer) }
|
59
|
+
let(:sports_car_adapter) { Horza.adapt(SportsCar) }
|
62
60
|
|
63
61
|
# Reset base config with each iteration
|
64
62
|
before { Horza.configure { |config| config.adapter = adapter } }
|
65
63
|
after do
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
64
|
+
User.delete_all
|
65
|
+
Employer.delete_all
|
66
|
+
Customer.delete_all
|
67
|
+
SportsCar.delete_all
|
70
68
|
end
|
71
69
|
|
72
70
|
context '#context_for_entity' do
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
end
|
78
|
-
|
79
|
-
context 'when model exists in namespace' do
|
80
|
-
it 'Returns correct class' do
|
81
|
-
expect(Horza.adapter.context_for_entity(:user)).to eq HorzaSpec::User
|
82
|
-
end
|
83
|
-
end
|
84
|
-
|
85
|
-
context 'when model does not exist' do
|
86
|
-
it 'throws error class' do
|
87
|
-
expect { Horza.adapter.context_for_entity(:not_a_thing) }.to raise_error Horza::Errors::NoContextForEntity
|
88
|
-
end
|
89
|
-
end
|
90
|
-
|
91
|
-
context 'in development mode' do
|
92
|
-
before do
|
93
|
-
Horza.reset
|
94
|
-
Horza.configure do |config|
|
95
|
-
config.adapter = adapter
|
96
|
-
config.development_mode = true
|
97
|
-
end
|
98
|
-
end
|
99
|
-
after do
|
100
|
-
Horza.reset
|
101
|
-
end
|
102
|
-
|
103
|
-
context 'when model exists' do
|
104
|
-
it 'Returns correct class' do
|
105
|
-
expect(Horza.adapter.context_for_entity(:simple_record).to_s).to eq 'SimpleRecord'
|
106
|
-
end
|
107
|
-
end
|
108
|
-
|
109
|
-
context 'when model does not exist' do
|
110
|
-
it 'throws error class' do
|
111
|
-
expect { Horza.adapter.context_for_entity(:not_a_thing) }.to raise_error Horza::Errors::NoContextForEntity
|
112
|
-
end
|
113
|
-
end
|
114
|
-
|
115
|
-
context 'when model exists but has been lazy loaded' do
|
116
|
-
context 'without namespace' do
|
117
|
-
before do
|
118
|
-
Object.send(:remove_const, :SimpleRecord)
|
119
|
-
end
|
120
|
-
|
121
|
-
it 'lazy loads' do
|
122
|
-
expect(Horza.adapter.context_for_entity(:simple_record).to_s).to eq 'SimpleRecord'
|
123
|
-
end
|
124
|
-
end
|
125
|
-
|
126
|
-
context 'within namespace' do
|
127
|
-
before do
|
128
|
-
Lazy.send(:remove_const, :LazyRecord)
|
129
|
-
Object.send(:remove_const, :Lazy)
|
130
|
-
end
|
131
|
-
|
132
|
-
it 'lazy loads' do
|
133
|
-
expect(Horza.adapter.context_for_entity(:lazy_record).to_s).to eq 'Lazy::LazyRecord'
|
134
|
-
end
|
135
|
-
end
|
136
|
-
end
|
71
|
+
it 'Returns correct class' do
|
72
|
+
expect(Horza::DependencyLoading).to receive(:resolve_dependency).with("simple_record")
|
73
|
+
|
74
|
+
Horza.adapter.context_for_entity(:simple_record)
|
137
75
|
end
|
76
|
+
|
138
77
|
end
|
139
78
|
|
140
79
|
describe '#adapt' do
|
141
|
-
subject { Horza.adapt(
|
80
|
+
subject { Horza.adapt(User) }
|
142
81
|
it 'returns the adaptor class' do
|
143
82
|
expect(subject.is_a? Horza::Adapters::ActiveRecord).to be true
|
144
83
|
end
|
145
84
|
it 'sets the model as context' do
|
146
|
-
expect(subject.context).to eq
|
85
|
+
expect(subject.context).to eq User
|
147
86
|
end
|
148
87
|
end
|
149
88
|
|
150
89
|
describe 'Queries' do
|
151
|
-
let(:user) {
|
90
|
+
let(:user) { User.create }
|
152
91
|
let(:single_entity_klass) { Horza::Entities::Single }
|
153
92
|
|
154
93
|
describe '#get!' do
|
@@ -182,15 +121,15 @@ describe Horza do
|
|
182
121
|
describe '#find_first!' do
|
183
122
|
context 'when users exist' do
|
184
123
|
before do
|
185
|
-
3.times {
|
186
|
-
2.times {
|
124
|
+
3.times { User.create(last_name: last_name) }
|
125
|
+
2.times { User.create(last_name: 'OTHER') }
|
187
126
|
end
|
188
127
|
it 'returns single Entity' do
|
189
128
|
expect(user_adapter.find_first(conditions: { last_name: last_name }).is_a? Horza::Entities::Single).to be true
|
190
129
|
end
|
191
130
|
|
192
131
|
it 'returns user' do
|
193
|
-
expect(user_adapter.find_first!(conditions: { last_name: last_name }).to_h).to eq
|
132
|
+
expect(user_adapter.find_first!(conditions: { last_name: last_name }).to_h).to eq User.where(last_name: last_name).order('id DESC').first.attributes
|
194
133
|
end
|
195
134
|
end
|
196
135
|
|
@@ -215,8 +154,8 @@ describe Horza do
|
|
215
154
|
|
216
155
|
context 'when users exist' do
|
217
156
|
before do
|
218
|
-
3.times {
|
219
|
-
2.times {
|
157
|
+
3.times { User.create(conditions) }
|
158
|
+
2.times { User.create(last_name: 'OTHER') }
|
220
159
|
end
|
221
160
|
it 'returns user' do
|
222
161
|
expect(user_adapter.find_all(options).length).to eq 3
|
@@ -232,7 +171,7 @@ describe Horza do
|
|
232
171
|
let(:total) { 20 }
|
233
172
|
let(:offset) { 7 }
|
234
173
|
before do
|
235
|
-
total.times {
|
174
|
+
total.times { User.create(last_name: 'Smith') }
|
236
175
|
end
|
237
176
|
it 'offsets response' do
|
238
177
|
expect(user_adapter.find_all(conditions: { last_name: 'Smith' }, offset: offset).length).to eq total - offset
|
@@ -250,7 +189,7 @@ describe Horza do
|
|
250
189
|
describe '#create' do
|
251
190
|
context 'when parameters are valid' do
|
252
191
|
it 'creates the record' do
|
253
|
-
expect { customer_adapter.create(last_name: last_name) }.to change(
|
192
|
+
expect { customer_adapter.create(last_name: last_name) }.to change(Customer, :count).by(1)
|
254
193
|
end
|
255
194
|
|
256
195
|
it 'returns the entity' do
|
@@ -260,7 +199,7 @@ describe Horza do
|
|
260
199
|
|
261
200
|
context 'when parameters are invalid' do
|
262
201
|
it 'does not create the record' do
|
263
|
-
expect { customer_adapter.create }.to change(
|
202
|
+
expect { customer_adapter.create }.to change(Customer, :count).by(0)
|
264
203
|
end
|
265
204
|
|
266
205
|
it 'returns nil' do
|
@@ -278,7 +217,7 @@ describe Horza do
|
|
278
217
|
end
|
279
218
|
|
280
219
|
describe '#create_as_child' do
|
281
|
-
let(:employer) {
|
220
|
+
let(:employer) { Employer.create }
|
282
221
|
let(:parent) do
|
283
222
|
{
|
284
223
|
id: employer.id,
|
@@ -289,7 +228,7 @@ describe Horza do
|
|
289
228
|
|
290
229
|
context 'when parameters are valid' do
|
291
230
|
it 'creates the record' do
|
292
|
-
expect { action }.to change(
|
231
|
+
expect { action }.to change(User, :count).by(1)
|
293
232
|
end
|
294
233
|
|
295
234
|
it 'returns the entity' do
|
@@ -307,7 +246,7 @@ describe Horza do
|
|
307
246
|
end
|
308
247
|
|
309
248
|
it 'does not create the record' do
|
310
|
-
expect { action }.to change(
|
249
|
+
expect { action }.to change(User, :count).by(0)
|
311
250
|
end
|
312
251
|
|
313
252
|
it 'returns nil' do
|
@@ -317,7 +256,7 @@ describe Horza do
|
|
317
256
|
end
|
318
257
|
|
319
258
|
describe '#create_as_child!' do
|
320
|
-
let(:employer) {
|
259
|
+
let(:employer) { Employer.create }
|
321
260
|
let(:action) { user_adapter.create_as_child!(parent, last_name: last_name) }
|
322
261
|
|
323
262
|
context 'when parameters are invalid' do
|
@@ -335,7 +274,7 @@ describe Horza do
|
|
335
274
|
end
|
336
275
|
|
337
276
|
describe '#update' do
|
338
|
-
let(:customer) {
|
277
|
+
let(:customer) { Customer.create(last_name: last_name) }
|
339
278
|
|
340
279
|
context 'when parameters are valid' do
|
341
280
|
let(:updated_last_name) { 'Smith' }
|
@@ -359,7 +298,7 @@ describe Horza do
|
|
359
298
|
end
|
360
299
|
|
361
300
|
describe '#update!' do
|
362
|
-
let(:customer) {
|
301
|
+
let(:customer) { Customer.create(last_name: last_name) }
|
363
302
|
|
364
303
|
context 'when parameters are invalid' do
|
365
304
|
it 'throws error' do
|
@@ -375,13 +314,13 @@ describe Horza do
|
|
375
314
|
end
|
376
315
|
|
377
316
|
describe '#delete' do
|
378
|
-
let!(:customer) {
|
317
|
+
let!(:customer) { Customer.create(last_name: last_name) }
|
379
318
|
|
380
319
|
context 'when record exists' do
|
381
320
|
let(:updated_last_name) { 'Smith' }
|
382
321
|
|
383
322
|
it 'destroys the record' do
|
384
|
-
expect { customer_adapter.delete(customer.id) }.to change(
|
323
|
+
expect { customer_adapter.delete(customer.id) }.to change(Customer, :count).by(-1)
|
385
324
|
end
|
386
325
|
|
387
326
|
it 'returns true' do
|
@@ -397,7 +336,7 @@ describe Horza do
|
|
397
336
|
end
|
398
337
|
|
399
338
|
describe '#delete!' do
|
400
|
-
let(:customer) {
|
339
|
+
let(:customer) { Customer.create(last_name: last_name) }
|
401
340
|
|
402
341
|
context 'when record does not exist' do
|
403
342
|
it 'returns nil' do
|
@@ -408,9 +347,9 @@ describe Horza do
|
|
408
347
|
|
409
348
|
context '#association' do
|
410
349
|
context 'direct relation' do
|
411
|
-
let(:employer) {
|
412
|
-
let!(:user1) {
|
413
|
-
let!(:user2) {
|
350
|
+
let(:employer) { Employer.create }
|
351
|
+
let!(:user1) { User.create(employer: employer) }
|
352
|
+
let!(:user2) { User.create(employer: employer) }
|
414
353
|
|
415
354
|
context 'parent' do
|
416
355
|
it 'returns parent' do
|
@@ -423,7 +362,7 @@ describe Horza do
|
|
423
362
|
result = employer_adapter.association(id: employer.id, target: :users)
|
424
363
|
expect(result.length).to eq 2
|
425
364
|
expect(result.first.is_a? Horza::Entities::Single).to be true
|
426
|
-
expect(result.first.to_hash).to eq
|
365
|
+
expect(result.first.to_hash).to eq User.order('id DESC').first.attributes
|
427
366
|
end
|
428
367
|
end
|
429
368
|
|
@@ -434,14 +373,14 @@ describe Horza do
|
|
434
373
|
end
|
435
374
|
|
436
375
|
context 'valid ancestry with no saved childred' do
|
437
|
-
let(:employer2) {
|
438
|
-
it 'returns empty collection
|
376
|
+
let(:employer2) { Employer.create }
|
377
|
+
it 'returns empty collection' do
|
439
378
|
expect(employer_adapter.association(id: employer2.id, target: :users).empty?).to be true
|
440
379
|
end
|
441
380
|
end
|
442
381
|
|
443
382
|
context 'valid ancestry with no saved parent' do
|
444
|
-
let(:user2) {
|
383
|
+
let(:user2) { User.create }
|
445
384
|
it 'returns nil' do
|
446
385
|
expect(user_adapter.association(id: user2.id, target: :employer)).to be nil
|
447
386
|
end
|
@@ -453,8 +392,8 @@ describe Horza do
|
|
453
392
|
let(:conditions) { { last_name: 'Turner' } }
|
454
393
|
|
455
394
|
before do
|
456
|
-
turner_total.times { employer.users <<
|
457
|
-
other_total.times { employer.users <<
|
395
|
+
turner_total.times { employer.users << User.create(conditions.merge(employer: employer)) }
|
396
|
+
other_total.times { employer.users << User.create(employer: employer) }
|
458
397
|
end
|
459
398
|
|
460
399
|
context 'limit' do
|
@@ -478,7 +417,7 @@ describe Horza do
|
|
478
417
|
context 'order' do
|
479
418
|
it 'orders response' do
|
480
419
|
horza_response = employer_adapter.association(id: employer.id, target: :users, conditions: conditions, order: { id: :asc })
|
481
|
-
ar_response =
|
420
|
+
ar_response = User.where(conditions).order('id asc')
|
482
421
|
expect(horza_response.first.id).to eq ar_response.first.id
|
483
422
|
expect(horza_response.last.id).to eq ar_response.last.id
|
484
423
|
end
|
@@ -488,7 +427,7 @@ describe Horza do
|
|
488
427
|
context 'simple' do
|
489
428
|
it 'works as expected' do
|
490
429
|
horza_response = employer_adapter.association(id: employer.id, target: :users, conditions: conditions, order: { id: :asc }, eager_load: true)
|
491
|
-
ar_response =
|
430
|
+
ar_response = User.where(conditions).order('id asc')
|
492
431
|
expect(horza_response.first.id).to eq ar_response.first.id
|
493
432
|
expect(horza_response.last.id).to eq ar_response.last.id
|
494
433
|
end
|
@@ -498,9 +437,9 @@ describe Horza do
|
|
498
437
|
end
|
499
438
|
|
500
439
|
context 'using via' do
|
501
|
-
let(:employer) {
|
502
|
-
let(:user) {
|
503
|
-
let(:sportscar) {
|
440
|
+
let(:employer) { Employer.create }
|
441
|
+
let(:user) { User.create(employer: employer) }
|
442
|
+
let(:sportscar) { SportsCar.create(employer: employer) }
|
504
443
|
|
505
444
|
before do
|
506
445
|
employer.sports_cars << sportscar
|
@@ -510,6 +449,13 @@ describe Horza do
|
|
510
449
|
expect(user_adapter.association(id: user.id, target: :sports_cars, via: [:employer]).first).to eq sportscar.attributes
|
511
450
|
end
|
512
451
|
|
452
|
+
context 'valid ancestry with no saved :via association' do
|
453
|
+
it 'returns empty collection' do
|
454
|
+
user.update_attribute(:employer_id, nil)
|
455
|
+
expect(user_adapter.association(id: user.id, target: :sports_cars, via: [:employer])).to be nil
|
456
|
+
end
|
457
|
+
end
|
458
|
+
|
513
459
|
context 'with eager loading' do
|
514
460
|
it 'works as expected' do
|
515
461
|
horza_response = user_adapter.association(id: user.id, target: :sports_cars, via: [:employer], order: { id: :asc }, eager_load: true)
|
@@ -561,8 +507,8 @@ describe Horza do
|
|
561
507
|
|
562
508
|
context 'without conditions' do
|
563
509
|
context 'when one join record exists' do
|
564
|
-
let!(:employer) {
|
565
|
-
let!(:user) {
|
510
|
+
let!(:employer) { Employer.create(name: 'Corporation ltd.', boss_email: 'boss@boss.com') }
|
511
|
+
let!(:user) { User.create(employer: employer, first_name: 'John', last_name: 'Turner', email: 'email@email.com') }
|
566
512
|
|
567
513
|
context 'without fields' do
|
568
514
|
it 'returns joined record' do
|
@@ -595,8 +541,8 @@ describe Horza do
|
|
595
541
|
end
|
596
542
|
|
597
543
|
context 'complex predicate' do
|
598
|
-
let!(:match_user) {
|
599
|
-
let!(:match_user2) {
|
544
|
+
let!(:match_user) { User.create(employer: employer, first_name: 'John', last_name: 'Turner', email: 'boss@boss.com') }
|
545
|
+
let!(:match_user2) { User.create(employer: employer, first_name: 'Helen', last_name: 'Jones', email: 'boss@boss.com') }
|
600
546
|
it 'returns joined records and the specified fields' do
|
601
547
|
result = user_adapter.join(complex_predicate)
|
602
548
|
expect(result.length).to eq 2
|
@@ -610,8 +556,8 @@ describe Horza do
|
|
610
556
|
end
|
611
557
|
|
612
558
|
context 'when no join record exists' do
|
613
|
-
let!(:employer) {
|
614
|
-
let!(:user) {
|
559
|
+
let!(:employer) { Employer.create(name: 'Corporation ltd.') }
|
560
|
+
let!(:user) { User.create(employer_id: 9999, first_name: 'John', last_name: 'Turner', email: 'email@email.com') }
|
615
561
|
|
616
562
|
it 'returns an empty collection' do
|
617
563
|
result = user_adapter.join(simple)
|
@@ -620,10 +566,10 @@ describe Horza do
|
|
620
566
|
end
|
621
567
|
|
622
568
|
context 'when multiple join records exists' do
|
623
|
-
let!(:employer) {
|
624
|
-
let!(:user) {
|
625
|
-
let!(:user2) {
|
626
|
-
let!(:user3) {
|
569
|
+
let!(:employer) { Employer.create(name: 'Corporation ltd.') }
|
570
|
+
let!(:user) { User.create(employer: employer, first_name: 'John', last_name: 'Turner', email: 'email@turner.com') }
|
571
|
+
let!(:user2) { User.create(employer: employer, first_name: 'Adam', last_name: 'Boots', email: 'email@boots.com') }
|
572
|
+
let!(:user3) { User.create(employer: employer, first_name: 'Tim', last_name: 'Socks', email: 'email@socks.com') }
|
627
573
|
|
628
574
|
it 'returns an empty collection' do
|
629
575
|
result = user_adapter.join(simple)
|
@@ -633,11 +579,11 @@ describe Horza do
|
|
633
579
|
end
|
634
580
|
|
635
581
|
context 'with conditions' do
|
636
|
-
let!(:employer) {
|
637
|
-
let!(:employer2) {
|
638
|
-
let!(:user) {
|
639
|
-
let!(:user2) {
|
640
|
-
let!(:user3) {
|
582
|
+
let!(:employer) { Employer.create(name: 'Corporation ltd.') }
|
583
|
+
let!(:employer2) { Employer.create(name: 'BigBucks ltd.') }
|
584
|
+
let!(:user) { User.create(employer: employer, first_name: 'John', last_name: 'Turner', email: 'email@turner.com') }
|
585
|
+
let!(:user2) { User.create(employer: employer, first_name: 'Adam', last_name: 'Boots', email: 'email@boots.com') }
|
586
|
+
let!(:user3) { User.create(employer: employer2, first_name: 'Tim', last_name: 'Socks', email: 'email@socks.com') }
|
641
587
|
|
642
588
|
it 'returns only the joins that match the conditions' do
|
643
589
|
result = user_adapter.join(conditions)
|
@@ -647,11 +593,11 @@ describe Horza do
|
|
647
593
|
end
|
648
594
|
|
649
595
|
context 'limits/offset' do
|
650
|
-
let!(:employer) {
|
651
|
-
let!(:employer2) {
|
652
|
-
let!(:user) {
|
653
|
-
let!(:user2) {
|
654
|
-
let!(:user3) {
|
596
|
+
let!(:employer) { Employer.create(name: 'Corporation ltd.') }
|
597
|
+
let!(:employer2) { Employer.create(name: 'BigBucks ltd.') }
|
598
|
+
let!(:user) { User.create(employer: employer, first_name: 'John', last_name: 'Turner', email: 'email@turner.com') }
|
599
|
+
let!(:user2) { User.create(employer: employer, first_name: 'Adam', last_name: 'Turner', email: 'email@boots.com') }
|
600
|
+
let!(:user3) { User.create(employer: employer2, first_name: 'Tim', last_name: 'Socks', email: 'email@socks.com') }
|
655
601
|
|
656
602
|
it 'limits the joins that match the conditions' do
|
657
603
|
params = conditions.merge(limit: 1)
|
@@ -673,7 +619,7 @@ describe Horza do
|
|
673
619
|
describe 'Entities' do
|
674
620
|
describe 'Collection' do
|
675
621
|
let(:members) do
|
676
|
-
3.times.map {
|
622
|
+
3.times.map { User.create }
|
677
623
|
end
|
678
624
|
|
679
625
|
let(:single_entity_klass) { Horza::Entities::SingleWithActiveModel }
|
@@ -721,7 +667,7 @@ describe Horza do
|
|
721
667
|
|
722
668
|
context '#singular_entity_class' do
|
723
669
|
context 'when singular entity class does not exist' do
|
724
|
-
let(:dummy_model) {
|
670
|
+
let(:dummy_model) { DummyModel.create }
|
725
671
|
|
726
672
|
module TestNamespace
|
727
673
|
class DummyModels < Horza::Entities::Collection
|
@@ -734,7 +680,7 @@ describe Horza do
|
|
734
680
|
end
|
735
681
|
|
736
682
|
context 'when singular entity class exists' do
|
737
|
-
let(:other_dummy_model) {
|
683
|
+
let(:other_dummy_model) { OtherDummyModel.create }
|
738
684
|
|
739
685
|
module TestNamespace
|
740
686
|
class OtherDummyModels < Horza::Entities::Collection
|
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Horza::Configuration do
|
4
|
+
|
5
|
+
describe "#adapter" do
|
6
|
+
it "not set" do
|
7
|
+
expect { subject.adapter }.to raise_error(Horza::Errors::AdapterError, /No adapter configured/)
|
8
|
+
end
|
9
|
+
|
10
|
+
context "setting adapter" do
|
11
|
+
it "finds adapter class if given" do
|
12
|
+
subject.adapter = :active_record
|
13
|
+
|
14
|
+
expect(subject.adapter).to eq Horza::Adapters::ActiveRecord
|
15
|
+
end
|
16
|
+
|
17
|
+
it "raises if adapter class doesn't exist" do
|
18
|
+
expect { subject.adapter = :missing }.to raise_error(Horza::Errors::AdapterError, /No adapter found/)
|
19
|
+
end
|
20
|
+
|
21
|
+
it "doesn't raise if no name is given" do
|
22
|
+
expect { subject.adapter = nil }.to_not raise_error(Horza::Errors::AdapterError)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,94 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Horza::DependencyLoading do
|
4
|
+
|
5
|
+
before(:each) do
|
6
|
+
Horza.configuration.constant_paths += ["spec"]
|
7
|
+
ActiveSupport::Dependencies.autoload_paths += ["spec"]
|
8
|
+
end
|
9
|
+
|
10
|
+
after(:each) do
|
11
|
+
Horza.clear_constant_paths
|
12
|
+
ActiveSupport::Dependencies.autoload_paths.clear
|
13
|
+
end
|
14
|
+
|
15
|
+
describe "::resolve_dependency" do
|
16
|
+
|
17
|
+
it "resolves constant by file name" do
|
18
|
+
const = Horza::DependencyLoading.resolve_dependency("test_employer")
|
19
|
+
expect(const.name).to eq "TestConstants::TestEmployer"
|
20
|
+
end
|
21
|
+
|
22
|
+
it "resolves constant by constant name" do
|
23
|
+
const = Horza::DependencyLoading.resolve_dependency("TestEmployer")
|
24
|
+
expect(const.name).to eq "TestConstants::TestEmployer"
|
25
|
+
end
|
26
|
+
|
27
|
+
it "raises if #constant_paths is empty" do
|
28
|
+
Horza.clear_constant_paths
|
29
|
+
|
30
|
+
expect { Horza::DependencyLoading.resolve_dependency("test_employer") }.to raise_error(ArgumentError)
|
31
|
+
end
|
32
|
+
|
33
|
+
it "raises if #constant_paths has nested directory paths" do
|
34
|
+
Horza.configuration.constant_paths += ["spec/test_constants"]
|
35
|
+
|
36
|
+
expect { Horza::DependencyLoading.resolve_dependency("test_employer") }.to raise_error
|
37
|
+
end
|
38
|
+
|
39
|
+
it "returns constant if already loaded" do
|
40
|
+
Object.const_set(:A, Class.new)
|
41
|
+
|
42
|
+
constant = Horza::DependencyLoading.resolve_dependency("a")
|
43
|
+
expect(constant).to eq A
|
44
|
+
|
45
|
+
Object.send(:remove_const, :A)
|
46
|
+
end
|
47
|
+
|
48
|
+
context "finds multiple matched constant_paths" do
|
49
|
+
|
50
|
+
it "resolves constant for first matched file_path" do
|
51
|
+
|
52
|
+
with_clashing_file do
|
53
|
+
const = Horza::DependencyLoading.resolve_dependency("test_employer")
|
54
|
+
expect(const.name).to eq "TestEmployer"
|
55
|
+
end
|
56
|
+
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
describe "::search_for_file" do
|
62
|
+
context "constant_paths are given" do
|
63
|
+
it "returns file path if matched" do
|
64
|
+
file_path = Horza::DependencyLoading.search_for_file("test_employer")
|
65
|
+
expect(file_path).to eq "spec/test_constants/test_employer.rb"
|
66
|
+
end
|
67
|
+
|
68
|
+
it "raises if file path is not matched" do
|
69
|
+
expect { Horza::DependencyLoading.search_for_file("employer") }.to raise_error(Horza::DependencyLoading::MissingFile)
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
|
75
|
+
describe "::constant_name_for_path" do
|
76
|
+
it "returns a loadable constant name for file path" do
|
77
|
+
name = Horza::DependencyLoading.constant_name_for_path("spec/test_constants/any_constant.rb")
|
78
|
+
|
79
|
+
expect(name).to eq ["TestConstants::AnyConstant"]
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
def with_clashing_file
|
84
|
+
file_name = "spec/test_employer.rb"
|
85
|
+
|
86
|
+
File.open(file_name, "w+") do |f|
|
87
|
+
f.write("class TestEmployer;end")
|
88
|
+
end
|
89
|
+
|
90
|
+
yield
|
91
|
+
|
92
|
+
FileUtils.rm(file_name)
|
93
|
+
end
|
94
|
+
end
|
data/spec/horza_spec.rb
CHANGED
@@ -1,52 +1,5 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
|
-
describe Horza do
|
4
|
-
context '#adapter' do
|
5
|
-
context 'when adapter is not configured' do
|
6
|
-
before { Horza.reset }
|
7
|
-
after { Horza.reset }
|
8
|
-
it 'throws error' do
|
9
|
-
expect { Horza.adapter }.to raise_error(Horza::Errors::AdapterNotConfigured)
|
10
|
-
end
|
11
|
-
end
|
12
|
-
|
13
|
-
context 'when adapter is configured' do
|
14
|
-
before do
|
15
|
-
Horza.reset
|
16
|
-
Horza.configure { |config| config.adapter = :active_record }
|
17
|
-
end
|
18
|
-
after { Horza.reset }
|
19
|
-
it 'returns appropriate class' do
|
20
|
-
expect(Horza.adapter).to eq Horza::Adapters::ActiveRecord
|
21
|
-
end
|
22
|
-
end
|
23
|
-
end
|
24
|
-
|
25
|
-
context '#configuration #namespaces' do
|
26
|
-
context 'when namespaces are not configured' do
|
27
|
-
before { Horza.reset }
|
28
|
-
after { Horza.reset }
|
29
|
-
it 'returns empty array' do
|
30
|
-
expect(Horza.configuration.namespaces.is_a? Array).to be true
|
31
|
-
expect(Horza.configuration.namespaces.empty?).to be true
|
32
|
-
end
|
33
|
-
end
|
34
|
-
|
35
|
-
context 'when namespaces are configured' do
|
36
|
-
module HorzaNamespace
|
37
|
-
end
|
38
|
-
|
39
|
-
before do
|
40
|
-
Horza.reset
|
41
|
-
Horza.configure { |config| config.namespaces = [HorzaNamespace] }
|
42
|
-
end
|
43
|
-
after { Horza.reset }
|
44
|
-
it 'returns configured namespaces class' do
|
45
|
-
expect(Horza.configuration.namespaces).to eq [HorzaNamespace]
|
46
|
-
end
|
47
|
-
end
|
48
|
-
end
|
49
|
-
end
|
50
3
|
|
51
4
|
describe Horza::Entities::Single do
|
52
5
|
subject { Horza::Entities::Single.new(first_name: 'Blake') }
|
@@ -0,0 +1,16 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Horza::SharedConfig do
|
4
|
+
subject(:target_class) { Class.new.send(:extend, Horza::SharedConfig) }
|
5
|
+
|
6
|
+
it "expose same Horza config instance to target class" do
|
7
|
+
expect(subject.configuration).to be Horza.configuration
|
8
|
+
end
|
9
|
+
|
10
|
+
it "delegates config methods to Horza" do
|
11
|
+
[:reset, :constant_paths,:clear_constant_paths, :adapter, :adapter=].each do |_meth_|
|
12
|
+
expect(Horza).to receive(_meth_)
|
13
|
+
target_class.send _meth_
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: horza
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 1.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Blake Turner
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-11-
|
11
|
+
date: 2015-11-30 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: hashie
|
@@ -28,70 +28,70 @@ dependencies:
|
|
28
28
|
name: activesupport
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
|
-
- -
|
31
|
+
- - ~>
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version:
|
33
|
+
version: '3.2'
|
34
34
|
type: :runtime
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
|
-
- -
|
38
|
+
- - ~>
|
39
39
|
- !ruby/object:Gem::Version
|
40
|
-
version:
|
40
|
+
version: '3.2'
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
42
|
name: rspec
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
44
44
|
requirements:
|
45
|
-
- -
|
45
|
+
- - '>='
|
46
46
|
- !ruby/object:Gem::Version
|
47
|
-
version:
|
47
|
+
version: '0'
|
48
48
|
type: :development
|
49
49
|
prerelease: false
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
51
51
|
requirements:
|
52
|
-
- -
|
52
|
+
- - '>='
|
53
53
|
- !ruby/object:Gem::Version
|
54
|
-
version:
|
54
|
+
version: '0'
|
55
55
|
- !ruby/object:Gem::Dependency
|
56
56
|
name: byebug
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
58
58
|
requirements:
|
59
|
-
- -
|
59
|
+
- - '>='
|
60
60
|
- !ruby/object:Gem::Version
|
61
61
|
version: '4.0'
|
62
62
|
type: :development
|
63
63
|
prerelease: false
|
64
64
|
version_requirements: !ruby/object:Gem::Requirement
|
65
65
|
requirements:
|
66
|
-
- -
|
66
|
+
- - '>='
|
67
67
|
- !ruby/object:Gem::Version
|
68
68
|
version: '4.0'
|
69
69
|
- !ruby/object:Gem::Dependency
|
70
70
|
name: activerecord
|
71
71
|
requirement: !ruby/object:Gem::Requirement
|
72
72
|
requirements:
|
73
|
-
- -
|
73
|
+
- - ~>
|
74
74
|
- !ruby/object:Gem::Version
|
75
|
-
version: 3.2
|
75
|
+
version: '3.2'
|
76
76
|
type: :development
|
77
77
|
prerelease: false
|
78
78
|
version_requirements: !ruby/object:Gem::Requirement
|
79
79
|
requirements:
|
80
|
-
- -
|
80
|
+
- - ~>
|
81
81
|
- !ruby/object:Gem::Version
|
82
|
-
version: 3.2
|
82
|
+
version: '3.2'
|
83
83
|
- !ruby/object:Gem::Dependency
|
84
84
|
name: sqlite3
|
85
85
|
requirement: !ruby/object:Gem::Requirement
|
86
86
|
requirements:
|
87
|
-
- -
|
87
|
+
- - '>='
|
88
88
|
- !ruby/object:Gem::Version
|
89
89
|
version: '0'
|
90
90
|
type: :development
|
91
91
|
prerelease: false
|
92
92
|
version_requirements: !ruby/object:Gem::Requirement
|
93
93
|
requirements:
|
94
|
-
- -
|
94
|
+
- - '>='
|
95
95
|
- !ruby/object:Gem::Version
|
96
96
|
version: '0'
|
97
97
|
description: Horza is a shapeshifter that provides common inputs and outputs for your
|
@@ -101,9 +101,6 @@ executables: []
|
|
101
101
|
extensions: []
|
102
102
|
extra_rdoc_files: []
|
103
103
|
files:
|
104
|
-
- LICENSE.txt
|
105
|
-
- README.md
|
106
|
-
- lib/horza.rb
|
107
104
|
- lib/horza/adapters/abstract_adapter.rb
|
108
105
|
- lib/horza/adapters/active_record/active_record.rb
|
109
106
|
- lib/horza/adapters/active_record/arel_join.rb
|
@@ -112,14 +109,24 @@ files:
|
|
112
109
|
- lib/horza/adapters/options.rb
|
113
110
|
- lib/horza/configuration.rb
|
114
111
|
- lib/horza/core_extensions/string.rb
|
115
|
-
- lib/horza/
|
112
|
+
- lib/horza/dependency_loading.rb
|
116
113
|
- lib/horza/entities/collection.rb
|
117
114
|
- lib/horza/entities/single.rb
|
118
115
|
- lib/horza/entities/single_with_active_model.rb
|
116
|
+
- lib/horza/entities.rb
|
119
117
|
- lib/horza/errors.rb
|
118
|
+
- lib/horza/shared_config.rb
|
119
|
+
- lib/horza/version.rb
|
120
|
+
- lib/horza.rb
|
121
|
+
- LICENSE.txt
|
122
|
+
- README.md
|
120
123
|
- spec/active_record_spec.rb
|
124
|
+
- spec/configuration_spec.rb
|
125
|
+
- spec/dependency_loading_spec.rb
|
121
126
|
- spec/horza_spec.rb
|
127
|
+
- spec/shared_config_spec.rb
|
122
128
|
- spec/spec_helper.rb
|
129
|
+
- spec/test_constants/test_employer.rb
|
123
130
|
homepage: https://github.com/onfido/horza
|
124
131
|
licenses:
|
125
132
|
- MIT
|
@@ -130,22 +137,25 @@ require_paths:
|
|
130
137
|
- lib
|
131
138
|
required_ruby_version: !ruby/object:Gem::Requirement
|
132
139
|
requirements:
|
133
|
-
- -
|
140
|
+
- - '>='
|
134
141
|
- !ruby/object:Gem::Version
|
135
142
|
version: '0'
|
136
143
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
137
144
|
requirements:
|
138
|
-
- -
|
145
|
+
- - '>='
|
139
146
|
- !ruby/object:Gem::Version
|
140
147
|
version: '0'
|
141
148
|
requirements: []
|
142
149
|
rubyforge_project:
|
143
|
-
rubygems_version: 2.
|
150
|
+
rubygems_version: 2.0.14
|
144
151
|
signing_key:
|
145
152
|
specification_version: 4
|
146
153
|
summary: Keep your app ORM-agnostic
|
147
154
|
test_files:
|
148
155
|
- spec/active_record_spec.rb
|
156
|
+
- spec/configuration_spec.rb
|
157
|
+
- spec/dependency_loading_spec.rb
|
149
158
|
- spec/horza_spec.rb
|
159
|
+
- spec/shared_config_spec.rb
|
150
160
|
- spec/spec_helper.rb
|
151
|
-
|
161
|
+
- spec/test_constants/test_employer.rb
|