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