quality_extensions 1.1.4 → 1.1.6
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/Xfind_bug_test.rb +28 -0
- data/lib/quality_extensions/array/all_same.rb +40 -0
- data/lib/quality_extensions/array/delete_if_bang.rb +145 -0
- data/lib/quality_extensions/array/expand_ranges.rb +3 -53
- data/lib/quality_extensions/array/include_any_of.rb +23 -0
- data/lib/quality_extensions/array/justify.rb +305 -0
- data/lib/quality_extensions/array/{average.rb → mean.rb} +1 -1
- data/lib/quality_extensions/array/select_if_bang.rb +0 -0
- data/lib/quality_extensions/array/sum.rb +30 -0
- data/lib/quality_extensions/enumerable/all_same.rb +43 -0
- data/lib/quality_extensions/enumerable/group_by_and_map.rb +110 -0
- data/lib/quality_extensions/enumerable/select_bang.rb +49 -0
- data/lib/quality_extensions/enumerable/select_while.rb +337 -52
- data/lib/quality_extensions/enumerable/select_with_index.rb +145 -0
- data/lib/quality_extensions/hash/hash_select.rb +5 -2
- data/lib/quality_extensions/hash/merge_if.rb +48 -0
- data/lib/quality_extensions/kernel/example_printer.rb +10 -3
- data/lib/quality_extensions/kernel/require_all.rb +24 -8
- data/lib/quality_extensions/kernel/sleep_loudly.rb +108 -0
- data/lib/quality_extensions/kernel/uninterruptable.rb +22 -0
- data/lib/quality_extensions/matrix/indexable.rb +68 -0
- data/lib/quality_extensions/matrix/linked_vectors.rb +137 -0
- data/lib/quality_extensions/module/class_methods.rb +2 -0
- data/lib/quality_extensions/object/non.rb +12 -0
- data/lib/quality_extensions/pathname.rb +435 -7
- data/lib/quality_extensions/range_list.rb +222 -0
- data/lib/quality_extensions/safe_nil.rb +5 -3
- data/lib/quality_extensions/string/each_char_with_index.rb +1 -2
- data/lib/quality_extensions/string/integer_eh.rb +3 -0
- data/lib/quality_extensions/string/numeric_eh.rb +74 -0
- data/lib/quality_extensions/string/safe_in_comment.rb +38 -0
- data/lib/quality_extensions/string/safe_numeric_conversion.rb +102 -0
- data/lib/quality_extensions/string/shell_escape.rb +4 -4
- data/lib/quality_extensions/string/with_knowledge_of_color.rb +8 -0
- data/lib/quality_extensions/table.rb +116 -0
- data/lib/quality_extensions/template.rb +4 -5
- data/lib/quality_extensions/template.rb_test_unit.rb +33 -0
- data/lib/quality_extensions/test/difference_highlighting-minitest.rb +321 -0
- data/lib/quality_extensions/test/difference_highlighting-test_unit.rb +325 -0
- data/lib/quality_extensions/test/difference_highlighting.rb +6 -314
- data/lib/quality_extensions/timeout/countdown_timer.rb +1 -0
- data/lib/quality_extensions/vector/enumerable.rb +51 -0
- metadata +35 -5
@@ -0,0 +1,222 @@
|
|
1
|
+
#--
|
2
|
+
# Author:: Tyler Rick
|
3
|
+
# Copyright:: Copyright (c) 2009, Tyler Rick
|
4
|
+
# License:: Ruby License
|
5
|
+
# Submit to Facets?::
|
6
|
+
# Developer notes::
|
7
|
+
# History::
|
8
|
+
#++
|
9
|
+
|
10
|
+
require 'delegate'
|
11
|
+
require 'facets/kernel/silence'
|
12
|
+
|
13
|
+
module Kernel
|
14
|
+
def RangeList(*args)
|
15
|
+
RangeList.new(*args)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
# A RangeList is a mixed array of numbers and ranges.
|
20
|
+
#
|
21
|
+
# It can be used to to represent "discontiguous ranges" (something a single Range object cannot do, unfortunately), for example [1..3, 5, 7..9],
|
22
|
+
#
|
23
|
+
# RangeList([1..3, 5, 7..9]).to_a
|
24
|
+
# => [1, 2, 3, 5, 6, 7]
|
25
|
+
#
|
26
|
+
# A RangeList acts like a range:
|
27
|
+
# * iterators like each will yield each element from a range (expanding them to the array of elements they represent) rather than the range itself
|
28
|
+
# RangeList([1..2, 4]).map {|e| e} # => [1, 2, 4]
|
29
|
+
# * to_a expands any ranges in the RangeList using expand_ranges and returns a simple array composed of its atomic elements and elements from the expanded ranges
|
30
|
+
#
|
31
|
+
# In every other respect, however, a RangeList behaves like a range.
|
32
|
+
#
|
33
|
+
class RangeList < DelegateClass(::Array)
|
34
|
+
include Enumerable
|
35
|
+
|
36
|
+
class FormatError < StandardError; end
|
37
|
+
|
38
|
+
def initialize(*args)
|
39
|
+
if args.size == 1 and args[0].is_a?(Range)
|
40
|
+
super(@array = [args[0]])
|
41
|
+
else
|
42
|
+
super(@array = Array.new(*args))
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
def self.superclass; Array; end
|
47
|
+
# def ===(a)
|
48
|
+
# p a.class
|
49
|
+
# end
|
50
|
+
|
51
|
+
def to_range_list
|
52
|
+
self
|
53
|
+
end
|
54
|
+
|
55
|
+
# Converts to a normal array, expanding all Ranges contained in this array, replacing the range with the list of *elements* that the range represents (range.+to_a+) .
|
56
|
+
#
|
57
|
+
def expand_ranges
|
58
|
+
new_array = []
|
59
|
+
@array.each do |item|
|
60
|
+
silence_warnings do # Object.to_a: warning: default `to_a' will be obsolete
|
61
|
+
if item.respond_to?(:to_a)
|
62
|
+
new_array.concat item.to_a
|
63
|
+
else
|
64
|
+
new_array.concat [item]
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
new_array
|
69
|
+
end
|
70
|
+
alias_method :to_a, :expand_ranges
|
71
|
+
|
72
|
+
def each
|
73
|
+
expand_ranges.each { |element| yield element }
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
|
78
|
+
class String
|
79
|
+
|
80
|
+
#Range_list_item_format = /(\d+)(-(\d+))?/ # if only - is allowed as delimiter within a range
|
81
|
+
Range_list_item_format = /(\d+)((-|\.\.|\.\.\.)(\d+))?/
|
82
|
+
Range_list_format = /^#{Range_list_item_format}(,#{Range_list_item_format})*$/
|
83
|
+
|
84
|
+
# A "range list" is an array of numbers and ranges, for example [1..3, 5, 7..9], and is a way to represent "discontiguous ranges" (something a single Range object cannot do, unfortunately).
|
85
|
+
#
|
86
|
+
# See also: Array#expand_ranges
|
87
|
+
#
|
88
|
+
# Name: to_range_list? parse_range_list?
|
89
|
+
#
|
90
|
+
# To do:
|
91
|
+
# * Allow other format styles besides a-b and a..b and a...b : (a,b), [a,b], [a,b)
|
92
|
+
# * Allow indeterminate ranges like '7-' (7 to infinity)?
|
93
|
+
#
|
94
|
+
def to_range_list
|
95
|
+
raise RangeList::FormatError unless match(Range_list_format)
|
96
|
+
array = split(',')
|
97
|
+
array.map! {|e|
|
98
|
+
md = e.match(/^#{Range_list_item_format}$/)
|
99
|
+
range_type = md[3]
|
100
|
+
points = [md[1], md[4]].compact.map(&:to_i)
|
101
|
+
case points.size
|
102
|
+
when 1
|
103
|
+
points[0]
|
104
|
+
when 2
|
105
|
+
case range_type
|
106
|
+
when '...'
|
107
|
+
points[0] ... points[1]
|
108
|
+
when '-', '..'
|
109
|
+
points[0] .. points[1]
|
110
|
+
else
|
111
|
+
raise "Unexpected range_type #{range_type}"
|
112
|
+
end
|
113
|
+
end
|
114
|
+
}
|
115
|
+
array.to_range_list
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
|
120
|
+
class Array
|
121
|
+
def to_range_list
|
122
|
+
RangeList.new(self)
|
123
|
+
end
|
124
|
+
|
125
|
+
# Converts array to a RangeList and expands all Ranges contained in this array, replacing the range with the list of *elements* that the range represents (range.+to_a+) .
|
126
|
+
#
|
127
|
+
def expand_ranges
|
128
|
+
to_range_list.expand_ranges
|
129
|
+
end
|
130
|
+
|
131
|
+
# def self.===(other)
|
132
|
+
# other.is_a?(RangeList) || super
|
133
|
+
# end
|
134
|
+
end
|
135
|
+
|
136
|
+
|
137
|
+
|
138
|
+
|
139
|
+
|
140
|
+
# _____ _
|
141
|
+
# |_ _|__ ___| |_
|
142
|
+
# | |/ _ \/ __| __|
|
143
|
+
# | | __/\__ \ |_
|
144
|
+
# |_|\___||___/\__|
|
145
|
+
#
|
146
|
+
=begin test
|
147
|
+
require 'spec'
|
148
|
+
|
149
|
+
describe RangeList do
|
150
|
+
it 'thinks it is a subclass of Array' do
|
151
|
+
RangeList.superclass.should == Array
|
152
|
+
#(Array === RangeList.new).should == true
|
153
|
+
end
|
154
|
+
|
155
|
+
it 'you can use RangeList() as an alias for RangeList.new()' do
|
156
|
+
RangeList([1,2..3]).to_a.should == [1,2,3]
|
157
|
+
end
|
158
|
+
|
159
|
+
it '#to_a expands ranges to their respective elements' do
|
160
|
+
RangeList.new([1,2..3]). to_a.should == [1,2,3]
|
161
|
+
RangeList.new([1,2...3]).to_a.should == [1,2]
|
162
|
+
end
|
163
|
+
|
164
|
+
it 'behaves like an Array: <<, concat, ...' do
|
165
|
+
array = RangeList.new
|
166
|
+
array << (1..2)
|
167
|
+
array.concat [3..4]
|
168
|
+
array.push 9
|
169
|
+
array.should == [1..2, 3..4, 9]
|
170
|
+
end
|
171
|
+
|
172
|
+
it 'behaves like a Range: iterators yield elements from expanded ranges rather than ranges themselves' do
|
173
|
+
RangeList(1..2).enum_for(:each).to_a.should == [1,2]
|
174
|
+
|
175
|
+
RangeList([1..3, 5, 7..9]).enum_for(:each).to_a.should ==
|
176
|
+
RangeList([1..3, 5, 7..9]).to_a
|
177
|
+
|
178
|
+
RangeList(1..2).enum_for(:each).to_a.should == [1,2]
|
179
|
+
|
180
|
+
RangeList([1..2, 4]).map {|e| e}.should == [1, 2, 4]
|
181
|
+
end
|
182
|
+
end
|
183
|
+
|
184
|
+
describe 'String#to_range_list' do
|
185
|
+
it 'works when you simply have a number' do
|
186
|
+
"1".to_range_list.should == [1]
|
187
|
+
end
|
188
|
+
|
189
|
+
it 'works when you simply have a list of numbers' do
|
190
|
+
"1,2".to_range_list.should == [1,2]
|
191
|
+
end
|
192
|
+
|
193
|
+
it 'works when you throw in a range' do
|
194
|
+
"1,2-3". to_range_list.should == [1,2..3]
|
195
|
+
"1,2..3". to_range_list.should == [1,2..3]
|
196
|
+
"1,2...3".to_range_list.should == [1,2...3]
|
197
|
+
end
|
198
|
+
|
199
|
+
it 'works even for the complicatedest range list you can think up' do
|
200
|
+
"1..3,5,7...9,11-12". to_range_list.should == [1..3,5,7...9,11..12]
|
201
|
+
end
|
202
|
+
end
|
203
|
+
|
204
|
+
describe 'Array#to_range_list' do
|
205
|
+
it 'works' do
|
206
|
+
[].to_range_list.should be_instance_of(RangeList)
|
207
|
+
[1..3,5,7...9,11..12]. to_range_list.should == [1..3,5,7...9,11..12]
|
208
|
+
[1..3,5,7...9,11..12]. to_range_list.should be_instance_of RangeList
|
209
|
+
end
|
210
|
+
end
|
211
|
+
|
212
|
+
describe 'Array#expand_ranges' do
|
213
|
+
it 'works' do
|
214
|
+
[].expand_ranges.should be_instance_of(Array)
|
215
|
+
[1, 2, 3]. expand_ranges.should == [1, 2, 3]
|
216
|
+
[1..3]. expand_ranges.should == [1, 2, 3]
|
217
|
+
[1..3, 5..7]. expand_ranges.should == [1, 2, 3, 5, 6, 7]
|
218
|
+
end
|
219
|
+
end
|
220
|
+
|
221
|
+
=end
|
222
|
+
|
@@ -12,7 +12,9 @@
|
|
12
12
|
$LOAD_PATH << File.expand_path(File.join(File.dirname(__FILE__), '..', '..'))
|
13
13
|
require 'singleton'
|
14
14
|
require 'rubygems'
|
15
|
-
require '
|
15
|
+
require 'builder/blankslate'
|
16
|
+
#require 'facets/basicobject'
|
17
|
+
#puts Object.methods.include?(:blank_slate_method_added) # not there?
|
16
18
|
|
17
19
|
|
18
20
|
class Object
|
@@ -50,8 +52,8 @@ end
|
|
50
52
|
|
51
53
|
# Extending BasicObject because it provides us with a clean slate. It is similar to Object except it has almost all the standard methods stripped away so that
|
52
54
|
# we will hit method_missing for almost all method routing.
|
53
|
-
class SafeNil <
|
54
|
-
include Singleton # I assume this is because it's faster than instantiating a new object each time.
|
55
|
+
class SafeNil < BlankSlate
|
56
|
+
include ::Singleton # I assume this is because it's faster than instantiating a new object each time.
|
55
57
|
|
56
58
|
#undef inspect # Use nil's version of inspect... although I wonder whether it would be better to have it return "SafeNil" so you know it's different than a normal nil.
|
57
59
|
def inspect
|
@@ -8,7 +8,6 @@
|
|
8
8
|
|
9
9
|
$LOAD_PATH << File.expand_path(File.join(File.dirname(__FILE__), '..', '..'))
|
10
10
|
require 'rubygems'
|
11
|
-
require 'quality_extensions/enumerable/enum'
|
12
11
|
|
13
12
|
class String
|
14
13
|
def each_char_with_index
|
@@ -34,7 +33,7 @@ require 'test/unit'
|
|
34
33
|
class TheTest < Test::Unit::TestCase
|
35
34
|
def test_1
|
36
35
|
assert_equal [[0, "a"], [1, "b"], [2, "c"]],
|
37
|
-
'abc'.
|
36
|
+
'abc'.to_enum(:each_char_with_index).to_a
|
38
37
|
end
|
39
38
|
end
|
40
39
|
=end
|
@@ -0,0 +1,74 @@
|
|
1
|
+
#--
|
2
|
+
# Author:: Tyler Rick
|
3
|
+
# Copyright:: Copyright (c) 2009, Tyler Rick and others
|
4
|
+
# Credits::
|
5
|
+
# - http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/14518
|
6
|
+
# - http://www.ruby-forum.com/topic/123422
|
7
|
+
# License:: Ruby License
|
8
|
+
# Submit to Facets?::
|
9
|
+
# Developer notes::
|
10
|
+
# History::
|
11
|
+
#++
|
12
|
+
|
13
|
+
class String
|
14
|
+
# returns true if the string is a valid number (which can be converted to an actual number using the Float() or String#to_f methods); otherwise returns false
|
15
|
+
def numeric?
|
16
|
+
!self.empty? && !!Float(self) rescue false
|
17
|
+
end
|
18
|
+
|
19
|
+
# returns true if the string is a valid integer (which can be converted to an Integer using the Integer() or String#to_i methods); otherwise returns false
|
20
|
+
def integer?
|
21
|
+
# not the empty string and containing only 1 or more digits
|
22
|
+
!self.empty? && !!(self =~ /\A[-+]?\d+\Z/)
|
23
|
+
end
|
24
|
+
#def integer?
|
25
|
+
# !!Integer(self) rescue false
|
26
|
+
#end
|
27
|
+
end
|
28
|
+
|
29
|
+
# _____ _
|
30
|
+
# |_ _|__ ___| |_
|
31
|
+
# | |/ _ \/ __| __|
|
32
|
+
# | | __/\__ \ |_
|
33
|
+
# |_|\___||___/\__|
|
34
|
+
#
|
35
|
+
=begin test
|
36
|
+
require 'spec'
|
37
|
+
|
38
|
+
describe 'String#numeric?' do
|
39
|
+
it 'returns true for valid numbers' do
|
40
|
+
'3'.numeric?.should == true
|
41
|
+
'+3'.numeric?.should == true
|
42
|
+
'-3'.numeric?.should == true
|
43
|
+
'3.14'.numeric?.should == true
|
44
|
+
'-3.14'.numeric?.should == true
|
45
|
+
end
|
46
|
+
|
47
|
+
it 'returns false for invalid numbers' do
|
48
|
+
'3.14.1'.numeric?.should == false
|
49
|
+
'1,2'.numeric?.should == false
|
50
|
+
'a'.numeric?.should == false
|
51
|
+
'3a'.numeric?.should == false
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
describe 'String#integer?' do
|
56
|
+
it 'returns true for valid numbers' do
|
57
|
+
'3'.integer?.should == true
|
58
|
+
'+3'.integer?.should == true
|
59
|
+
'-3'.integer?.should == true
|
60
|
+
end
|
61
|
+
|
62
|
+
it 'returns false for non-integer strings' do
|
63
|
+
'3.14'.integer?.should == false
|
64
|
+
'-3.14'.integer?.should == false
|
65
|
+
end
|
66
|
+
|
67
|
+
it 'returns false for invalid numbers' do
|
68
|
+
'3.14.1'.integer?.should == false
|
69
|
+
'1,2'.integer?.should == false
|
70
|
+
'a'.integer?.should == false
|
71
|
+
'3a'.integer?.should == false
|
72
|
+
end
|
73
|
+
end
|
74
|
+
=end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
#--
|
2
|
+
# Author:: Tyler Rick
|
3
|
+
# Copyright:: Copyright (c) 2009, Tyler Rick
|
4
|
+
# License:: Ruby License
|
5
|
+
# Submit to Facets?::
|
6
|
+
# Developer notes::
|
7
|
+
# History::
|
8
|
+
#++
|
9
|
+
|
10
|
+
|
11
|
+
|
12
|
+
class String
|
13
|
+
def safe_in_comment
|
14
|
+
gsub('-', '-')
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
|
19
|
+
|
20
|
+
|
21
|
+
|
22
|
+
|
23
|
+
# _____ _
|
24
|
+
# |_ _|__ ___| |_
|
25
|
+
# | |/ _ \/ __| __|
|
26
|
+
# | | __/\__ \ |_
|
27
|
+
# |_|\___||___/\__|
|
28
|
+
#
|
29
|
+
=begin test
|
30
|
+
require 'spec/autorun'
|
31
|
+
|
32
|
+
describe 'safe_in_comment' do
|
33
|
+
it 'works' do
|
34
|
+
'1-2'.safe_in_comment.should == '1-2'
|
35
|
+
end
|
36
|
+
end
|
37
|
+
=end
|
38
|
+
|
@@ -0,0 +1,102 @@
|
|
1
|
+
#--
|
2
|
+
# Author:: Tyler Rick
|
3
|
+
# Copyright:: Copyright (c) 2001, Leo [ slonika AT yahoo DOT com ], Tyler Rick
|
4
|
+
# Credits::
|
5
|
+
# - http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/14518
|
6
|
+
# License:: Ruby License
|
7
|
+
# Submit to Facets?::
|
8
|
+
# Developer notes::
|
9
|
+
# History::
|
10
|
+
#++
|
11
|
+
|
12
|
+
|
13
|
+
# Conversion from a String to Numbers should raise an exception if the string has
|
14
|
+
# an improper format. Strangely enough, Ruby's standard conversion functions do not
|
15
|
+
# provide for any kind of error handling and return number '0' on failure.
|
16
|
+
# Therefore, in Ruby one cannot possibly distinguish between these two cases:
|
17
|
+
# "0".to_i # -> 0
|
18
|
+
# "not-a-number".to_i # -> 0
|
19
|
+
|
20
|
+
# The following code augments standard conversion functions String#to_i and
|
21
|
+
# String#to_f with the error handling code so that an attempt to convert a
|
22
|
+
# string not suited for numeric conversion will raise NumericError exception.
|
23
|
+
|
24
|
+
class NumericError < RuntimeError
|
25
|
+
end
|
26
|
+
|
27
|
+
require 'facets/kernel/require_local'
|
28
|
+
require_local 'numeric_eh'
|
29
|
+
|
30
|
+
|
31
|
+
class String
|
32
|
+
alias __std__to_i to_i if ! method_defined? :__std__to_i
|
33
|
+
alias __std__to_f to_f if ! method_defined? :__std__to_f
|
34
|
+
alias __std__hex hex if ! method_defined? :__std__hex
|
35
|
+
alias __std__oct oct if ! method_defined? :__std__oct
|
36
|
+
|
37
|
+
def to_i()
|
38
|
+
case self
|
39
|
+
when /^[-+]?0\d/ then __std__oct
|
40
|
+
when /^[-+]?0x[a-f\d]/i then __std__hex
|
41
|
+
when /^[-+]?\d/ then __std__to_i
|
42
|
+
else raise NumericError, "Cannot convert string to Integer!"
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
def to_f()
|
47
|
+
case self
|
48
|
+
when /^[-+]?\d/ then __std__to_f
|
49
|
+
else raise NumericError, "Cannot convert string to Float!"
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
end
|
54
|
+
|
55
|
+
# _____ _
|
56
|
+
# |_ _|__ ___| |_
|
57
|
+
# | |/ _ \/ __| __|
|
58
|
+
# | | __/\__ \ |_
|
59
|
+
# |_|\___||___/\__|
|
60
|
+
#
|
61
|
+
=begin test
|
62
|
+
require 'spec'
|
63
|
+
|
64
|
+
describe 'String#numeric?' do
|
65
|
+
it 'returns true for valid numbers' do
|
66
|
+
'3'.to_f.should == 3
|
67
|
+
'+3'.to_f.should == 3
|
68
|
+
'-3'.to_f.should == -3
|
69
|
+
'3.14'.to_f.should == 3.14
|
70
|
+
'-3.14'.to_f.should == -3.14
|
71
|
+
|
72
|
+
# Debatable!: Should also work for strings that are not valid floats but can still be converted
|
73
|
+
'3.14.1'.to_f.should == 3.14
|
74
|
+
'1,2'.to_f.should == 1
|
75
|
+
'3a'.to_f.should == 3
|
76
|
+
end
|
77
|
+
|
78
|
+
it 'returns raises an Exception for non-convertable strings' do
|
79
|
+
lambda { 'garbage'.to_f }.should raise_error(NumericError)
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
describe 'String#to_i' do
|
84
|
+
it 'returns works for valid numbers' do
|
85
|
+
'3'.to_i.should == 3
|
86
|
+
'+3'.to_i.should == 3
|
87
|
+
'-3'.to_i.should == -3
|
88
|
+
|
89
|
+
# Debatable!: Should also work for strings that are not valid integers but can still be converted
|
90
|
+
# Question: should we make it raise NumericError in these cases? and require a .to_f.to_i if they want to convert strings to floats to integers?
|
91
|
+
'3.14'.to_i.should == 3
|
92
|
+
'-3.14'.to_i.should == -3
|
93
|
+
'3.14.1'.to_i.should == 3
|
94
|
+
'1,2'.to_i.should == 1
|
95
|
+
'3a'.to_i.should == 3
|
96
|
+
end
|
97
|
+
|
98
|
+
it 'returns raises an Exception for non-convertable strings' do
|
99
|
+
lambda { 'garbage'.to_i }.should raise_error(NumericError)
|
100
|
+
end
|
101
|
+
end
|
102
|
+
=end
|
@@ -43,10 +43,10 @@ class TheTest < Test::Unit::TestCase
|
|
43
43
|
end
|
44
44
|
|
45
45
|
# Escape has changed its behavior in newer versions. It wants to return it as type Escape::ShellEscaped.
|
46
|
-
def test_type
|
47
|
-
assert_equal Escape::ShellEscaped, 'a'.shell_escape.class
|
48
|
-
assert_equal 'a', 'a'.shell_escape.to_s
|
49
|
-
end
|
46
|
+
# def test_type
|
47
|
+
# assert_equal Escape::ShellEscaped, 'a'.shell_escape.class
|
48
|
+
# assert_equal 'a', 'a'.shell_escape.to_s
|
49
|
+
# end
|
50
50
|
end
|
51
51
|
=end
|
52
52
|
|
@@ -55,23 +55,31 @@ gem 'colored'
|
|
55
55
|
require 'colored'
|
56
56
|
|
57
57
|
class TheTest < Test::Unit::TestCase
|
58
|
+
|
58
59
|
def test_strip_color
|
59
60
|
assert "abc" != "abc".blue
|
60
61
|
assert_equal "abc", "abc".blue.strip_color
|
62
|
+
|
63
|
+
assert "abc" != "abc".underline
|
64
|
+
assert_equal "abc", "a#{'b'.underline}c".strip_color
|
61
65
|
end
|
66
|
+
|
62
67
|
def test_length_without_color
|
63
68
|
assert_equal 12, "abc".blue.length
|
64
69
|
assert_equal 3, "abc".blue.length_without_color
|
65
70
|
end
|
71
|
+
|
66
72
|
def test_nonprinting_characters_used_for_color
|
67
73
|
assert_equal "\e[34m\e[0m", 'abc'.blue.nonprinting_characters_used_for_color
|
68
74
|
end
|
75
|
+
|
69
76
|
def test_ljust_with_color
|
70
77
|
assert_equal "abc ", 'abc'. ljust( 5)
|
71
78
|
assert_equal "abc ", 'abc'.blue.ljust_with_color(5).strip_color
|
72
79
|
assert_equal "\e[34mabc\e[0m ", 'abc'.blue.ljust_with_color(5)
|
73
80
|
assert_equal "\e[34mabc\e[0m\e[44m \e[0m\e[44m \e[0m", 'abc'.blue.ljust_with_color(5, ' '.on_blue)
|
74
81
|
end
|
82
|
+
|
75
83
|
def test_rjust_with_color
|
76
84
|
assert_equal " abc", 'abc'. rjust( 5)
|
77
85
|
assert_equal " abc", 'abc'.blue.rjust_with_color(5).strip_color
|
@@ -0,0 +1,116 @@
|
|
1
|
+
#--
|
2
|
+
# Author:: Tyler Rick
|
3
|
+
# Copyright:: Copyright (c) 2009, Tyler Rick
|
4
|
+
# License:: Ruby license
|
5
|
+
# Submit to Facets?::
|
6
|
+
# Developer notes::
|
7
|
+
# This was started back when I was under the impression that Matrix wouldn't work with
|
8
|
+
# non-numerical elements. I was prepared to fork Matrix to make it work better with
|
9
|
+
# strings and such. But it seems like Matrix works fine with string elements.
|
10
|
+
#
|
11
|
+
# I added matrix/indexable.rb and matrix/linked_vectors.rb to make working with Matrixes
|
12
|
+
# more enjoyable. And now it looks like I won't have to create a Table class to compete
|
13
|
+
# with Matrix after all!
|
14
|
+
# Changes::
|
15
|
+
#++
|
16
|
+
|
17
|
+
=begin notes
|
18
|
+
> Matrix[['a', 'b'], ['c', 'd']].column(0)
|
19
|
+
=> Vector["a", "c"]
|
20
|
+
|
21
|
+
> Matrix[['a', 'b'], ['c', 'd']].t.row(0)
|
22
|
+
=> Vector["a", "c"]
|
23
|
+
|
24
|
+
> Matrix[['a', 'b'], ['c', 'd']].row(0)
|
25
|
+
=> Vector["a", "b"]
|
26
|
+
|
27
|
+
|
28
|
+
|
29
|
+
NArray has nice slice and pretty print features that are worth copying.
|
30
|
+
|
31
|
+
> NArray[['a', 'b'], ['c', 'd']][0..1,0..1]
|
32
|
+
=> NArray.object(2,2):
|
33
|
+
[ [ "a", "b" ],
|
34
|
+
[ "c", "d" ] ]
|
35
|
+
|
36
|
+
> NArray[['a', 'b'], ['c', 'd']][0..1,1]
|
37
|
+
=> NArray.object(2):
|
38
|
+
[ "c", "d" ]
|
39
|
+
|
40
|
+
> NArray[['a', 'b'], ['c', 'd']].transpose
|
41
|
+
=> NArray.object(2,2):
|
42
|
+
[ [ "a", "b" ],
|
43
|
+
[ "c", "d" ] ]
|
44
|
+
=end
|
45
|
+
|
46
|
+
|
47
|
+
require 'delegate'
|
48
|
+
|
49
|
+
# A table is...
|
50
|
+
class Table < DelegateClass(::Array)
|
51
|
+
include Enumerable
|
52
|
+
|
53
|
+
def self.[](*args)
|
54
|
+
Table.new(*args)
|
55
|
+
end
|
56
|
+
|
57
|
+
# See /usr/lib/ruby/1.8/matrix.rb
|
58
|
+
# Creates a table using rows as an array of row arrays.
|
59
|
+
def self.rows(rows)
|
60
|
+
end
|
61
|
+
|
62
|
+
# Creates a table using columns as an array of column arrays.
|
63
|
+
def self.columns(columns)
|
64
|
+
end
|
65
|
+
|
66
|
+
def self.superclass; Array; end
|
67
|
+
|
68
|
+
def initialize(*args)
|
69
|
+
pp args
|
70
|
+
@rows = super(args)
|
71
|
+
#super(@rows = Array.new(*args))
|
72
|
+
end
|
73
|
+
|
74
|
+
def +(other)
|
75
|
+
# should work for tables of strings too
|
76
|
+
end
|
77
|
+
|
78
|
+
end
|
79
|
+
|
80
|
+
#module Kernel
|
81
|
+
# def Table(*args)
|
82
|
+
# Table.new(*args)
|
83
|
+
# end
|
84
|
+
#end
|
85
|
+
|
86
|
+
|
87
|
+
# _____ _
|
88
|
+
# |_ _|__ ___| |_
|
89
|
+
# | |/ _ \/ __| __|
|
90
|
+
# | | __/\__ \ |_
|
91
|
+
# |_|\___||___/\__|
|
92
|
+
#
|
93
|
+
=begin test
|
94
|
+
require 'spec'
|
95
|
+
require 'pp'
|
96
|
+
|
97
|
+
describe Table do
|
98
|
+
it 'thinks it is a subclass of Array' do
|
99
|
+
Table.superclass.should == Array
|
100
|
+
#(Array === Table.new).should == true
|
101
|
+
end
|
102
|
+
|
103
|
+
describe 'initialization' do
|
104
|
+
it '' do
|
105
|
+
Table[[1,2],[3,4]].to_a.should == [[1,2],[3,4]]
|
106
|
+
end
|
107
|
+
it '' do
|
108
|
+
Table.new([1,2],[3,4]).to_a.should == [[1,2],[3,4]]
|
109
|
+
#Table.new([[1,2],[3,4]]).to_a.should == [[1,2],[3,4]]
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
end
|
114
|
+
=end
|
115
|
+
|
116
|
+
|
@@ -4,7 +4,7 @@
|
|
4
4
|
# License:: Ruby License
|
5
5
|
# Submit to Facets?::
|
6
6
|
# Developer notes::
|
7
|
-
#
|
7
|
+
# History::
|
8
8
|
#++
|
9
9
|
|
10
10
|
|
@@ -22,12 +22,11 @@
|
|
22
22
|
# |_|\___||___/\__|
|
23
23
|
#
|
24
24
|
=begin test
|
25
|
-
require '
|
25
|
+
require 'spec'
|
26
26
|
|
27
|
-
|
28
|
-
|
27
|
+
describe '' do
|
28
|
+
it '' do
|
29
29
|
end
|
30
|
-
|
31
30
|
end
|
32
31
|
=end
|
33
32
|
|
@@ -0,0 +1,33 @@
|
|
1
|
+
#--
|
2
|
+
# Author:: Tyler Rick
|
3
|
+
# Copyright:: Copyright (c) 2009, Tyler Rick
|
4
|
+
# License:: Ruby License
|
5
|
+
# Submit to Facets?::
|
6
|
+
# Developer notes::
|
7
|
+
# Changes::
|
8
|
+
#++
|
9
|
+
|
10
|
+
|
11
|
+
|
12
|
+
|
13
|
+
|
14
|
+
|
15
|
+
|
16
|
+
|
17
|
+
|
18
|
+
# _____ _
|
19
|
+
# |_ _|__ ___| |_
|
20
|
+
# | |/ _ \/ __| __|
|
21
|
+
# | | __/\__ \ |_
|
22
|
+
# |_|\___||___/\__|
|
23
|
+
#
|
24
|
+
=begin test
|
25
|
+
require 'test/unit'
|
26
|
+
|
27
|
+
class TheTest < Test::Unit::TestCase
|
28
|
+
def test_1
|
29
|
+
end
|
30
|
+
|
31
|
+
end
|
32
|
+
=end
|
33
|
+
|