trax_core 0.0.5 → 0.0.6
Sign up to get free protection for your applications and to get access to all the features.
- 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
|