range_extd 1.0 → 2.0
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.
- checksums.yaml +4 -4
- data/ChangeLog +31 -10
- data/Makefile +7 -3
- data/News +8 -0
- data/README.en.rdoc +1163 -250
- data/README.ja.rdoc +1163 -250
- data/Rakefile +11 -5
- data/lib/range_extd/infinity.rb +426 -0
- data/lib/range_extd/load_all.rb +19 -0
- data/lib/range_extd/nil_class.rb +41 -0
- data/lib/range_extd/nowhere.rb +135 -0
- data/lib/range_extd/numeric.rb +160 -0
- data/lib/range_extd/object.rb +53 -0
- data/lib/range_extd/range.rb +401 -0
- data/lib/{range_extd/range_extd.rb → range_extd.rb} +440 -628
- data/range_extd.gemspec +50 -0
- data/test/all_required_test.rb +173 -0
- data/test/test_range_extd.rb +649 -157
- data/test/test_range_extd_nowhere.rb +84 -0
- metadata +29 -16
- data/lib/range_extd/infinity/infinity.rb +0 -392
data/range_extd.gemspec
ADDED
@@ -0,0 +1,50 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
|
3
|
+
require 'rake'
|
4
|
+
require 'date'
|
5
|
+
|
6
|
+
Gem::Specification.new do |s|
|
7
|
+
s.name = %q{range_extd}.sub(/.*/){|c| (c == File.basename(Dir.pwd)) ? c : raise("ERROR: s.name=(#{c}) in gemspec seems wrong!")}
|
8
|
+
s.version = "2.0".sub(/.*/){|c| fs = Dir.glob('changelog', File::FNM_CASEFOLD); raise('More than one ChangeLog exist!') if fs.size > 1; warn("WARNING: Version(s.version=#{c}) already exists in #{fs[0]} - ok?") if fs.size == 1 && !IO.readlines(fs[0]).grep(/^\(Version: #{Regexp.quote c}\)$/).empty? ; c } # n.b., In macOS, changelog and ChangeLog are identical in default.
|
9
|
+
# s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
10
|
+
# s.executables << 'hola'
|
11
|
+
# s.bindir = 'bin'
|
12
|
+
s.authors = ["Masa Sakano"]
|
13
|
+
s.date = %q{2022-09-08}.sub(/.*/){|c| (Date.parse(c) == Date.today) ? c : raise("ERROR: s.date=(#{c}) is not today!")}
|
14
|
+
s.summary = %q{RangeExtd - Extended Range class with exclude_begin and open-ends}
|
15
|
+
s.description = %q{Package for a subclass of Range, RangeExtd, containing RangeExtd::Infinity and RangeExtd::Nowhere. RangeExtd defines ranges that enable an exclusion of the begin boundary, in addition to the end boundary as in the built-in Range, and accepts open-ended ranges to infinity for either (or both) positive/negative direction. The open-ended boundaries are represented by two constant objects, POSITIVE and NEGATIVE of RangeExtd::Infinity, and they are a generalised Infinity of Float::INFINITY to any Comparable objects, which are in practice similar to built-in beginless/endless Ranges.}
|
16
|
+
# s.email = %q{abc@example.com}
|
17
|
+
s.extra_rdoc_files = [
|
18
|
+
# "LICENSE",
|
19
|
+
"README.en.rdoc",
|
20
|
+
"README.ja.rdoc",
|
21
|
+
]
|
22
|
+
s.license = 'MIT'
|
23
|
+
s.files = FileList['.gitignore','lib/**/*.rb','[A-Z]*', 'test/**/*.rb'].to_a.delete_if{ |f|
|
24
|
+
ret = false
|
25
|
+
arignore = IO.readlines('.gitignore')
|
26
|
+
arignore.map{|i| i.chomp}.each do |suffix|
|
27
|
+
if File.fnmatch(suffix, File.basename(f))
|
28
|
+
ret = true
|
29
|
+
break
|
30
|
+
end
|
31
|
+
end
|
32
|
+
ret
|
33
|
+
}
|
34
|
+
s.files.reject! { |fn| File.symlink? fn }
|
35
|
+
|
36
|
+
# s.add_runtime_dependency 'library', '~> 2.2', '>= 2.2.1' # 2.2.1 <= Ver < 2.3.0
|
37
|
+
# s.add_development_dependency "bourne", [">= 0"]
|
38
|
+
s.homepage = %q{https://www.wisebabel.com}
|
39
|
+
s.rdoc_options = ["--charset=UTF-8"]
|
40
|
+
|
41
|
+
# s.require_paths = ["lib"]
|
42
|
+
s.required_ruby_version = '>= 2.7'
|
43
|
+
s.test_files = Dir['test/**/*.rb']
|
44
|
+
s.test_files.reject! { |fn| File.symlink? fn }
|
45
|
+
# s.requirements << 'libmagick, v6.0' # Simply, info to users.
|
46
|
+
# s.rubygems_version = %q{1.3.5} # This is always set automatically!!
|
47
|
+
|
48
|
+
s.metadata["yard.run"] = "yri" # use "yard" to build full HTML docs.
|
49
|
+
end
|
50
|
+
|
@@ -0,0 +1,173 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
|
3
|
+
# tests for the case where all the files (to modify NilClass, Object etc) are required.
|
4
|
+
|
5
|
+
$stdout.sync=true
|
6
|
+
$stderr.sync=true
|
7
|
+
# print '$LOAD_PATH=';p $LOAD_PATH
|
8
|
+
arlibbase = %w(range_extd/load_all) # require all in one go.
|
9
|
+
|
10
|
+
arlibrelbase = arlibbase.map{|i| "../lib/"+i}
|
11
|
+
|
12
|
+
arlibrelbase.each do |elibbase|
|
13
|
+
require_relative elibbase
|
14
|
+
end
|
15
|
+
|
16
|
+
# But checking/displaying the required files individually.
|
17
|
+
arlibbase = %w(range_extd/nowhere range_extd/nil_class range_extd/object range_extd/numeric range_extd/range range_extd range_extd/infinity range_extd/load_all)
|
18
|
+
arlibrelbase = arlibbase.map{|i| "../lib/"+i}
|
19
|
+
print "NOTE: Running: "; p File.basename(__FILE__)
|
20
|
+
print "NOTE: Library relative paths: "; p arlibrelbase
|
21
|
+
arlibbase4full = arlibbase.map{|i| i.sub(%r@^(../)+@, "")}+%w(range_extd)
|
22
|
+
puts "NOTE: Library full paths for #{arlibbase4full.inspect}: "
|
23
|
+
arlibbase4full.each do |elibbase|
|
24
|
+
ar = $LOADED_FEATURES.grep(/(^|\/)#{Regexp.quote(File.basename(elibbase))}(\.rb)?$/)
|
25
|
+
print elibbase+": " if ar.empty?; p ar
|
26
|
+
end
|
27
|
+
|
28
|
+
|
29
|
+
#################################################
|
30
|
+
# Unit Test
|
31
|
+
#################################################
|
32
|
+
|
33
|
+
require 'rational' if !defined?(Rational) # For Ruby 1.8
|
34
|
+
|
35
|
+
gem "minitest"
|
36
|
+
require 'minitest/autorun'
|
37
|
+
|
38
|
+
class TestUnitNilClass < MiniTest::Test
|
39
|
+
T = true
|
40
|
+
F = false
|
41
|
+
InfF = Float::INFINITY
|
42
|
+
InfP = RangeExtd::Infinity::POSITIVE
|
43
|
+
InfN = RangeExtd::Infinity::NEGATIVE
|
44
|
+
|
45
|
+
class CLC2
|
46
|
+
include Comparable
|
47
|
+
end
|
48
|
+
|
49
|
+
# Used in test_range_c3c4 and test_rangeextd_new_infinity_c3
|
50
|
+
class CLC3
|
51
|
+
include Comparable
|
52
|
+
# alias :original_compare :<=> if !self.method_defined?(:original_compare) # No overwriting.
|
53
|
+
def <=>(c)
|
54
|
+
if c == 7
|
55
|
+
"XXX" # Bad statement. Just for the sake of test.
|
56
|
+
elsif c == 8
|
57
|
+
-1
|
58
|
+
elsif c.class == CLC4
|
59
|
+
-1 # basically, CLC3 < CLC4
|
60
|
+
else # When self does not know what to do with c.
|
61
|
+
super # to call Object#<=>
|
62
|
+
#original_compare(c) # to call the original
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
# Used in test_range_c3c4
|
68
|
+
class CLC4
|
69
|
+
include Comparable
|
70
|
+
def <=>(c)
|
71
|
+
if c.class == CLC3
|
72
|
+
1 # basically, CLC3 < CLC4
|
73
|
+
else
|
74
|
+
super
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
def setup
|
80
|
+
end
|
81
|
+
|
82
|
+
def teardown
|
83
|
+
end
|
84
|
+
|
85
|
+
def test_nil_class
|
86
|
+
nowhere = RangeExtd::Nowhere::NOWHERE
|
87
|
+
refute(nil.eql?(nowhere))
|
88
|
+
assert( nil == nowhere )
|
89
|
+
assert_equal 0, ( nil <=> nowhere )
|
90
|
+
|
91
|
+
refute nil.nowhere?
|
92
|
+
assert_equal NilClass, nil.class_raw
|
93
|
+
assert_equal NilClass, nil.class
|
94
|
+
end # def test_nil_class
|
95
|
+
|
96
|
+
# When "range_extd/numeric" is required,
|
97
|
+
# InfP (RangeExtd::Infinity::POSITIVE) and InfN (RangeExtd::Infinity::NEGATIVE)
|
98
|
+
# are always comparable with any comparable objects except for
|
99
|
+
# Float::INFINITY, in which case ArgumentError is raised.
|
100
|
+
def test_infinity_compare
|
101
|
+
assert_operator 7.7, '<', InfF
|
102
|
+
assert_operator 7.7, '<', InfP
|
103
|
+
assert_operator 7.7, '>', InfN
|
104
|
+
assert_operator InfP, '>', 7.7
|
105
|
+
assert_operator InfN, '<', 7.7
|
106
|
+
assert_operator 8, '<', InfF
|
107
|
+
assert_operator 8, '<', InfP
|
108
|
+
assert_operator Rational(2, 3), '<', InfF
|
109
|
+
assert_operator Rational(2, 3), '<', InfP
|
110
|
+
assert_operator InfP, '>', Rational(2, 3)
|
111
|
+
assert_operator InfN, '<', Rational(2, 3)
|
112
|
+
assert_operator 'h', '<', InfP
|
113
|
+
assert_operator 'h', '>', InfN
|
114
|
+
assert_raises(ArgumentError) { InfF < InfP }
|
115
|
+
assert_raises(ArgumentError) { InfP < InfF }
|
116
|
+
assert_raises(ArgumentError) { InfP < -InfF }
|
117
|
+
assert_raises(ArgumentError) { InfP > InfF }
|
118
|
+
assert_raises(ArgumentError) { InfP > -InfF }
|
119
|
+
assert_raises(ArgumentError) { InfN < InfF }
|
120
|
+
assert_raises(ArgumentError) { InfN < -InfF }
|
121
|
+
assert_raises(ArgumentError) { InfF < Object.new }
|
122
|
+
assert_raises(ArgumentError) { InfP < Object.new }
|
123
|
+
assert_nil (InfF <=> InfP)
|
124
|
+
assert_nil (InfP <=> InfF)
|
125
|
+
assert_equal(-1, 7.7 <=> InfP)
|
126
|
+
assert_equal( 1, 7.7 <=> InfN)
|
127
|
+
assert_equal( 1, InfP <=> 7.7)
|
128
|
+
assert_equal(-1, InfN <=> 7.7)
|
129
|
+
assert_equal(-1, 5 <=> InfP)
|
130
|
+
assert_equal( 1, 5 <=> InfN)
|
131
|
+
assert_equal( 1, InfP <=> 5)
|
132
|
+
assert_equal(-1, InfN <=> 5)
|
133
|
+
assert_equal(-1, 'h' <=> InfP)
|
134
|
+
assert_equal(-1, InfN <=> 'h')
|
135
|
+
#assert_raises(ArgumentError) { puts "########## #{(InfP > InfF).inspect}";InfP < InfF }
|
136
|
+
#puts "########## #{(InfP <=> InfF).inspect}"
|
137
|
+
end
|
138
|
+
|
139
|
+
# Tests of examples in the document.
|
140
|
+
def test_in_document
|
141
|
+
# class Infinity
|
142
|
+
assert_equal( -1, (?z <=> RangeExtd::Infinity::POSITIVE))
|
143
|
+
assert_equal 1, (RangeExtd::Infinity::POSITIVE <=> ?z)
|
144
|
+
assert_equal( -1, (50 <=> RangeExtd::Infinity::POSITIVE))
|
145
|
+
assert_equal 1, (RangeExtd::Infinity::POSITIVE <=> 50)
|
146
|
+
end
|
147
|
+
|
148
|
+
def test_rangeextd_new_infinity_c2
|
149
|
+
c2 = CLC2.new
|
150
|
+
assert_nil (c2 <=> 1) # Object#<=>
|
151
|
+
assert_equal(-1, (c2 <=> RangeExtd::Infinity::POSITIVE))
|
152
|
+
assert_equal 1, (c2 <=> RangeExtd::Infinity::NEGATIVE)
|
153
|
+
r=(c2..RangeExtd::Infinity::POSITIVE)
|
154
|
+
assert_equal RangeExtd::Infinity::POSITIVE, r.end
|
155
|
+
r=(RangeExtd::Infinity::NEGATIVE..c2)
|
156
|
+
assert_equal RangeExtd::Infinity::NEGATIVE, r.begin
|
157
|
+
|
158
|
+
assert_raises(ArgumentError){ (true..RangeExtd::Infinity::POSITIVE) } # => bad value for range
|
159
|
+
end # def test_rangeextd_new_infinity_c2
|
160
|
+
|
161
|
+
def test_rangeextd_new_infinity_c3
|
162
|
+
c3 = CLC3.new
|
163
|
+
assert_equal(-1, (c3 <=> RangeExtd::Infinity::POSITIVE))
|
164
|
+
assert_equal 1, (c3 <=> RangeExtd::Infinity::NEGATIVE)
|
165
|
+
|
166
|
+
r=(c3..RangeExtd::Infinity::POSITIVE)
|
167
|
+
assert_equal RangeExtd::Infinity::POSITIVE, r.end
|
168
|
+
r=(RangeExtd::Infinity::NEGATIVE..c3)
|
169
|
+
assert_equal RangeExtd::Infinity::NEGATIVE, r.begin
|
170
|
+
end # def test_rangeextd_new_infinity_c3
|
171
|
+
|
172
|
+
end # class TestUnitNilClass < MiniTest::Test
|
173
|
+
|