trax_core 0.0.6 → 0.0.7
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/abstract_methods.rb +68 -0
- data/lib/trax/core/concern.rb +47 -0
- data/lib/trax/core/configuration.rb +26 -1
- data/lib/trax/core/eager_autoload_namespace.rb +1 -1
- data/lib/trax/core/eager_load_namespace.rb +18 -0
- data/lib/trax/core/errors.rb +11 -0
- data/lib/trax/core/ext/enumerable.rb +5 -0
- data/lib/trax/core/ext/module.rb +7 -0
- data/lib/trax/core/ext/object.rb +36 -16
- data/lib/trax/core/ext/string.rb +9 -0
- data/lib/trax/core/fs.rb +238 -0
- data/lib/trax/core/has_mixins.rb +49 -0
- data/lib/trax/core/inheritance.rb +22 -0
- data/lib/trax/core/isolated_mixin.rb +77 -0
- data/lib/trax/core/mixable.rb +57 -0
- data/lib/trax/core/mixin.rb +42 -0
- data/lib/trax/core/mixin_registry.rb +10 -0
- data/lib/trax/core.rb +11 -0
- data/lib/trax_core/version.rb +1 -1
- data/spec/support/ecom/widget.rb +0 -1
- data/spec/support/fake_namespace/priceable.rb +27 -0
- data/spec/support/fake_namespace.rb +5 -0
- data/spec/support/storefront/category.rb +4 -0
- data/spec/support/storefront/product.rb +7 -0
- data/spec/support/storefront.rb +4 -0
- data/spec/trax/core/ext/module_spec.rb +10 -0
- data/spec/trax/core/ext/object_spec.rb +9 -0
- data/spec/trax/core/has_mixins_spec.rb +19 -0
- metadata +27 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 0fea6e82d277b0d2b84405221ea0c6604efbc2d1
|
4
|
+
data.tar.gz: 19e536032336156466c42a90df643e080f2a584e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 02861133c520bfb36217068f12ba983d865bf5d87d478d34e9486753a8e50073250f12ee3f4ddb72384593ceffdb5f629da35ec81220b3e84440154550d79a84
|
7
|
+
data.tar.gz: ef5faec34cb92cf6c37078f979911955f02c6c13a45320a1201479b8a061e532a3c7a90b161c5dba4af3b8d61d290da27b9b6c27092dabe989c68ccd1d0871fc
|
@@ -0,0 +1,68 @@
|
|
1
|
+
module Trax
|
2
|
+
module Core
|
3
|
+
module AbstractMethods
|
4
|
+
extend ::ActiveSupport::Concern
|
5
|
+
|
6
|
+
included do
|
7
|
+
private
|
8
|
+
class_attribute :_abstract_methods, :_abstract_class_methods, :_abstract_class_attributes
|
9
|
+
self._abstract_methods = []
|
10
|
+
self._abstract_class_methods = []
|
11
|
+
self._abstract_class_attributes = []
|
12
|
+
end
|
13
|
+
|
14
|
+
module ClassMethods
|
15
|
+
def abstract_method(*method_names)
|
16
|
+
_abstract_methods.push(*method_names)
|
17
|
+
end
|
18
|
+
alias :abstract_methods :abstract_method
|
19
|
+
|
20
|
+
def abstract_class_method(*method_names)
|
21
|
+
_abstract_class_methods.push(*method_names)
|
22
|
+
end
|
23
|
+
alias :abstract_class_methods :abstract_class_method
|
24
|
+
|
25
|
+
def abstract_class_attribute(*method_names)
|
26
|
+
_abstract_class_attributes.push(*method_names)
|
27
|
+
class_attribute(*method_names)
|
28
|
+
end
|
29
|
+
alias :abstract_class_attributes :abstract_class_attribute
|
30
|
+
|
31
|
+
def inherited(subklass)
|
32
|
+
klass = super(subklass)
|
33
|
+
|
34
|
+
trace = ::TracePoint.new(:end) do |tracepoint|
|
35
|
+
if tracepoint.self == subklass #modules also trace end we only care about the class end
|
36
|
+
trace.disable
|
37
|
+
|
38
|
+
if _abstract_methods.any?
|
39
|
+
missing_instance_methods = ( Array(_abstract_methods) - subklass.instance_methods(false) )
|
40
|
+
|
41
|
+
raise NotImplementedError, "#{subklass} must implement the following instance method(s) \n" \
|
42
|
+
<< "#{missing_instance_methods}" if missing_instance_methods.any?
|
43
|
+
end
|
44
|
+
|
45
|
+
if _abstract_class_methods.any?
|
46
|
+
missing_class_methods = ( Array(_abstract_class_methods) - subklass.singleton_methods(false) )
|
47
|
+
|
48
|
+
raise NotImplementedError, "#{subklass} must implement the following class method(s) \n" \
|
49
|
+
<< "#{missing_class_methods}" if missing_class_methods.any?
|
50
|
+
end
|
51
|
+
|
52
|
+
if _abstract_class_attributes.any?
|
53
|
+
missing_class_attributes = _abstract_class_attributes.select{|_property| subklass.__send__(_property).blank? }
|
54
|
+
|
55
|
+
raise NotImplementedError, "#{subklass} must set the following class attributes(s) \n" \
|
56
|
+
<< "#{missing_class_attributes}" if missing_class_attributes.any?
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
trace.enable
|
62
|
+
|
63
|
+
klass
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
module Trax
|
2
|
+
module Core
|
3
|
+
module Concern
|
4
|
+
def included(base = nil, &block)
|
5
|
+
super(base, &block)
|
6
|
+
|
7
|
+
trace = ::TracePoint.new(:end) do |tracepoint|
|
8
|
+
if tracepoint.self == base
|
9
|
+
trace.disable
|
10
|
+
|
11
|
+
if self.instance_variable_defined?(:@_after_included_block)
|
12
|
+
base.instance_eval(&self.instance_variable_get(:@_after_included_block))
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
trace.enable
|
18
|
+
end
|
19
|
+
|
20
|
+
def self.extended(base)
|
21
|
+
base.extend(::ActiveSupport::Concern)
|
22
|
+
|
23
|
+
super(base)
|
24
|
+
|
25
|
+
trace = ::TracePoint.new(:end) do |tracepoint|
|
26
|
+
if tracepoint.self == base
|
27
|
+
trace.disable
|
28
|
+
|
29
|
+
if base.instance_variable_defined?(:@_after_extended_block)
|
30
|
+
base.instance_variable_get(:@_after_extended_block).call
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
trace.enable
|
36
|
+
end
|
37
|
+
|
38
|
+
def after_extended(&block)
|
39
|
+
self.instance_variable_set(:@_after_extended_block, block)
|
40
|
+
end
|
41
|
+
|
42
|
+
def after_included(&block)
|
43
|
+
self.instance_variable_set(:@_after_included_block, block)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -7,10 +7,12 @@ module Trax
|
|
7
7
|
class Configuration
|
8
8
|
include ActiveModel::Validations
|
9
9
|
|
10
|
+
class_attribute :source
|
11
|
+
|
10
12
|
def initialize
|
11
13
|
set_default_values
|
12
14
|
|
13
|
-
yield self
|
15
|
+
yield self if block_given?
|
14
16
|
|
15
17
|
raise_errors unless self.valid?
|
16
18
|
end
|
@@ -22,6 +24,8 @@ module Trax
|
|
22
24
|
end
|
23
25
|
|
24
26
|
def self.inherited(subklass)
|
27
|
+
super(subklass)
|
28
|
+
|
25
29
|
subklass.class_attribute :configurable_options
|
26
30
|
subklass.configurable_options = {}
|
27
31
|
end
|
@@ -31,9 +35,30 @@ module Trax
|
|
31
35
|
|
32
36
|
validates_presence_of(attr_name) if(options.key?(:required))
|
33
37
|
|
38
|
+
if(options.key?(:validates))
|
39
|
+
validates(attr_name, options[:validates])
|
40
|
+
end
|
41
|
+
|
42
|
+
define_method("#{attr_name}=") do |val|
|
43
|
+
value = options.key?(:setter) ? options[:setter].call(val) : val
|
44
|
+
instance_variable_set("@#{attr_name}", value)
|
45
|
+
|
46
|
+
raise_errors unless self.valid?
|
47
|
+
end
|
48
|
+
|
49
|
+
if(options.key?(:getter))
|
50
|
+
define_method(attr_name) do |val|
|
51
|
+
options[:getter].call(val)
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
34
55
|
self.configurable_options[attr_name] = options
|
35
56
|
end
|
36
57
|
|
58
|
+
def merge!(options = {})
|
59
|
+
options.each_pair{ |k,v| __send__("#{k}=", v) }
|
60
|
+
end
|
61
|
+
|
37
62
|
def raise_errors
|
38
63
|
raise Trax::Core::Errors::ConfigurationError.new(
|
39
64
|
:messages => self.errors.full_messages,
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module Trax
|
2
|
+
module Core
|
3
|
+
module EagerLoadNamespace
|
4
|
+
def self.extended(base)
|
5
|
+
source_file_path = caller[0].partition(":")[0]
|
6
|
+
|
7
|
+
base.module_attribute(:eager_autoload_filepath) { source_file_path }
|
8
|
+
base.module_attribute(:module_path) { ::Pathname.new(::File.path(base.eager_autoload_filepath).gsub(".rb", "")) }
|
9
|
+
|
10
|
+
::Trax::Core::FS::Directory.new(base.module_path).files.each do |file|
|
11
|
+
load file
|
12
|
+
end
|
13
|
+
|
14
|
+
super(base)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
data/lib/trax/core/errors.rb
CHANGED
@@ -92,6 +92,17 @@ module Trax
|
|
92
92
|
"#{messages.join('\n')}"
|
93
93
|
}
|
94
94
|
end
|
95
|
+
|
96
|
+
class MixinNotRegistered < ::Trax::Core::Errors::Base
|
97
|
+
argument :mixin
|
98
|
+
argument :source
|
99
|
+
argument :mixin_namespace
|
100
|
+
|
101
|
+
message {
|
102
|
+
"#{source} tried to load mixin: #{mixin}, whichdoes not exist in " \
|
103
|
+
"registry. Registered mixins were #{mixin_namespace.mixin_registry.keys.join(', ')} \n"
|
104
|
+
}
|
105
|
+
end
|
95
106
|
end
|
96
107
|
end
|
97
108
|
end
|
data/lib/trax/core/ext/module.rb
CHANGED
@@ -1,4 +1,11 @@
|
|
1
1
|
class Module
|
2
|
+
def module_attribute(*attribute_names, &block)
|
3
|
+
attribute_names.each do |_attribute_name|
|
4
|
+
singleton_class.__send__("attr_accessor", _attribute_name)
|
5
|
+
instance_variable_set("@#{_attribute_name}", block.call) if block_given?
|
6
|
+
end
|
7
|
+
end
|
8
|
+
|
2
9
|
def recursively_define_namespaced_class(class_name, class_to_inherit_from = Object)
|
3
10
|
paths = class_name.split("::")
|
4
11
|
const_name = paths.shift
|
data/lib/trax/core/ext/object.rb
CHANGED
@@ -1,35 +1,55 @@
|
|
1
1
|
require "active_support/core_ext/object/try"
|
2
|
-
|
2
|
+
require 'pry'
|
3
3
|
class Object
|
4
4
|
# Defines a Configuration Class within a target module namespace, or nested class
|
5
5
|
# i.e. configuration_for(::Ecommerce::Cart) will define
|
6
6
|
# Ecommerce::Cart::Configuration class, inherited form Trax::Core::Configuration
|
7
7
|
# And we can then define specific configuration options, for that class, on that class
|
8
|
-
def configuration_for(target, &blk)
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
8
|
+
def configuration_for(target, as = :configuration, run_configuration = false, &blk)
|
9
|
+
configuration_ivar_name = (as == :configuration) ? :configuration : :"#{as}_configuration"
|
10
|
+
configuration_ivar_name_shortcut = (as == :configuration) ? :config : :"#{as}_config"
|
11
|
+
target.const_set(configuration_ivar_name.to_s.classify, ::Class.new(::Trax::Core::Configuration))
|
12
|
+
configuration_klass = target.const_get(configuration_ivar_name.to_s.classify)
|
13
|
+
configuration_klass.source = target
|
13
14
|
|
14
|
-
|
15
|
-
|
15
|
+
configurer_method_name = (as == :configuration) ? :configure : :"configure_#{as}"
|
16
|
+
target.singleton_class.__send__(:attr_accessor, configuration_ivar_name)
|
17
|
+
target.singleton_class.instance_variable_set("@#{configuration_ivar_name}", configuration_klass.instance_eval(&blk))
|
18
|
+
target.singleton_class.__send__(:alias_method, configuration_ivar_name_shortcut, configuration_ivar_name)
|
16
19
|
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
20
|
+
target.define_singleton_method(configurer_method_name) do |&block|
|
21
|
+
if block
|
22
|
+
return instance_variable_set("@#{configuration_ivar_name}", configuration_klass.new(&block)) if !instance_variable_get("@#{configuration_ivar_name}")
|
23
|
+
return instance_variable_get("@#{configuration_ivar_name}").instance_eval(&block)
|
24
|
+
else
|
25
|
+
return instance_variable_set("@#{configuration_ivar_name}", configuration_klass.new) if !instance_variable_get("@#{configuration_ivar_name}")
|
26
|
+
return instance_variable_get("@#{configuration_ivar_name}")
|
23
27
|
end
|
24
28
|
end
|
29
|
+
|
30
|
+
target.__send__(configurer_method_name) if run_configuration
|
25
31
|
end
|
26
32
|
|
27
|
-
def define_configuration_options(&block)
|
28
|
-
configuration_for(self, &block)
|
33
|
+
def define_configuration_options(as=:configuration, run_configuration = false, &block)
|
34
|
+
configuration_for(self, as, run_configuration, &block)
|
35
|
+
end
|
36
|
+
|
37
|
+
def define_configuration_options!(as=:configuration, &block)
|
38
|
+
define_configuration_options(as, true, &block)
|
29
39
|
end
|
30
40
|
|
31
41
|
alias_method :define_configuration, :define_configuration_options
|
32
42
|
alias_method :has_configuration, :define_configuration_options
|
43
|
+
alias_method :has_configurable_options, :define_configuration_options
|
44
|
+
alias_method :has_configurable_options!, :define_configuration_options!
|
45
|
+
|
46
|
+
def remove_instance_variables(*args)
|
47
|
+
args.map{ |ivar_name|
|
48
|
+
remove_instance_variable(:"@#{ivar_name}") if instance_variable_defined?(:"@#{ivar_name}")
|
49
|
+
}
|
50
|
+
self
|
51
|
+
end
|
52
|
+
alias_method :reset_instance_variables, :remove_instance_variables
|
33
53
|
|
34
54
|
#following method stolen from abrandoned https://rubygems.org/gems/try_chain
|
35
55
|
def try_chain(*symbols)
|
data/lib/trax/core/fs.rb
ADDED
@@ -0,0 +1,238 @@
|
|
1
|
+
# clearly this should be its own gem
|
2
|
+
# or at least parts of it
|
3
|
+
# But this is an advanced set of file tools built around ruby stdlib file/dir clases
|
4
|
+
# that lets you do stuff like collect all the files in the current directory
|
5
|
+
# and its a WIP I ripped out of my project hastily so u done been warned
|
6
|
+
|
7
|
+
# Examples:
|
8
|
+
#
|
9
|
+
# Get all files in the current dir
|
10
|
+
# ::Trax::Core::FS::CurrentDirectory.new.files
|
11
|
+
#
|
12
|
+
# Get all ruby files in current dir
|
13
|
+
# ::Trax::Core::FS::CurrentDirectory.new.files.by_extension(".rb")
|
14
|
+
#
|
15
|
+
# Get all ruby files in target directory
|
16
|
+
# ::Trax::Core::FS::Directory.new('/users/jayre/whatever').files.by_extension(".rb")
|
17
|
+
#
|
18
|
+
# RECURSIVELY get files + children files + childrens children (yarr)
|
19
|
+
# ::Trax::Core::FS::Directory.new('/users/jayre/whatever').files(true)
|
20
|
+
#
|
21
|
+
|
22
|
+
module Trax
|
23
|
+
module Core
|
24
|
+
module FS
|
25
|
+
module Scopes
|
26
|
+
def by_extension(*extensions)
|
27
|
+
matches = select{ |file|
|
28
|
+
extensions.include?(file.extension)
|
29
|
+
}
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
class Files < SimpleDelegator
|
34
|
+
include ::Enumerable
|
35
|
+
include ::Trax::Core::FS::Scopes
|
36
|
+
|
37
|
+
attr_accessor :files
|
38
|
+
|
39
|
+
def initialize(*args)
|
40
|
+
@files = (args || []).flatten.compact.uniq
|
41
|
+
end
|
42
|
+
|
43
|
+
def __getobj__
|
44
|
+
@files
|
45
|
+
end
|
46
|
+
|
47
|
+
def each(&block)
|
48
|
+
@files.each do |file|
|
49
|
+
block.call(file)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
class Directory < SimpleDelegator
|
55
|
+
attr_accessor :files, :directories, :path
|
56
|
+
|
57
|
+
def self.[](path)
|
58
|
+
file_path = path.is_a?(Pathname) ? path : ::Pathname.new(path)
|
59
|
+
new(file_path)
|
60
|
+
end
|
61
|
+
|
62
|
+
def [](arg)
|
63
|
+
self.class.new(@path.join(arg).to_s)
|
64
|
+
end
|
65
|
+
|
66
|
+
def initialize(file_path)
|
67
|
+
@path = ::Pathname.new(file_path)
|
68
|
+
@dir = ::Dir[@path]
|
69
|
+
end
|
70
|
+
|
71
|
+
def all
|
72
|
+
@all ||= ::Dir[path.join("*")].map do |folder_or_file|
|
73
|
+
listing = ::Pathname.new(folder_or_file)
|
74
|
+
listing.directory? ? self.class.new(listing) : ::Trax::Core::FS::Listing.new(listing)
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
def directories(*args)
|
79
|
+
folders(*args)
|
80
|
+
end
|
81
|
+
|
82
|
+
def each
|
83
|
+
yield(entries)
|
84
|
+
end
|
85
|
+
|
86
|
+
def entries
|
87
|
+
@entries ||= ::Dir.entries(path).map do |file_path|
|
88
|
+
directory_file_path = ::Pathname.new(file_path) unless file_path.is_a?(Pathname)
|
89
|
+
directory_file_path.directory? ? ::Trax::Core::FS::Directory.new(directory_file_path) : ::Listing.new(directory_file_path)
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
def files(recurse = false)
|
94
|
+
@files ||= begin
|
95
|
+
if recurse
|
96
|
+
current_directory_files = Files.new(all.select{|file_path| file_path.is_a?(::Trax::Core::FS::Listing) })
|
97
|
+
|
98
|
+
directories.map do |dir|
|
99
|
+
next unless dir.files(true) && dir.files(true).any?
|
100
|
+
current_directory_files.files += dir.files(true)
|
101
|
+
end if directories.any?
|
102
|
+
|
103
|
+
current_directory_files || ::Trax::Core::FS::Files.new
|
104
|
+
else
|
105
|
+
Files.new(all.select{|file_path| file_path.is_a?(::Trax::Core::FS::Listing) })
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
def folders(recurse = false)
|
111
|
+
@folders ||= begin
|
112
|
+
if recurse
|
113
|
+
current_directory_directories = all.select{|file_path| file_path.is_a?(::Trax::Core::FS::Directory) }
|
114
|
+
|
115
|
+
current_directory_directories += folders(true).map do |dir|
|
116
|
+
dir.directories(true).any? ? dir.directories(true) : []
|
117
|
+
end if directories(true) && directories(true).any?
|
118
|
+
|
119
|
+
current_directory_directories
|
120
|
+
else
|
121
|
+
all.select{ |file_path| file_path.is_a?(::Trax::Core::FS::Directory) }
|
122
|
+
end
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
def glob(*args)
|
127
|
+
args.map do |arg|
|
128
|
+
self.dup[arg].flatten.compact.uniq.map{|_path| ::Trax::Core::FS::Listing.new(_path) }
|
129
|
+
end.flatten.compact.uniq
|
130
|
+
end
|
131
|
+
|
132
|
+
def __getobj__
|
133
|
+
@dir
|
134
|
+
end
|
135
|
+
|
136
|
+
def recursive_files
|
137
|
+
files(true)
|
138
|
+
end
|
139
|
+
|
140
|
+
def recursive_folders
|
141
|
+
folders(true)
|
142
|
+
end
|
143
|
+
|
144
|
+
def reload
|
145
|
+
remove_instance_variable(:@folders) if defined?(:@folders)
|
146
|
+
remove_instance_variable(:@files) if defined?(:@files)
|
147
|
+
self
|
148
|
+
end
|
149
|
+
|
150
|
+
def images
|
151
|
+
files.select{|file| file.image? }
|
152
|
+
end
|
153
|
+
end
|
154
|
+
|
155
|
+
class CurrentFileDirectory < SimpleDelegator
|
156
|
+
include ::Enumerable
|
157
|
+
|
158
|
+
def self.[](path)
|
159
|
+
file_path = path.is_a?(::Pathname) ? path : ::Pathname.new(path)
|
160
|
+
new(file_path)
|
161
|
+
end
|
162
|
+
|
163
|
+
attr_accessor :directory, :path
|
164
|
+
|
165
|
+
def initialize
|
166
|
+
source_file_path = caller[3].partition(":")[0]
|
167
|
+
@path = ::Pathname.new(::File.dirname(source_file_path))
|
168
|
+
@directory = ::Trax::Core::FS::Directory.new(@path)
|
169
|
+
end
|
170
|
+
|
171
|
+
def __getobj__
|
172
|
+
@directory
|
173
|
+
end
|
174
|
+
|
175
|
+
def each
|
176
|
+
yield @directory
|
177
|
+
end
|
178
|
+
end
|
179
|
+
|
180
|
+
class CurrentDirectory < CurrentFileDirectory
|
181
|
+
|
182
|
+
end
|
183
|
+
|
184
|
+
class CurrentWorkingDirectory < SimpleDelegator
|
185
|
+
include ::Enumerable
|
186
|
+
|
187
|
+
attr_accessor :directory, :path
|
188
|
+
|
189
|
+
def initialize
|
190
|
+
@path = ::Pathname.new(::Dir.pwd)
|
191
|
+
@directory = ::Trax::Core::FS::Directory.new(@path)
|
192
|
+
end
|
193
|
+
|
194
|
+
def __getobj__
|
195
|
+
@directory
|
196
|
+
end
|
197
|
+
|
198
|
+
def each
|
199
|
+
yield @directory
|
200
|
+
end
|
201
|
+
end
|
202
|
+
|
203
|
+
class Listing < Pathname
|
204
|
+
def bitmap?
|
205
|
+
return sample[0,2] == "MB"
|
206
|
+
end
|
207
|
+
|
208
|
+
def copy_to(destination)
|
209
|
+
::FileUtils.cp(self, destination)
|
210
|
+
end
|
211
|
+
|
212
|
+
alias_method :extension, :extname
|
213
|
+
alias_method :ext, :extname
|
214
|
+
|
215
|
+
def gif?
|
216
|
+
return sample[0,4] == "GIF8"
|
217
|
+
end
|
218
|
+
|
219
|
+
def image?
|
220
|
+
bitmap? || gif? || jpeg?
|
221
|
+
end
|
222
|
+
|
223
|
+
def jpeg?
|
224
|
+
return sample[0,4] == "\xff\xd8\xff\xe0"
|
225
|
+
end
|
226
|
+
|
227
|
+
def sample
|
228
|
+
@sample ||= begin
|
229
|
+
f = ::File.open(self.to_s, 'rb')
|
230
|
+
result = f.read(9)
|
231
|
+
f.close
|
232
|
+
result
|
233
|
+
end
|
234
|
+
end
|
235
|
+
end
|
236
|
+
end
|
237
|
+
end
|
238
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
module Trax
|
2
|
+
module Core
|
3
|
+
module HasMixins
|
4
|
+
module ClassMethods
|
5
|
+
def register_mixin(mixin_klass, key = nil)
|
6
|
+
mixin_key = mixin_klass.respond_to?(:mixin_registry_key) ? mixin_klass.mixin_registry_key : (key || mixin_klass.name.demodulize.underscore.to_sym)
|
7
|
+
|
8
|
+
return if mixin_registry.key?(mixin_key)
|
9
|
+
mixin_registry[mixin_key] = mixin_klass
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
def self.extended(base)
|
14
|
+
base.module_attribute(:mixin_registry) { Hash.new }
|
15
|
+
base.extend(ClassMethods)
|
16
|
+
|
17
|
+
base.define_configuration_options! do
|
18
|
+
option :auto_include, :default => false
|
19
|
+
option :auto_include_mixins, :default => []
|
20
|
+
end
|
21
|
+
|
22
|
+
mixin_module = base.const_set("Mixin", ::Module.new)
|
23
|
+
mixin_module.module_attribute(:mixin_namespace) { base }
|
24
|
+
mixin_module.extend(::Trax::Core::Mixin)
|
25
|
+
|
26
|
+
mixin_module.module_eval do
|
27
|
+
def self.extended(base)
|
28
|
+
base.extend(Trax::Core::Mixin)
|
29
|
+
super(base)
|
30
|
+
mixin_namespace.register_mixin(base)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
mixable_module = base.const_set("Mixable", ::Module.new)
|
35
|
+
mixable_module.module_attribute(:mixin_namespace) { base }
|
36
|
+
mixable_module.extend(::ActiveSupport::Concern)
|
37
|
+
|
38
|
+
mixable_module.included do
|
39
|
+
class_attribute :mixin_namespace
|
40
|
+
self.mixin_namespace = base
|
41
|
+
end
|
42
|
+
|
43
|
+
mixable_module.include(::Trax::Core::Mixable)
|
44
|
+
|
45
|
+
super(base)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module Trax
|
2
|
+
module Core
|
3
|
+
module Inheritance
|
4
|
+
extend ::ActiveSupport::Concern
|
5
|
+
|
6
|
+
module ClassMethods
|
7
|
+
def inherited(subklass)
|
8
|
+
klass = super(subklass)
|
9
|
+
klass.class_attribute(:_after_inherited_block)
|
10
|
+
|
11
|
+
trace = ::TracePoint.new(:end) do |tracepoint|
|
12
|
+
if tracepoint.self == subklass
|
13
|
+
trace.disable
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
trace.enable
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,77 @@
|
|
1
|
+
module Trax
|
2
|
+
module Core
|
3
|
+
module IsolatedMixin
|
4
|
+
def included(base = nil, &block)
|
5
|
+
unless base.respond_to?(:_concerns)
|
6
|
+
base.class_attribute :_concerns_config
|
7
|
+
base._concerns_confg = {}
|
8
|
+
end
|
9
|
+
|
10
|
+
base.extend(ClassMethods)
|
11
|
+
|
12
|
+
super(base, &block)
|
13
|
+
|
14
|
+
trace = ::TracePoint.new(:end) do |tracepoint|
|
15
|
+
if tracepoint.self == base
|
16
|
+
trace.disable
|
17
|
+
|
18
|
+
if self.instance_variable_defined?(:@_after_included_block)
|
19
|
+
base.instance_eval(&self.instance_variable_get(:@_after_included_block))
|
20
|
+
end
|
21
|
+
|
22
|
+
if self.instance_variable_defined?(:@_on_concern_included_block)
|
23
|
+
base.instance_exec(base._concerns_config[self.name.demodulize.underscore.to_sym], &self.instance_variable_get(:@_on_concern_included_block))
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
trace.enable
|
29
|
+
end
|
30
|
+
|
31
|
+
def self.extended(base)
|
32
|
+
base.extend(::ActiveSupport::Concern)
|
33
|
+
base.extend(::Trax::Core::IsolatedMixin::ClassMethods)
|
34
|
+
|
35
|
+
super(base)
|
36
|
+
|
37
|
+
trace = ::TracePoint.new(:end) do |tracepoint|
|
38
|
+
if tracepoint.self == base
|
39
|
+
trace.disable
|
40
|
+
|
41
|
+
if base.instance_variable_defined?(:@_after_extended_block)
|
42
|
+
base.instance_variable_get(:@_after_extended_block).call
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
trace.enable
|
48
|
+
end
|
49
|
+
|
50
|
+
module ClassMethods
|
51
|
+
def configure_concern(name, options = {})
|
52
|
+
_concerns_config[name] = options
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
def after_extended(&block)
|
57
|
+
self.instance_variable_set(:@_after_extended_block, block)
|
58
|
+
end
|
59
|
+
|
60
|
+
def after_included(&block)
|
61
|
+
self.instance_variable_set(:@_after_included_block, block)
|
62
|
+
end
|
63
|
+
|
64
|
+
def mixed_in(&block)
|
65
|
+
after_included(&block)
|
66
|
+
end
|
67
|
+
|
68
|
+
def mixed(&block)
|
69
|
+
after_included(&block)
|
70
|
+
end
|
71
|
+
|
72
|
+
def on_concern_included(&block)
|
73
|
+
self.instance_variable_set(:@_on_concern_included_block, block)
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
module Trax
|
2
|
+
module Core
|
3
|
+
module Mixable
|
4
|
+
extend ::ActiveSupport::Concern
|
5
|
+
|
6
|
+
included do
|
7
|
+
class_attribute :registered_mixins
|
8
|
+
|
9
|
+
self.registered_mixins = {}
|
10
|
+
end
|
11
|
+
|
12
|
+
module ClassMethods
|
13
|
+
def mixin(key, options = {})
|
14
|
+
raise ::Trax::Core::Errors::MixinNotRegistered.new(
|
15
|
+
source: self.name,
|
16
|
+
mixin: key,
|
17
|
+
mixin_namespace: mixin_namespace
|
18
|
+
) unless mixin_namespace.mixin_registry.key?(key)
|
19
|
+
|
20
|
+
mixin_module = mixin_namespace.mixin_registry[key]
|
21
|
+
self.registered_mixins[key] = mixin_module
|
22
|
+
|
23
|
+
self.class_eval do
|
24
|
+
include(mixin_module) unless self.ancestors.include?(mixin_module)
|
25
|
+
|
26
|
+
options = {} if options.is_a?(TrueClass)
|
27
|
+
options = { options => true } if options.is_a?(Symbol)
|
28
|
+
|
29
|
+
if mixin_module.instance_variable_defined?(:@_before_mixed_in_block)
|
30
|
+
_before_mixed_in_block = mixin_module.instance_variable_get(:@_before_mixed_in_block)
|
31
|
+
|
32
|
+
instance_exec(&_before_mixed_in_block)
|
33
|
+
end
|
34
|
+
|
35
|
+
if mixin_module.instance_variable_defined?(:@_on_mixed_in_block)
|
36
|
+
_on_mixed_in_block = mixin_module.instance_variable_get(:@_on_mixed_in_block)
|
37
|
+
|
38
|
+
instance_exec(options, &_on_mixed_in_block)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
def mixins(*args)
|
44
|
+
options = args.extract_options!
|
45
|
+
|
46
|
+
if(!options.blank?)
|
47
|
+
options.each_pair do |key, val|
|
48
|
+
self.mixin(key, val)
|
49
|
+
end
|
50
|
+
else
|
51
|
+
args.map{ |key| mixin(key) }
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
module Trax
|
2
|
+
module Core
|
3
|
+
module Mixin
|
4
|
+
def on_mixed_in(&block)
|
5
|
+
self.instance_variable_set(:@_on_mixed_in_block, block)
|
6
|
+
end
|
7
|
+
|
8
|
+
def before_mixed_in(&block)
|
9
|
+
self.instance_variable_set(:@_before_mixed_in_block, block)
|
10
|
+
end
|
11
|
+
|
12
|
+
def self.extended(base)
|
13
|
+
base.extend(::ActiveSupport::Concern)
|
14
|
+
|
15
|
+
super(base)
|
16
|
+
|
17
|
+
trace = ::TracePoint.new(:end) do |tracepoint|
|
18
|
+
if tracepoint.self == base
|
19
|
+
trace.disable
|
20
|
+
|
21
|
+
if base.instance_variable_defined?(:@_after_extended_block)
|
22
|
+
puts "CALLING AFTER EXTENDED"
|
23
|
+
base.instance_variable_get(:@_after_extended_block).call
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
trace.enable
|
29
|
+
|
30
|
+
super(base)
|
31
|
+
|
32
|
+
mixin_namespace.register_mixin(base) unless self == ::Trax::Core::Mixin
|
33
|
+
end
|
34
|
+
|
35
|
+
module ClassMethods
|
36
|
+
def on_mixed_in(&block)
|
37
|
+
self.instance_variable_set(:@_on_mixed_in_block, block)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
data/lib/trax/core.rb
CHANGED
@@ -1,14 +1,25 @@
|
|
1
1
|
require 'active_support/all'
|
2
2
|
require_relative './array'
|
3
|
+
require_relative './core/ext/enumerable'
|
3
4
|
require_relative './core/ext/module'
|
4
5
|
require_relative './core/ext/object'
|
6
|
+
require_relative './core/ext/string'
|
5
7
|
|
6
8
|
module Trax
|
7
9
|
module Core
|
8
10
|
extend ::ActiveSupport::Autoload
|
9
11
|
|
12
|
+
autoload :AbstractMethods
|
10
13
|
autoload :Configuration
|
14
|
+
autoload :Concern
|
15
|
+
autoload :EagerLoadNamespace
|
11
16
|
autoload :EagerAutoloadNamespace
|
12
17
|
autoload :Errors
|
18
|
+
autoload :FS
|
19
|
+
autoload :HasMixins
|
20
|
+
autoload :Inheritance
|
21
|
+
autoload :Mixin
|
22
|
+
autoload :Mixable
|
23
|
+
autoload :MixinRegistry
|
13
24
|
end
|
14
25
|
end
|
data/lib/trax_core/version.rb
CHANGED
data/spec/support/ecom/widget.rb
CHANGED
@@ -0,0 +1,27 @@
|
|
1
|
+
module FakeNamespace
|
2
|
+
module Priceable
|
3
|
+
extend ::FakeNamespace::Mixin
|
4
|
+
|
5
|
+
included do
|
6
|
+
class_attribute :default_starting_price
|
7
|
+
end
|
8
|
+
|
9
|
+
on_mixed_in do |options|
|
10
|
+
self.default_starting_price = options[:default_starting_price]
|
11
|
+
end
|
12
|
+
|
13
|
+
def some_instance_method
|
14
|
+
"some_instance_method_return"
|
15
|
+
end
|
16
|
+
|
17
|
+
def starting_price
|
18
|
+
@starting_price || self.class.default_starting_price
|
19
|
+
end
|
20
|
+
|
21
|
+
module ClassMethods
|
22
|
+
def some_class_method
|
23
|
+
"some_class_method_return"
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -3,6 +3,16 @@ require 'spec_helper'
|
|
3
3
|
describe ::Module do
|
4
4
|
subject { Trax::Core }
|
5
5
|
|
6
|
+
describe ".module_attribute" do
|
7
|
+
before(:all) do
|
8
|
+
Trax.module_attribute(:some_fake_hash) do
|
9
|
+
{}
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
it { Trax.some_fake_hash.should be_a(Hash) }
|
14
|
+
end
|
15
|
+
|
6
16
|
describe ".recursively_define_namespaced_class" do
|
7
17
|
context "when class namespace does not exist at global module level" do
|
8
18
|
before do
|
@@ -23,4 +23,13 @@ describe ::Object do
|
|
23
23
|
SomeFakeClass.new.try_chain(:class, :name, :underscore).should eq "some_fake_class"
|
24
24
|
end
|
25
25
|
end
|
26
|
+
|
27
|
+
describe ".remove_instance_variables" do
|
28
|
+
it "reset instance variables by symbol names" do
|
29
|
+
obj = SomeFakeClass.new
|
30
|
+
obj.instance_variable_set(:@someivar, "anything")
|
31
|
+
obj.reset_instance_variables(:someivar)
|
32
|
+
obj.instance_variable_get(:@someivar).should be nil
|
33
|
+
end
|
34
|
+
end
|
26
35
|
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe ::Trax::Core::HasMixins do
|
4
|
+
subject { FakeNamespace }
|
5
|
+
|
6
|
+
it { expect(subject.const_defined?("Mixin")).to eq true }
|
7
|
+
it { expect(subject.mixin_registry).to be_a(Hash) }
|
8
|
+
it { expect(subject::Mixin.mixin_namespace).to eq FakeNamespace }
|
9
|
+
|
10
|
+
context "Priceable Mixin" do
|
11
|
+
it {
|
12
|
+
expect(::Storefront::Product.new.starting_price).to eq 9.99
|
13
|
+
}
|
14
|
+
|
15
|
+
it "includes class methods" do
|
16
|
+
expect(::Storefront::Product.some_class_method).to eq "some_class_method_return"
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
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.7
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jason Ayre
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-
|
11
|
+
date: 2015-05-07 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: hashie
|
@@ -265,11 +265,23 @@ files:
|
|
265
265
|
- lib/trax.rb
|
266
266
|
- lib/trax/array.rb
|
267
267
|
- lib/trax/core.rb
|
268
|
+
- lib/trax/core/abstract_methods.rb
|
269
|
+
- lib/trax/core/concern.rb
|
268
270
|
- lib/trax/core/configuration.rb
|
269
271
|
- lib/trax/core/eager_autoload_namespace.rb
|
272
|
+
- lib/trax/core/eager_load_namespace.rb
|
270
273
|
- lib/trax/core/errors.rb
|
274
|
+
- lib/trax/core/ext/enumerable.rb
|
271
275
|
- lib/trax/core/ext/module.rb
|
272
276
|
- lib/trax/core/ext/object.rb
|
277
|
+
- lib/trax/core/ext/string.rb
|
278
|
+
- lib/trax/core/fs.rb
|
279
|
+
- lib/trax/core/has_mixins.rb
|
280
|
+
- lib/trax/core/inheritance.rb
|
281
|
+
- lib/trax/core/isolated_mixin.rb
|
282
|
+
- lib/trax/core/mixable.rb
|
283
|
+
- lib/trax/core/mixin.rb
|
284
|
+
- lib/trax/core/mixin_registry.rb
|
273
285
|
- lib/trax_core.rb
|
274
286
|
- lib/trax_core/version.rb
|
275
287
|
- spec/spec_helper.rb
|
@@ -277,11 +289,17 @@ files:
|
|
277
289
|
- spec/support/ecom/widget.rb
|
278
290
|
- spec/support/ecom/widget_category.rb
|
279
291
|
- spec/support/errors.rb
|
292
|
+
- spec/support/fake_namespace.rb
|
293
|
+
- spec/support/fake_namespace/priceable.rb
|
294
|
+
- spec/support/storefront.rb
|
295
|
+
- spec/support/storefront/category.rb
|
296
|
+
- spec/support/storefront/product.rb
|
280
297
|
- spec/trax/array_spec.rb
|
281
298
|
- spec/trax/core/eager_autoload_namespace_spec.rb
|
282
299
|
- spec/trax/core/errors_spec.rb
|
283
300
|
- spec/trax/core/ext/module_spec.rb
|
284
301
|
- spec/trax/core/ext/object_spec.rb
|
302
|
+
- spec/trax/core/has_mixins_spec.rb
|
285
303
|
- spec/trax/core_spec.rb
|
286
304
|
- trax_core.gemspec
|
287
305
|
homepage: http://github.com/jasonayre/trax_core
|
@@ -304,7 +322,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
304
322
|
version: '0'
|
305
323
|
requirements: []
|
306
324
|
rubyforge_project:
|
307
|
-
rubygems_version: 2.
|
325
|
+
rubygems_version: 2.4.5
|
308
326
|
signing_key:
|
309
327
|
specification_version: 4
|
310
328
|
summary: Core Trax Dependencies
|
@@ -314,9 +332,15 @@ test_files:
|
|
314
332
|
- spec/support/ecom/widget.rb
|
315
333
|
- spec/support/ecom/widget_category.rb
|
316
334
|
- spec/support/errors.rb
|
335
|
+
- spec/support/fake_namespace.rb
|
336
|
+
- spec/support/fake_namespace/priceable.rb
|
337
|
+
- spec/support/storefront.rb
|
338
|
+
- spec/support/storefront/category.rb
|
339
|
+
- spec/support/storefront/product.rb
|
317
340
|
- spec/trax/array_spec.rb
|
318
341
|
- spec/trax/core/eager_autoload_namespace_spec.rb
|
319
342
|
- spec/trax/core/errors_spec.rb
|
320
343
|
- spec/trax/core/ext/module_spec.rb
|
321
344
|
- spec/trax/core/ext/object_spec.rb
|
345
|
+
- spec/trax/core/has_mixins_spec.rb
|
322
346
|
- spec/trax/core_spec.rb
|