theusual 0.0.1
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 +7 -0
- data/lib/theusual.rb +41 -0
- data/lib/theusual/array.rb +80 -0
- data/lib/theusual/hash.rb +136 -0
- data/lib/theusual/ipaddr.rb +54 -0
- data/lib/theusual/mongoid.rb +37 -0
- data/lib/theusual/ssh.rb +53 -0
- data/lib/theusual/time.rb +19 -0
- data/test/test_array.rb +121 -0
- data/test/test_hash.rb +350 -0
- data/test/test_ip_addr.rb +49 -0
- data/test/test_time.rb +30 -0
- metadata +96 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 4d35f965de136645227b101c3dbc948e09f69704
|
4
|
+
data.tar.gz: 24cfeec64ea6e738575d21ca496d07c4619e224d
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: ccebdfa7247d0e2ff714f7762bc9f1bc9d7f1c6c26d0ca380edc3a1e1c269cd1bd47b5b82cb0e7aa4d301c354900225bfbd0d7b5e9b52642d5442e4b482d202f
|
7
|
+
data.tar.gz: 11881d146b47a2d59814c0ee5e967159487a7ebc73865e920f8c38814d85035ad9747e2eabd16527e94e56f97c632f5ce27dfbfe80052242643ea371ec4a20db
|
data/lib/theusual.rb
ADDED
@@ -0,0 +1,41 @@
|
|
1
|
+
module TheUsual
|
2
|
+
VERSION = '0.0.1'
|
3
|
+
|
4
|
+
MODULES = [
|
5
|
+
'array',
|
6
|
+
'hash',
|
7
|
+
'ipaddr',
|
8
|
+
'mongoid',
|
9
|
+
'net/ssh',
|
10
|
+
'time',
|
11
|
+
]
|
12
|
+
|
13
|
+
def self.load *modules
|
14
|
+
# some modules need to be explicitly required
|
15
|
+
needs_load = [
|
16
|
+
'ipaddr',
|
17
|
+
'mongoid',
|
18
|
+
'net/ssh',
|
19
|
+
]
|
20
|
+
|
21
|
+
# some of our filenames need to be remapped
|
22
|
+
paths = {
|
23
|
+
'net/ssh' => 'ssh',
|
24
|
+
}
|
25
|
+
|
26
|
+
raise ArgumentError if modules.empty?
|
27
|
+
|
28
|
+
modules = MODULES if [:all, 'all', '*'].include? modules.first
|
29
|
+
|
30
|
+
modules.flatten.map(&:to_s).each do |_module|
|
31
|
+
raise ArgumentError unless MODULES.include? _module
|
32
|
+
|
33
|
+
# load standard lib
|
34
|
+
require _module if needs_load.include? _module
|
35
|
+
|
36
|
+
# monkey patch
|
37
|
+
name = paths[_module] || _module
|
38
|
+
require_relative "theusual/#{name}.rb"
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,80 @@
|
|
1
|
+
class Array
|
2
|
+
##### Numerical Operations #####
|
3
|
+
def sum
|
4
|
+
numerics?
|
5
|
+
inject 0, &:+
|
6
|
+
end
|
7
|
+
alias_method :total, :sum
|
8
|
+
|
9
|
+
|
10
|
+
def avg
|
11
|
+
numerics?
|
12
|
+
return Float::NAN if empty?
|
13
|
+
|
14
|
+
map(&:to_f).sum / count
|
15
|
+
end
|
16
|
+
alias_method :average, :avg
|
17
|
+
alias_method :mean, :avg
|
18
|
+
|
19
|
+
|
20
|
+
def std
|
21
|
+
numerics?
|
22
|
+
return Float::NAN if empty?
|
23
|
+
|
24
|
+
mean = avg
|
25
|
+
|
26
|
+
Math.sqrt(
|
27
|
+
map { |sample| (mean - sample.to_f) ** 2 }.reduce(:+) / count.to_f
|
28
|
+
)
|
29
|
+
end
|
30
|
+
alias_method :standard_deviation, :std
|
31
|
+
|
32
|
+
|
33
|
+
##### String Operations #####
|
34
|
+
def grepv regex
|
35
|
+
reject { |elem| elem =~ regex }
|
36
|
+
end
|
37
|
+
|
38
|
+
|
39
|
+
def gsub(regex, replacement)
|
40
|
+
map { |string| string.gsub(regex, replacement) }
|
41
|
+
end
|
42
|
+
|
43
|
+
def gsub!(regex, replacement)
|
44
|
+
map! { |string| string.gsub(regex, replacement) }
|
45
|
+
end
|
46
|
+
|
47
|
+
|
48
|
+
##### Misc Operations #####
|
49
|
+
def compact(modifier = nil)
|
50
|
+
falsy = modifier == :falsy
|
51
|
+
blanks = falsy || modifier == :blanks
|
52
|
+
|
53
|
+
reject do |v|
|
54
|
+
isblank = blanks && v.respond_to?(:empty?) && v.empty?
|
55
|
+
isfalsy = falsy && (v == 0)
|
56
|
+
|
57
|
+
!v || isblank || isfalsy
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
def compact!(modifier = nil)
|
62
|
+
res = compact(modifier)
|
63
|
+
clear
|
64
|
+
|
65
|
+
# TODO: is there a better way than shift/reverse?
|
66
|
+
res.each {|x| unshift x}
|
67
|
+
reverse!
|
68
|
+
end
|
69
|
+
|
70
|
+
|
71
|
+
private
|
72
|
+
|
73
|
+
def numerics?
|
74
|
+
# make sure values are all Numeric or numbers within strings
|
75
|
+
map do |x|
|
76
|
+
Float(x)
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
end
|
@@ -0,0 +1,136 @@
|
|
1
|
+
class Hash
|
2
|
+
|
3
|
+
class << self
|
4
|
+
|
5
|
+
# map any Enumerable into a Hash, like Hash[obj.map ... ]
|
6
|
+
def map(obj, &block)
|
7
|
+
Hash[
|
8
|
+
obj.map do |*args|
|
9
|
+
block.call *args
|
10
|
+
end.compact
|
11
|
+
]
|
12
|
+
end
|
13
|
+
|
14
|
+
end # class << self
|
15
|
+
|
16
|
+
|
17
|
+
def select_keys(*keys)
|
18
|
+
if keys.length == 1 and keys.first.class < Enumerable
|
19
|
+
keys = keys.first
|
20
|
+
end
|
21
|
+
|
22
|
+
Hash.map keys do |k|
|
23
|
+
[ k, self[k] ]
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def select_keys!(*keys)
|
28
|
+
replace select_keys *keys
|
29
|
+
end
|
30
|
+
|
31
|
+
|
32
|
+
def compact(modifier = nil)
|
33
|
+
falsy = modifier == :falsy
|
34
|
+
blanks = falsy || modifier == :blanks
|
35
|
+
|
36
|
+
reject do |k, v|
|
37
|
+
isblank = blanks && v.respond_to?(:empty?) && v.empty?
|
38
|
+
isfalsy = falsy && (v == 0)
|
39
|
+
|
40
|
+
!v || isblank || isfalsy
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
def compact!(modifier = nil)
|
45
|
+
replace compact(modifier)
|
46
|
+
end
|
47
|
+
|
48
|
+
|
49
|
+
# map the block's results back to a hash
|
50
|
+
def hmap(&block)
|
51
|
+
Hash[ map {|k, v| block.call(k, v) }.compact ]
|
52
|
+
end
|
53
|
+
|
54
|
+
def hmap!(&block)
|
55
|
+
replace hmap &block
|
56
|
+
end
|
57
|
+
|
58
|
+
|
59
|
+
# map keys, but preserve associated values
|
60
|
+
# ie. http://apidock.com/rails/v4.2.7/Hash/transform_keys
|
61
|
+
def kmap(&block)
|
62
|
+
Hash[map do |k, v|
|
63
|
+
[ block.arity == 1 ? block.call(k) : block.call(k, v), v ]
|
64
|
+
end]
|
65
|
+
|
66
|
+
end
|
67
|
+
|
68
|
+
def kmap!(&block)
|
69
|
+
replace kmap &block
|
70
|
+
end
|
71
|
+
|
72
|
+
|
73
|
+
# map values, but preserve associated keys
|
74
|
+
# ie. http://apidock.com/rails/v4.2.7/Hash/transform_values
|
75
|
+
def vmap(&block)
|
76
|
+
Hash[map do |k, v|
|
77
|
+
[ k, block.arity == 1 ? block.call(v) : block.call(k, v) ]
|
78
|
+
end]
|
79
|
+
end
|
80
|
+
|
81
|
+
def vmap!(&block)
|
82
|
+
replace vmap &block
|
83
|
+
end
|
84
|
+
|
85
|
+
|
86
|
+
# sort by key values, for pretty printing
|
87
|
+
def ksort(&block)
|
88
|
+
Hash[
|
89
|
+
sort_by do |k, v|
|
90
|
+
if block
|
91
|
+
yield k
|
92
|
+
else
|
93
|
+
k
|
94
|
+
end
|
95
|
+
end
|
96
|
+
]
|
97
|
+
end
|
98
|
+
|
99
|
+
def ksort!(&block)
|
100
|
+
replace ksort &block
|
101
|
+
end
|
102
|
+
|
103
|
+
|
104
|
+
def vsort(&block)
|
105
|
+
Hash[
|
106
|
+
sort_by do |k, v|
|
107
|
+
if block
|
108
|
+
yield v
|
109
|
+
else
|
110
|
+
v
|
111
|
+
end
|
112
|
+
end
|
113
|
+
]
|
114
|
+
end
|
115
|
+
|
116
|
+
def vsort!(&block)
|
117
|
+
replace vsort &block
|
118
|
+
end
|
119
|
+
|
120
|
+
|
121
|
+
# set like operator
|
122
|
+
def -(other)
|
123
|
+
raise TypeError unless other.class <= Hash
|
124
|
+
select {|k,v| !other.has_key? k}
|
125
|
+
end
|
126
|
+
|
127
|
+
|
128
|
+
private
|
129
|
+
|
130
|
+
# replace contents of hash with new stuff
|
131
|
+
def replace(hash)
|
132
|
+
clear
|
133
|
+
merge! hash
|
134
|
+
end
|
135
|
+
|
136
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
class IPAddr
|
2
|
+
class << self
|
3
|
+
# eg. 8.8.8 => 8.8.8.0/24
|
4
|
+
def new(addr = '::', family = Socket::AF_UNSPEC)
|
5
|
+
# already an IPAddr, so simply return a clone
|
6
|
+
return addr.clone if addr.is_a? IPAddr
|
7
|
+
|
8
|
+
addr ||= '::'
|
9
|
+
if addr == '::'
|
10
|
+
family = Socket::AF_INET6
|
11
|
+
elsif !addr.inspect.include? '/'
|
12
|
+
addr = addr.to_s
|
13
|
+
count = addr.split('.').count
|
14
|
+
if (1..3).include? count
|
15
|
+
# given a shortened addr...kindly reformat
|
16
|
+
addr = case count
|
17
|
+
when 3
|
18
|
+
addr + '.0/24'
|
19
|
+
when 2
|
20
|
+
addr + '.0.0/16'
|
21
|
+
when 1
|
22
|
+
addr + '.0.0.0/8'
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
super addr, family
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
|
32
|
+
# eg. 8.8.8.8/24 => 8.8.8
|
33
|
+
def short(size = nil)
|
34
|
+
if ipv4?
|
35
|
+
unless size
|
36
|
+
mask = inspect.split('/')[1].chomp('>')
|
37
|
+
size = 8 * mask.split('.').select {|x| x == '255'}.count
|
38
|
+
end
|
39
|
+
|
40
|
+
case size
|
41
|
+
when 32
|
42
|
+
to_s
|
43
|
+
when 24
|
44
|
+
to_s.split('.').first(3).join('.')
|
45
|
+
when 16
|
46
|
+
to_s.split('.').first(2).join('.')
|
47
|
+
when 8
|
48
|
+
to_s.split('.').first
|
49
|
+
else
|
50
|
+
to_s
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
if defined? Mongoid
|
2
|
+
|
3
|
+
module Mongoid::Document
|
4
|
+
alias :as_doc :as_document
|
5
|
+
end
|
6
|
+
|
7
|
+
class Mongoid::Criteria
|
8
|
+
def as_doc
|
9
|
+
to_a.map &:as_doc
|
10
|
+
end
|
11
|
+
alias_method :as_docs, :as_doc
|
12
|
+
|
13
|
+
# can't seem to override Mongoid::Document::last, so put this
|
14
|
+
# functionality here
|
15
|
+
def last(n = 1)
|
16
|
+
order(_id: -1).limit(n)
|
17
|
+
end
|
18
|
+
|
19
|
+
# see http://apidock.com/rails/ActiveRecord/Batches/find_in_batches
|
20
|
+
def find_in_batches(opts = {}, &block)
|
21
|
+
batch_size = opts[:batch_size] || 1000
|
22
|
+
offset = opts[:start] || 0
|
23
|
+
|
24
|
+
loop do
|
25
|
+
docs = skip(offset).limit(batch_size).to_a
|
26
|
+
|
27
|
+
if docs.empty?
|
28
|
+
break
|
29
|
+
else
|
30
|
+
yield docs
|
31
|
+
offset += batch_size
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
end
|
data/lib/theusual/ssh.rb
ADDED
@@ -0,0 +1,53 @@
|
|
1
|
+
# Most of this code was copied from:
|
2
|
+
# http://www.rubydoc.info/github/net-ssh/net-ssh/Net/SSH/Connection/Session
|
3
|
+
|
4
|
+
if defined? Net::SSH
|
5
|
+
|
6
|
+
class Net::SSH::Connection::Session
|
7
|
+
|
8
|
+
# use a psuedo TTY so we can run sudo commands on more secured cloud instances
|
9
|
+
def suexec(command, &block)
|
10
|
+
open_channel do |channel|
|
11
|
+
channel.request_pty
|
12
|
+
|
13
|
+
# add sudo prefix if need be
|
14
|
+
command = "sudo #{command}" unless /^sudo /.match command
|
15
|
+
|
16
|
+
channel.exec(command) do |ch, success|
|
17
|
+
raise "could not execute command: #{command.inspect}" unless success
|
18
|
+
|
19
|
+
channel.on_data do |ch2, data|
|
20
|
+
if block
|
21
|
+
block.call(ch2, :stdout, data)
|
22
|
+
else
|
23
|
+
$stdout.print(data)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
channel.on_extended_data do |ch2, type, data|
|
28
|
+
if block
|
29
|
+
block.call(ch2, :stderr, data)
|
30
|
+
else
|
31
|
+
$stderr.print(data)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
|
39
|
+
def suexec!(command, &block)
|
40
|
+
block ||= Proc.new do |ch, type, data|
|
41
|
+
ch[:result] ||= ""
|
42
|
+
ch[:result] << data
|
43
|
+
end
|
44
|
+
|
45
|
+
channel = suexec(command, &block)
|
46
|
+
channel.wait
|
47
|
+
|
48
|
+
return channel[:result]
|
49
|
+
end
|
50
|
+
|
51
|
+
end
|
52
|
+
|
53
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
class Time
|
2
|
+
def humanize
|
3
|
+
a = (Time.now.utc - self.utc).to_i
|
4
|
+
|
5
|
+
case a
|
6
|
+
when 0 then 'just now'
|
7
|
+
when 1 then 'a second ago'
|
8
|
+
when 2..59 then a.to_s + ' seconds ago'
|
9
|
+
when 60..119 then 'a minute ago' #120 = 2 minutes
|
10
|
+
when 120..3540 then (a / 60).to_i.to_s + ' minutes ago'
|
11
|
+
when 3541..7100 then 'an hour ago' # 3600 = 1 hour
|
12
|
+
when 7101..82800 then ((a + 99) / 3600).to_i.to_s + ' hours ago'
|
13
|
+
when 82801..172000 then 'a day ago' # 86400 = 1 day
|
14
|
+
when 172001..518400 then ((a + 800) / (60 * 60 * 24)).to_i.to_s + ' days ago'
|
15
|
+
when 518400..1036800 then 'a week ago'
|
16
|
+
else ((a+180000)/(60*60*24*7)).to_i.to_s + ' weeks ago'
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
data/test/test_array.rb
ADDED
@@ -0,0 +1,121 @@
|
|
1
|
+
require 'minitest/autorun'
|
2
|
+
require 'theusual'
|
3
|
+
TheUsual::load 'array'
|
4
|
+
|
5
|
+
|
6
|
+
class ArrayTest < Minitest::Test
|
7
|
+
|
8
|
+
def test_sum
|
9
|
+
assert_equal(
|
10
|
+
6,
|
11
|
+
[1,2,3].sum
|
12
|
+
)
|
13
|
+
end
|
14
|
+
|
15
|
+
def test_avg
|
16
|
+
assert_equal(
|
17
|
+
2,
|
18
|
+
[1,2,3].avg
|
19
|
+
)
|
20
|
+
|
21
|
+
assert_equal(
|
22
|
+
2.5,
|
23
|
+
[1,2,3,4].avg
|
24
|
+
)
|
25
|
+
end
|
26
|
+
|
27
|
+
def test_std
|
28
|
+
# TODO
|
29
|
+
end
|
30
|
+
|
31
|
+
def test_grepv
|
32
|
+
data = ['a', 'ab', 'bab', 'bbb', 'ccc'].sort
|
33
|
+
|
34
|
+
assert_equal(
|
35
|
+
['a', 'ab', 'bab'].sort,
|
36
|
+
data.grep(/a/).sort
|
37
|
+
)
|
38
|
+
|
39
|
+
assert_equal(
|
40
|
+
['bbb', 'ccc'],
|
41
|
+
data.grepv(/a/).sort
|
42
|
+
)
|
43
|
+
end
|
44
|
+
|
45
|
+
def test_gsub
|
46
|
+
assert_equal(
|
47
|
+
['a_a', '_a_'],
|
48
|
+
['aba', 'bab'].gsub(/b/, '_')
|
49
|
+
)
|
50
|
+
|
51
|
+
assert_equal(
|
52
|
+
['a__A'],
|
53
|
+
['abBA'].gsub(/b/i, '_')
|
54
|
+
)
|
55
|
+
|
56
|
+
res = ['aba']
|
57
|
+
assert_equal(
|
58
|
+
['a_a'],
|
59
|
+
res.gsub!(/b/, '_')
|
60
|
+
)
|
61
|
+
assert_equal(
|
62
|
+
['a_a'],
|
63
|
+
res
|
64
|
+
)
|
65
|
+
end
|
66
|
+
|
67
|
+
def test_compact
|
68
|
+
assert_equal(
|
69
|
+
[0, true, 'hi'],
|
70
|
+
[0, true, 'hi'].compact
|
71
|
+
)
|
72
|
+
|
73
|
+
assert_equal(
|
74
|
+
[0, ''],
|
75
|
+
[nil, 0, false, ''].compact
|
76
|
+
)
|
77
|
+
|
78
|
+
assert_equal(
|
79
|
+
[0],
|
80
|
+
[nil, 0, false, ''].compact(:blanks)
|
81
|
+
)
|
82
|
+
|
83
|
+
assert_equal(
|
84
|
+
[],
|
85
|
+
[nil, 0, false, ''].compact(:falsy)
|
86
|
+
)
|
87
|
+
|
88
|
+
assert_equal(
|
89
|
+
[1, 'a'],
|
90
|
+
[nil, 0, false, '', 1, 'a'].compact(:falsy)
|
91
|
+
)
|
92
|
+
|
93
|
+
data = [nil, 0, false, '', 1, 'a']
|
94
|
+
assert_equal(
|
95
|
+
[1, 'a'],
|
96
|
+
data.compact!(:falsy)
|
97
|
+
)
|
98
|
+
assert_equal(
|
99
|
+
[1, 'a'],
|
100
|
+
data.compact!(:falsy)
|
101
|
+
)
|
102
|
+
end
|
103
|
+
|
104
|
+
end
|
105
|
+
|
106
|
+
|
107
|
+
|
108
|
+
|
109
|
+
|
110
|
+
|
111
|
+
|
112
|
+
|
113
|
+
|
114
|
+
|
115
|
+
|
116
|
+
|
117
|
+
|
118
|
+
|
119
|
+
|
120
|
+
|
121
|
+
|
data/test/test_hash.rb
ADDED
@@ -0,0 +1,350 @@
|
|
1
|
+
require 'minitest/autorun'
|
2
|
+
require 'theusual'
|
3
|
+
TheUsual::load 'hash'
|
4
|
+
|
5
|
+
|
6
|
+
class HashTest < Minitest::Test
|
7
|
+
|
8
|
+
def test_Hash
|
9
|
+
data = {
|
10
|
+
c: 2,
|
11
|
+
b: 3,
|
12
|
+
a: 1,
|
13
|
+
}
|
14
|
+
|
15
|
+
assert_equal(
|
16
|
+
data,
|
17
|
+
Hash.map(data.keys) {|x| [x, data[x]]}
|
18
|
+
)
|
19
|
+
|
20
|
+
assert_equal(
|
21
|
+
{},
|
22
|
+
Hash.map([]) {|x| nil}
|
23
|
+
)
|
24
|
+
|
25
|
+
assert_equal(
|
26
|
+
{},
|
27
|
+
Hash.map([1,2,3]) {|x| nil}
|
28
|
+
)
|
29
|
+
|
30
|
+
assert_equal(
|
31
|
+
{nil => 3},
|
32
|
+
Hash.map([1,2,3]) {|x| [nil, x]}
|
33
|
+
)
|
34
|
+
end
|
35
|
+
|
36
|
+
|
37
|
+
def test_select_keys
|
38
|
+
data = {
|
39
|
+
c: 2,
|
40
|
+
b: 3,
|
41
|
+
a: 1,
|
42
|
+
}
|
43
|
+
|
44
|
+
assert_equal(
|
45
|
+
{c: 2, a: 1},
|
46
|
+
data.select_keys(:c, :a)
|
47
|
+
)
|
48
|
+
|
49
|
+
assert_equal(
|
50
|
+
{c: 2, a: 1},
|
51
|
+
data.select_keys([:c, :a])
|
52
|
+
)
|
53
|
+
|
54
|
+
assert_equal(
|
55
|
+
{c: 2, z: nil},
|
56
|
+
data.select_keys(:c, :z)
|
57
|
+
)
|
58
|
+
|
59
|
+
|
60
|
+
assert_equal(
|
61
|
+
{c: 2, a: 1},
|
62
|
+
data.select_keys!(:c, :a)
|
63
|
+
)
|
64
|
+
assert_equal(
|
65
|
+
{c: 2, a: 1},
|
66
|
+
data
|
67
|
+
)
|
68
|
+
end
|
69
|
+
|
70
|
+
|
71
|
+
def test_compact
|
72
|
+
data = {
|
73
|
+
a: nil,
|
74
|
+
b: 'b',
|
75
|
+
c: false,
|
76
|
+
d: '',
|
77
|
+
e: 0,
|
78
|
+
}
|
79
|
+
|
80
|
+
assert_equal(
|
81
|
+
{
|
82
|
+
b: 'b',
|
83
|
+
d: '',
|
84
|
+
e: 0,
|
85
|
+
},
|
86
|
+
data.compact
|
87
|
+
)
|
88
|
+
|
89
|
+
assert_equal(
|
90
|
+
{
|
91
|
+
b: 'b',
|
92
|
+
e: 0,
|
93
|
+
},
|
94
|
+
data.compact(:blanks)
|
95
|
+
)
|
96
|
+
|
97
|
+
assert_equal(
|
98
|
+
{b: 'b'},
|
99
|
+
data.compact(:falsy)
|
100
|
+
)
|
101
|
+
|
102
|
+
assert_equal(
|
103
|
+
{b: 'b'},
|
104
|
+
data.compact!(:falsy)
|
105
|
+
)
|
106
|
+
assert_equal(
|
107
|
+
{b: 'b'},
|
108
|
+
data
|
109
|
+
)
|
110
|
+
end
|
111
|
+
|
112
|
+
|
113
|
+
def test_hmap
|
114
|
+
data = {
|
115
|
+
c: 2,
|
116
|
+
b: 3,
|
117
|
+
a: 1,
|
118
|
+
}
|
119
|
+
|
120
|
+
assert_equal(
|
121
|
+
{
|
122
|
+
c: 4,
|
123
|
+
b: 6,
|
124
|
+
a: 2,
|
125
|
+
},
|
126
|
+
data.hmap {|k,v| [k, v * 2]}
|
127
|
+
)
|
128
|
+
|
129
|
+
assert_equal(
|
130
|
+
{
|
131
|
+
cc: 4,
|
132
|
+
bb: 6,
|
133
|
+
aa: 2,
|
134
|
+
},
|
135
|
+
data.hmap {|k,v| [(k.to_s * 2).to_sym, v * 2]}
|
136
|
+
)
|
137
|
+
|
138
|
+
assert_equal(
|
139
|
+
{},
|
140
|
+
{}.hmap {|k,v| [k, v * 2]}
|
141
|
+
)
|
142
|
+
|
143
|
+
assert_equal(
|
144
|
+
{},
|
145
|
+
{a: 1}.hmap {|k,v| nil}
|
146
|
+
)
|
147
|
+
|
148
|
+
|
149
|
+
assert_equal(
|
150
|
+
{
|
151
|
+
c: 4,
|
152
|
+
b: 6,
|
153
|
+
a: 2,
|
154
|
+
},
|
155
|
+
data.hmap! {|k,v| [k, v * 2]}
|
156
|
+
)
|
157
|
+
assert_equal(
|
158
|
+
{
|
159
|
+
c: 4,
|
160
|
+
b: 6,
|
161
|
+
a: 2,
|
162
|
+
},
|
163
|
+
data
|
164
|
+
)
|
165
|
+
end
|
166
|
+
|
167
|
+
|
168
|
+
def test_kmap
|
169
|
+
data = {
|
170
|
+
'a' => 1,
|
171
|
+
'b' => 2,
|
172
|
+
'c' => 3,
|
173
|
+
}
|
174
|
+
|
175
|
+
assert_equal(
|
176
|
+
{
|
177
|
+
'aa' => 1,
|
178
|
+
'bb' => 2,
|
179
|
+
'cc' => 3,
|
180
|
+
},
|
181
|
+
data.kmap {|k| k * 2}
|
182
|
+
)
|
183
|
+
|
184
|
+
assert_equal(
|
185
|
+
{
|
186
|
+
'aa' => 1,
|
187
|
+
'bb' => 2,
|
188
|
+
'cc' => 3,
|
189
|
+
},
|
190
|
+
data.kmap {|k,v| k * 2}
|
191
|
+
)
|
192
|
+
|
193
|
+
assert_equal(
|
194
|
+
{
|
195
|
+
'aa' => 1,
|
196
|
+
'bb' => 2,
|
197
|
+
'cc' => 3,
|
198
|
+
},
|
199
|
+
data.kmap! {|k,v| k * 2}
|
200
|
+
)
|
201
|
+
assert_equal(
|
202
|
+
{
|
203
|
+
'aa' => 1,
|
204
|
+
'bb' => 2,
|
205
|
+
'cc' => 3,
|
206
|
+
},
|
207
|
+
data
|
208
|
+
)
|
209
|
+
end
|
210
|
+
|
211
|
+
|
212
|
+
def test_vmap
|
213
|
+
data = {
|
214
|
+
a: 1,
|
215
|
+
b: 2,
|
216
|
+
c: 3,
|
217
|
+
}
|
218
|
+
|
219
|
+
assert_equal(
|
220
|
+
{
|
221
|
+
a: 2,
|
222
|
+
b: 4,
|
223
|
+
c: 6,
|
224
|
+
},
|
225
|
+
data.vmap {|v| v * 2}
|
226
|
+
)
|
227
|
+
|
228
|
+
assert_equal(
|
229
|
+
{
|
230
|
+
a: 2,
|
231
|
+
b: 4,
|
232
|
+
c: 6,
|
233
|
+
},
|
234
|
+
data.vmap {|k,v| v * 2}
|
235
|
+
)
|
236
|
+
|
237
|
+
assert_equal(
|
238
|
+
{
|
239
|
+
a: :a,
|
240
|
+
b: :b,
|
241
|
+
c: :c,
|
242
|
+
},
|
243
|
+
data.vmap {|k,v| k}
|
244
|
+
)
|
245
|
+
|
246
|
+
|
247
|
+
assert_equal(
|
248
|
+
{
|
249
|
+
a: 2,
|
250
|
+
b: 4,
|
251
|
+
c: 6,
|
252
|
+
},
|
253
|
+
data.vmap! {|v| v * 2}
|
254
|
+
)
|
255
|
+
assert_equal(
|
256
|
+
{
|
257
|
+
a: 2,
|
258
|
+
b: 4,
|
259
|
+
c: 6,
|
260
|
+
},
|
261
|
+
data
|
262
|
+
)
|
263
|
+
end
|
264
|
+
|
265
|
+
|
266
|
+
def test_ksort
|
267
|
+
data = {
|
268
|
+
cx: 2,
|
269
|
+
by: 3,
|
270
|
+
az: 1,
|
271
|
+
}
|
272
|
+
|
273
|
+
assert_equal(
|
274
|
+
{
|
275
|
+
az: 1,
|
276
|
+
by: 3,
|
277
|
+
cx: 2,
|
278
|
+
}.to_a,
|
279
|
+
data.ksort.to_a
|
280
|
+
)
|
281
|
+
|
282
|
+
assert_equal(
|
283
|
+
{
|
284
|
+
cx: 2,
|
285
|
+
by: 3,
|
286
|
+
az: 1,
|
287
|
+
}.to_a,
|
288
|
+
data.ksort {|k| k.to_s.reverse }.to_a
|
289
|
+
)
|
290
|
+
|
291
|
+
assert_equal(
|
292
|
+
{
|
293
|
+
az: 1,
|
294
|
+
by: 3,
|
295
|
+
cx: 2,
|
296
|
+
},
|
297
|
+
data.ksort!
|
298
|
+
)
|
299
|
+
assert_equal(
|
300
|
+
{
|
301
|
+
az: 1,
|
302
|
+
by: 3,
|
303
|
+
cx: 2,
|
304
|
+
},
|
305
|
+
data
|
306
|
+
)
|
307
|
+
end
|
308
|
+
|
309
|
+
|
310
|
+
def test_vsort
|
311
|
+
data = {
|
312
|
+
c: 2,
|
313
|
+
b: 3,
|
314
|
+
a: 1,
|
315
|
+
}
|
316
|
+
|
317
|
+
assert_equal(
|
318
|
+
{a: 1, c: 2, b: 3}.to_a,
|
319
|
+
data.vsort.to_a
|
320
|
+
)
|
321
|
+
|
322
|
+
assert_equal(
|
323
|
+
{b: 3, c: 2, a: 1}.to_a,
|
324
|
+
data.vsort {|v| -v}.to_a
|
325
|
+
)
|
326
|
+
|
327
|
+
assert_equal(
|
328
|
+
{a: 1, c: 2, b: 3}.to_a,
|
329
|
+
data.vsort!.to_a
|
330
|
+
)
|
331
|
+
assert_equal(
|
332
|
+
{a: 1, c: 2, b: 3}.to_a,
|
333
|
+
data.to_a
|
334
|
+
)
|
335
|
+
end
|
336
|
+
|
337
|
+
|
338
|
+
def test_diff
|
339
|
+
assert_equal(
|
340
|
+
{a: 1, b: 2, c: 3},
|
341
|
+
{a: 1, b: 2, c: 3} - {}
|
342
|
+
)
|
343
|
+
|
344
|
+
assert_equal(
|
345
|
+
{a: 1, c: 3},
|
346
|
+
{a: 1, b: 2, c: 3} - {b: 1}
|
347
|
+
)
|
348
|
+
end
|
349
|
+
|
350
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
require 'minitest/autorun'
|
2
|
+
require 'theusual'
|
3
|
+
TheUsual::load 'ipaddr'
|
4
|
+
|
5
|
+
|
6
|
+
class IPAddrTest < Minitest::Test
|
7
|
+
|
8
|
+
def test_all
|
9
|
+
assert_equal(
|
10
|
+
'8.8.8.8',
|
11
|
+
IPAddr.new('8.8.8.8').to_s
|
12
|
+
)
|
13
|
+
|
14
|
+
assert_equal(
|
15
|
+
'8.8.8.0',
|
16
|
+
IPAddr.new('8.8.8.0/24').to_s
|
17
|
+
)
|
18
|
+
|
19
|
+
assert_equal(
|
20
|
+
'8.8.8.0',
|
21
|
+
IPAddr.new('8.8.8').to_s
|
22
|
+
)
|
23
|
+
|
24
|
+
assert_equal(
|
25
|
+
'8.8.8',
|
26
|
+
IPAddr.new('8.8.8.0/24').short
|
27
|
+
)
|
28
|
+
|
29
|
+
assert_equal(
|
30
|
+
'8.8.8',
|
31
|
+
IPAddr.new('8.8.8').short
|
32
|
+
)
|
33
|
+
|
34
|
+
assert_equal(
|
35
|
+
'8.8.8.0',
|
36
|
+
IPAddr.new('8.8.8.0').short
|
37
|
+
)
|
38
|
+
|
39
|
+
assert_equal(
|
40
|
+
'8.8',
|
41
|
+
IPAddr.new('8.8.8.8/16').short
|
42
|
+
)
|
43
|
+
|
44
|
+
# make sure this doesn't explode
|
45
|
+
addr = IPAddr.new('8.8.8.8')
|
46
|
+
IPAddr.new addr
|
47
|
+
end
|
48
|
+
|
49
|
+
end
|
data/test/test_time.rb
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
require 'minitest/autorun'
|
2
|
+
require 'theusual'
|
3
|
+
TheUsual::load 'time'
|
4
|
+
|
5
|
+
|
6
|
+
class TimeTest < Minitest::Test
|
7
|
+
|
8
|
+
def test_all
|
9
|
+
assert_equal(
|
10
|
+
'just now',
|
11
|
+
Time.new.humanize
|
12
|
+
)
|
13
|
+
|
14
|
+
assert_equal(
|
15
|
+
'a second ago',
|
16
|
+
(Time.new - 1).humanize
|
17
|
+
)
|
18
|
+
|
19
|
+
assert_equal(
|
20
|
+
'2 seconds ago',
|
21
|
+
(Time.new - 2).humanize
|
22
|
+
)
|
23
|
+
|
24
|
+
assert_equal(
|
25
|
+
'a minute ago',
|
26
|
+
(Time.new - 60).humanize
|
27
|
+
)
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|
metadata
ADDED
@@ -0,0 +1,96 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: theusual
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Daniel Pepper
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2017-01-18 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: rake
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '10'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '10'
|
27
|
+
description: |
|
28
|
+
TheUsual
|
29
|
+
======
|
30
|
+
|
31
|
+
A handful of useful hacks...good for any project
|
32
|
+
|
33
|
+
|
34
|
+
#### Install
|
35
|
+
```gem install theusual```
|
36
|
+
|
37
|
+
|
38
|
+
#### Usage
|
39
|
+
```
|
40
|
+
require 'theusual'
|
41
|
+
TheUsual::load :all
|
42
|
+
|
43
|
+
Hash.map [:a, :b, :c] do |v|
|
44
|
+
[ v, v ]
|
45
|
+
end
|
46
|
+
=> { a: :a, b: :b, c: :c }
|
47
|
+
|
48
|
+
|
49
|
+
[:a, nil, '', :b].compact :blanks
|
50
|
+
=> [ :a, :b ]
|
51
|
+
```
|
52
|
+
email:
|
53
|
+
executables: []
|
54
|
+
extensions: []
|
55
|
+
extra_rdoc_files: []
|
56
|
+
files:
|
57
|
+
- lib/theusual.rb
|
58
|
+
- lib/theusual/array.rb
|
59
|
+
- lib/theusual/hash.rb
|
60
|
+
- lib/theusual/ipaddr.rb
|
61
|
+
- lib/theusual/mongoid.rb
|
62
|
+
- lib/theusual/ssh.rb
|
63
|
+
- lib/theusual/time.rb
|
64
|
+
- test/test_array.rb
|
65
|
+
- test/test_hash.rb
|
66
|
+
- test/test_ip_addr.rb
|
67
|
+
- test/test_time.rb
|
68
|
+
homepage: https://github.com/d1hotpep/theusualrb
|
69
|
+
licenses:
|
70
|
+
- MIT
|
71
|
+
metadata: {}
|
72
|
+
post_install_message:
|
73
|
+
rdoc_options: []
|
74
|
+
require_paths:
|
75
|
+
- lib
|
76
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
77
|
+
requirements:
|
78
|
+
- - ">="
|
79
|
+
- !ruby/object:Gem::Version
|
80
|
+
version: '0'
|
81
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
82
|
+
requirements:
|
83
|
+
- - ">="
|
84
|
+
- !ruby/object:Gem::Version
|
85
|
+
version: '0'
|
86
|
+
requirements: []
|
87
|
+
rubyforge_project:
|
88
|
+
rubygems_version: 2.5.1
|
89
|
+
signing_key:
|
90
|
+
specification_version: 4
|
91
|
+
summary: TheUsual
|
92
|
+
test_files:
|
93
|
+
- test/test_array.rb
|
94
|
+
- test/test_hash.rb
|
95
|
+
- test/test_ip_addr.rb
|
96
|
+
- test/test_time.rb
|