trick_bag 0.55.0 → 0.56.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +8 -0
- data/README.md +2 -1
- data/RELEASE_NOTES.md +5 -0
- data/lib/trick_bag/collections/collection_access.rb +18 -1
- data/lib/trick_bag/numeric/bitmap.rb +204 -0
- data/lib/trick_bag/timing/timing.rb +8 -0
- data/lib/trick_bag/validations/other_validations.rb +5 -0
- data/lib/trick_bag/version.rb +1 -1
- data/spec/trick_bag/collections/collection_access_spec.rb +5 -0
- data/spec/trick_bag/numeric/bitmap_spec.rb +225 -0
- data/spec/trick_bag/timing/timing_spec.rb +9 -2
- data/spec/trick_bag/validations/other_validations_spec.rb +11 -5
- metadata +8 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d4818c34b17f75700285ef836328c5dd0a543862
|
4
|
+
data.tar.gz: 081c5c721ca498f42bcc05031e2f4ddac2d73ac8
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 088282d53b429a5657106ac4e1e94988a47468db31018e812c20479c3545995baa8f474d1d45ceaa1ee018f6af2930d58f215004994cf65a6790900b2a9186e3
|
7
|
+
data.tar.gz: 7487f2e3e6d233af9c420797d092aab6c0a96a0d56b2a7479d70a12f02da0cbf80c3c5045a9e272d7cb2f09f987b66ac88b3720e2a48b2a561ad40bbca8136aa
|
data/.travis.yml
ADDED
data/README.md
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
[![Build Status](https://travis-ci.org/keithrbennett/trick_bag.svg?branch=master)](https://travis-ci.org/keithrbennett/trick_bag)
|
2
|
+
|
1
3
|
# TrickBag
|
2
4
|
|
3
5
|
This gem is a collection of useful classes and modules for Ruby development.
|
@@ -21,7 +23,6 @@ Or install it yourself as:
|
|
21
23
|
|
22
24
|
See the unit tests in the spec directory tree for usage examples.
|
23
25
|
|
24
|
-
TODO: Write usage instructions here
|
25
26
|
|
26
27
|
## Contributing
|
27
28
|
|
data/RELEASE_NOTES.md
CHANGED
@@ -6,6 +6,7 @@ module CollectionAccess
|
|
6
6
|
|
7
7
|
module_function
|
8
8
|
|
9
|
+
|
9
10
|
# Accesses a collection with a single string that represents n levels of depth.
|
10
11
|
# See the spec file for examples, but here's one:
|
11
12
|
#
|
@@ -23,11 +24,27 @@ module CollectionAccess
|
|
23
24
|
# @separator the string to use to separate the
|
24
25
|
def access(collection, key_string, separator = '.')
|
25
26
|
|
27
|
+
is_number_string = ->(s) do
|
28
|
+
begin
|
29
|
+
Integer(s)
|
30
|
+
true
|
31
|
+
rescue
|
32
|
+
false
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
26
36
|
keys = key_string.split(separator)
|
27
37
|
return_object = collection
|
28
38
|
|
29
39
|
keys.each_with_index do |key, index|
|
30
|
-
|
40
|
+
|
41
|
+
if return_object.kind_of?(Array)
|
42
|
+
unless is_number_string.(key)
|
43
|
+
raise "Key is not a number string: #{key}"
|
44
|
+
end
|
45
|
+
key = key.to_i
|
46
|
+
end
|
47
|
+
|
31
48
|
begin
|
32
49
|
return_object = return_object[key]
|
33
50
|
rescue => e
|
@@ -0,0 +1,204 @@
|
|
1
|
+
require 'forwardable'
|
2
|
+
|
3
|
+
module TrickBag
|
4
|
+
module Numeric
|
5
|
+
|
6
|
+
|
7
|
+
# Provides class methods for converting between the various representations
|
8
|
+
# of a bitmap: number, binary encoded string, array, and sparse array.
|
9
|
+
#
|
10
|
+
# An instance can be created that will hold on to bitmap data and be used
|
11
|
+
# to test bits and convert to other formats.
|
12
|
+
class Bitmap
|
13
|
+
|
14
|
+
extend Forwardable
|
15
|
+
|
16
|
+
# This is the internal representation of the bitmap value:
|
17
|
+
attr_reader :number
|
18
|
+
|
19
|
+
[:&, :|, :^, :hash].each do |method_name|
|
20
|
+
def_delegator :@number, method_name
|
21
|
+
end
|
22
|
+
|
23
|
+
def number=(new_number)
|
24
|
+
self.assert_nonnegative(new_number)
|
25
|
+
@number = new_number
|
26
|
+
end
|
27
|
+
|
28
|
+
|
29
|
+
# The constructor is made private because:
|
30
|
+
#
|
31
|
+
# 1) each type of initialization requires its own validation, and it
|
32
|
+
# would be wasteful to do the validation unnecessarily
|
33
|
+
# 2) to enforce that the more descriptively
|
34
|
+
# named class methods should be used to create instances.
|
35
|
+
private_class_method :new
|
36
|
+
|
37
|
+
|
38
|
+
# Class methods for converting between representations:
|
39
|
+
|
40
|
+
# Converts from a binary string to a number, e.g. "\x01\x00" => 256
|
41
|
+
def self.binary_string_to_number(string)
|
42
|
+
string = string.clone.force_encoding(Encoding::ASCII_8BIT)
|
43
|
+
string.bytes.inject(0) do |number, byte|
|
44
|
+
number * 256 + byte.ord
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
|
49
|
+
# Converts a number to a binary encoded string, e.g. 256 => "\x01\x00"
|
50
|
+
def self.number_to_binary_string(number, min_length = 0)
|
51
|
+
assert_nonnegative(number)
|
52
|
+
binary_string = ''.force_encoding(Encoding::ASCII_8BIT)
|
53
|
+
|
54
|
+
while number > 0
|
55
|
+
byte_value = number & 0xFF
|
56
|
+
binary_string << byte_value
|
57
|
+
number >>= 8
|
58
|
+
end
|
59
|
+
|
60
|
+
binary_string.reverse.rjust(min_length, "\x00")
|
61
|
+
end
|
62
|
+
|
63
|
+
|
64
|
+
# Converts a number to an array of place values, e.g. 9 => [8, 0, 0, 1]
|
65
|
+
def self.number_to_value_array(number)
|
66
|
+
assert_nonnegative(number)
|
67
|
+
array = []
|
68
|
+
bit_value = 1
|
69
|
+
while number > 0
|
70
|
+
array << ((number & 1 == 1) ? bit_value : 0)
|
71
|
+
number >>= 1
|
72
|
+
bit_value <<= 1
|
73
|
+
end
|
74
|
+
array.reverse
|
75
|
+
end
|
76
|
+
|
77
|
+
|
78
|
+
# Converts from a value array to a number, e.g. [8, 0, 0, 1] => 9
|
79
|
+
def self.value_array_to_number(value_array)
|
80
|
+
value_array.inject(&:+)
|
81
|
+
end
|
82
|
+
|
83
|
+
|
84
|
+
# Converts a number to an array of bit values, e.g. 9 => [1, 0, 0, 1]
|
85
|
+
def self.number_to_bit_array(number)
|
86
|
+
assert_nonnegative(number)
|
87
|
+
array = []
|
88
|
+
while number > 0
|
89
|
+
array << (number & 1)
|
90
|
+
number >>= 1
|
91
|
+
end
|
92
|
+
array.reverse
|
93
|
+
end
|
94
|
+
|
95
|
+
|
96
|
+
# Converts an array of bit values, e.g. [1, 0, 0, 1], to a number, e.g. 9
|
97
|
+
def self.bit_array_to_number(bit_array)
|
98
|
+
return nil if bit_array.empty?
|
99
|
+
multiplier = 1
|
100
|
+
bit_array.inject(0) do |result, n|
|
101
|
+
result += n * multiplier
|
102
|
+
multiplier *= 2
|
103
|
+
result
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
|
108
|
+
# Converts a number to a sparse array containing bit positions that are set/true/1.
|
109
|
+
# Note that these are bit positions, e.g. 76543210, and not bit column values
|
110
|
+
# such as 128/64/32/16/8/4/2/1.
|
111
|
+
def self.number_to_set_bit_positions_array(number)
|
112
|
+
assert_nonnegative(number)
|
113
|
+
array = []
|
114
|
+
position = 0
|
115
|
+
while number > 0
|
116
|
+
array << position if number & 1 == 1
|
117
|
+
position += 1
|
118
|
+
number >>= 1
|
119
|
+
end
|
120
|
+
array
|
121
|
+
end
|
122
|
+
|
123
|
+
|
124
|
+
# Converts an array of bit position numbers to a numeric value, e.g. [0, 2] => 5
|
125
|
+
def self.set_bit_position_array_to_number(position_array)
|
126
|
+
return nil if position_array.empty?
|
127
|
+
position_array.inject(0) do |result, n|
|
128
|
+
result += 2 ** n
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
132
|
+
|
133
|
+
def self.binary_string_to_bit_value_array(string)
|
134
|
+
number = binary_string_to_number(string)
|
135
|
+
number_to_bit_array(number)
|
136
|
+
end
|
137
|
+
|
138
|
+
# Class methods to create instances from the various representation types
|
139
|
+
# handled in the class methods above:
|
140
|
+
|
141
|
+
def self.from_number(number)
|
142
|
+
new(number)
|
143
|
+
end
|
144
|
+
|
145
|
+
def self.from_binary_string(string)
|
146
|
+
new(binary_string_to_number(string))
|
147
|
+
end
|
148
|
+
|
149
|
+
def self.from_value_array(array)
|
150
|
+
new(value_array_to_number(array))
|
151
|
+
end
|
152
|
+
|
153
|
+
def self.from_bit_array(array)
|
154
|
+
new(bit_array_to_number(array))
|
155
|
+
end
|
156
|
+
|
157
|
+
def self.from_set_bit_position_array(array)
|
158
|
+
new(set_bit_position_array_to_number(array))
|
159
|
+
end
|
160
|
+
|
161
|
+
def self.from_number(number)
|
162
|
+
new(number)
|
163
|
+
end
|
164
|
+
|
165
|
+
|
166
|
+
def self.assert_nonnegative(number)
|
167
|
+
unless number.is_a?(Integer) && number >= 0
|
168
|
+
raise ArgumentError.new(
|
169
|
+
"Parameter must be a nonnegative Integer (Fixnum, Bignum) " +
|
170
|
+
"but is #{number.inspect} (a #{number.class})")
|
171
|
+
end
|
172
|
+
end
|
173
|
+
|
174
|
+
|
175
|
+
def to_binary_string(min_length = 0)
|
176
|
+
self.class.number_to_binary_string(number, min_length)
|
177
|
+
end
|
178
|
+
|
179
|
+
def to_value_array
|
180
|
+
self.class.number_to_value_array(number)
|
181
|
+
end
|
182
|
+
|
183
|
+
def to_bit_array
|
184
|
+
self.class.number_to_bit_array(number)
|
185
|
+
end
|
186
|
+
|
187
|
+
def to_set_bit_position_array
|
188
|
+
self.class.number_to_set_bit_positions_array(number)
|
189
|
+
end
|
190
|
+
|
191
|
+
|
192
|
+
def initialize(number)
|
193
|
+
self.class.assert_nonnegative(number)
|
194
|
+
@number = number
|
195
|
+
end
|
196
|
+
|
197
|
+
def ==(other)
|
198
|
+
other.is_a?(self.class) && other.number == self.number
|
199
|
+
end
|
200
|
+
end
|
201
|
+
end
|
202
|
+
end
|
203
|
+
|
204
|
+
|
@@ -15,8 +15,16 @@ module Timing
|
|
15
15
|
# that returns a truthy value that indicates no further retries are necessary
|
16
16
|
# @param sleep_interval number of seconds (fractions ok) to wait between tries
|
17
17
|
# @param timeout_secs maximum number of seconds (fractions ok) during which to retry
|
18
|
+
# @return true if/when the predicate returns true, false if it times out
|
18
19
|
#
|
19
20
|
# Ex: TrickBag::Timing.retry_until_true_or_timeout(->{false}, 1.0, 5)
|
21
|
+
#
|
22
|
+
# Example Code:
|
23
|
+
#
|
24
|
+
# require 'trick_bag'
|
25
|
+
# predicate = -> { false }
|
26
|
+
# print "Waiting 10 seconds for true to be returned (but it won't):\n"
|
27
|
+
# TrickBag::Timing.retry_until_true_or_timeout(predicate, 1, 10)
|
20
28
|
def retry_until_true_or_timeout(
|
21
29
|
predicate, sleep_interval, timeout_secs, output_stream = $stdout)
|
22
30
|
|
@@ -30,6 +30,8 @@ module Validations
|
|
30
30
|
end
|
31
31
|
|
32
32
|
|
33
|
+
# Note: This method is not supported in JRuby.
|
34
|
+
#
|
33
35
|
# When a gem project has a .gemspec, this uses bundle exec to verify that requiring
|
34
36
|
# that gem name does not result in an error. (An error would occur, for example,
|
35
37
|
# if a gem required by the project gem is not specified as a dependency in
|
@@ -38,6 +40,9 @@ module Validations
|
|
38
40
|
# @return a hash containing the :exit_status (0 = success), output (stdout + stderr),
|
39
41
|
# and the :process_status (Process::Status object).
|
40
42
|
def test_gem_dependency_specs(gem_name)
|
43
|
+
|
44
|
+
raise "This method not supported in JRuby" if /java/.match(RUBY_PLATFORM)
|
45
|
+
|
41
46
|
command = %Q{bundle exec ruby -e "require '#{gem_name}'"}
|
42
47
|
|
43
48
|
output, process_status = Open3.capture2e(command)
|
data/lib/trick_bag/version.rb
CHANGED
@@ -52,6 +52,11 @@ describe CollectionAccess do
|
|
52
52
|
h = { 'h' => ['a', 'b'] }
|
53
53
|
expect(-> { CollectionAccess.access(h, 'x.1.2') }).to raise_error
|
54
54
|
end
|
55
|
+
|
56
|
+
it 'raises an error when accessing a string that should be a number' do
|
57
|
+
h = { 'x' => ['a', 'b'] }
|
58
|
+
expect(-> { CollectionAccess.access(h, 'x.x') }).to raise_error
|
59
|
+
end
|
55
60
|
end
|
56
61
|
|
57
62
|
|
@@ -0,0 +1,225 @@
|
|
1
|
+
require_relative '../../spec_helper'
|
2
|
+
|
3
|
+
require 'trick_bag/numeric/bitmap'
|
4
|
+
|
5
|
+
module TrickBag
|
6
|
+
module Numeric
|
7
|
+
|
8
|
+
|
9
|
+
describe Bitmap do
|
10
|
+
|
11
|
+
|
12
|
+
specify 'the constructor should not permit being explicitly called outside the class' do
|
13
|
+
expect(-> { Bitmap.new }).to raise_error
|
14
|
+
end
|
15
|
+
|
16
|
+
|
17
|
+
context '.binary_string_to_number' do
|
18
|
+
|
19
|
+
it 'computes byte values correctly' do
|
20
|
+
expect(Bitmap.binary_string_to_number("\xFF")).to eq(255)
|
21
|
+
expect(Bitmap.binary_string_to_number("\x0D")).to eq(13)
|
22
|
+
end
|
23
|
+
|
24
|
+
it 'considers the left-most byte most significant' do
|
25
|
+
expect(Bitmap.binary_string_to_number("\x01\x00")).to eq(256)
|
26
|
+
end
|
27
|
+
|
28
|
+
# Unspecified encoding results in UTF-8 anyway, but this makes it explicit:
|
29
|
+
it 'correctly handles non-ASCII_8BIT strings' do
|
30
|
+
expect(Bitmap.binary_string_to_number("\x01\x00".force_encoding(Encoding::UTF_8))).to eq(256)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
|
36
|
+
context '.number_to_binary_string' do
|
37
|
+
|
38
|
+
specify '256 => "\x01\00"' do
|
39
|
+
expect(Bitmap.number_to_binary_string(256)).to eq("\x01\x00")
|
40
|
+
end
|
41
|
+
|
42
|
+
specify 'a negative number should result in an error' do
|
43
|
+
expect { Bitmap.number_to_binary_string(-1) }.to raise_error(ArgumentError)
|
44
|
+
end
|
45
|
+
|
46
|
+
specify 'when requested, zero padding will left pad with zeros' do
|
47
|
+
expect(Bitmap.number_to_binary_string(256, 8)).to eq("#{"\x00" * 6}\x01\x00")
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
|
52
|
+
context '.number_to_value_array' do
|
53
|
+
|
54
|
+
specify '9 => [8, 0, 0, 1]' do
|
55
|
+
expect(Bitmap.number_to_value_array(9)).to eq([8, 0, 0, 1])
|
56
|
+
end
|
57
|
+
|
58
|
+
specify '256 => [256] + ([0] * 8)' do
|
59
|
+
expect(Bitmap.number_to_value_array(256)).to eq([256] + [0] * 8)
|
60
|
+
end
|
61
|
+
|
62
|
+
specify 'a negative number should result in an error' do
|
63
|
+
expect { Bitmap.number_to_value_array(-1) }.to raise_error(ArgumentError)
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
context '.value_array_to_number' do
|
68
|
+
|
69
|
+
specify '[8, 0, 0, 1] => 9' do
|
70
|
+
expect(Bitmap.value_array_to_number([8, 0, 0, 1])).to eq(9)
|
71
|
+
end
|
72
|
+
|
73
|
+
specify '[] => nil' do
|
74
|
+
expect(Bitmap.value_array_to_number([])).to eq(nil)
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
context '.bit_array_to_number' do
|
79
|
+
|
80
|
+
specify '[1, 0, 0, 1] => 9' do
|
81
|
+
expect(Bitmap.bit_array_to_number([1, 0, 0, 1])).to eq(9)
|
82
|
+
end
|
83
|
+
|
84
|
+
specify '[] => nil' do
|
85
|
+
expect(Bitmap.bit_array_to_number([])).to eq(nil)
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
|
90
|
+
context '.number_to_bit_array' do
|
91
|
+
|
92
|
+
specify '9 => [1, 0, 0, 1]' do
|
93
|
+
expect(Bitmap.number_to_bit_array(9)).to eq([1, 0, 0, 1])
|
94
|
+
end
|
95
|
+
|
96
|
+
specify '256 => [1] + ([0] * 8)' do
|
97
|
+
expect(Bitmap.number_to_bit_array(256)).to eq([1] + [0] * 8)
|
98
|
+
end
|
99
|
+
|
100
|
+
specify 'a negative number should result in an error' do
|
101
|
+
expect { Bitmap.number_to_bit_array(-1) }.to raise_error(ArgumentError)
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
|
106
|
+
context '.binary_string_to_bit_value_array' do
|
107
|
+
it 'computes byte values correctly' do
|
108
|
+
expect(Bitmap.binary_string_to_bit_value_array("\xFF")).to eq([1] * 8)
|
109
|
+
expect(Bitmap.binary_string_to_bit_value_array("\x0D")).to eq([1,1,0,1])
|
110
|
+
end
|
111
|
+
|
112
|
+
it 'considers the left-most byte most significant' do
|
113
|
+
expect(Bitmap.binary_string_to_bit_value_array("\x01\x00")).to eq([1] + [0] * 8)
|
114
|
+
end
|
115
|
+
|
116
|
+
# Unspecified encoding results in UTF-8 anyway, but this makes it explicit:
|
117
|
+
it 'correctly handles non-ASCII_8BIT strings' do
|
118
|
+
expect(Bitmap.binary_string_to_bit_value_array("\x01\x00".force_encoding(Encoding::UTF_8))).to eq([1] + [0] * 8)
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
|
123
|
+
context '.number_to_set_bit_positions_array' do
|
124
|
+
|
125
|
+
specify '9 => [0, 3]' do
|
126
|
+
expect(Bitmap.number_to_set_bit_positions_array(9)).to eq([0, 3])
|
127
|
+
end
|
128
|
+
|
129
|
+
specify 'a negative number should result in an error' do
|
130
|
+
expect { Bitmap.number_to_set_bit_positions_array(-1) }.to raise_error(ArgumentError)
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
134
|
+
|
135
|
+
context '.set_bit_position_array_to_number' do
|
136
|
+
|
137
|
+
specify '[0, 8] => 256' do
|
138
|
+
expect(Bitmap.set_bit_position_array_to_number([0, 8])).to eq(257)
|
139
|
+
end
|
140
|
+
|
141
|
+
specify '[] => nil' do
|
142
|
+
expect(Bitmap.set_bit_position_array_to_number([])).to eq(nil)
|
143
|
+
end
|
144
|
+
end
|
145
|
+
|
146
|
+
|
147
|
+
context 'test factory methods' do
|
148
|
+
|
149
|
+
specify 'from_number' do
|
150
|
+
expect(Bitmap.from_number(256).number).to eq(256)
|
151
|
+
end
|
152
|
+
|
153
|
+
specify 'from_binary_string' do
|
154
|
+
expect(Bitmap.from_binary_string("\x01\x00").number).to eq(256)
|
155
|
+
end
|
156
|
+
|
157
|
+
specify 'from_value_array' do
|
158
|
+
expect(Bitmap.from_value_array([8, 0, 0, 1]).number).to eq(9)
|
159
|
+
end
|
160
|
+
|
161
|
+
specify 'from_bit_array' do
|
162
|
+
expect(Bitmap.from_bit_array([1, 0, 0, 1]).number).to eq(9)
|
163
|
+
end
|
164
|
+
|
165
|
+
specify 'from_set_bit_position_array' do
|
166
|
+
expect(Bitmap.from_set_bit_position_array([0, 3]).number).to eq(9)
|
167
|
+
end
|
168
|
+
end
|
169
|
+
|
170
|
+
context 'test output methods' do
|
171
|
+
|
172
|
+
specify 'to_binary_string' do
|
173
|
+
bitmap = Bitmap.from_number(258)
|
174
|
+
expect(bitmap.to_binary_string).to eq("\x01\x02")
|
175
|
+
end
|
176
|
+
|
177
|
+
specify 'to_value_array' do
|
178
|
+
bitmap = Bitmap.from_number(258)
|
179
|
+
# expect(bitmap.to_value_array).to eq([0, 2, 0, 0, 0, 0, 0, 0, 256])
|
180
|
+
expect(bitmap.to_value_array).to eq([256, 0, 0, 0, 0, 0, 0, 2, 0])
|
181
|
+
end
|
182
|
+
|
183
|
+
specify 'to_bit_array' do
|
184
|
+
bitmap = Bitmap.from_number(258)
|
185
|
+
expect(bitmap.to_bit_array).to eq([1, 0, 0, 0, 0, 0, 0, 1, 0])
|
186
|
+
end
|
187
|
+
|
188
|
+
specify 'to_set_bit_position_array' do
|
189
|
+
bitmap = Bitmap.from_number(258)
|
190
|
+
expect(bitmap.to_set_bit_position_array).to eq([1, 8])
|
191
|
+
end
|
192
|
+
end
|
193
|
+
|
194
|
+
|
195
|
+
context 'binary operators' do
|
196
|
+
specify '3 & 2 => 2' do
|
197
|
+
expect(Bitmap.from_number(3) & 2).to eq(2)
|
198
|
+
end
|
199
|
+
|
200
|
+
specify '3 | 2 => 3' do
|
201
|
+
expect(Bitmap.from_number(3) | 2).to eq(3)
|
202
|
+
end
|
203
|
+
|
204
|
+
specify '3 ^ 2 => 1' do
|
205
|
+
expect(Bitmap.from_number(3) ^ 2).to eq(1)
|
206
|
+
end
|
207
|
+
|
208
|
+
end
|
209
|
+
|
210
|
+
context 'hash, ==' do
|
211
|
+
specify 'instances created with the same value are ==' do
|
212
|
+
expect(Bitmap.from_number(1234)).to eq(Bitmap.from_number(1234))
|
213
|
+
end
|
214
|
+
|
215
|
+
specify 'instances created with different values are !=' do
|
216
|
+
expect(Bitmap.from_number(1234)).to_not eq(Bitmap.from_number(5678))
|
217
|
+
end
|
218
|
+
|
219
|
+
specify 'instances created with the same value have the same hash' do
|
220
|
+
expect(Bitmap.from_number(1234).hash).to eq(Bitmap.from_number(1234).hash)
|
221
|
+
end
|
222
|
+
end
|
223
|
+
end
|
224
|
+
end
|
225
|
+
|
@@ -7,12 +7,19 @@ module TrickBag
|
|
7
7
|
describe Timing do
|
8
8
|
|
9
9
|
context '.retry_until_true_or_timeout' do
|
10
|
-
it 'returns when the predicate returns true' do
|
10
|
+
it 'returns true when the predicate returns true' do
|
11
11
|
count = 0
|
12
12
|
predicate = ->{ count += 1; count == 3 }
|
13
|
-
Timing.retry_until_true_or_timeout(predicate, 0, 1, StringIO.new)
|
13
|
+
return_value = Timing.retry_until_true_or_timeout(predicate, 0, 1, StringIO.new)
|
14
|
+
expect(return_value).to be(true)
|
14
15
|
expect(count).to eq(3)
|
15
16
|
end
|
17
|
+
|
18
|
+
it 'returns false when the predicate fails to return true and a timeout occurs' do
|
19
|
+
predicate = -> { false }
|
20
|
+
return_value = Timing.retry_until_true_or_timeout(predicate, 0, 0.1, StringIO.new)
|
21
|
+
expect(return_value).to be(false)
|
22
|
+
end
|
16
23
|
end
|
17
24
|
|
18
25
|
|
@@ -28,11 +28,17 @@ module TrickBag
|
|
28
28
|
end
|
29
29
|
|
30
30
|
specify 'this gem contains all necessary gem dependency specifications' do
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
31
|
+
|
32
|
+
if /java/.match(RUBY_PLATFORM)
|
33
|
+
STDERR.puts "Running in JRuby; bypassing test of Validations.test_gem_dependency_specs, not supported."
|
34
|
+
expect(-> { test_gem_dependency_specs('trick_bag') }).to raise_error
|
35
|
+
else
|
36
|
+
require 'open3'
|
37
|
+
result = test_gem_dependency_specs('trick_bag')
|
38
|
+
exit_status = result[:exit_status]
|
39
|
+
if exit_status != 0
|
40
|
+
fail "Exit status was #{exit_status}, output was:\n#{output}."
|
41
|
+
end
|
36
42
|
end
|
37
43
|
end
|
38
44
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: trick_bag
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.56.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Keith Bennett
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2015-01-15 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: os
|
@@ -88,6 +88,7 @@ extensions: []
|
|
88
88
|
extra_rdoc_files: []
|
89
89
|
files:
|
90
90
|
- ".gitignore"
|
91
|
+
- ".travis.yml"
|
91
92
|
- Gemfile
|
92
93
|
- Guardfile
|
93
94
|
- LICENSE.txt
|
@@ -109,6 +110,7 @@ files:
|
|
109
110
|
- lib/trick_bag/io/temp_files.rb
|
110
111
|
- lib/trick_bag/io/text_mode_status_updater.rb
|
111
112
|
- lib/trick_bag/meta/classes.rb
|
113
|
+
- lib/trick_bag/numeric/bitmap.rb
|
112
114
|
- lib/trick_bag/numeric/multi_counter.rb
|
113
115
|
- lib/trick_bag/numeric/start_and_max.rb
|
114
116
|
- lib/trick_bag/numeric/totals.rb
|
@@ -136,6 +138,7 @@ files:
|
|
136
138
|
- spec/trick_bag/io/temp_files_spec.rb
|
137
139
|
- spec/trick_bag/io/text_mode_status_updater_spec.rb
|
138
140
|
- spec/trick_bag/meta/classes_spec.rb
|
141
|
+
- spec/trick_bag/numeric/bitmap_spec.rb
|
139
142
|
- spec/trick_bag/numeric/multi_counter_spec.rb
|
140
143
|
- spec/trick_bag/numeric/start_and_max_spec.rb
|
141
144
|
- spec/trick_bag/numeric/totals_spec.rb
|
@@ -167,7 +170,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
167
170
|
version: '0'
|
168
171
|
requirements: []
|
169
172
|
rubyforge_project:
|
170
|
-
rubygems_version: 2.
|
173
|
+
rubygems_version: 2.4.2
|
171
174
|
signing_key:
|
172
175
|
specification_version: 4
|
173
176
|
summary: Miscellaneous general useful tools.
|
@@ -187,6 +190,7 @@ test_files:
|
|
187
190
|
- spec/trick_bag/io/temp_files_spec.rb
|
188
191
|
- spec/trick_bag/io/text_mode_status_updater_spec.rb
|
189
192
|
- spec/trick_bag/meta/classes_spec.rb
|
193
|
+
- spec/trick_bag/numeric/bitmap_spec.rb
|
190
194
|
- spec/trick_bag/numeric/multi_counter_spec.rb
|
191
195
|
- spec/trick_bag/numeric/start_and_max_spec.rb
|
192
196
|
- spec/trick_bag/numeric/totals_spec.rb
|
@@ -197,3 +201,4 @@ test_files:
|
|
197
201
|
- spec/trick_bag/validations/object_validations_spec.rb
|
198
202
|
- spec/trick_bag/validations/other_validations_spec.rb
|
199
203
|
- spec/trick_bag/validations/regex_validations_spec.rb
|
204
|
+
has_rdoc:
|