vex 0.2
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/Manifest +112 -0
- data/Rakefile +53 -0
- data/VERSION +1 -0
- data/config/README +2 -0
- data/config/dependencies.rb +10 -0
- data/config/gem.yml +7 -0
- data/init.rb +36 -0
- data/lib/nokogiri/nokogiri_ext.rb +96 -0
- data/lib/vex.rb +5 -0
- data/lib/vex/action_controller.rb +4 -0
- data/lib/vex/action_controller/verify_action.rb +97 -0
- data/lib/vex/action_controller/whitelisted_actions.rb +45 -0
- data/lib/vex/active_record.rb +3 -0
- data/lib/vex/active_record/__init__.rb +0 -0
- data/lib/vex/active_record/advisory_lock.rb +11 -0
- data/lib/vex/active_record/advisory_lock/mysql_adapter.rb +16 -0
- data/lib/vex/active_record/advisory_lock/sqlite_adapter.rb +78 -0
- data/lib/vex/active_record/belongs_to_many.rb +143 -0
- data/lib/vex/active_record/find_by_extension.rb +70 -0
- data/lib/vex/active_record/gem.rb +8 -0
- data/lib/vex/active_record/lite_table.rb +139 -0
- data/lib/vex/active_record/lite_view.rb +140 -0
- data/lib/vex/active_record/mass_load.rb +65 -0
- data/lib/vex/active_record/mysql_backup.rb +21 -0
- data/lib/vex/active_record/plugins/default_value_for/LICENSE.TXT +19 -0
- data/lib/vex/active_record/plugins/default_value_for/README.rdoc +421 -0
- data/lib/vex/active_record/plugins/default_value_for/Rakefile +6 -0
- data/lib/vex/active_record/plugins/default_value_for/init.rb +91 -0
- data/lib/vex/active_record/plugins/default_value_for/test.rb +279 -0
- data/lib/vex/active_record/plugins/default_value_for/test.sqlite3 +0 -0
- data/lib/vex/active_record/random_id.rb +56 -0
- data/lib/vex/active_record/resolver.rb +49 -0
- data/lib/vex/active_record/serialize_hash.rb +125 -0
- data/lib/vex/active_record/to_html.rb +53 -0
- data/lib/vex/active_record/validate.rb +76 -0
- data/lib/vex/active_record/validation_error_ext.rb +68 -0
- data/lib/vex/base.rb +2 -0
- data/lib/vex/base/app.rb +75 -0
- data/lib/vex/base/array/at_random.rb +17 -0
- data/lib/vex/base/array/cross.rb +26 -0
- data/lib/vex/base/array/each_batch.rb +32 -0
- data/lib/vex/base/array/parallel_map.rb +98 -0
- data/lib/vex/base/deprecation.rb +41 -0
- data/lib/vex/base/enumerable/deep.rb +95 -0
- data/lib/vex/base/enumerable/enumerable_ext.rb +59 -0
- data/lib/vex/base/enumerable/progress.rb +71 -0
- data/lib/vex/base/filesystem/fast_copy.rb +61 -0
- data/lib/vex/base/filesystem/grep.rb +34 -0
- data/lib/vex/base/filesystem/lock.rb +43 -0
- data/lib/vex/base/filesystem/lock.rb.test.lck +0 -0
- data/lib/vex/base/filesystem/lock.rb.test.pid +1 -0
- data/lib/vex/base/filesystem/make_dirs.rb +94 -0
- data/lib/vex/base/filesystem/parse_filename.rb +36 -0
- data/lib/vex/base/filesystem/tmp_file.rb +87 -0
- data/lib/vex/base/filesystem/write.rb +43 -0
- data/lib/vex/base/hash/compact.rb +38 -0
- data/lib/vex/base/hash/cross.rb +117 -0
- data/lib/vex/base/hash/easy_access.rb +141 -0
- data/lib/vex/base/hash/ensure_keys.rb +18 -0
- data/lib/vex/base/hash/extract.rb +71 -0
- data/lib/vex/base/hash/extras.rb +62 -0
- data/lib/vex/base/hash/inspect.rb +17 -0
- data/lib/vex/base/hash/simple_access_methods.rb +74 -0
- data/lib/vex/base/invalid_argument/invalid_argument.rb +97 -0
- data/lib/vex/base/local_conf.rb +35 -0
- data/lib/vex/base/net/http_ext.rb +227 -0
- data/lib/vex/base/net/socket_ext.rb +43 -0
- data/lib/vex/base/object/insp.rb +123 -0
- data/lib/vex/base/object/multiple_attributes.rb +58 -0
- data/lib/vex/base/object/singleton_methods.rb +23 -0
- data/lib/vex/base/object/with_benchmark.rb +110 -0
- data/lib/vex/base/range_array.rb +40 -0
- data/lib/vex/base/range_ext.rb +28 -0
- data/lib/vex/base/safe_token.rb +156 -0
- data/lib/vex/base/string/string_ext.rb +136 -0
- data/lib/vex/base/thread/deferred.rb +52 -0
- data/lib/vex/base/thread/sleep.rb +11 -0
- data/lib/vex/base/time/date_ext.rb +12 -0
- data/lib/vex/boot.rb +40 -0
- data/lib/vex/boot/array.rb +22 -0
- data/lib/vex/boot/blank.rb +41 -0
- data/lib/vex/boot/string.rb +60 -0
- data/migration/create_request_log.rb +28 -0
- data/r.rb +35 -0
- data/script/console +19 -0
- data/script/rebuild +7 -0
- data/tasks/echoe.rake +52 -0
- data/tasks/validate_db.rake +14 -0
- data/test/ar.rb +30 -0
- data/test/auto.rb +31 -0
- data/test/base-tests/local_conf.rb +25 -0
- data/test/base.rb +2 -0
- data/test/boot.rb +3 -0
- data/test/config/local.defaults.yml +4 -0
- data/test/config/local.yml +8 -0
- data/test/test.sqlite3 +0 -0
- data/test/test.sqlite3.Class#create.lck +0 -0
- data/test/test.sqlite3.Class#create.lck.lck +0 -0
- data/test/test.sqlite3.Class#create.lck.pid +1 -0
- data/test/test.sqlite3.Class#create.pid +1 -0
- data/test/test.sqlite3.LiteView.make.holders__view_dummy.lck +0 -0
- data/test/test.sqlite3.LiteView.make.holders__view_dummy.lck.lck +0 -0
- data/test/test.sqlite3.LiteView.make.holders__view_dummy.lck.pid +1 -0
- data/test/test.sqlite3.LiteView.make.holders__view_dummy.pid +1 -0
- data/test/test.sqlite3.vex.lck +0 -0
- data/test/test_helper.rb +49 -0
- data/test/tmp/copy.dat +1 -0
- data/test/tmp/lock.sqlite3 +0 -0
- data/test/tmp/lock.sqlite3.etest.lck +0 -0
- data/test/tmp/lock.sqlite3.etest.pid +1 -0
- data/test/tmp/somedata.dat +61 -0
- data/vex.gemspec +49 -0
- data/vex.tmproj +186 -0
- metadata +305 -0
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
#
|
|
2
|
+
# - allows to use hash.xx.yy where you would have to use
|
|
3
|
+
# hash["xx"][:yy] etc.
|
|
4
|
+
#
|
|
5
|
+
# - supports
|
|
6
|
+
#
|
|
7
|
+
# hash.xx?
|
|
8
|
+
#
|
|
9
|
+
# as a shortcut for hash.key?(:xx) || hash.key?("xx")
|
|
10
|
+
#
|
|
11
|
+
# - does not support assignment, though; i.e.
|
|
12
|
+
#
|
|
13
|
+
# hash.yy = zz
|
|
14
|
+
#
|
|
15
|
+
# will raise a NoMethodError.
|
|
16
|
+
#
|
|
17
|
+
class Hash
|
|
18
|
+
module EasyAccess
|
|
19
|
+
def self.extended(host)
|
|
20
|
+
host.instance_variable_set "@easy_accessible", true
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def method_missing(sym, *args, &block)
|
|
24
|
+
return super if block_given?
|
|
25
|
+
|
|
26
|
+
if args.length == 0 && sym.to_s =~ /^(.*)\?$/
|
|
27
|
+
!! EasyAccess.check(self, $1)
|
|
28
|
+
elsif args.length == 0
|
|
29
|
+
EasyAccess.fetch(self, sym)
|
|
30
|
+
elsif args.length == 1 && sym.to_s =~ /^(.*)\=$/
|
|
31
|
+
v = args.first
|
|
32
|
+
v = v.dup if v.is_a?(Hash)
|
|
33
|
+
EasyAccess.set(self, $1, v)
|
|
34
|
+
else
|
|
35
|
+
super
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def respond_to?(sym)
|
|
40
|
+
key = case sym.to_s
|
|
41
|
+
when /^(.*)[=\?]$/
|
|
42
|
+
$1
|
|
43
|
+
else
|
|
44
|
+
sym.to_s
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
EasyAccess.check(self, key) || super
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def self.check_key(hash, key)
|
|
51
|
+
key if hash.key?(key)
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
def self.check(hash, key)
|
|
55
|
+
check_key(hash, key.to_s) || check_key(hash, key.to_sym)
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
def self.fetch(hash, key)
|
|
59
|
+
if !(k = check(hash, key))
|
|
60
|
+
raise NoMethodError, "undefined key `#{key}' for #{self.inspect}"
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
easy_access hash.fetch(k)
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
def self.set(hash, key, value)
|
|
67
|
+
k = check(hash, key) || key
|
|
68
|
+
hash[k] = value
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
def self.easy_access(obj)
|
|
72
|
+
obj.easy_access! if obj.is_a?(Hash)
|
|
73
|
+
obj
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
def easy_access
|
|
78
|
+
dup.easy_access!
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
def easy_access!
|
|
82
|
+
# extend always returns self
|
|
83
|
+
extend(EasyAccess)
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
def easy_accessible?
|
|
87
|
+
@easy_accessible
|
|
88
|
+
end
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
module Hash::EasyAccess::Etest
|
|
92
|
+
def test_easy_access_hashes
|
|
93
|
+
h = { :a => { "b" => "ccc" }}
|
|
94
|
+
h1 = h.easy_access!
|
|
95
|
+
assert h.easy_accessible?
|
|
96
|
+
assert h1.easy_accessible?
|
|
97
|
+
|
|
98
|
+
assert_equal("ccc", h.a.b)
|
|
99
|
+
assert h1.object_id == h.object_id
|
|
100
|
+
|
|
101
|
+
assert h.a?
|
|
102
|
+
assert !h.b?
|
|
103
|
+
assert h.a.b?
|
|
104
|
+
assert !h.a.c?
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
def test_easy_access_hashes_2
|
|
108
|
+
h = { :a => { "b" => "ccc" }}
|
|
109
|
+
h1 = h.easy_access
|
|
110
|
+
assert !h.easy_accessible?
|
|
111
|
+
assert h1.easy_accessible?
|
|
112
|
+
|
|
113
|
+
assert_equal("ccc", h1.a.b)
|
|
114
|
+
assert h1.object_id != h.object_id
|
|
115
|
+
|
|
116
|
+
assert h1.a?
|
|
117
|
+
assert !h1.b?
|
|
118
|
+
assert h1.a.b?
|
|
119
|
+
assert !h1.a.c?
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
def test_easy_access_assigns
|
|
123
|
+
h = { :a => { "b" => "ccc" }}
|
|
124
|
+
h.easy_access!
|
|
125
|
+
|
|
126
|
+
h.a = 2
|
|
127
|
+
|
|
128
|
+
assert_equal({ :a => 2}, h)
|
|
129
|
+
|
|
130
|
+
h.b = 2
|
|
131
|
+
assert_equal({ :a => 2, "b" => 2}, h)
|
|
132
|
+
|
|
133
|
+
v = { :c => { :d => 2 } }
|
|
134
|
+
assert !v.easy_accessible?
|
|
135
|
+
|
|
136
|
+
h.b = v
|
|
137
|
+
assert_equal(2, h.b.c.d)
|
|
138
|
+
assert !v.easy_accessible?
|
|
139
|
+
assert h.b.easy_accessible?
|
|
140
|
+
end
|
|
141
|
+
end if VEX_TEST == "base"
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
module Hash::EnsureKeys
|
|
2
|
+
def keys?(*keys)
|
|
3
|
+
(keys - self.keys()).empty?
|
|
4
|
+
end
|
|
5
|
+
end
|
|
6
|
+
|
|
7
|
+
class Hash
|
|
8
|
+
include EnsureKeys
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
module Hash::EnsureKeys::Etest
|
|
12
|
+
def test_ensure_keys
|
|
13
|
+
h = { :a => "a" }
|
|
14
|
+
assert_equal true, h.keys?(:a)
|
|
15
|
+
assert_equal true, h.keys?
|
|
16
|
+
assert_equal false, h.keys?(:a, :b)
|
|
17
|
+
end
|
|
18
|
+
end if VEX_TEST == "base"
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
module Hash::Extract
|
|
2
|
+
def extract(*args)
|
|
3
|
+
extract_mapped(:[], *args)
|
|
4
|
+
end
|
|
5
|
+
|
|
6
|
+
# i.e. extract_and_delete
|
|
7
|
+
def extract!(*args)
|
|
8
|
+
extract_mapped(:delete, *args)
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
private
|
|
12
|
+
|
|
13
|
+
def extract_mapped(sym, *args)
|
|
14
|
+
translate = args.extract_options!
|
|
15
|
+
|
|
16
|
+
hash = args.inject({}) do |hash, k|
|
|
17
|
+
hash.update k => self.send(sym, k) if has_key?(k)
|
|
18
|
+
hash
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
translate.inject(hash) do |hash, (k, v)|
|
|
22
|
+
if has_key?(k)
|
|
23
|
+
value = self.send(sym, k)
|
|
24
|
+
hash.update v => value unless v.nil?
|
|
25
|
+
end
|
|
26
|
+
hash
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
class Hash
|
|
32
|
+
include Extract
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
module Hash::Extract::Etest
|
|
36
|
+
def test_extract
|
|
37
|
+
h = { :a => "1", :b => "2" }
|
|
38
|
+
assert_equal(h.extract(:a, :c), {:a => "1"})
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def orig
|
|
42
|
+
{ 1 => 2, 3 => 4, 5 => 6}
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def test_extract_w_delete!
|
|
46
|
+
h = orig
|
|
47
|
+
assert_equal ({1=>2}), h.extract!(1, 2, 3 => nil)
|
|
48
|
+
assert_equal ({5 => 6}), h
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def test_extract!
|
|
52
|
+
h = orig
|
|
53
|
+
assert_equal ({1=>2, 3 => 4}), h.extract!(1, 2, 3)
|
|
54
|
+
assert_equal ({5 => 6}), h
|
|
55
|
+
|
|
56
|
+
h = orig
|
|
57
|
+
assert_equal ({1=>2, :a => 4}), h.extract!(1, 2, 3 => :a)
|
|
58
|
+
assert_equal ({5 => 6}), h
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
def test_extract2
|
|
62
|
+
assert_nothing_raised {
|
|
63
|
+
h = orig.freeze
|
|
64
|
+
assert_equal ({1=>2, 3 => 4}), h.extract(1, 2, 3)
|
|
65
|
+
assert_equal orig, h
|
|
66
|
+
|
|
67
|
+
assert_equal ({1=>2, :a => 4}), h.extract(1, 2, 3 => :a)
|
|
68
|
+
assert_equal orig, h
|
|
69
|
+
}
|
|
70
|
+
end
|
|
71
|
+
end if VEX_TEST == "base"
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
module Hash::Extras
|
|
2
|
+
def self.included(klass)
|
|
3
|
+
klass.extend ClassMethods
|
|
4
|
+
end
|
|
5
|
+
|
|
6
|
+
module ClassMethods
|
|
7
|
+
def create(keys, values)
|
|
8
|
+
self[*keys.zip(values).flatten]
|
|
9
|
+
end
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
# compare
|
|
13
|
+
def hmap(&block)
|
|
14
|
+
self.inject({}) { |h, i|
|
|
15
|
+
h.update i[0] => yield(i[0], i[1])
|
|
16
|
+
h
|
|
17
|
+
}
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def delete_all(*args)
|
|
21
|
+
args.inject([]) do |array, arg|
|
|
22
|
+
array << delete(arg)
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def select_entries(*args)
|
|
27
|
+
args.inject([]) do |array, arg|
|
|
28
|
+
array << self[arg]
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
class Hash
|
|
34
|
+
include Extras
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
module Hash::Extras::Etest
|
|
38
|
+
def test_create
|
|
39
|
+
h = Hash.create([:a, :b], ["aa", "bb"])
|
|
40
|
+
|
|
41
|
+
assert_equal({ :a => "aa", :b => "bb"}, h)
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def test_hmap
|
|
45
|
+
h = { 1 => "a", 2 => "b" }
|
|
46
|
+
assert_equal({ 1 => "a", 2 => "bb"}, h.hmap do |k,v| v * k end)
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def test_delete_all
|
|
50
|
+
h = { 1 => "a", 2 => "b" }
|
|
51
|
+
assert_equal([ "a", nil ], h.delete_all(1, 3))
|
|
52
|
+
assert_equal({ 2 => "b"}, h)
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
def test_select
|
|
56
|
+
h = { 1 => "a", 2 => "b" }
|
|
57
|
+
h_orig = h.dup
|
|
58
|
+
|
|
59
|
+
assert_equal([ "a", nil ], h.select_entries(1, 3))
|
|
60
|
+
assert_equal(h_orig, h)
|
|
61
|
+
end
|
|
62
|
+
end if VEX_TEST == "base"
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
|
|
2
|
+
class Hash
|
|
3
|
+
def inspect
|
|
4
|
+
"{" + to_a.sort_by do |k, v|
|
|
5
|
+
k.to_s
|
|
6
|
+
end.map do |k,v|
|
|
7
|
+
"#{k.inspect} => #{v.inspect}"
|
|
8
|
+
end.join(", ") + "}"
|
|
9
|
+
end
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
module Hash::Etest
|
|
13
|
+
def test_inspect
|
|
14
|
+
h = {"b" => 2, :a => 2}
|
|
15
|
+
assert_equal('{:a => 2, "b" => 2}', h.inspect)
|
|
16
|
+
end
|
|
17
|
+
end if VEX_TEST == "base"
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
class Hash
|
|
2
|
+
def with_simple_access
|
|
3
|
+
Deprecation.report "Hash#with_simple_access", "Hash#easy_access"
|
|
4
|
+
easy_access!
|
|
5
|
+
end
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
module Hash::SimpleAccessMethods; end
|
|
9
|
+
|
|
10
|
+
module Hash::SimpleAccessMethods::Etest
|
|
11
|
+
def test_simple_access
|
|
12
|
+
h = { :a => "aa", :b => "bb", "c" => "cc" }
|
|
13
|
+
Deprecation.quiet do
|
|
14
|
+
h.with_simple_access
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
assert_equal("aa", h.a)
|
|
18
|
+
assert_equal("bb", h.b)
|
|
19
|
+
assert_equal("cc", h.c)
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def test_missing_methods
|
|
23
|
+
h = { :a => "aa", :b => "bb", "c" => "cc" }
|
|
24
|
+
Deprecation.quiet do
|
|
25
|
+
h.with_simple_access
|
|
26
|
+
end
|
|
27
|
+
assert_raise(NoMethodError) { h.x }
|
|
28
|
+
assert_raise(NoMethodError) { h.a(1) }
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def test_assignments
|
|
32
|
+
h = { :a => "aa", :b => "bb", "c" => "cc" }
|
|
33
|
+
Deprecation.quiet do
|
|
34
|
+
h.with_simple_access
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
h.a = 2
|
|
38
|
+
assert_equal(2, h.a)
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def test_respond_to
|
|
42
|
+
h = { :a => "aa", :b => "bb", "c" => "cc" }
|
|
43
|
+
Deprecation.quiet do
|
|
44
|
+
h.with_simple_access
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
assert(h.respond_to?(:a))
|
|
48
|
+
assert(h.respond_to?(:b))
|
|
49
|
+
assert(h.respond_to?(:c))
|
|
50
|
+
assert(h.respond_to?(:"a="))
|
|
51
|
+
|
|
52
|
+
assert(h.respond_to?("a="))
|
|
53
|
+
assert(h.respond_to?("a"))
|
|
54
|
+
|
|
55
|
+
assert(h.respond_to?("c="))
|
|
56
|
+
assert(h.respond_to?("c"))
|
|
57
|
+
|
|
58
|
+
# inherited methods
|
|
59
|
+
assert(h.respond_to?("keys"))
|
|
60
|
+
|
|
61
|
+
# inherited methods
|
|
62
|
+
assert(!h.respond_to?("unknown_key"))
|
|
63
|
+
assert(!h.respond_to?("unknown_key="))
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
def test_simple_access_deep
|
|
67
|
+
h = { :a => { :b => "bb" } }
|
|
68
|
+
Deprecation.quiet do
|
|
69
|
+
h.with_simple_access
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
assert_equal("bb", h.a.b)
|
|
73
|
+
end
|
|
74
|
+
end if VEX_TEST == "base"
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
def ArgumentError.message(default_text, *args)
|
|
2
|
+
msg = args.first.is_a?(String) ? args.shift : default_text
|
|
3
|
+
|
|
4
|
+
case args.length
|
|
5
|
+
when 0 then msg
|
|
6
|
+
when 1 then "#{msg}: #{args.first.inspect}"
|
|
7
|
+
else "#{msg}: #{args.inspect}"
|
|
8
|
+
end
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
class InvalidArgument < ArgumentError
|
|
12
|
+
def initialize(*args)
|
|
13
|
+
super ArgumentError.message("Invalid argument", *args)
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def invalid_argument!(*args)
|
|
18
|
+
raise InvalidArgument.new(*args)
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
class MissingOptions < ArgumentError
|
|
22
|
+
def initialize(*args)
|
|
23
|
+
super ArgumentError.message("Missing options", *args)
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def missing_options!(*args)
|
|
28
|
+
raise MissingOptions.new(*args)
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
class MissingImplementation < ArgumentError
|
|
32
|
+
def initialize(*args)
|
|
33
|
+
super ArgumentError.message("Missing options", *args)
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
class Module
|
|
38
|
+
def not_implemented(*args)
|
|
39
|
+
class_eval args.map { |arg| "def #{arg}(*args); not_implemented!; end\n" }.join
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
class Object
|
|
44
|
+
def not_implemented!
|
|
45
|
+
raise MissingImplementation.new "#{self.class}##{caller_method_name}"
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
private
|
|
49
|
+
|
|
50
|
+
def caller_method_name
|
|
51
|
+
parse_caller(caller(2).first).last || "unknown"
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
def parse_caller(at)
|
|
55
|
+
if /^(.+?):(\d+)(?::in `(.*)')?/ =~ at
|
|
56
|
+
file = Regexp.last_match[1]
|
|
57
|
+
line = Regexp.last_match[2].to_i
|
|
58
|
+
method = Regexp.last_match[3]
|
|
59
|
+
[file, line, method]
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
module Module::Etest
|
|
65
|
+
class X
|
|
66
|
+
not_implemented :a, :b
|
|
67
|
+
|
|
68
|
+
def c(x)
|
|
69
|
+
invalid_argument! "This is strange" unless x == 0
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
def d(x)
|
|
73
|
+
missing_options! :a, :b unless x.keys?(:a, :b)
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
def test_missing
|
|
78
|
+
assert_raise(MissingImplementation) { X.new.a }
|
|
79
|
+
assert_raise(MissingImplementation) { X.new.a 1, 2 }
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
def test_missing_options
|
|
83
|
+
assert_raises_kind_of(ArgumentError) {
|
|
84
|
+
X.new.d :a => "b", :c => "d"
|
|
85
|
+
}
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
def test_invalid_argument
|
|
89
|
+
assert_raises_kind_of(ArgumentError) {
|
|
90
|
+
X.new.c 1
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
assert_nothing_raised {
|
|
94
|
+
X.new.c 0
|
|
95
|
+
}
|
|
96
|
+
end
|
|
97
|
+
end if VEX_TEST == "base"
|