mharris_ext 1.7.1 → 1.8.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 +6 -14
- data/Gemfile +9 -0
- data/README +100 -5
- data/Rakefile +3 -43
- data/VERSION +1 -0
- data/VERSION.yml +2 -2
- data/lib/mharris_ext/accessor.rb +2 -2
- data/lib/mharris_ext/benchmark.rb +4 -4
- data/lib/mharris_ext/cmd.rb +11 -14
- data/lib/mharris_ext/enumerable.rb +20 -66
- data/lib/mharris_ext/fileutils.rb +5 -23
- data/lib/mharris_ext/from_hash.rb +12 -9
- data/lib/mharris_ext/gems.rb +1 -2
- data/lib/mharris_ext/object.rb +1 -6
- data/lib/mharris_ext/present.rb +14 -5
- data/lib/mharris_ext.rb +2 -2
- data/mharris_ext.gemspec +15 -65
- data/test/helpers_test.rb +247 -0
- data/test/mharris_ext_test.rb +18 -5
- data/test/test_helper.rb +20 -6
- metadata +45 -31
- data/features/mharris_ext.feature +0 -9
- data/features/steps/mharris_ext_steps.rb +0 -0
- data/features/support/env.rb +0 -13
checksums.yaml
CHANGED
|
@@ -1,15 +1,7 @@
|
|
|
1
1
|
---
|
|
2
|
-
|
|
3
|
-
metadata.gz:
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
metadata.gz: !binary |-
|
|
9
|
-
ODk3N2IwOTNjZjJjOGQxMjc5NWE4YmQ3OWYzYjNlNWI2MDgyMDgyNjBmYWY3
|
|
10
|
-
MWZhZTY1OGFkOWE2MDQ4OTkxM2I1ZDI3MTkyY2RkMzA4ZTA2MDU3NGViMzUx
|
|
11
|
-
NTNhNDIyMDlmMmRkNDEwMWQxZTg2ZDhmMzY4NjE2MWYzYzVkNGU=
|
|
12
|
-
data.tar.gz: !binary |-
|
|
13
|
-
YzUyY2ZkMWVkMDcxZGI2ZDAwNTU4ZWM4YTMxOWJjM2IyMzIwNDcwNTM1NzBm
|
|
14
|
-
NTRiODU0OWU5OGEzODc1NTExOGNiM2QyZTg1MGEzODIxNTg0OTJhMzEzNDk2
|
|
15
|
-
MTE3Y2Q0NWRiOGU4ZThkOTg5NGUwZDY4MjU1NThhY2M2MjlhMTU=
|
|
2
|
+
SHA256:
|
|
3
|
+
metadata.gz: 8b1c00fe9fc9db8c94212b12960e5cf57ca42ff0c9201e85931cbdbcc2a66142
|
|
4
|
+
data.tar.gz: 6e3bf943aa7e4dedf2ee76dade33a4d1008e4f7d6ff2a55f22c291cdba0cc800
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: 3db5d208524aaa9447723af3e2dce5ed3f6c67d92c6c037784cc2473f9fc2a6cc8ad5766594d775feee7a5b3ebfa2c3742708f1d44b61d529054924488db2692
|
|
7
|
+
data.tar.gz: aa2cd71652e5b1dc264f33340e91ec54764faf8b91985154cd11bb1419e6ff0881ff246bec259dfcefee0ece5d739f893e327817544019560cec5563fa5086c1
|
data/Gemfile
ADDED
data/README
CHANGED
|
@@ -1,7 +1,102 @@
|
|
|
1
|
-
mharris_ext
|
|
2
|
-
Description goes here.
|
|
1
|
+
= mharris_ext
|
|
3
2
|
|
|
4
|
-
|
|
5
|
-
|
|
3
|
+
Small Ruby helpers used by the playoff-odds applications. Requiring the gem adds
|
|
4
|
+
core extensions and top-level helpers. Ruby 2.7 or newer is required; the local
|
|
5
|
+
development setup uses Ruby 3.3.7.
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
== Development
|
|
8
|
+
|
|
9
|
+
bundle install
|
|
10
|
+
bundle exec rake test
|
|
11
|
+
bundle exec rake build
|
|
12
|
+
|
|
13
|
+
Tests use Minitest and SimpleCov, require no services, and include Active Support
|
|
14
|
+
load-order checks. Coverage is written to coverage/index.html. The built gem is
|
|
15
|
+
written to pkg/. VERSION is the authoritative version; VERSION.yml is retained
|
|
16
|
+
for compatibility with older tooling. Jeweler, RCov and the placeholder Cucumber
|
|
17
|
+
task are no longer part of the build or test workflow.
|
|
18
|
+
|
|
19
|
+
The only runtime dependency is fattr. File.write is provided by Ruby, so Facets
|
|
20
|
+
is no longer required. Bundler 2.4 or newer is recommended for development and
|
|
21
|
+
for commands that use ec's unbundled child environment.
|
|
22
|
+
|
|
23
|
+
== Initialization and lazy attributes
|
|
24
|
+
|
|
25
|
+
require 'mharris_ext'
|
|
26
|
+
|
|
27
|
+
class Options
|
|
28
|
+
include FromHash
|
|
29
|
+
attr_accessor :name, :enabled
|
|
30
|
+
fattr(:retries) { 3 }
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
options = Options.new(name: 'example', enabled: false)
|
|
34
|
+
options.from_hash(name: 'renamed') # updates and returns the same object
|
|
35
|
+
copy = Options.from_hash(name: 'another')
|
|
36
|
+
|
|
37
|
+
Unknown attributes raise rather than being ignored. attr_accessor_nn :value
|
|
38
|
+
provides an accessor that rejects nil when read; false and zero are valid values.
|
|
39
|
+
|
|
40
|
+
== Collections and formatting
|
|
41
|
+
|
|
42
|
+
3.of { [] } # three distinct arrays
|
|
43
|
+
(1..7).nths(3) # [[1, 2], [3, 4, 5], [6, 7]]
|
|
44
|
+
[1, 2, 3].nths_hash(2) # {0 => [1, 2], 1 => [3]}
|
|
45
|
+
[1, 2, 3].sum_b { |x| x * x } # 14
|
|
46
|
+
[1, 2, 3].avg_b { |x| x * x } # 4.666...
|
|
47
|
+
{a: 1, b: 2}.map_value { |x| x * 2 }
|
|
48
|
+
(-1234567).commify # "-1,234,567"
|
|
49
|
+
'1234.50'.commify # "1,234.50"
|
|
50
|
+
'x'.rpad(3) # "x "
|
|
51
|
+
12.lpad(4) # "0012"
|
|
52
|
+
|
|
53
|
+
Partition counts must be positive integers. Partitions preserve input order,
|
|
54
|
+
include every element, and may be empty when more partitions than elements are
|
|
55
|
+
requested. nths_hashx remains an alias of nths_hash. An empty avg_b retains its
|
|
56
|
+
existing NaN result.
|
|
57
|
+
|
|
58
|
+
blank? and present? respect existing implementations, including Active Support.
|
|
59
|
+
When Active Support is absent, nil, false, empty collections and whitespace-only
|
|
60
|
+
strings are blank. Ruby's native Object#tap is preserved.
|
|
61
|
+
|
|
62
|
+
== Files and commands
|
|
63
|
+
|
|
64
|
+
File.create('example.txt', 'first')
|
|
65
|
+
File.append('example.txt', '-last')
|
|
66
|
+
mkdir_recursive('tmp/nested/path')
|
|
67
|
+
mkdir_recursive(dir: 'tmp/another/path')
|
|
68
|
+
mv_making_dir('example.txt', 'tmp/archive')
|
|
69
|
+
rm_r_if('tmp/archive')
|
|
70
|
+
ec('ruby --version', silent: true)
|
|
71
|
+
tm('work') { perform_work }
|
|
72
|
+
|
|
73
|
+
Directory helpers load FileUtils themselves. ec executes a shell command,
|
|
74
|
+
returns stdout, and raises on a nonzero status. When Bundler is loaded, its
|
|
75
|
+
with_unbundled_env API isolates the child command from the current bundle.
|
|
76
|
+
Without silent: true, the command and stdout are printed.
|
|
77
|
+
|
|
78
|
+
Other helpers include Regexp.escaped, Time#short_dt, Object#local_methods,
|
|
79
|
+
all_dirs_recursive, eat_exceptions, bt, and print_memory_usage!. The memory
|
|
80
|
+
reporter returns a Thread and reports resident memory in kilobytes on systems
|
|
81
|
+
with ps; stop and join that thread when finished.
|
|
82
|
+
|
|
83
|
+
== 1.8.0 compatibility fixes
|
|
84
|
+
|
|
85
|
+
* Removed the obsolete Facets File.write require and dependency.
|
|
86
|
+
* Integer#of replaces the defunct Fixnum extension.
|
|
87
|
+
* File helpers use File.exist? and load their standard-library dependency.
|
|
88
|
+
* ec uses current Bundler APIs; timing uses a monotonic clock.
|
|
89
|
+
* Fixed the memory reporter's removed String#to_a call.
|
|
90
|
+
* Preserved Ruby's tap and existing Active Support blank?/present? methods.
|
|
91
|
+
* Fixed false-valued non-nil accessors and the FromHash class factory.
|
|
92
|
+
* Consolidated partition code, supported general Enumerable inputs, and moved
|
|
93
|
+
load-time assertions into tests while keeping the old alias available.
|
|
94
|
+
* Fixed comma formatting for signed numbers and decimal fractions.
|
|
95
|
+
|
|
96
|
+
Validated on Ruby 3.3.7 with Active Support 8.1.3.1. The built package also passed
|
|
97
|
+
isolated smoke checks on Ruby 3.0.6, 3.2.2 and 3.3.7. Both the simulation library's
|
|
98
|
+
269 examples and the Rails application's 9 integration tests also passed with
|
|
99
|
+
this checkout on the Ruby load path. Consumers must update their dependency
|
|
100
|
+
requirements and lockfiles to use this release.
|
|
101
|
+
|
|
102
|
+
Copyright (c) 2008 Mike Harris. See LICENSE for the MIT license.
|
data/Rakefile
CHANGED
|
@@ -1,49 +1,9 @@
|
|
|
1
|
-
require '
|
|
2
|
-
|
|
3
|
-
begin
|
|
4
|
-
require 'jeweler'
|
|
5
|
-
Jeweler::Tasks.new do |s|
|
|
6
|
-
s.name = "mharris_ext"
|
|
7
|
-
s.summary = %Q{mharris717 utility methods}
|
|
8
|
-
s.email = "mharris717@gmail.com"
|
|
9
|
-
s.homepage = "http://github.com/GFunk911/mharris_ext"
|
|
10
|
-
s.description = "mharris717 utlity methods"
|
|
11
|
-
s.authors = ["Mike Harris"]
|
|
12
|
-
s.add_dependency 'fattr'
|
|
13
|
-
s.add_dependency 'facets'
|
|
14
|
-
end
|
|
15
|
-
rescue LoadError
|
|
16
|
-
puts "Jeweler not available. Install it with: sudo gem install technicalpickles-jeweler -s http://gems.github.com"
|
|
17
|
-
end
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
1
|
+
require 'bundler/gem_tasks'
|
|
21
2
|
require 'rake/testtask'
|
|
3
|
+
|
|
22
4
|
Rake::TestTask.new(:test) do |t|
|
|
23
5
|
t.libs << 'lib' << 'test'
|
|
24
6
|
t.pattern = 'test/**/*_test.rb'
|
|
25
|
-
t.verbose = false
|
|
26
7
|
end
|
|
27
8
|
|
|
28
|
-
|
|
29
|
-
require 'rcov/rcovtask'
|
|
30
|
-
Rcov::RcovTask.new do |t|
|
|
31
|
-
t.libs << 'test'
|
|
32
|
-
t.test_files = FileList['test/**/*_test.rb']
|
|
33
|
-
t.verbose = true
|
|
34
|
-
end
|
|
35
|
-
rescue LoadError
|
|
36
|
-
puts "RCov is not available. In order to run rcov, you must: sudo gem install spicycode-rcov"
|
|
37
|
-
end
|
|
38
|
-
|
|
39
|
-
begin
|
|
40
|
-
require 'cucumber/rake/task'
|
|
41
|
-
Cucumber::Rake::Task.new(:features)
|
|
42
|
-
rescue LoadError
|
|
43
|
-
puts "Cucumber is not available. In order to run features, you must: sudo gem install cucumber"
|
|
44
|
-
end
|
|
45
|
-
|
|
46
|
-
task :default => :test
|
|
47
|
-
|
|
48
|
-
Jeweler::GemcutterTasks.new
|
|
49
|
-
|
|
9
|
+
task default: :test
|
data/VERSION
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
1.8.0
|
data/VERSION.yml
CHANGED
data/lib/mharris_ext/accessor.rb
CHANGED
|
@@ -2,7 +2,7 @@ class Object
|
|
|
2
2
|
def attr_accessor_nn_one(sym)
|
|
3
3
|
define_method(sym) do
|
|
4
4
|
res = instance_variable_get("@#{sym}")
|
|
5
|
-
raise "method #{sym} cannot return nil value"
|
|
5
|
+
raise "method #{sym} cannot return nil value" if res.nil?
|
|
6
6
|
res
|
|
7
7
|
end
|
|
8
8
|
attr_writer(sym)
|
|
@@ -10,4 +10,4 @@ class Object
|
|
|
10
10
|
def attr_accessor_nn(*args)
|
|
11
11
|
args.flatten.each { |x| attr_accessor_nn_one(x) }
|
|
12
12
|
end
|
|
13
|
-
end
|
|
13
|
+
end
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
def tm(msg="Thing")
|
|
2
|
-
t =
|
|
1
|
+
def tm(msg = "Thing")
|
|
2
|
+
t = Process.clock_gettime(Process::CLOCK_MONOTONIC)
|
|
3
3
|
res = yield
|
|
4
|
-
seconds =
|
|
4
|
+
seconds = Process.clock_gettime(Process::CLOCK_MONOTONIC) - t
|
|
5
5
|
puts "#{msg} took #{seconds} seconds"
|
|
6
6
|
res
|
|
7
7
|
end
|
|
@@ -9,7 +9,7 @@ end
|
|
|
9
9
|
def print_memory_usage!
|
|
10
10
|
Thread.new do
|
|
11
11
|
loop do
|
|
12
|
-
mem = `ps -
|
|
12
|
+
mem = `ps -o rss= -p #{Process.pid}`.strip
|
|
13
13
|
puts "Memory: #{mem} #{Time.now}"
|
|
14
14
|
sleep(10)
|
|
15
15
|
end
|
data/lib/mharris_ext/cmd.rb
CHANGED
|
@@ -1,23 +1,20 @@
|
|
|
1
1
|
def has_bundler?
|
|
2
|
-
Bundler
|
|
3
|
-
true
|
|
4
|
-
rescue => exp
|
|
5
|
-
return false
|
|
2
|
+
!!defined?(Bundler)
|
|
6
3
|
end
|
|
7
4
|
|
|
8
5
|
module MharrisExt
|
|
9
|
-
def self.ec(cmd,ops={})
|
|
6
|
+
def self.ec(cmd,ops = {})
|
|
10
7
|
puts cmd unless ops[:silent]
|
|
11
|
-
|
|
12
|
-
if has_bundler?
|
|
13
|
-
Bundler.with_clean_env do
|
|
14
|
-
res = `#{cmd}`
|
|
15
|
-
end
|
|
16
|
-
else
|
|
8
|
+
run = proc do
|
|
17
9
|
res = `#{cmd}`
|
|
10
|
+
[res, $?]
|
|
18
11
|
end
|
|
19
|
-
|
|
20
|
-
|
|
12
|
+
res, status = if has_bundler?
|
|
13
|
+
Bundler.with_unbundled_env(&run)
|
|
14
|
+
else
|
|
15
|
+
run.call
|
|
16
|
+
end
|
|
17
|
+
raise "bad cmd #{status.to_i} #{cmd} #{res}" unless status.success?
|
|
21
18
|
puts res unless ops[:silent]
|
|
22
19
|
res
|
|
23
20
|
end
|
|
@@ -25,4 +22,4 @@ end
|
|
|
25
22
|
|
|
26
23
|
def ec(*args)
|
|
27
24
|
MharrisExt.ec(*args)
|
|
28
|
-
end
|
|
25
|
+
end
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
class
|
|
1
|
+
class Integer
|
|
2
2
|
def of
|
|
3
3
|
res = []
|
|
4
|
-
|
|
4
|
+
times { res << yield }
|
|
5
5
|
res
|
|
6
6
|
end
|
|
7
7
|
end
|
|
@@ -12,80 +12,29 @@ module Enumerable
|
|
|
12
12
|
each { |x| res += x }
|
|
13
13
|
res
|
|
14
14
|
end
|
|
15
|
+
|
|
15
16
|
def sum_b
|
|
16
17
|
map { |x| yield(x) }.sum
|
|
17
18
|
end
|
|
19
|
+
|
|
18
20
|
def avg_b(&b)
|
|
19
21
|
sum_b(&b).to_f / size.to_f
|
|
20
22
|
end
|
|
21
|
-
end
|
|
22
23
|
|
|
23
|
-
module Enumerable
|
|
24
|
-
def nths_hashx(num)
|
|
25
|
-
res = {}
|
|
26
|
-
s = e_f = e_i = 0
|
|
27
|
-
n_size = size.to_f / num.to_f
|
|
28
|
-
total_segment_size = 0
|
|
29
|
-
(0...num).each do |n|
|
|
30
|
-
s = e_i
|
|
31
|
-
e_f = e_f + n_size
|
|
32
|
-
e_i = (e_f+0.5).to_i
|
|
33
|
-
seg = self[s...e_i]
|
|
34
|
-
# puts %w(s e_f e_i seg).map { |x| "#{x}: #{send(x)}" }.join("\n")
|
|
35
|
-
#puts "s: #{s}, e_f: #{e_f}, e_i: #{e_i}, seg: #{seg.inspect}"
|
|
36
|
-
res[n] = seg
|
|
37
|
-
total_segment_size += res[n].size
|
|
38
|
-
end
|
|
39
|
-
unless total_segment_size == size
|
|
40
|
-
puts inspect
|
|
41
|
-
puts res.inspect
|
|
42
|
-
raise "nths_hash is bad"
|
|
43
|
-
end
|
|
44
|
-
res
|
|
45
|
-
end
|
|
46
24
|
def nths(num)
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
s = e_i
|
|
53
|
-
e_f = e_f + n_size
|
|
54
|
-
e_i = (e_f+0.5).to_i
|
|
55
|
-
seg = self[s...e_i]
|
|
56
|
-
# puts %w(s e_f e_i seg).map { |x| "#{x}: #{send(x)}" }.join("\n")
|
|
57
|
-
#puts "s: #{s}, e_f: #{e_f}, e_i: #{e_i}, seg: #{seg.inspect}"
|
|
58
|
-
res << seg
|
|
59
|
-
total_segment_size += res[n].size
|
|
25
|
+
raise ArgumentError, 'number of partitions must be a positive integer' unless num.is_a?(Integer) && num > 0
|
|
26
|
+
items = to_a
|
|
27
|
+
size_per = items.size.fdiv(num)
|
|
28
|
+
Array.new(num) do |i|
|
|
29
|
+
items[(i * size_per).round...((i + 1) * size_per).round]
|
|
60
30
|
end
|
|
61
|
-
unless total_segment_size == size
|
|
62
|
-
puts inspect
|
|
63
|
-
puts res.inspect
|
|
64
|
-
raise "nths_hash is bad"
|
|
65
|
-
end
|
|
66
|
-
res
|
|
67
31
|
end
|
|
32
|
+
|
|
68
33
|
def nths_hash(num)
|
|
69
|
-
|
|
70
|
-
nths(num).each_with_index { |x,i| res[i] = x }
|
|
71
|
-
res
|
|
34
|
+
nths(num).each_with_index.to_h { |x,i| [i,x] }
|
|
72
35
|
end
|
|
73
|
-
end
|
|
74
|
-
|
|
75
|
-
res = [1,2,3,4,5,6].nths_hash(3)
|
|
76
|
-
exp = {0 => [1,2], 1 => [3,4], 2 => [5,6]}
|
|
77
|
-
unless res == exp
|
|
78
|
-
puts res.inspect
|
|
79
|
-
puts exp.inspect
|
|
80
|
-
raise "nths_hash doesn't work"
|
|
81
|
-
end
|
|
82
36
|
|
|
83
|
-
|
|
84
|
-
exp = {0 => [1,2], 1 => [3,4,5], 2 => [6,7]}
|
|
85
|
-
unless res == exp
|
|
86
|
-
puts res.inspect
|
|
87
|
-
puts exp.inspect
|
|
88
|
-
raise "nths_hash doesn't work"
|
|
37
|
+
alias_method :nths_hashx, :nths_hash
|
|
89
38
|
end
|
|
90
39
|
|
|
91
40
|
class Hash
|
|
@@ -104,8 +53,13 @@ end
|
|
|
104
53
|
|
|
105
54
|
class String
|
|
106
55
|
def commify
|
|
107
|
-
|
|
108
|
-
|
|
56
|
+
if (parts = /\A([+-]?)(\d+)(\.\d+)?\z/.match(self))
|
|
57
|
+
digits = parts[2].reverse.scan(/.{1,3}/).join(',').reverse
|
|
58
|
+
"#{parts[1]}#{digits}#{parts[3]}"
|
|
59
|
+
else
|
|
60
|
+
# Preserve the legacy grouping behavior for nonnumeric strings.
|
|
61
|
+
return self if length <= 3
|
|
62
|
+
self[0...-3].commify + ',' + self[-3..-1]
|
|
63
|
+
end
|
|
109
64
|
end
|
|
110
65
|
end
|
|
111
|
-
|
|
@@ -1,8 +1,7 @@
|
|
|
1
|
+
require 'fileutils'
|
|
2
|
+
|
|
1
3
|
def all_dirs_recursive(dir)
|
|
2
4
|
raise "null dir" unless dir
|
|
3
|
-
init_slash = (dir[0..0] == '/')
|
|
4
|
-
#raise "can't handle initial slash" if dir[0..0] == '/'
|
|
5
|
-
#puts "all_dirs_recursive #{dir}"
|
|
6
5
|
dir.split("/")[0..-1].inject([]) do |paths,dir|
|
|
7
6
|
last_path = (paths.empty? ? "" : "#{paths[-1]}/")
|
|
8
7
|
paths + ["#{last_path}#{dir}"]
|
|
@@ -10,43 +9,26 @@ def all_dirs_recursive(dir)
|
|
|
10
9
|
end
|
|
11
10
|
|
|
12
11
|
def mkdir_if(dir)
|
|
13
|
-
|
|
14
|
-
#puts "not making #{dir}"
|
|
15
|
-
else
|
|
16
|
-
#puts "making #{dir}"
|
|
17
|
-
FileUtils.mkdir(dir)
|
|
18
|
-
end
|
|
12
|
+
FileUtils.mkdir(dir) unless File.exist?(dir)
|
|
19
13
|
end
|
|
20
14
|
|
|
21
15
|
def mkdir_recursive(ops)
|
|
22
16
|
dir = ops.is_a?(Hash) ? ops[:dir] : ops
|
|
23
|
-
#puts "mkdir_recursive #{dir}"
|
|
24
17
|
all_dirs_recursive(dir).each do |dir|
|
|
25
18
|
mkdir_if(dir)
|
|
26
19
|
end
|
|
27
20
|
end
|
|
28
21
|
|
|
29
22
|
def mv_making_dir(f,new_dir)
|
|
30
|
-
#puts "mv_making_dir #{f} #{new_dir}"
|
|
31
23
|
mkdir_recursive(new_dir)
|
|
32
24
|
FileUtils.mv(f,new_dir)
|
|
33
25
|
end
|
|
34
26
|
|
|
35
|
-
unless all_dirs_recursive("a/b/c") == ["a","a/b","a/b/c"]
|
|
36
|
-
res = all_dirs_recursive("a/b/c")
|
|
37
|
-
raise "all_dirs_recursive doesn't work #{res.inspect}"
|
|
38
|
-
end
|
|
39
|
-
|
|
40
|
-
unless all_dirs_recursive("/a/b/c") == ["/a","/a/b","/a/b/c"]
|
|
41
|
-
res = all_dirs_recursive("/a/b/c")
|
|
42
|
-
raise "all_dirs_recursive doesn't work #{res.inspect}"
|
|
43
|
-
end
|
|
44
|
-
|
|
45
27
|
def rm_r_if(dir)
|
|
46
|
-
FileUtils.rm_r(dir) if
|
|
28
|
+
FileUtils.rm_r(dir) if File.exist?(dir)
|
|
47
29
|
end
|
|
48
30
|
|
|
49
31
|
def eat_exceptions
|
|
50
32
|
yield
|
|
51
33
|
rescue
|
|
52
|
-
end
|
|
34
|
+
end
|
|
@@ -1,19 +1,22 @@
|
|
|
1
1
|
module FromHash
|
|
2
|
+
def self.included(base)
|
|
3
|
+
base.extend(ClassMethods)
|
|
4
|
+
end
|
|
5
|
+
|
|
6
|
+
module ClassMethods
|
|
7
|
+
def from_hash(ops = {})
|
|
8
|
+
new.from_hash(ops)
|
|
9
|
+
end
|
|
10
|
+
end
|
|
11
|
+
|
|
2
12
|
def from_hash(ops)
|
|
3
13
|
ops.each do |k,v|
|
|
4
14
|
send("#{k}=",v)
|
|
5
15
|
end
|
|
6
16
|
self
|
|
7
17
|
end
|
|
8
|
-
|
|
18
|
+
|
|
19
|
+
def initialize(ops = {})
|
|
9
20
|
from_hash(ops)
|
|
10
21
|
end
|
|
11
22
|
end
|
|
12
|
-
|
|
13
|
-
class Class
|
|
14
|
-
def self.from_hash(ops={})
|
|
15
|
-
res = new
|
|
16
|
-
res.from_hash(ops)
|
|
17
|
-
res
|
|
18
|
-
end
|
|
19
|
-
end
|
data/lib/mharris_ext/gems.rb
CHANGED
|
@@ -1,2 +1 @@
|
|
|
1
|
-
require '
|
|
2
|
-
require 'fattr'
|
|
1
|
+
require 'fattr'
|
data/lib/mharris_ext/object.rb
CHANGED
data/lib/mharris_ext/present.rb
CHANGED
|
@@ -1,8 +1,17 @@
|
|
|
1
1
|
class Object
|
|
2
|
-
|
|
3
|
-
|
|
2
|
+
unless method_defined?(:blank?)
|
|
3
|
+
def blank?
|
|
4
|
+
if is_a?(String)
|
|
5
|
+
/\A[[:space:]]*\z/.match?(self)
|
|
6
|
+
else
|
|
7
|
+
respond_to?(:empty?) ? !!empty? : !self
|
|
8
|
+
end
|
|
9
|
+
end
|
|
4
10
|
end
|
|
5
|
-
|
|
6
|
-
|
|
11
|
+
|
|
12
|
+
unless method_defined?(:present?)
|
|
13
|
+
def present?
|
|
14
|
+
!blank?
|
|
15
|
+
end
|
|
7
16
|
end
|
|
8
|
-
end
|
|
17
|
+
end
|
data/lib/mharris_ext.rb
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
|
|
2
|
-
Dir[
|
|
1
|
+
require_relative 'mharris_ext/gems'
|
|
2
|
+
Dir[File.join(__dir__, 'mharris_ext', '*.rb')].sort.each { |x| require x }
|
data/mharris_ext.gemspec
CHANGED
|
@@ -1,67 +1,17 @@
|
|
|
1
|
-
# Generated by jeweler
|
|
2
|
-
# DO NOT EDIT THIS FILE DIRECTLY
|
|
3
|
-
# Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
|
|
4
|
-
# -*- encoding: utf-8 -*-
|
|
5
|
-
|
|
6
1
|
Gem::Specification.new do |s|
|
|
7
|
-
s.name =
|
|
8
|
-
s.version =
|
|
9
|
-
|
|
10
|
-
s.
|
|
11
|
-
s.authors = [
|
|
12
|
-
s.
|
|
13
|
-
s.
|
|
14
|
-
s.
|
|
15
|
-
s.
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
s.
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
"Rakefile",
|
|
23
|
-
"VERSION.yml",
|
|
24
|
-
"features/mharris_ext.feature",
|
|
25
|
-
"features/steps/mharris_ext_steps.rb",
|
|
26
|
-
"features/support/env.rb",
|
|
27
|
-
"lib/mharris_ext.rb",
|
|
28
|
-
"lib/mharris_ext/accessor.rb",
|
|
29
|
-
"lib/mharris_ext/benchmark.rb",
|
|
30
|
-
"lib/mharris_ext/cmd.rb",
|
|
31
|
-
"lib/mharris_ext/enumerable.rb",
|
|
32
|
-
"lib/mharris_ext/file.rb",
|
|
33
|
-
"lib/mharris_ext/fileutils.rb",
|
|
34
|
-
"lib/mharris_ext/from_hash.rb",
|
|
35
|
-
"lib/mharris_ext/gems.rb",
|
|
36
|
-
"lib/mharris_ext/methods.rb",
|
|
37
|
-
"lib/mharris_ext/object.rb",
|
|
38
|
-
"lib/mharris_ext/present.rb",
|
|
39
|
-
"lib/mharris_ext/regexp.rb",
|
|
40
|
-
"lib/mharris_ext/string.rb",
|
|
41
|
-
"lib/mharris_ext/time.rb",
|
|
42
|
-
"lib/mharris_ext/trace.rb",
|
|
43
|
-
"mharris_ext.gemspec",
|
|
44
|
-
"test/mharris_ext_test.rb",
|
|
45
|
-
"test/test_helper.rb"
|
|
46
|
-
]
|
|
47
|
-
s.homepage = "http://github.com/GFunk911/mharris_ext"
|
|
48
|
-
s.require_paths = ["lib"]
|
|
49
|
-
s.rubygems_version = "2.0.7"
|
|
50
|
-
s.summary = "mharris717 utility methods"
|
|
51
|
-
|
|
52
|
-
if s.respond_to? :specification_version then
|
|
53
|
-
s.specification_version = 4
|
|
54
|
-
|
|
55
|
-
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
|
56
|
-
s.add_runtime_dependency(%q<fattr>, [">= 0"])
|
|
57
|
-
s.add_runtime_dependency(%q<facets>, [">= 0"])
|
|
58
|
-
else
|
|
59
|
-
s.add_dependency(%q<fattr>, [">= 0"])
|
|
60
|
-
s.add_dependency(%q<facets>, [">= 0"])
|
|
61
|
-
end
|
|
62
|
-
else
|
|
63
|
-
s.add_dependency(%q<fattr>, [">= 0"])
|
|
64
|
-
s.add_dependency(%q<facets>, [">= 0"])
|
|
65
|
-
end
|
|
2
|
+
s.name = 'mharris_ext'
|
|
3
|
+
s.version = File.read(File.expand_path('VERSION', __dir__)).strip
|
|
4
|
+
s.summary = 'Mike Harris Ruby utility methods'
|
|
5
|
+
s.description = 'Small Ruby helpers for object initialization, collections, files, and shell commands.'
|
|
6
|
+
s.authors = ['Mike Harris']
|
|
7
|
+
s.email = 'mharris717@gmail.com'
|
|
8
|
+
s.homepage = 'https://github.com/mharris717/mharris_ext'
|
|
9
|
+
s.license = 'MIT'
|
|
10
|
+
s.required_ruby_version = '>= 2.7'
|
|
11
|
+
s.require_paths = ['lib']
|
|
12
|
+
s.files = Dir['lib/**/*.rb', 'test/**/*.rb'] + %w[LICENSE README Rakefile VERSION VERSION.yml Gemfile mharris_ext.gemspec]
|
|
13
|
+
s.metadata = { 'source_code_uri' => s.homepage }
|
|
14
|
+
s.add_dependency 'fattr', '~> 2.4'
|
|
15
|
+
s.add_development_dependency 'bundler', '>= 2.4'
|
|
16
|
+
s.add_development_dependency 'rake', '~> 13.3'
|
|
66
17
|
end
|
|
67
|
-
|
|
@@ -0,0 +1,247 @@
|
|
|
1
|
+
require_relative 'test_helper'
|
|
2
|
+
|
|
3
|
+
class CollectionsTest < Minitest::Test
|
|
4
|
+
def test_integer_of_returns_fresh_results
|
|
5
|
+
rows = 3.of { [] }
|
|
6
|
+
assert_equal [[], [], []], rows
|
|
7
|
+
assert_equal 3, rows.map(&:object_id).uniq.size
|
|
8
|
+
assert_equal [], 0.of { flunk }
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def test_partition_distribution_and_legacy_alias
|
|
12
|
+
assert_equal [[1, 2], [3, 4], [5, 6]], (1..6).to_a.nths(3)
|
|
13
|
+
assert_equal [[1, 2], [3, 4, 5], [6, 7]], (1..7).to_a.nths(3)
|
|
14
|
+
assert_equal [[], [1], [], [2], []], [1, 2].nths(5)
|
|
15
|
+
assert_equal [[], [], []], [].nths(3)
|
|
16
|
+
expected = {0 => [1, 2], 1 => [3, 4, 5], 2 => [6, 7]}
|
|
17
|
+
assert_equal expected, (1..7).to_a.nths_hash(3)
|
|
18
|
+
assert_equal expected, (1..7).to_a.nths_hashx(3)
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def test_partitions_any_enumerable_without_losing_elements
|
|
22
|
+
assert_equal [[1, 2], [3, 4, 5], [6, 7]], (1..7).nths(3)
|
|
23
|
+
(1..17).each do |n|
|
|
24
|
+
parts = (1..31).each.nths(n)
|
|
25
|
+
assert_equal n, parts.size
|
|
26
|
+
assert_equal (1..31).to_a, parts.flatten
|
|
27
|
+
assert_operator parts.map(&:size).max - parts.map(&:size).min, :<=, 1
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def test_invalid_partition_counts_are_rejected
|
|
32
|
+
[0, -1, 1.5, '2', nil].each do |n|
|
|
33
|
+
assert_raises(ArgumentError) { [1, 2].nths(n) }
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def test_aggregation_and_hash_mapping
|
|
38
|
+
assert_equal 6, [1, 2, 3].sumx
|
|
39
|
+
assert_equal 14, [1, 2, 3].sum_b { |x| x * x }
|
|
40
|
+
assert_in_delta 14.0 / 3, [1, 2, 3].avg_b { |x| x * x }
|
|
41
|
+
assert_equal({a: 2, b: 4}, {a: 1, b: 2}.map_value { |x| x * 2 })
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
class ObjectHelpersTest < Minitest::Test
|
|
46
|
+
def test_from_hash_initialization_updates_and_factory
|
|
47
|
+
klass = Class.new do
|
|
48
|
+
include FromHash
|
|
49
|
+
attr_accessor :name, :active
|
|
50
|
+
end
|
|
51
|
+
x = klass.new(name: 'one', active: false)
|
|
52
|
+
assert_equal 'one', x.name
|
|
53
|
+
assert_equal false, x.active
|
|
54
|
+
assert_same x, x.from_hash('name' => 'two')
|
|
55
|
+
assert_equal 'two', x.name
|
|
56
|
+
assert_equal 'three', klass.from_hash(name: 'three').name
|
|
57
|
+
assert_raises(NoMethodError) { klass.new(unknown: 1) }
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
def test_non_nil_accessor_accepts_false
|
|
61
|
+
klass = Class.new { attr_accessor_nn :value }
|
|
62
|
+
x = klass.new
|
|
63
|
+
assert_raises(RuntimeError) { x.value }
|
|
64
|
+
x.value = false
|
|
65
|
+
assert_equal false, x.value
|
|
66
|
+
x.value = 0
|
|
67
|
+
assert_equal 0, x.value
|
|
68
|
+
x.value = nil
|
|
69
|
+
assert_raises(RuntimeError) { x.value }
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
def test_blank_and_present_without_active_support
|
|
73
|
+
[nil, false, '', ' ', "\u2003", [], {}].each do |x|
|
|
74
|
+
assert x.blank?, "#{x.inspect} should be blank"
|
|
75
|
+
refute x.present?
|
|
76
|
+
end
|
|
77
|
+
[true, 0, '0', [nil], {a: nil}, Object.new].each do |x|
|
|
78
|
+
refute x.blank?, "#{x.inspect} should be present"
|
|
79
|
+
assert x.present?
|
|
80
|
+
end
|
|
81
|
+
x = Object.new
|
|
82
|
+
def x.empty?; true; end
|
|
83
|
+
assert x.blank?
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
def test_preserves_ruby_tap
|
|
87
|
+
out, = run_ruby(<<~RUBY)
|
|
88
|
+
before = Object.instance_method(:tap)
|
|
89
|
+
require 'mharris_ext'
|
|
90
|
+
raise 'tap was replaced' unless Object.instance_method(:tap) == before
|
|
91
|
+
x = Object.new
|
|
92
|
+
raise unless x.tap { |v| raise unless v.equal?(x) }.equal?(x)
|
|
93
|
+
puts 'native tap'
|
|
94
|
+
RUBY
|
|
95
|
+
assert_equal "native tap\n", out
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
def test_active_support_load_order
|
|
99
|
+
[true, false].each do |rails_first|
|
|
100
|
+
code = <<~RUBY
|
|
101
|
+
require 'active_support/core_ext/object/blank' if #{rails_first}
|
|
102
|
+
before = Object.instance_method(:blank?) if #{rails_first}
|
|
103
|
+
require 'mharris_ext'
|
|
104
|
+
raise 'Active Support blank? replaced' if #{rails_first} && Object.instance_method(:blank?) != before
|
|
105
|
+
require 'active_support/core_ext/object/blank'
|
|
106
|
+
[nil, false, '', ' ', [], {}].each { |x| raise x.inspect unless x.blank? && !x.present? }
|
|
107
|
+
raise unless 0.present?
|
|
108
|
+
puts 'compatible'
|
|
109
|
+
RUBY
|
|
110
|
+
out, = run_ruby(code)
|
|
111
|
+
assert_equal "compatible\n", out
|
|
112
|
+
end
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
def test_local_methods
|
|
116
|
+
x = Class.new { def special_helper; end }.new
|
|
117
|
+
assert_includes x.local_methods, :special_helper
|
|
118
|
+
end
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
class FormattingTest < Minitest::Test
|
|
122
|
+
def test_padding_preserves_existing_call_shapes
|
|
123
|
+
assert_equal 'x ', 'x'.rpad(3)
|
|
124
|
+
assert_equal ' x', 'x'.lpad(3)
|
|
125
|
+
assert_equal 'long', 'long'.rpad(2)
|
|
126
|
+
assert_equal 'x....', 'x'.rpad(3, '..')
|
|
127
|
+
assert_equal '0012', 12.lpad(4)
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
def test_commify_signed_and_decimal_numbers
|
|
131
|
+
assert_equal '1,234,567', 1234567.commify
|
|
132
|
+
assert_equal '-123', (-123).commify
|
|
133
|
+
assert_equal '-1,234,567', (-1234567).commify
|
|
134
|
+
assert_equal '1,234.56', '1234.56'.commify
|
|
135
|
+
assert_equal '+1,234.50', '+1234.50'.commify
|
|
136
|
+
assert_equal '12', 12.commify
|
|
137
|
+
end
|
|
138
|
+
|
|
139
|
+
def test_regexp_and_time
|
|
140
|
+
pattern = Regexp.escaped('a.b[0]')
|
|
141
|
+
assert_match pattern, 'a.b[0]'
|
|
142
|
+
refute_match pattern, 'axb0'
|
|
143
|
+
assert_equal '09/04 13:02:03', Time.new(2026, 9, 4, 13, 2, 3).short_dt
|
|
144
|
+
end
|
|
145
|
+
end
|
|
146
|
+
|
|
147
|
+
class FileHelpersTest < Minitest::Test
|
|
148
|
+
def test_file_creation_append_and_native_write
|
|
149
|
+
Dir.mktmpdir do |dir|
|
|
150
|
+
file = File.join(dir, 'sample')
|
|
151
|
+
File.create(file, 'first')
|
|
152
|
+
File.append(file, '-last')
|
|
153
|
+
assert_equal 'first-last', File.read(file)
|
|
154
|
+
assert_equal 3, File.write(file, 'new')
|
|
155
|
+
assert_equal 'new', File.read(file)
|
|
156
|
+
end
|
|
157
|
+
end
|
|
158
|
+
|
|
159
|
+
def test_path_expansion
|
|
160
|
+
assert_equal ['a', 'a/b', 'a/b/c'], all_dirs_recursive('a/b/c')
|
|
161
|
+
assert_equal ['/a', '/a/b', '/a/b/c'], all_dirs_recursive('/a/b/c')
|
|
162
|
+
assert_raises(RuntimeError) { all_dirs_recursive(nil) }
|
|
163
|
+
end
|
|
164
|
+
|
|
165
|
+
def test_directory_helpers_use_supported_ruby_file_apis
|
|
166
|
+
Dir.mktmpdir do |dir|
|
|
167
|
+
target = File.join(dir, 'a', 'b')
|
|
168
|
+
mkdir_recursive(dir: target)
|
|
169
|
+
mkdir_recursive(target)
|
|
170
|
+
assert File.directory?(target)
|
|
171
|
+
source = File.join(dir, 'source.txt')
|
|
172
|
+
File.write(source, 'hello')
|
|
173
|
+
mv_making_dir(source, target)
|
|
174
|
+
assert_equal 'hello', File.read(File.join(target, 'source.txt'))
|
|
175
|
+
rm_r_if(File.join(dir, 'a'))
|
|
176
|
+
refute File.exist?(target)
|
|
177
|
+
rm_r_if(File.join(dir, 'missing'))
|
|
178
|
+
end
|
|
179
|
+
end
|
|
180
|
+
|
|
181
|
+
def test_optional_exception_swallowing
|
|
182
|
+
assert_nil eat_exceptions { raise 'expected' }
|
|
183
|
+
assert_equal 42, eat_exceptions { 42 }
|
|
184
|
+
end
|
|
185
|
+
end
|
|
186
|
+
|
|
187
|
+
class CommandHelpersTest < Minitest::Test
|
|
188
|
+
def ruby_command(code)
|
|
189
|
+
Shellwords.join([RbConfig.ruby, '-e', code])
|
|
190
|
+
end
|
|
191
|
+
|
|
192
|
+
def test_success_and_silent_output
|
|
193
|
+
out, err = capture_io do
|
|
194
|
+
assert_equal 'ok', ec(ruby_command("print 'ok'"), silent: true)
|
|
195
|
+
end
|
|
196
|
+
assert_empty out
|
|
197
|
+
assert_empty err
|
|
198
|
+
end
|
|
199
|
+
|
|
200
|
+
def test_nonzero_exit_reports_failure
|
|
201
|
+
error = assert_raises(RuntimeError) { ec(ruby_command("print 'failure'; exit 7"), silent: true) }
|
|
202
|
+
assert_match(/bad cmd/, error.message)
|
|
203
|
+
assert_match(/failure/, error.message)
|
|
204
|
+
end
|
|
205
|
+
|
|
206
|
+
def test_unbundles_child_processes_with_current_bundler
|
|
207
|
+
assert has_bundler?
|
|
208
|
+
assert_equal 'unset', ec(ruby_command("print ENV.fetch('BUNDLE_GEMFILE', 'unset')"), silent: true)
|
|
209
|
+
end
|
|
210
|
+
|
|
211
|
+
def test_also_runs_without_bundler
|
|
212
|
+
out, err, status = Bundler.with_unbundled_env do
|
|
213
|
+
Open3.capture3(RbConfig.ruby, '-Ilib', '-e', <<~RUBY)
|
|
214
|
+
require 'mharris_ext'
|
|
215
|
+
raise if has_bundler?
|
|
216
|
+
print ec(#{ruby_command("print 'ok'").inspect}, silent: true)
|
|
217
|
+
RUBY
|
|
218
|
+
end
|
|
219
|
+
assert status.success?, err
|
|
220
|
+
assert_equal 'ok', out
|
|
221
|
+
end
|
|
222
|
+
end
|
|
223
|
+
|
|
224
|
+
class DiagnosticHelpersTest < Minitest::Test
|
|
225
|
+
def test_timing_returns_the_block_result
|
|
226
|
+
out, = capture_io { assert_equal 42, tm('job') { 42 } }
|
|
227
|
+
assert_match(/job took .* seconds/, out)
|
|
228
|
+
end
|
|
229
|
+
|
|
230
|
+
def test_backtrace_printing
|
|
231
|
+
out, = capture_io { bt }
|
|
232
|
+
assert_includes out, 'test_backtrace_printing'
|
|
233
|
+
end
|
|
234
|
+
|
|
235
|
+
def test_memory_report_thread_can_be_stopped
|
|
236
|
+
x = Object.new
|
|
237
|
+
lines = Queue.new
|
|
238
|
+
x.define_singleton_method(:`) { |_| " 1234\n" }
|
|
239
|
+
x.define_singleton_method(:puts) { |s| lines << s }
|
|
240
|
+
thread = x.send(:print_memory_usage!)
|
|
241
|
+
line = Timeout.timeout(2) { lines.pop }
|
|
242
|
+
assert_match(/Memory: 1234/, line)
|
|
243
|
+
ensure
|
|
244
|
+
thread&.kill
|
|
245
|
+
thread&.join
|
|
246
|
+
end
|
|
247
|
+
end
|
data/test/mharris_ext_test.rb
CHANGED
|
@@ -1,7 +1,20 @@
|
|
|
1
|
-
|
|
1
|
+
require_relative 'test_helper'
|
|
2
2
|
|
|
3
|
-
class MharrisExtTest < Test
|
|
4
|
-
|
|
5
|
-
|
|
3
|
+
class MharrisExtTest < Minitest::Test
|
|
4
|
+
def test_loads_without_facets_and_preserves_builtin_file_write
|
|
5
|
+
out, err = run_ruby(<<~RUBY)
|
|
6
|
+
original = File.method(:write)
|
|
7
|
+
require 'mharris_ext'
|
|
8
|
+
raise 'Facets loaded' if $LOADED_FEATURES.any? { |x| x.include?('/facets/') }
|
|
9
|
+
raise 'File.write replaced' unless File.method(:write) == original
|
|
10
|
+
puts 'loaded'
|
|
11
|
+
RUBY
|
|
12
|
+
assert_equal "loaded\n", out
|
|
13
|
+
assert_empty err
|
|
6
14
|
end
|
|
7
|
-
|
|
15
|
+
|
|
16
|
+
def test_fattr_is_still_available
|
|
17
|
+
klass = Class.new { fattr(:answer) { 42 } }
|
|
18
|
+
assert_equal 42, klass.new.answer
|
|
19
|
+
end
|
|
20
|
+
end
|
data/test/test_helper.rb
CHANGED
|
@@ -1,10 +1,24 @@
|
|
|
1
|
-
require '
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
1
|
+
require 'simplecov'
|
|
2
|
+
SimpleCov.start do
|
|
3
|
+
add_filter '/test/'
|
|
4
|
+
track_files 'lib/**/*.rb'
|
|
5
|
+
end
|
|
6
|
+
require 'minitest/autorun'
|
|
7
|
+
require 'minitest/mock'
|
|
8
|
+
require 'open3'
|
|
9
|
+
require 'rbconfig'
|
|
10
|
+
require 'shellwords'
|
|
11
|
+
require 'tmpdir'
|
|
12
|
+
require 'timeout'
|
|
13
|
+
require 'stringio'
|
|
5
14
|
|
|
6
|
-
$LOAD_PATH.unshift(File.
|
|
15
|
+
$LOAD_PATH.unshift(File.expand_path('../lib', __dir__))
|
|
7
16
|
require 'mharris_ext'
|
|
8
17
|
|
|
9
|
-
class Test
|
|
18
|
+
class Minitest::Test
|
|
19
|
+
def run_ruby(code)
|
|
20
|
+
out, err, status = Open3.capture3(RbConfig.ruby, '-Ilib', '-e', code)
|
|
21
|
+
assert status.success?, "#{out}\n#{err}"
|
|
22
|
+
[out, err]
|
|
23
|
+
end
|
|
10
24
|
end
|
metadata
CHANGED
|
@@ -1,58 +1,70 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: mharris_ext
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.
|
|
4
|
+
version: 1.8.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Mike Harris
|
|
8
|
-
autorequire:
|
|
8
|
+
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date:
|
|
11
|
+
date: 2026-09-05 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: fattr
|
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
|
16
16
|
requirements:
|
|
17
|
-
- -
|
|
17
|
+
- - "~>"
|
|
18
18
|
- !ruby/object:Gem::Version
|
|
19
|
-
version: '
|
|
19
|
+
version: '2.4'
|
|
20
20
|
type: :runtime
|
|
21
21
|
prerelease: false
|
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
|
23
23
|
requirements:
|
|
24
|
-
- -
|
|
24
|
+
- - "~>"
|
|
25
25
|
- !ruby/object:Gem::Version
|
|
26
|
-
version: '
|
|
26
|
+
version: '2.4'
|
|
27
27
|
- !ruby/object:Gem::Dependency
|
|
28
|
-
name:
|
|
28
|
+
name: bundler
|
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
|
30
30
|
requirements:
|
|
31
|
-
- -
|
|
31
|
+
- - ">="
|
|
32
32
|
- !ruby/object:Gem::Version
|
|
33
|
-
version: '
|
|
34
|
-
type: :
|
|
33
|
+
version: '2.4'
|
|
34
|
+
type: :development
|
|
35
|
+
prerelease: false
|
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
37
|
+
requirements:
|
|
38
|
+
- - ">="
|
|
39
|
+
- !ruby/object:Gem::Version
|
|
40
|
+
version: '2.4'
|
|
41
|
+
- !ruby/object:Gem::Dependency
|
|
42
|
+
name: rake
|
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
|
44
|
+
requirements:
|
|
45
|
+
- - "~>"
|
|
46
|
+
- !ruby/object:Gem::Version
|
|
47
|
+
version: '13.3'
|
|
48
|
+
type: :development
|
|
35
49
|
prerelease: false
|
|
36
50
|
version_requirements: !ruby/object:Gem::Requirement
|
|
37
51
|
requirements:
|
|
38
|
-
- -
|
|
52
|
+
- - "~>"
|
|
39
53
|
- !ruby/object:Gem::Version
|
|
40
|
-
version: '
|
|
41
|
-
description:
|
|
54
|
+
version: '13.3'
|
|
55
|
+
description: Small Ruby helpers for object initialization, collections, files, and
|
|
56
|
+
shell commands.
|
|
42
57
|
email: mharris717@gmail.com
|
|
43
58
|
executables: []
|
|
44
59
|
extensions: []
|
|
45
|
-
extra_rdoc_files:
|
|
46
|
-
- LICENSE
|
|
47
|
-
- README
|
|
60
|
+
extra_rdoc_files: []
|
|
48
61
|
files:
|
|
62
|
+
- Gemfile
|
|
49
63
|
- LICENSE
|
|
50
64
|
- README
|
|
51
65
|
- Rakefile
|
|
66
|
+
- VERSION
|
|
52
67
|
- VERSION.yml
|
|
53
|
-
- features/mharris_ext.feature
|
|
54
|
-
- features/steps/mharris_ext_steps.rb
|
|
55
|
-
- features/support/env.rb
|
|
56
68
|
- lib/mharris_ext.rb
|
|
57
69
|
- lib/mharris_ext/accessor.rb
|
|
58
70
|
- lib/mharris_ext/benchmark.rb
|
|
@@ -70,29 +82,31 @@ files:
|
|
|
70
82
|
- lib/mharris_ext/time.rb
|
|
71
83
|
- lib/mharris_ext/trace.rb
|
|
72
84
|
- mharris_ext.gemspec
|
|
85
|
+
- test/helpers_test.rb
|
|
73
86
|
- test/mharris_ext_test.rb
|
|
74
87
|
- test/test_helper.rb
|
|
75
|
-
homepage:
|
|
76
|
-
licenses:
|
|
77
|
-
|
|
78
|
-
|
|
88
|
+
homepage: https://github.com/mharris717/mharris_ext
|
|
89
|
+
licenses:
|
|
90
|
+
- MIT
|
|
91
|
+
metadata:
|
|
92
|
+
source_code_uri: https://github.com/mharris717/mharris_ext
|
|
93
|
+
post_install_message:
|
|
79
94
|
rdoc_options: []
|
|
80
95
|
require_paths:
|
|
81
96
|
- lib
|
|
82
97
|
required_ruby_version: !ruby/object:Gem::Requirement
|
|
83
98
|
requirements:
|
|
84
|
-
- -
|
|
99
|
+
- - ">="
|
|
85
100
|
- !ruby/object:Gem::Version
|
|
86
|
-
version: '
|
|
101
|
+
version: '2.7'
|
|
87
102
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
88
103
|
requirements:
|
|
89
|
-
- -
|
|
104
|
+
- - ">="
|
|
90
105
|
- !ruby/object:Gem::Version
|
|
91
106
|
version: '0'
|
|
92
107
|
requirements: []
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
signing_key:
|
|
108
|
+
rubygems_version: 3.5.22
|
|
109
|
+
signing_key:
|
|
96
110
|
specification_version: 4
|
|
97
|
-
summary:
|
|
111
|
+
summary: Mike Harris Ruby utility methods
|
|
98
112
|
test_files: []
|
|
File without changes
|
data/features/support/env.rb
DELETED