horza 0.5.2 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/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
|