trax_core 0.0.5 → 0.0.6
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/lib/trax/core.rb +4 -0
- data/lib/trax/core/configuration.rb +45 -0
- data/lib/trax/core/errors.rb +97 -0
- data/lib/trax/core/ext/module.rb +13 -0
- data/lib/trax/core/ext/object.rb +47 -0
- data/lib/trax_core.rb +1 -0
- data/lib/trax_core/version.rb +1 -1
- data/spec/support/errors.rb +11 -0
- data/spec/trax/core/errors_spec.rb +23 -0
- data/spec/trax/core/ext/module_spec.rb +80 -0
- data/spec/trax/core/ext/object_spec.rb +26 -0
- data/trax_core.gemspec +1 -0
- metadata +29 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a0ab417a5f629ffa26dd2ed8aa06606ad0ef8da8
|
4
|
+
data.tar.gz: 0e40b82964838f3a67ce14188f88fa50a3f53b6b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0fb3074b04d8a8d4aef67b29c74d0d26fdaf448aeef86e4840a41fd123f6882fce2d93257022440aab3f60678617166ce20e913cef86ebd92595c6fb5af7ced6
|
7
|
+
data.tar.gz: cb0cc1e316457f2d1a8b62eca08c36de77011b8c752ab7fe364107f40a7b093b245f56de65c8acc90e6400877a5cd690406b80d1a6be2ae9230d972f0ec74e04
|
data/lib/trax/core.rb
CHANGED
@@ -1,10 +1,14 @@
|
|
1
1
|
require 'active_support/all'
|
2
2
|
require_relative './array'
|
3
|
+
require_relative './core/ext/module'
|
4
|
+
require_relative './core/ext/object'
|
3
5
|
|
4
6
|
module Trax
|
5
7
|
module Core
|
6
8
|
extend ::ActiveSupport::Autoload
|
7
9
|
|
10
|
+
autoload :Configuration
|
8
11
|
autoload :EagerAutoloadNamespace
|
12
|
+
autoload :Errors
|
9
13
|
end
|
10
14
|
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
require 'hashie/dash'
|
2
|
+
require 'active_model'
|
3
|
+
require 'active_model/validations'
|
4
|
+
|
5
|
+
module Trax
|
6
|
+
module Core
|
7
|
+
class Configuration
|
8
|
+
include ActiveModel::Validations
|
9
|
+
|
10
|
+
def initialize
|
11
|
+
set_default_values
|
12
|
+
|
13
|
+
yield self
|
14
|
+
|
15
|
+
raise_errors unless self.valid?
|
16
|
+
end
|
17
|
+
|
18
|
+
def set_default_values
|
19
|
+
self.class.configurable_options.select{|attr_name, hash| hash.key?(:default) }.each_pair do |attr_name,hash|
|
20
|
+
__send__("#{attr_name}=", hash[:default])
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def self.inherited(subklass)
|
25
|
+
subklass.class_attribute :configurable_options
|
26
|
+
subklass.configurable_options = {}
|
27
|
+
end
|
28
|
+
|
29
|
+
def self.option(attr_name, options = {})
|
30
|
+
attr_accessor attr_name
|
31
|
+
|
32
|
+
validates_presence_of(attr_name) if(options.key?(:required))
|
33
|
+
|
34
|
+
self.configurable_options[attr_name] = options
|
35
|
+
end
|
36
|
+
|
37
|
+
def raise_errors
|
38
|
+
raise Trax::Core::Errors::ConfigurationError.new(
|
39
|
+
:messages => self.errors.full_messages,
|
40
|
+
:source => self.class.name
|
41
|
+
)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,97 @@
|
|
1
|
+
require 'hashie/dash'
|
2
|
+
require 'hashie/mash'
|
3
|
+
|
4
|
+
module Trax
|
5
|
+
module Core
|
6
|
+
module Errors
|
7
|
+
# A simple inheritable error class
|
8
|
+
# Because Im sick of defining in every project a base error class
|
9
|
+
# and IMO arguments should have explicit names when thrown to give context to the error
|
10
|
+
# (while not being order dependent)
|
11
|
+
# and perhaps its a bad idea to require arguments when throwing errors, but
|
12
|
+
# you can still make them as generic as you want
|
13
|
+
# & the idea is fail fast and provide more targeted & descriptive error tracking data
|
14
|
+
|
15
|
+
# Example:
|
16
|
+
#
|
17
|
+
# class AbstractInstanceMethodNotDefined < ::Trax::Core::Errors::Base
|
18
|
+
# argument :method_name, :required => true
|
19
|
+
# argument :klass, :required => true
|
20
|
+
#
|
21
|
+
# message {
|
22
|
+
# "Abstract instance method, #{method_name} not defined for #{klass}"
|
23
|
+
# }
|
24
|
+
# end
|
25
|
+
#
|
26
|
+
# raise ::AbstractInstanceMethodNotDefined.new(:method_name => "my_method", :klass => self.class.name)
|
27
|
+
|
28
|
+
class Arguments < ::Hashie::Dash
|
29
|
+
end
|
30
|
+
|
31
|
+
class Base < StandardError
|
32
|
+
class_attribute :_message
|
33
|
+
|
34
|
+
#on inherit of Trax::Core::Errors::Base, inherit from arguments class above to provide simple
|
35
|
+
#dsl options / typecasting and stuff to our errors.
|
36
|
+
def self.inherited(subklass)
|
37
|
+
subklass.class_eval do
|
38
|
+
arguments_class_name = "#{subklass.name.demodulize}Arguments"
|
39
|
+
arguments_klass = const_set(arguments_class_name, ::Class.new(::Trax::Core::Errors::Arguments)) unless const_defined?(arguments_class_name)
|
40
|
+
@_permitted_arguments_klass = arguments_klass
|
41
|
+
@_permitted_arguments = arguments_klass.new
|
42
|
+
|
43
|
+
attr_reader :_permitted_arguments
|
44
|
+
attr_reader :_permitted_arguments_klass
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
def self.argument(method_name, *args)
|
49
|
+
permitted_arguments_klass.property(method_name, *args)
|
50
|
+
|
51
|
+
define_method(method_name) do
|
52
|
+
arguments_instance.__send__(method_name)
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
def self.permitted_arguments_klass
|
57
|
+
@_permitted_arguments_klass
|
58
|
+
end
|
59
|
+
|
60
|
+
def self.permitted_arguments
|
61
|
+
@_permitted_arguments
|
62
|
+
end
|
63
|
+
|
64
|
+
def self.message(&block)
|
65
|
+
self._message = block
|
66
|
+
end
|
67
|
+
|
68
|
+
# if no properties have been defined using argument method, wrap in Mash
|
69
|
+
def self.error_arguments_klass
|
70
|
+
@error_arguments_klass ||= (permitted_arguments_klass.properties.length) ? permitted_arguments_klass : ::Hashie::Mash
|
71
|
+
end
|
72
|
+
|
73
|
+
attr_reader :arguments_instance
|
74
|
+
|
75
|
+
def initialize(_attributes = {})
|
76
|
+
@arguments_instance = self.class.permitted_arguments_klass.new(_attributes)
|
77
|
+
|
78
|
+
super(message)
|
79
|
+
end
|
80
|
+
|
81
|
+
def message
|
82
|
+
self.instance_eval(&self.class._message)
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
class ConfigurationError < ::Trax::Core::Errors::Base
|
87
|
+
argument :source, :required => true
|
88
|
+
argument :messages
|
89
|
+
|
90
|
+
message {
|
91
|
+
"Error configuring #{source}, \n" \
|
92
|
+
"#{messages.join('\n')}"
|
93
|
+
}
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
class Module
|
2
|
+
def recursively_define_namespaced_class(class_name, class_to_inherit_from = Object)
|
3
|
+
paths = class_name.split("::")
|
4
|
+
const_name = paths.shift
|
5
|
+
|
6
|
+
if paths.length > 0
|
7
|
+
self.const_set(const_name, ::Module.new) unless self.constants.include?(:"#{const_name}")
|
8
|
+
"#{self.name}::#{const_name}".safe_constantize.recursively_define_namespaced_class(paths.join("::"), class_to_inherit_from)
|
9
|
+
else
|
10
|
+
self.const_set(const_name, ::Class.new(class_to_inherit_from)) unless self.constants.include?(:"#{const_name}")
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
require "active_support/core_ext/object/try"
|
2
|
+
|
3
|
+
class Object
|
4
|
+
# Defines a Configuration Class within a target module namespace, or nested class
|
5
|
+
# i.e. configuration_for(::Ecommerce::Cart) will define
|
6
|
+
# Ecommerce::Cart::Configuration class, inherited form Trax::Core::Configuration
|
7
|
+
# And we can then define specific configuration options, for that class, on that class
|
8
|
+
def configuration_for(target, &blk)
|
9
|
+
target.class_eval do
|
10
|
+
class << self
|
11
|
+
attr_accessor :_configuration
|
12
|
+
end
|
13
|
+
|
14
|
+
const_set("Configuration", ::Class.new(::Trax::Core::Configuration))
|
15
|
+
const_get("Configuration").instance_eval(&blk)
|
16
|
+
|
17
|
+
def self.configure(&block)
|
18
|
+
@_configuration = const_get("Configuration").new(&block)
|
19
|
+
end
|
20
|
+
|
21
|
+
def self.config
|
22
|
+
_configuration
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def define_configuration_options(&block)
|
28
|
+
configuration_for(self, &block)
|
29
|
+
end
|
30
|
+
|
31
|
+
alias_method :define_configuration, :define_configuration_options
|
32
|
+
alias_method :has_configuration, :define_configuration_options
|
33
|
+
|
34
|
+
#following method stolen from abrandoned https://rubygems.org/gems/try_chain
|
35
|
+
def try_chain(*symbols)
|
36
|
+
return nil if self.nil?
|
37
|
+
|
38
|
+
symbols = symbols.flatten
|
39
|
+
symbols.compact!
|
40
|
+
|
41
|
+
symbols.reduce(self) do |result, symbol|
|
42
|
+
result = result.try(symbol)
|
43
|
+
break nil if result.nil?
|
44
|
+
result
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
data/lib/trax_core.rb
CHANGED
data/lib/trax_core/version.rb
CHANGED
@@ -0,0 +1,11 @@
|
|
1
|
+
module Errors
|
2
|
+
class SiteBrokenError < ::Trax::Core::Errors::Base
|
3
|
+
argument :request_url, :required => true
|
4
|
+
argument :request_id, :required => true
|
5
|
+
|
6
|
+
message {
|
7
|
+
"Oh no, the site broke on #{request_url}" \
|
8
|
+
"for current_request_id #{request_id}!"
|
9
|
+
}
|
10
|
+
end
|
11
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe ::Trax::Core::Errors do
|
4
|
+
subject { ::Errors::SiteBrokenError }
|
5
|
+
|
6
|
+
it { expect{ subject.new }.to raise_error(ArgumentError) }
|
7
|
+
|
8
|
+
it do
|
9
|
+
expect do
|
10
|
+
raise subject.new(
|
11
|
+
:request_url => 'http://www.somewhere.com',
|
12
|
+
:request_id => 'asdasdsdad1231421'
|
13
|
+
)
|
14
|
+
end.to raise_error(subject)
|
15
|
+
end
|
16
|
+
|
17
|
+
it do
|
18
|
+
subject.new(
|
19
|
+
:request_url => 'http://www.somewhere.com',
|
20
|
+
:request_id => 'asdasdsdad1231421'
|
21
|
+
).to_s.should include('http://www.somewhere.com')
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,80 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe ::Module do
|
4
|
+
subject { Trax::Core }
|
5
|
+
|
6
|
+
describe ".recursively_define_namespaced_class" do
|
7
|
+
context "when class namespace does not exist at global module level" do
|
8
|
+
before do
|
9
|
+
Trax.recursively_define_namespaced_class("Somefake::Thing")
|
10
|
+
end
|
11
|
+
|
12
|
+
it { Trax::Somefake::Thing.class == Object }
|
13
|
+
end
|
14
|
+
|
15
|
+
context "when class namespace does exist at global module level" do
|
16
|
+
before do
|
17
|
+
Trax.recursively_define_namespaced_class("Core::FakeKlass", Hash)
|
18
|
+
end
|
19
|
+
|
20
|
+
it { Trax::Core::FakeKlass.superclass.should == Hash }
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
describe ".configuration_for" do
|
25
|
+
before do
|
26
|
+
::Trax.recursively_define_namespaced_class("Core::FakeNamespace", Module)
|
27
|
+
|
28
|
+
::Trax::Core::FakeNamespace.configuration_for(Trax::Core::FakeNamespace) do
|
29
|
+
option :something, :required => true
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
subject{ ::Trax::Core::FakeNamespace::Configuration }
|
34
|
+
|
35
|
+
its(:superclass) { should eq ::Trax::Core::Configuration }
|
36
|
+
|
37
|
+
it "sets up configuration options" do
|
38
|
+
::Trax::Core::FakeNamespace.configure do |config|
|
39
|
+
config.something = 'anything'
|
40
|
+
end
|
41
|
+
|
42
|
+
::Trax::Core::FakeNamespace.config.something.should eq 'anything'
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
describe ".configuration_options" do
|
47
|
+
before do
|
48
|
+
::Trax.recursively_define_namespaced_class("Core::SomeFakeKlass", Hash)
|
49
|
+
|
50
|
+
::Trax::Core::SomeFakeKlass.define_configuration_options do
|
51
|
+
option :base_url, :required => true
|
52
|
+
option :subdomains, :default => []
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
it "blows up if required and not set" do
|
57
|
+
expect {
|
58
|
+
::Trax::Core::SomeFakeKlass.configure do |config|
|
59
|
+
config.subdomains = [:blah, :blah]
|
60
|
+
end
|
61
|
+
|
62
|
+
}.to raise_error(Trax::Core::Errors::ConfigurationError)
|
63
|
+
end
|
64
|
+
|
65
|
+
it "sets defaults" do
|
66
|
+
::Trax.recursively_define_namespaced_class("Core::YetAnotherFakeClass", Hash)
|
67
|
+
|
68
|
+
Trax::Core::YetAnotherFakeClass.define_configuration_options do
|
69
|
+
option :base_url
|
70
|
+
option :allowed_ips, :default => [ '192.231.1234' ]
|
71
|
+
end
|
72
|
+
|
73
|
+
::Trax::Core::YetAnotherFakeClass.configure do |config|
|
74
|
+
config.base_url = 'somewhere'
|
75
|
+
end
|
76
|
+
|
77
|
+
::Trax::Core::YetAnotherFakeClass.config.allowed_ips[0].should eq '192.231.1234'
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe ::Object do
|
4
|
+
before do
|
5
|
+
class SomeFakeClass < OpenStruct
|
6
|
+
end
|
7
|
+
end
|
8
|
+
|
9
|
+
subject do
|
10
|
+
SomeFakeClass
|
11
|
+
end
|
12
|
+
|
13
|
+
describe ".try_chain" do
|
14
|
+
it "wraps multiple calls to try and calls try on return value" do
|
15
|
+
subject.try_chain(:name, :underscore).should eq "some_fake_class"
|
16
|
+
end
|
17
|
+
|
18
|
+
it "handles return if nil is in chain" do
|
19
|
+
subject.try_chain(:name, :somefakemethod).should be_nil
|
20
|
+
end
|
21
|
+
|
22
|
+
it "handles instances of class" do
|
23
|
+
SomeFakeClass.new.try_chain(:class, :name, :underscore).should eq "some_fake_class"
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
data/trax_core.gemspec
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: trax_core
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.6
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jason Ayre
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2015-03-21 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: hashie
|
@@ -38,6 +38,20 @@ dependencies:
|
|
38
38
|
- - ">="
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: activemodel
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
41
55
|
- !ruby/object:Gem::Dependency
|
42
56
|
name: bundler
|
43
57
|
requirement: !ruby/object:Gem::Requirement
|
@@ -251,15 +265,23 @@ files:
|
|
251
265
|
- lib/trax.rb
|
252
266
|
- lib/trax/array.rb
|
253
267
|
- lib/trax/core.rb
|
268
|
+
- lib/trax/core/configuration.rb
|
254
269
|
- lib/trax/core/eager_autoload_namespace.rb
|
270
|
+
- lib/trax/core/errors.rb
|
271
|
+
- lib/trax/core/ext/module.rb
|
272
|
+
- lib/trax/core/ext/object.rb
|
255
273
|
- lib/trax_core.rb
|
256
274
|
- lib/trax_core/version.rb
|
257
275
|
- spec/spec_helper.rb
|
258
276
|
- spec/support/ecom.rb
|
259
277
|
- spec/support/ecom/widget.rb
|
260
278
|
- spec/support/ecom/widget_category.rb
|
279
|
+
- spec/support/errors.rb
|
261
280
|
- spec/trax/array_spec.rb
|
262
281
|
- spec/trax/core/eager_autoload_namespace_spec.rb
|
282
|
+
- spec/trax/core/errors_spec.rb
|
283
|
+
- spec/trax/core/ext/module_spec.rb
|
284
|
+
- spec/trax/core/ext/object_spec.rb
|
263
285
|
- spec/trax/core_spec.rb
|
264
286
|
- trax_core.gemspec
|
265
287
|
homepage: http://github.com/jasonayre/trax_core
|
@@ -282,7 +304,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
282
304
|
version: '0'
|
283
305
|
requirements: []
|
284
306
|
rubyforge_project:
|
285
|
-
rubygems_version: 2.
|
307
|
+
rubygems_version: 2.2.2
|
286
308
|
signing_key:
|
287
309
|
specification_version: 4
|
288
310
|
summary: Core Trax Dependencies
|
@@ -291,6 +313,10 @@ test_files:
|
|
291
313
|
- spec/support/ecom.rb
|
292
314
|
- spec/support/ecom/widget.rb
|
293
315
|
- spec/support/ecom/widget_category.rb
|
316
|
+
- spec/support/errors.rb
|
294
317
|
- spec/trax/array_spec.rb
|
295
318
|
- spec/trax/core/eager_autoload_namespace_spec.rb
|
319
|
+
- spec/trax/core/errors_spec.rb
|
320
|
+
- spec/trax/core/ext/module_spec.rb
|
321
|
+
- spec/trax/core/ext/object_spec.rb
|
296
322
|
- spec/trax/core_spec.rb
|