trax_core 0.0.6 → 0.0.7
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/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
|