quality_extensions 1.1.4 → 1.1.6
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/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
|
+
|