trick_bag 0.64.3 → 0.65.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 28ae94cfcd0c241ef6cd4d87ecae15af4a9929bf
4
- data.tar.gz: ed2d558acf885889dff1ac5d187ffaaad87dd502
3
+ metadata.gz: 8b34121c64f4b175d63fe000e9580a2eb02941bf
4
+ data.tar.gz: fbd4317c8832954b89d7b55c4cbb3fd3824aaa49
5
5
  SHA512:
6
- metadata.gz: 5cee6f95c71a61a9e4b7fed223afdbea81957a7befca0b4fff3b7ba2d39db48f5c1ce63f91d17bf95124c7756ce5834bb08f42f50a6471244097f3fbb33eebeb
7
- data.tar.gz: 129f258783beb2feec46186284e07a0f1af10181ae538f1b10e5bf3785a924ae40b6130dc298f52debc32776f8d841371046c868b36290c6da1452dd87acf6bb
6
+ metadata.gz: 5a00d89a5c4d466c72221b506ef17f39d10ffe07b156ba03da8978a878b80e5ee7892374ba52303c102e65396629164c616587cd5313a1a427d1ef0211f57403
7
+ data.tar.gz: b1db69949c83dcf4b4ef3c7e69a9fe3a35191ca8d90bb0b6d3868d23aa09baf850aff9e1135c331cc21e343cddab452df1be5a69d6c2cbafe606918f24642f17
@@ -1,5 +1,11 @@
1
1
  language: ruby
2
2
 
3
+
4
+ # This intended to fix bundler bug in Ruby 1.9.3 (see https://github.com/travis-ci/travis-ci/issues/5239)
5
+ before_install:
6
+ - gem install bundler
7
+
8
+
3
9
  rvm:
4
10
  - 2.0.0
5
11
  - 1.9.3
@@ -1,3 +1,13 @@
1
+ ## v0.64.5
2
+
3
+ * Modified .travis.yml. as per suggestion on web to fix bundler problem:
4
+ NoMethodError: undefined method `spec' for nil:NilClass
5
+
6
+ ## v0.64.4
7
+
8
+ * Fix net-ssh version error on Ruby versions < 2. v0.64.2 did not work.
9
+
10
+
1
11
  ## v0.64.3
2
12
 
3
13
  * Fix retry_until_true_or_timeout bug.
@@ -1,7 +1,4 @@
1
1
  # Load all *.rb files in lib/trick_bag and below.
2
- # Use a lambda so that the intermediate variables do not survive this file.
3
- ->() {
4
- start_dir = File.join(File.dirname(__FILE__), 'trick_bag') # the lib directory
5
- file_mask = "#{start_dir}/**/*.rb"
6
- Dir[file_mask].each { |file| require file }
7
- }.()
2
+ start_dir = File.join(File.dirname(__FILE__), 'trick_bag') # the lib directory
3
+ file_mask = "#{start_dir}/**/*.rb"
4
+ Dir[file_mask].each { |file| require file }
@@ -1,9 +1,28 @@
1
- # Supports access to nested hashes with a string instead of multiple []'s.
2
- # Inspired by Josh Szmajda's dot_notation gem at https://github.com/joshsz/dot_notation,
1
+ # Supports access to nested hashes, arrays, etc., with a string instead of multiple []'s.
2
+ # (e.g. 'myhostname.interfaces.0' instead of ['myhostname']['interfaces'][0])
3
+ #
4
+ # Inspired by Josh Szmajda's dot_notation gem at https://github.com/joshsz/dot_notation.
5
+ #
6
+ # The examples below assume a variable 'h' containing { x: [:red, :green, :blue] }
7
+ #
8
+ # 2 approaches are supported:
9
+ #
10
+ # 1) a method named 'access' to which you pass the aggregate object (collection)
11
+ # the keys as a single string or as an array, and, optionally, the separator
12
+ # character (which defaults to '.')
13
+ #
14
+ # 2) a lambda returned by the 'accessor' method that holds on to the collection so that
15
+ # you can call the lambda as if it were the object itself. This lambda calls the
16
+ # aforementioned 'access' method to do the main work.
17
+ #
18
+ # Please see the documentation of the methods below for further information.
19
+
3
20
 
4
21
  module TrickBag
5
22
  module CollectionAccess
6
23
 
24
+ class Error < RuntimeError; end
25
+
7
26
  module_function
8
27
 
9
28
 
@@ -28,7 +47,7 @@ module CollectionAccess
28
47
  begin
29
48
  Integer(object)
30
49
  rescue
31
- raise "Key cannot be converted to an Integer: #{object}"
50
+ raise Error.new("Key cannot be converted to an Integer: #{object}")
32
51
  end
33
52
  end
34
53
 
@@ -39,7 +58,7 @@ module CollectionAccess
39
58
  when String
40
59
  key_string_or_array.split(separator)
41
60
  else
42
- raise "Invalid data type: #{key_string_or_array.class}"
61
+ raise Error.new("Invalid data type: #{key_string_or_array.class}")
43
62
  end
44
63
  end
45
64
 
@@ -53,7 +72,7 @@ module CollectionAccess
53
72
  return_object = return_object[key]
54
73
  rescue => e
55
74
  this_key = keys[0..index].join(separator)
56
- raise "Error occurred processing key [#{this_key}] in [#{key_string_or_array}]: #{e}"
75
+ raise Error.new("Error occurred processing key [#{this_key}] in [#{key_string_or_array}]: #{e}")
57
76
  end
58
77
  end
59
78
  return_object
@@ -93,7 +93,7 @@ class LinkedList
93
93
  def to_a
94
94
  current_node = @first
95
95
  array = []
96
- while current_node != nil
96
+ while current_node
97
97
  array << current_node.value
98
98
  current_node = current_node.next
99
99
  end
@@ -13,7 +13,7 @@ module Enumerables
13
13
  #
14
14
  # Also supported is an optional fetch notification, a method or lambda that will
15
15
  # be called whenever a fetch is done. This can be useful to update counters,
16
- # provide user feedback (e.g. a progress bar)
16
+ # provide user feedback (e.g. a progress bar), etc.
17
17
  #
18
18
  # This is useful, for example, in network requests, when multiple requests can be sent
19
19
  # one immediately after another, and the responses can be collected as a group,
@@ -23,7 +23,7 @@ module Enumerables
23
23
  # to avoid the need to allow the lambda to modify the data array reference,
24
24
  # needlessly copying arrays,
25
25
  # and to eliminate the need for garbage collecting many array objects
26
- # (though the latter is not that important).
26
+ # (though the latter is rarely important).
27
27
  class BufferedEnumerable
28
28
 
29
29
  include Enumerable
@@ -52,12 +52,12 @@ class CompoundEnumerable
52
52
  def initialize(mode, keys, *enumerables)
53
53
 
54
54
  validate_inputs = ->do
55
- raise "Mode must be either :yields_arrays or :yields_hashes" unless [:yields_arrays, :yields_hashes].include?(mode)
56
- raise "Keys not provided" if mode == :yields_hashes && (! keys.is_a?(Array))
57
- raise "No enumerables provided" if enumerables.empty?
55
+ raise ArgumentError.new("Mode must be either :yields_arrays or :yields_hashes") unless [:yields_arrays, :yields_hashes].include?(mode)
56
+ raise ArgumentError.new("Keys not provided") if mode == :yields_hashes && (! keys.is_a?(Array))
57
+ raise ArgumentError.new("No enumerables provided") if enumerables.empty?
58
58
 
59
59
  if mode == :yields_hashes && (keys.size != enumerables.size)
60
- raise "Key array size (#{keys.size}) is different from enumerables size (#{enumerables.size})."
60
+ raise ArgumentError.new("Key array size (#{keys.size}) is different from enumerables size (#{enumerables.size}).")
61
61
  end
62
62
 
63
63
  end
@@ -106,6 +106,7 @@ class CompoundEnumerable
106
106
  new_values
107
107
  end
108
108
 
109
+ # TODO: Move conditional behavior outside of loop.
109
110
  enumerable.each do |thing|
110
111
  mode == :yields_arrays ? as_array.(thing) : as_hash.(thing)
111
112
  end
@@ -16,6 +16,10 @@ module Formatters
16
16
  # duration_to_s(1000.234567) => "16 m, 40.23456699999997 s"
17
17
  def duration_to_s(seconds)
18
18
 
19
+ unless seconds.is_a?(::Numeric)
20
+ raise ArgumentError.new("#{seconds} must be a number but is a #{seconds.class}.")
21
+ end
22
+
19
23
  seconds_in_minute = 60
20
24
  seconds_in_hour = 60 * seconds_in_minute
21
25
  seconds_in_day = 24 *seconds_in_hour
@@ -56,7 +60,7 @@ module Formatters
56
60
  # This is to disable the Diffy warning message "No newline at end of file"
57
61
  def end_with_nl(object)
58
62
  string = object.to_s
59
- needs_modifying = string && string.size > 0 && string[-1] != "\n"
63
+ needs_modifying = string.size > 0 && string[-1] != "\n"
60
64
  needs_modifying ? "#{string}\n" : string
61
65
  end
62
66
 
@@ -107,7 +111,8 @@ module Formatters
107
111
  }
108
112
 
109
113
  unless strategies.keys.include?(strategy)
110
- raise "Unsupported strategy: #{strategy}. Must be one of [#{strategies.keys.sort.join(', ')}]."
114
+ message = "Unsupported strategy: #{strategy}. Must be one of [#{strategies.keys.sort.join(', ')}]."
115
+ raise ArgumentError.new(message)
111
116
  end
112
117
 
113
118
  strategies[strategy].()
@@ -27,7 +27,9 @@ class TextModeStatusUpdater
27
27
  # Since this method uses ASCII escape sequences that would look messy in a file,
28
28
  # this method will silently return if the output stream is not a TTY, unless
29
29
  # @force_output_non_tty has been set to true.
30
- def print
30
+ #
31
+ # @param args Optional arguments to be passed to the text generator
32
+ def print(*args)
31
33
 
32
34
  # If output is being redirected, don't print anything; it will look like garbage;
33
35
  # But if output was forced (e.g. to write to a string), then allow it.
@@ -38,7 +40,7 @@ class TextModeStatusUpdater
38
40
  else
39
41
  @outstream.print(move_cursor_left_text(@prev_text_length))
40
42
  end
41
- text = @text_generator.().to_s
43
+ text = @text_generator.(*args).to_s
42
44
  @prev_text_length = text.length
43
45
  @outstream.print(clear_to_end_of_line_text + text)
44
46
  end
@@ -7,8 +7,9 @@ module Operators
7
7
  #
8
8
  # Ex: multi_eq(1, 1, 1, 2) => false; multi_eq(1, 1, 1, 1) => true
9
9
  def multi_eq(*values)
10
- values = values.first if values.is_a?(Array) && values.size == 1
11
- raise "Must be called with at least 2 parameters" if values.size < 2
10
+ # If there is only 1 arg, it must be an array of at least 2 elements.
11
+ values = values.first if values.first.is_a?(Array) && values.size == 1
12
+ raise ArgumentError.new("Must be called with at least 2 parameters; was: #{values.inspect}") if values.size < 2
12
13
  values[1..-1].all? { |value| value == values.first }
13
14
  end
14
15
  end
@@ -21,7 +21,7 @@ module System
21
21
  def command_available?(command)
22
22
  raise "Cannot be called on a non-Posix operating system." unless OS.posix?
23
23
  system("which #{command} > /dev/null")
24
- end
24
+ end
25
25
 
26
26
  end
27
27
  end
@@ -3,6 +3,8 @@ module Validations
3
3
 
4
4
  module_function
5
5
 
6
+ class ObjectValidationError < RuntimeError; end
7
+
6
8
 
7
9
  # Returns an array containing each symbol in vars for which the
8
10
  # corresponding instance variable in the specified object is nil.
@@ -17,7 +19,7 @@ module Validations
17
19
  def raise_on_nil_instance_vars(object, vars)
18
20
  nil_vars = nil_instance_vars(object, vars)
19
21
  unless nil_vars.empty?
20
- raise "The following instance variables were nil: #{nil_vars.join(', ')}."
22
+ raise ObjectValidationError.new("The following instance variables were nil: #{nil_vars.join(', ')}.")
21
23
  end
22
24
  end
23
25
  end
@@ -1,6 +1,8 @@
1
1
  module TrickBag
2
2
  module Validations
3
3
 
4
+ class InvalidValueError < RuntimeError; end
5
+
4
6
  module_function
5
7
 
6
8
  # Used to succinctly (for the caller) check to see that a value provided by the caller
@@ -25,7 +27,7 @@ module Validations
25
27
  if missing
26
28
  values_display_array = output_with_inspect ? valid_values.map(&:inspect) : valid_values.map(&:to_s)
27
29
  message = "Invalid #{label} '#{value}'; must be one of: [#{values_display_array.join(', ')}]."
28
- raise message
30
+ raise InvalidValueError.new(message)
29
31
  end
30
32
  end
31
33
 
@@ -1,3 +1,3 @@
1
1
  module TrickBag
2
- VERSION = '0.64.3'
2
+ VERSION = '0.65.0'
3
3
  end
@@ -55,14 +55,14 @@ describe CollectionAccess do
55
55
 
56
56
  it 'raises an error when accessing an invalid key' do
57
57
  h = { 'h' => ['a', 'b'] }
58
- expect(-> { CollectionAccess.access(h, 'x.1.2') }).to raise_error
59
- expect(-> { CollectionAccess.access(h, [x, 1, 2]) }).to raise_error
58
+ expect(-> { CollectionAccess.access(h, 'x.1.2') }).to raise_error(Error)
59
+ expect(-> { CollectionAccess.access(h, ['x', 1, 2]) }).to raise_error(Error)
60
60
  end
61
61
 
62
62
  it 'raises an error when accessing a string that should be a number' do
63
63
  h = { 'x' => ['a', 'b'] }
64
- expect(-> { CollectionAccess.access(h, 'x.x') }).to raise_error
65
- expect(-> { CollectionAccess.access(h, [x, x]) }).to raise_error
64
+ expect(-> { CollectionAccess.access(h, 'x.x') }).to raise_error(Error)
65
+ expect(-> { CollectionAccess.access(h, ['x', 'x']) }).to raise_error(Error)
66
66
  end
67
67
  end
68
68
 
@@ -9,17 +9,17 @@ module Enumerables
9
9
  context 'input validations' do
10
10
 
11
11
  specify 'an initialization error will be raised if no enumerables are specified' do
12
- expect(->{ CompoundEnumerable.array_enumerable() }).to raise_error
13
- expect(->{ CompoundEnumerable.hash_enumerable([:key]) }).to raise_error
12
+ expect(->{ CompoundEnumerable.array_enumerable() }).to raise_error(ArgumentError)
13
+ expect(->{ CompoundEnumerable.hash_enumerable([:key]) }).to raise_error(ArgumentError)
14
14
  end
15
15
 
16
16
  specify 'an initialization error will be raised if mode is not :yields_arrays or :yields_hashes' do
17
- expect(->{ CompoundEnumerable.new(:bad_mode, [], [])}).to raise_error
17
+ expect(->{ CompoundEnumerable.new(:bad_mode, [], [])}).to raise_error(ArgumentError)
18
18
  end
19
19
 
20
20
  specify 'an initialization error will be raised if key array size != enumerables size in :yields_hashes mode' do
21
- expect(->{ CompoundEnumerable.new(:yields_hashes, [:key1, :key2], [])}).to raise_error
22
- expect(->{ CompoundEnumerable.hash_enumerable([:key1, :key2], [])}).to raise_error
21
+ expect(->{ CompoundEnumerable.new(:yields_hashes, [:key1, :key2], [])}).to raise_error(ArgumentError)
22
+ expect(->{ CompoundEnumerable.hash_enumerable([:key1, :key2], [])}).to raise_error(ArgumentError)
23
23
  end
24
24
  end
25
25
 
@@ -7,7 +7,7 @@ module Enumerables
7
7
  describe FilteredEnumerable do
8
8
 
9
9
  let (:even_filter) { ->(n) { n.even? } }
10
- specify 'with no filter it behaves as a regular enumberable' do
10
+ specify 'with no filter it behaves as a regular enumerable' do
11
11
  e = FilteredEnumerable.new([1,2,3])
12
12
  expect(e.to_a).to eq([1, 2, 3])
13
13
  end
@@ -35,6 +35,17 @@ module Enumerables
35
35
  expect(FilteredEnumerable.new([]).each).to be_a(Enumerator)
36
36
  end
37
37
 
38
+ specify 'multiple enumerators on the same collection work correctly' do
39
+ array = (1..7).to_a
40
+
41
+ is_even_enumerable = FilteredEnumerable.new(array, ->(x) { x.even? })
42
+ is_odd_enumerable = FilteredEnumerable.new(array, ->(x) { x.odd? })
43
+ is_multiple_of_3_enumerable = FilteredEnumerable.new(array, ->(x) { x % 3 == 0 })
44
+
45
+ expect(is_even_enumerable.to_a).to eq([2, 4, 6])
46
+ expect(is_odd_enumerable.to_a).to eq([1, 3, 5, 7])
47
+ expect(is_multiple_of_3_enumerable.to_a).to eq([3, 6])
48
+ end
38
49
  end
39
50
  end
40
51
  end
@@ -10,7 +10,7 @@ describe Formatters do
10
10
  context ".duration_to_s" do
11
11
 
12
12
  specify "it will not permit a non-number" do
13
- expect(->() { Formatters.duration_to_s([])}).to raise_error
13
+ expect(->() { Formatters.duration_to_s([])}).to raise_error(ArgumentError)
14
14
  end
15
15
 
16
16
  expect_output_for_input = ->(expected_output, input) do
@@ -54,6 +54,10 @@ describe Formatters do
54
54
  expect(Formatters.end_with_nl(nil)).to eq('')
55
55
  end
56
56
 
57
+ specify 'it returns false\n for false' do
58
+ expect(Formatters.end_with_nl(false)).to eq("false\n")
59
+ end
60
+
57
61
  specify "it converts a number and then adds a new line" do
58
62
  expect(Formatters.end_with_nl(3)).to eq("3\n")
59
63
  end
@@ -88,7 +92,7 @@ describe Formatters do
88
92
  end
89
93
 
90
94
  specify "a bad strategy will result in a raised error" do
91
- expect(->() { Formatters.dos2unix('', :not_a_strategy) }).to raise_error
95
+ expect(->() { Formatters.dos2unix('', :not_a_strategy) }).to raise_error(ArgumentError)
92
96
  end
93
97
  end
94
98
 
@@ -33,11 +33,11 @@ end
33
33
  it 'should remove the class' do
34
34
  fn = -> do
35
35
  class ClassPatchTestClass; end
36
- ClassPatchTestClass.new # to illustrate that it's available
36
+ expect(ClassPatchTestClass.new.class).to eq(ClassPatchTestClass) # to illustrate that it's available
37
37
  Classes.undef_class('ClassPatchTestClass', TrickBag::Meta)
38
38
  end
39
39
  fn.()
40
- expect(->{ ClassPatchTestClass.new }).to raise_error
40
+ expect(->{ ClassPatchTestClass.new }).to raise_error(NameError)
41
41
  end
42
42
  end
43
43
 
@@ -10,7 +10,7 @@ describe Bitmap do
10
10
 
11
11
 
12
12
  specify 'the constructor should not permit being explicitly called outside the class' do
13
- expect(-> { Bitmap.new }).to raise_error
13
+ expect(-> { Bitmap.new(1) }).to raise_error(NoMethodError)
14
14
  end
15
15
 
16
16
 
@@ -15,7 +15,7 @@ module Numeric
15
15
  expect(Totals.map_percent_of_total([2, 4, 6, 8])).to eq([10, 20, 30, 40])
16
16
  end
17
17
 
18
- it "returns an empty array when handed an empty array" do
18
+ it "returns an empty array when passed an empty array" do
19
19
  expect(Totals.map_percent_of_total([])).to eq([])
20
20
  expect(Totals.map_fraction_of_total([])).to eq([])
21
21
  end
@@ -7,11 +7,11 @@ module TrickBag
7
7
  context "multi_eq" do
8
8
 
9
9
  specify "that calling with no params raises an error" do
10
- expect(->{ Operators.multi_eq() }).to raise_error
10
+ expect(->{ Operators.multi_eq() }).to raise_error(ArgumentError)
11
11
  end
12
12
 
13
- specify "that calling with no params raises an error" do
14
- expect(->{ Operators.multi_eq(1) }).to raise_error
13
+ specify "that calling with 1 param raises an error" do
14
+ expect(->{ Operators.multi_eq(1) }).to raise_error(ArgumentError)
15
15
  end
16
16
 
17
17
  test_return_value = ->(true_or_false, *values) do
@@ -8,15 +8,18 @@ module TrickBag
8
8
 
9
9
  include Validations
10
10
 
11
+ ObjectValidationError = TrickBag::Validations::ObjectValidationError
12
+
11
13
  specify 'a missing instance variable should raise an error' do
12
14
  vars = [:@this_name_could_not_possibly_be_defined_as_a_real_variable]
13
- expect(-> { raise_on_nil_instance_vars(self, vars) }).to raise_error
15
+ expect(-> { raise_on_nil_instance_vars(self, vars) }).to raise_error(ObjectValidationError)
14
16
  end
15
17
 
16
18
  specify 'an existing instance variable should NOT raise an error' do
17
19
  vars = [:@foo]
18
20
  -> { class AbCdEfG; def initialize; @foo = 'hi'; end; end }.()
19
21
  expect(-> { raise_on_nil_instance_vars(AbCdEfG.new, vars) }).not_to raise_error
22
+ Meta::Classes.undef_class('AbCdEfG')
20
23
  end
21
24
  end
22
25
  end
@@ -8,12 +8,14 @@ module TrickBag
8
8
 
9
9
  include Validations
10
10
 
11
+ InvalidValueError = TrickBag::Validations::InvalidValueError
12
+
11
13
  specify "*no* error is raised if the value is included" do
12
14
  expect(->{raise_on_invalid_value('foo', ['foo']) }).not_to raise_error
13
15
  end
14
16
 
15
17
  specify "an error *is* raised if the value is not included" do
16
- expect(->{raise_on_invalid_value('foo', []) }).to raise_error
18
+ expect(->{raise_on_invalid_value('foo', []) }).to raise_error(InvalidValueError)
17
19
  end
18
20
 
19
21
  specify "the error message is correct" do
@@ -22,7 +22,7 @@ Gem::Specification.new do |spec|
22
22
  spec.add_dependency "diffy", '~> 3.0'
23
23
 
24
24
 
25
- if RUBY_VERSION >= '2'
25
+ if RUBY_VERSION.split('.').first.to_i >= 2
26
26
  spec.add_dependency 'net-ssh'
27
27
  else
28
28
  spec.add_dependency 'net-ssh', '= 2.9.2'
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.64.3
4
+ version: 0.65.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: 2016-02-04 00:00:00.000000000 Z
11
+ date: 2017-06-04 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: os
@@ -221,7 +221,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
221
221
  version: '0'
222
222
  requirements: []
223
223
  rubyforge_project:
224
- rubygems_version: 2.5.1
224
+ rubygems_version: 2.6.11
225
225
  signing_key:
226
226
  specification_version: 4
227
227
  summary: Miscellaneous general useful tools.