ruby_ext 0.5.9 → 0.5.10
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.
- data/Rakefile +2 -3
- data/lib/rake_ext/project.rb +1 -2
- data/lib/rspec_ext.rb +37 -35
- data/lib/rspec_ext/nokogiri.rb +26 -0
- data/lib/ruby_ext/core.rb +3 -5
- data/lib/ruby_ext/core/array.rb +1 -1
- data/lib/ruby_ext/core/basic_object.rb +1 -1
- data/lib/ruby_ext/core/deep_clone.rb +3 -10
- data/lib/ruby_ext/core/enumerable.rb +3 -3
- data/lib/ruby_ext/core/false_class.rb +1 -1
- data/lib/ruby_ext/core/hash.rb +23 -7
- data/lib/ruby_ext/core/module.rb +37 -57
- data/lib/ruby_ext/core/multiple_inheritance.rb +3 -3
- data/lib/ruby_ext/core/must.rb +0 -16
- data/lib/ruby_ext/core/nil_class.rb +5 -0
- data/lib/ruby_ext/core/object.rb +7 -7
- data/lib/ruby_ext/core/open_object.rb +7 -25
- data/lib/ruby_ext/core/string.rb +1 -6
- data/lib/ruby_ext/more.rb +2 -0
- data/lib/ruby_ext/more/callbacks.rb +37 -0
- data/lib/ruby_ext/more/declarative_cache.rb +45 -56
- data/lib/yaml_fix.rb +9 -0
- data/spec/core/array_spec.rb +1 -1
- data/spec/core/deep_clone_spec.rb +4 -2
- data/spec/core/enumerable.rb +1 -1
- data/spec/core/module_spec.rb +65 -107
- data/spec/core/multiple_inheritance_spec.rb +4 -4
- data/spec/core/must_spec.rb +1 -1
- data/spec/core/object_spec.rb +6 -6
- data/spec/core/open_object_spec.rb +1 -1
- data/spec/more/callbacks_spec.rb +90 -20
- data/spec/more/declarative_cache_spec.rb +96 -75
- data/spec/more/observable_spec.rb +10 -34
- data/spec/more/open_constructor_spec.rb +14 -11
- data/spec/spec_helper.rb +2 -0
- metadata +5 -6
- data/lib/rspec_ext/xhtml.rb +0 -48
- data/lib/ruby_ext/fixes.rb +0 -6
- data/spec/core/spec_helper.rb +0 -2
- data/spec/more/spec_helper.rb +0 -2
data/Rakefile
CHANGED
@@ -3,11 +3,10 @@ $LOAD_PATH << lib_dir unless $LOAD_PATH.include? lib_dir
|
|
3
3
|
|
4
4
|
require 'rake_ext'
|
5
5
|
|
6
|
-
project
|
6
|
+
project \
|
7
7
|
name: "ruby_ext",
|
8
8
|
gem: true,
|
9
9
|
summary: "Ruby Extensions",
|
10
10
|
|
11
11
|
author: "Alexey Petrushin",
|
12
|
-
homepage: "http://github.com/alexeypetrushin/ruby_ext"
|
13
|
-
)
|
12
|
+
homepage: "http://github.com/alexeypetrushin/ruby_ext"
|
data/lib/rake_ext/project.rb
CHANGED
@@ -7,7 +7,7 @@ YAML::ENGINE.yamler = 'syck'
|
|
7
7
|
#
|
8
8
|
# Helper for releasing gem, add following code to Your Rakefile:
|
9
9
|
#
|
10
|
-
# project
|
10
|
+
# project \
|
11
11
|
# name: "fake_gem",
|
12
12
|
# gem: true,
|
13
13
|
# summary: "Makes any directory looks like Ruby Gem",
|
@@ -18,7 +18,6 @@ YAML::ENGINE.yamler = 'syck'
|
|
18
18
|
#
|
19
19
|
# author: "Alexey Petrushin",
|
20
20
|
# homepage: "http://github.com/alexeypetrushin/fake_gem"
|
21
|
-
# )
|
22
21
|
#
|
23
22
|
# use "rake gem" to release gem
|
24
23
|
#
|
data/lib/rspec_ext.rb
CHANGED
@@ -12,10 +12,6 @@
|
|
12
12
|
#
|
13
13
|
# CLASS_LOADER_GENERATE_TMP_FILES = true
|
14
14
|
|
15
|
-
|
16
|
-
#
|
17
|
-
# RSpec
|
18
|
-
#
|
19
15
|
require 'rspec'
|
20
16
|
require 'fileutils'
|
21
17
|
|
@@ -40,9 +36,17 @@ rspec do
|
|
40
36
|
end
|
41
37
|
|
42
38
|
rspec do
|
39
|
+
def self.before_all &block
|
40
|
+
before :all, &block
|
41
|
+
end
|
42
|
+
|
43
|
+
def self.after_all &block
|
44
|
+
after :all, &block
|
45
|
+
end
|
46
|
+
|
43
47
|
def self.with_load_path *paths
|
44
|
-
|
45
|
-
|
48
|
+
before_all{paths.each{|path| $LOAD_PATH << path}}
|
49
|
+
after_all{paths.each{|path| $LOAD_PATH.delete path}}
|
46
50
|
end
|
47
51
|
|
48
52
|
def with_load_path *paths, &b
|
@@ -76,16 +80,10 @@ rspec do
|
|
76
80
|
end
|
77
81
|
|
78
82
|
def self.with_spec_dir dir
|
79
|
-
|
80
|
-
|
83
|
+
before_all{@spec_dir = dir}
|
84
|
+
after_all{@spec_dir = nil}
|
81
85
|
end
|
82
86
|
|
83
|
-
# def self.with_spec_dir
|
84
|
-
|
85
|
-
# def self.spec_dir dir = nil
|
86
|
-
# @spec_dir ||= calculate_spec_dir_for_current_caller
|
87
|
-
# end
|
88
|
-
|
89
87
|
def self.spec_dir
|
90
88
|
self.calculate_default_spec_dir || raise(":spec_dir not defined!")
|
91
89
|
end
|
@@ -106,35 +104,39 @@ rspec do
|
|
106
104
|
args = args.first if args.size == 1 and args.first.is_a?(Array)
|
107
105
|
args.each{|c| Object.send :remove_const, c if Object.const_defined? c}
|
108
106
|
end
|
109
|
-
|
110
|
-
# def spec_tmp_dir
|
111
|
-
# $spec_tmp_dir || raise("you should call :with_tmp_spec_dir to be able to use :spec_tmp_dir!")
|
112
|
-
# end
|
113
107
|
end
|
114
108
|
|
115
109
|
|
116
|
-
#
|
117
|
-
# dirname, parent_dirname
|
118
|
-
#
|
119
110
|
class String
|
120
111
|
unless method_defined? :dirname
|
121
112
|
def dirname
|
122
113
|
File.expand_path(File.dirname(self))
|
123
114
|
end
|
124
115
|
end
|
125
|
-
end
|
126
116
|
|
117
|
+
def to_xhtml css = nil
|
118
|
+
require 'rspec_ext/nokogiri'
|
119
|
+
|
120
|
+
node = Nokogiri::HTML(self)
|
121
|
+
unless css
|
122
|
+
node
|
123
|
+
else
|
124
|
+
nodes = node.css(css)
|
125
|
+
raise "Elements for '#{css}' CSS query not found!" if nodes.size < 1
|
126
|
+
raise "Found more than one elment for '#{css}' CSS query!" if nodes.size > 1
|
127
|
+
nodes.first
|
128
|
+
end
|
129
|
+
end
|
130
|
+
end
|
127
131
|
|
128
|
-
#
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
# end
|
140
|
-
# end
|
132
|
+
# Stubbing every instances of class.
|
133
|
+
class Class
|
134
|
+
def instance_stub! &block
|
135
|
+
new_method = method :new
|
136
|
+
stub! :new do |*args|
|
137
|
+
instance = new_method.call *args
|
138
|
+
block.call instance
|
139
|
+
instance
|
140
|
+
end
|
141
|
+
end
|
142
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
# Helpers to express expectation about html nodes.
|
2
|
+
require 'nokogiri'
|
3
|
+
|
4
|
+
class RSpec::FuzzyHash < Hash
|
5
|
+
def == o
|
6
|
+
return true if super
|
7
|
+
|
8
|
+
if o.respond_to? :each
|
9
|
+
o.each do |k, v|
|
10
|
+
return false if (self[k.to_sym] || self[k.to_s]) != v
|
11
|
+
end
|
12
|
+
return true
|
13
|
+
end
|
14
|
+
|
15
|
+
false
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
::Nokogiri::XML::Node.class_eval do
|
20
|
+
def to_fuzzy_hash
|
21
|
+
h = RSpec::FuzzyHash.new
|
22
|
+
attributes.each{|n, v| h[n] = v.value}
|
23
|
+
h[:content] = content
|
24
|
+
h
|
25
|
+
end
|
26
|
+
end
|
data/lib/ruby_ext/core.rb
CHANGED
@@ -1,9 +1,5 @@
|
|
1
1
|
raise 'ruby 1.9.2 or higher required!' if RUBY_VERSION < '1.9.2'
|
2
2
|
|
3
|
-
require 'ruby_ext/fixes'
|
4
|
-
|
5
|
-
autoload :OpenObject, 'ruby_ext/core/open_object'
|
6
|
-
|
7
3
|
%w(
|
8
4
|
basic_object
|
9
5
|
nil_class
|
@@ -19,4 +15,6 @@ autoload :OpenObject, 'ruby_ext/core/open_object'
|
|
19
15
|
deep_clone
|
20
16
|
time
|
21
17
|
multiple_inheritance
|
22
|
-
).each{|f| require "ruby_ext/core/#{f}"}
|
18
|
+
).each{|f| require "ruby_ext/core/#{f}"}
|
19
|
+
|
20
|
+
autoload :OpenObject, 'ruby_ext/core/open_object'
|
data/lib/ruby_ext/core/array.rb
CHANGED
@@ -1,4 +1,6 @@
|
|
1
|
-
|
1
|
+
require 'date'
|
2
|
+
|
3
|
+
Object.class_eval do
|
2
4
|
def deep_clone
|
3
5
|
clone = self.clone
|
4
6
|
instance_variables.each do |name|
|
@@ -18,15 +20,6 @@ Hash.class_eval do
|
|
18
20
|
end
|
19
21
|
end
|
20
22
|
|
21
|
-
OpenObject.class_eval do
|
22
|
-
def deep_clone
|
23
|
-
clone = super
|
24
|
-
clone.clear
|
25
|
-
each{|k, v| clone[k.deep_clone] = v.deep_clone}
|
26
|
-
clone
|
27
|
-
end
|
28
|
-
end
|
29
|
-
|
30
23
|
Struct.class_eval do
|
31
24
|
def deep_clone
|
32
25
|
clone = super
|
@@ -1,5 +1,5 @@
|
|
1
|
-
|
2
|
-
class EveryProxy < BasicObject
|
1
|
+
Enumerable.class_eval do
|
2
|
+
class ::Enumerable::EveryProxy < BasicObject
|
3
3
|
def initialize enumerable
|
4
4
|
@enumerable = enumerable
|
5
5
|
end
|
@@ -12,6 +12,6 @@ module Enumerable
|
|
12
12
|
end
|
13
13
|
|
14
14
|
def every
|
15
|
-
EveryProxy.new
|
15
|
+
::Enumerable::EveryProxy.new self
|
16
16
|
end
|
17
17
|
end
|
data/lib/ruby_ext/core/hash.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
|
1
|
+
Hash.class_eval do
|
2
2
|
def subset *keys, &block
|
3
3
|
keys = keys.first if keys.first.is_a? Array
|
4
4
|
h = {}
|
@@ -27,14 +27,30 @@ class Hash
|
|
27
27
|
merge!( other_hash ){|key,left,right| left }
|
28
28
|
end
|
29
29
|
|
30
|
-
# Haml relies on :inspect default format,
|
31
|
-
#
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
30
|
+
# Haml relies on :inspect default format and it brokes haml, but I prefer new hash notation,
|
31
|
+
# disable it if You use Haml.
|
32
|
+
unless $dont_extend_hash_inspect
|
33
|
+
def inspect
|
34
|
+
"{" + collect{|k, v| "#{k}: #{v}"}.join(', ') + "}"
|
35
|
+
end
|
36
|
+
alias_method :to_s, :inspect
|
37
|
+
end
|
36
38
|
|
37
39
|
alias_method :blank?, :empty?
|
38
40
|
|
39
41
|
alias_method :to_h, :to_hash
|
42
|
+
|
43
|
+
# OpenObject.
|
44
|
+
|
45
|
+
def to_openobject deep = false
|
46
|
+
OpenObject.initialize_from self, deep
|
47
|
+
end
|
48
|
+
alias_method :to_oo, :to_openobject
|
49
|
+
|
50
|
+
alias_method :eql_without_oo, :==
|
51
|
+
def == other
|
52
|
+
true if self.equal? other
|
53
|
+
other == self if other.is_a? OpenObject
|
54
|
+
eql_without_oo other
|
55
|
+
end
|
40
56
|
end
|
data/lib/ruby_ext/core/module.rb
CHANGED
@@ -1,5 +1,3 @@
|
|
1
|
-
require 'set'
|
2
|
-
|
3
1
|
Module.class_eval do
|
4
2
|
def alias name = nil
|
5
3
|
if name
|
@@ -16,48 +14,26 @@ Module.class_eval do
|
|
16
14
|
end
|
17
15
|
|
18
16
|
def namespace
|
19
|
-
if @
|
17
|
+
if @module_namespace_cached
|
20
18
|
@module_namespace
|
21
19
|
else
|
22
|
-
@
|
20
|
+
@module_namespace_cached = true
|
23
21
|
@module_namespace = Module.namespace_for name
|
24
22
|
end
|
25
23
|
end
|
26
24
|
|
27
|
-
def each_namespace &block
|
28
|
-
current = namespace
|
29
|
-
while current do
|
30
|
-
block.call current
|
31
|
-
current = current.namespace
|
32
|
-
end
|
33
|
-
end
|
34
|
-
|
35
|
-
def each_ancestor include_standard = false, &block
|
36
|
-
if include_standard
|
37
|
-
ancestors.each{|a| block.call a unless a == self}
|
38
|
-
else
|
39
|
-
exclude = [self, Object, Kernel]
|
40
|
-
ancestors.each do |a|
|
41
|
-
block.call a unless exclude.include? a
|
42
|
-
end
|
43
|
-
end
|
44
|
-
end
|
45
|
-
|
46
|
-
def self_ancestors_and_namespaces &b
|
47
|
-
b.call self
|
48
|
-
each_ancestor &b
|
49
|
-
each_namespace &b
|
50
|
-
end
|
51
|
-
|
52
|
-
# TODO cache it?
|
53
25
|
def self.namespace_for class_name
|
54
|
-
|
55
|
-
|
56
|
-
list.
|
57
|
-
|
58
|
-
|
59
|
-
|
26
|
+
@namespace_for_cache ||= {}
|
27
|
+
unless @namespace_for_cache.include? class_name
|
28
|
+
list = class_name.split("::")
|
29
|
+
@namespace_for_cache[class_name] = if list.size > 1
|
30
|
+
list.pop
|
31
|
+
eval list.join("::"), TOPLEVEL_BINDING, __FILE__, __LINE__
|
32
|
+
else
|
33
|
+
nil
|
34
|
+
end
|
60
35
|
end
|
36
|
+
@namespace_for_cache[class_name]
|
61
37
|
end
|
62
38
|
|
63
39
|
def inheritable_accessor attribute_name, default_value
|
@@ -90,42 +66,46 @@ Module.class_eval do
|
|
90
66
|
end
|
91
67
|
end
|
92
68
|
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
['
|
109
|
-
|
110
|
-
]
|
69
|
+
METHOD_ESCAPE_SYMBOLS = {
|
70
|
+
'==' => 'assign',
|
71
|
+
'>' => 'gt',
|
72
|
+
'<' => 'lt',
|
73
|
+
'>=' => 'gte',
|
74
|
+
'<=' => 'lte',
|
75
|
+
'?' => 'qst',
|
76
|
+
'!' => 'imp',
|
77
|
+
'<=>' => 'lorg',
|
78
|
+
'*' => 'mp',
|
79
|
+
'+' => 'add',
|
80
|
+
'-' => 'sub',
|
81
|
+
'=' => 'assign',
|
82
|
+
'**' => 'pw',
|
83
|
+
'=~' => 'sim',
|
84
|
+
'[]' => 'sb'
|
85
|
+
}
|
111
86
|
|
112
87
|
def escape_method method
|
113
88
|
m = method.to_s.clone
|
114
|
-
|
89
|
+
METHOD_ESCAPE_SYMBOLS.each{|from, to| m.gsub! from, to}
|
115
90
|
raise "Invalid method name '#{method}'!" unless m =~ /^[_a-zA-Z0-9]+$/
|
116
91
|
m.to_sym
|
117
92
|
end
|
118
93
|
|
119
94
|
def attr_required *attrs
|
120
95
|
attrs.each do |attr|
|
121
|
-
|
96
|
+
iv_name = :"@#{attr}"
|
97
|
+
define_method attr do
|
98
|
+
variable = instance_variable_get iv_name
|
99
|
+
raise "attribute :#{attr} not defined on #{self}!" if iv_name == nil
|
100
|
+
variable
|
101
|
+
end
|
122
102
|
end
|
123
103
|
end
|
124
104
|
|
125
105
|
public :include, :define_method
|
126
106
|
|
127
107
|
# Copied from rails.
|
128
|
-
def delegate
|
108
|
+
def delegate *methods
|
129
109
|
options = methods.pop
|
130
110
|
unless options.is_a?(Hash) && to = options[:to]
|
131
111
|
raise ArgumentError, "Delegation needs a target. Supply an options hash with a :to key as the last argument (e.g. delegate :hello, :to => :greeter)."
|
@@ -16,16 +16,16 @@
|
|
16
16
|
#
|
17
17
|
class Module
|
18
18
|
def directly_included_by
|
19
|
-
@directly_included_by ||=
|
19
|
+
@directly_included_by ||= {}
|
20
20
|
end
|
21
21
|
|
22
22
|
def include2 mod
|
23
23
|
# unless mod.directly_included_by.include? self
|
24
|
-
mod.directly_included_by
|
24
|
+
mod.directly_included_by[self] = true
|
25
25
|
# end
|
26
26
|
|
27
27
|
include mod
|
28
|
-
directly_included_by.each do |child|
|
28
|
+
directly_included_by.each do |child, v|
|
29
29
|
child.include2 self
|
30
30
|
end
|
31
31
|
end
|