trick_bag 0.66.0 → 0.67.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 1d232e6acd5101ddede4f818540a495f8cb9a454
4
- data.tar.gz: b8b773b9d5b40ec1e7e8fe2d61888d59d9a35be0
3
+ metadata.gz: 7f8d5b7a9f77fdc75d8672b5947fd8075cca1ab5
4
+ data.tar.gz: e61fd4ec8b3d7dc55023e2323e7cf75f853d9389
5
5
  SHA512:
6
- metadata.gz: d90de4a2b882180737bc7ac377b75521e173b1796be0c1204a37a617c3221dfd3140fd391e3da8e9de2c19dff4c16c2b9b05011dc06fabd76a9324cf924aba75
7
- data.tar.gz: e9d782a5aebcd295387481e6551600747f36539b3ae20a31f4f6db69ec659efd04ac2ee35f3643781ddffa45fcbcbbbad49adbf32a0c1efaaa9d3fa252b29f8f
6
+ metadata.gz: 50b8e5a3407f1b725598a1f22de963682b5e68f154f575989af03e6a84f4e18c39e17c4975978eb8ea2e32c0f705f05fecd41701619524e7e20c40571342d7b6
7
+ data.tar.gz: edf428cd0e32c8f282ae0f80c84ba5a274d481e6973ba065ba4f1adeb3ebb5e2a43c70f40ccdde6ac5cfc98741faeab7b8b109519ea0b7bc0725c36129699561
data/.travis.yml CHANGED
@@ -7,8 +7,9 @@ before_install:
7
7
 
8
8
 
9
9
  rvm:
10
+ - 2.4.2
10
11
  - 2.0.0
11
- - 1.9.3
12
- - jruby-19mode
12
+ - jruby-1.7.26
13
+ - jruby-9.1.9.0
13
14
 
14
15
  script: "bundle exec rspec spec"
data/README.md CHANGED
@@ -21,7 +21,159 @@ Or install it yourself as:
21
21
 
22
22
  ## Usage
23
23
 
24
- See the unit tests in the spec directory tree for usage examples.
24
+ The best ways to understand the usage are to look at a) the unit tests in the spec directory tree,
25
+ b) the comments in the source files, and c) the source code itself. That said, here is a summary:
26
+
27
+ ### CollectionAccess
28
+
29
+ * `accessor` - returns lambda to simplify access to a deeply nested hash, as in
30
+ `customer_accessor['contact_info.address.city']`
31
+ instead of `customer['contact_info']['address']['city']`
32
+ * `#access` - worker method for above, also publicly available for use; called as:
33
+ `access(customer, 'contact_info', 'address', 'city')`
34
+ * `LinkedList` - a linked list implementation in Ruby
35
+
36
+ ### Enumerables
37
+
38
+ * `BufferedEnumerable` - enumerable handling the buffering and the timing of fetching;
39
+ you provide fetcher and (optionally) fetch notifier callables
40
+ * `CompoundEnumberable` - an enumerator used to provide all combinations of a set of Enumerables.
41
+ * `EndlessLastEnumerable` - wraps another enumerable, and after it is exhausted, yields the same value on successive calls
42
+ * `FileLineReader` - Reads a file containing strings, one on each line, and feeds them
43
+ in its each() method. Strips all lines' leading and trailing whitespace,
44
+ and ignores all empty lines and lines beginning with the comment character `#`.
45
+ Especially useful in reading configuration files.
46
+ * `FilteredEnumerable` - like `my_enumerable.lazy.select { ... }.lazy`, but supports changing the filter at any time
47
+
48
+ ### Formatters
49
+
50
+ * `BinaryToHexAndAscii` - formats bytes in hex and ASCII, e.g.:
51
+ ```
52
+ 0x 0 00 07 0E 15 | 1C 23 2A 31 | 38 3F 46 4D | 54 5B 62 69 .....#*18?FMT[bi
53
+ 0x 10 70 77 7E 85 | 8C 93 9A A1 | A8 AF B6 BD | C4 CB D2 D9 pw~.............
54
+ ```
55
+ * `ErbRenderer` - convenience class for ERB rendering; simplifies using a specific set of key/value pairs
56
+ as opposed to the current binding
57
+ * `Formatters.duration_to_s` - formats number of seconds to string like `11 d, 13 h, 46 m, 40 s`
58
+ * `Formatters.end_with_n` - reverse of `String#chomp` -
59
+ useful for use with utilities like Diffy that complain about lines without line endings.
60
+ * `Formatters.timestamp` - returns a timestamp string suitable for use in file names
61
+ in the year-month-day-hour-minute-second form, e.g. `2014-03-24_15-25-57`.
62
+ * `Formatters.replace_with_timestamp` - replaces a token with the timestamp, as in:
63
+ `my-app-result-{dt}.txt` => `my-app-result-2014-03-24_15-25-57.txt`
64
+ Especially useful for generating file names.
65
+ * `Formatters.dos2unix[!]` - formats a string with Unix line endings
66
+ * `Formatters.array_diff` - returns a nicely formatted string output of the difference
67
+ between 2 arrays
68
+ * `Formatters.string_to_verbose_char_list` - returns a list of chars in a string, 1 per line,
69
+ with several representations of the values, e.g.:
70
+ ```
71
+ Index Decimal Hex Binary Character
72
+ ----- ------- --- ------ ---------
73
+ 0 97 61 x 110 0001 b a
74
+ 1 49 31 x 11 0001 b 1
75
+ ```
76
+ * `Formatters.thousands_separated` - adds thousands separators to an Integer
77
+ string representation as appropriate
78
+
79
+
80
+ ### Functional
81
+
82
+ These methods provide a shorthand for testing whether or not an object
83
+ meets an Enumerable of conditional callables.
84
+
85
+
86
+ ### IO
87
+
88
+ * `Gitignore` - these methods simulate the results of git's file pattern matching
89
+ based on the .gitignore file. They can be useful, for example,
90
+ in determining which files to include in a gem build when git is not present.
91
+ * `Tempfiles.file_containing` - for the easy creation and deletion of a temp file
92
+ populated with text, wrapped around the code block you provide.
93
+ * `TextModeStatusUpdater` - provides an updatable and customizable status/information
94
+ line in a terminal, typically used to display progress.
95
+
96
+
97
+ ### Meta
98
+
99
+ * `attr` methods provide cleaner and more concise creation of attribute methods that
100
+ require control over accessibility (public, protected, private).
101
+ * `class?` - is this name the name of a class?
102
+ * `undef_class` - undefines a class; useful for unit testing code that dynamically creates classes.
103
+
104
+
105
+ ### Networking
106
+
107
+ * `SshOutputReader` - Runs an ssh command, collecting the stdout and stderr produced by it.
108
+ Optionally a predicate can be specified that, when called with the
109
+ instance of this class, returns true to close the channel or false to continue
110
+ (for example, when a certain string appears in the command's output).
111
+ There are instance methods to return the most recent and all accumulated text
112
+ for both stdout and stderr, so the predicate can easily inspect the text.
113
+
114
+
115
+ ### Numeric
116
+
117
+ * `Bitmapping` - methods for converting from binary string and bit array to number and back
118
+ * `Bitmap` - a simple bitmap implementation, with several initialization methods
119
+ * `KmgtNumericString` - converts number strings with optional suffixes of [kKmMgGtT] to integers.
120
+ Upper case letters represent powers of 1024, and lower case letters represent powers of 1000.
121
+ Also supports ranges, e.g. '1k..5k' will be converted by to_range to (1000..5000).
122
+ * `Multicounter` - simplifies accumulating counts of multiple objects.
123
+ * `StartAndMax` - provides an object that will tell you if the number exceeds
124
+ the starting point and if the number is >= the maximum (or if no maximum has been specified).
125
+ * `Totals` - provides methods for working with percent of total
126
+
127
+
128
+ ### Operators
129
+
130
+ * `multi_eq` - returns whether or not _all_ values passed are equal to each other
131
+
132
+
133
+ ### Timing
134
+
135
+ * `Elapser` - provides ways to specify and test for elapsed state
136
+ * `retry_until_true_or_timeout` - calls a predicate proc repeatedly,
137
+ sleeping the specified interval between calls, returning if the predicate returns true,
138
+ and giving up after the specified number of seconds.
139
+ Displays elapsed and remaining times on the terminal.
140
+ * `benchmark` - simplifies the output of benchmarking data with a text caption
141
+ * `try_with_timeout` - runs the passed block in a new thread, ensuring that its execution time
142
+ does not exceed the specified duration.
143
+
144
+
145
+ ### Validations
146
+
147
+ * hash validations - methods to see if any of the specified keys are missing from the hash,
148
+ and a method to raise an error with descriptive message if so
149
+ * object validations - method to see if any of the specified instance variables are nil, and another
150
+ method that raises an error with descriptive message if so
151
+ * `raise_on_invalid_value` - if the passed value is not in the list of valid values, raise an error
152
+ with descriptive message
153
+ * regex validations - for working with multiple regexes and strings with which to match them
154
+
155
+
156
+ ### Core Types
157
+
158
+ `clone_hash_except` - creates a copy of a hash except for the specified keys (this functionality
159
+ is already included in Rails, but not in Ruby itself)
160
+
161
+
162
+ ## Why?
163
+
164
+ This library was born when I was writing a lot of testing tools and data collection and analysis software.
165
+ At that time I also mentored a team of software testers using Ruby and Cucumber. I saw coding patterns that existed
166
+ in multiple places, in varying levels of functionality and quality, or sometimes, totally absent when
167
+ they would have been helpful. Why not implement these patterns once in a shared and tested library?
168
+
169
+ Some may be very thin layers over the underlying Ruby implementations (e.g. the _Elapser_ class),
170
+ and their usefulness may be questioned...but in the calling code, the use of these is more intention-revealing,
171
+ object oriented, and results in more concise calling code.
172
+
173
+ This gem's files, classes, and methods are for the most part isolated from each other and self-contained.
174
+ This means that if you like you can easily copy single methods or files from the gem and copy them into
175
+ your code base to eliminate a dependency on this gem. If you do this, then I suggest you include an
176
+ attribution to this gem so that future developers can consult it for fixes and enhancements.
25
177
 
26
178
 
27
179
  ## Contributing
data/RELEASE_NOTES.md CHANGED
@@ -1,9 +1,14 @@
1
+ ## v0.67.0
2
+
3
+ * Move Functional methods into Functional module.
4
+ * Improve README, esp. add class/method summaries.
5
+
6
+
1
7
  ## v0.66.0
2
8
 
3
9
  * Add TrickBag::Io::Gitignore.list_ignored_files.
4
10
 
5
11
 
6
-
7
12
  ## v0.65.1
8
13
 
9
14
  * Fix bug in TrickBag::Validations when raise_on_missing_keys was passed an array.
@@ -3,9 +3,9 @@ require 'set'
3
3
  module TrickBag
4
4
  module Enumerables
5
5
 
6
- # Takes an array as input. On successive calls to next, it returns the next
7
- # element in the array until the array has been exhausted, and then returns
8
- # the last element every time it's called.
6
+ # Takes an enumerable or number as input. On successive calls to next, it returns the next
7
+ # element in the that enumerable until it has been exhausted, and then returns
8
+ # the last element every time it's called. Especially useful in reading configuration files.
9
9
  #
10
10
  # You can use Ruby's array addition and multiplication features
11
11
  # to provide rich functionality, e.g.:
@@ -8,6 +8,14 @@ module Enumerables
8
8
  #
9
9
  # The filter is an optional parameter on the constructor, but can
10
10
  # also be set after creation with a mutator.
11
+ #
12
+ # If you do not intend to change the filter after it is created,
13
+ # you should probably just use Ruby's built in lazy enumerators, as in:
14
+ # e = (1..10000000000000000000000000000).lazy.select { |n| n.even? }.lazy
15
+ #
16
+ # This class really comes in handy when the filter needs to be changed during
17
+ # the enumerator's lifetime.
18
+
11
19
  class FilteredEnumerable
12
20
 
13
21
  include Enumerable
@@ -55,6 +55,7 @@ module Formatters
55
55
  end
56
56
 
57
57
 
58
+ # Reverse of String#chomp.
58
59
  # Convert to string if not already a string.
59
60
  # Append new line to string if the string is not empty and does not already end with one.
60
61
  # This is to disable the Diffy warning message "No newline at end of file"
@@ -80,7 +81,7 @@ module Formatters
80
81
  # for example:
81
82
  #
82
83
  # replace_with_timestamp('my-app-result-{dt}.txt') => "my-app-result-2014-03-24_15-25-57.txt"
83
- def replace_with_timestamp(string, marker = '{dt}', datetime = DateTime.now)
84
+ def replace_with_timestamp(string, marker = '{dt}', datetime = DateTime.now)
84
85
  string.gsub(marker, timestamp(datetime))
85
86
  end
86
87
 
@@ -1,4 +1,8 @@
1
1
  module TrickBag
2
+ module Functional
3
+
4
+ # These methods provide a shorthand for testing whether or not an object
5
+ # meets an Enumerable of conditional callables.
2
6
 
3
7
  module_function
4
8
 
@@ -23,3 +27,4 @@ module TrickBag
23
27
  conditions.any? { |condition| condition.(object) }
24
28
  end
25
29
  end
30
+ end
@@ -6,8 +6,8 @@ module TempFiles
6
6
 
7
7
  module_function
8
8
 
9
- # Creates a temporary file containing the specified text,
10
- # passes its filespec to the passed block, then deletes the file.
9
+ # For the easy creation and deletion of a temp file populated with text,
10
+ # wrapped around the code block you provide.
11
11
  #
12
12
  # @param text the text to write to the temporary file
13
13
  # @param file_prefix optional prefix for the temporary file's name
@@ -1,6 +1,8 @@
1
1
  module TrickBag
2
2
  module Io
3
3
 
4
+ # Provides an updatable and customizable status/information line in a terminal,
5
+ # typically used to display progress.
4
6
  # Updates the terminal line with text, erasing the original content and displaying at the same place.
5
7
  # Uses ANSI escape sequences for cursor positioning and clearing
6
8
  # (see http://www.oldlinux.org/Linux.old/Ref-docs/ASCII/ANSI%20Escape%20Sequences.htm).
@@ -1,7 +1,7 @@
1
1
  module TrickBag
2
2
  module Numeric
3
3
 
4
- # Supports multiple counts, each identified by a key.
4
+ # Simplifies accumulating counts of multiple objects.
5
5
  # Like a hash, but does not allow []=; increment is the only way to modify a value.
6
6
  class MultiCounter
7
7
 
@@ -1,8 +1,10 @@
1
1
  module TrickBag
2
2
  module Numeric
3
3
 
4
- # Like a Range, but includes useful functions with understandable names
5
- # that account for the limits or absences of limits.
4
+ # Provides an object that will tell you if the number exceeds the starting point
5
+ # and if the number is >= the maximum (or if no maximum has been specified).
6
+ # While this functionality can easily be duplicated with more primitive
7
+ # code, this class provides an object whose use will be simpler and more readable.
6
8
  class StartAndMax
7
9
 
8
10
  attr_reader :start_pos, :max_count
@@ -9,8 +9,10 @@ module Timing
9
9
 
10
10
 
11
11
  # Calls a predicate proc repeatedly, sleeping the specified interval
12
- # between calls, and giving up after the specified number of seconds.
12
+ # between calls, returning if the predicate returns true,
13
+ # and giving up after the specified number of seconds.
13
14
  # Displays elapsed and remaining times on the terminal.
15
+ # Outputs the time elapsed and the time to go.
14
16
  #
15
17
  # @param predicate something that can be called with .() or .call
16
18
  # that returns a truthy value that indicates no further retries are necessary
@@ -5,7 +5,7 @@ module TrickBag
5
5
 
6
6
  # NOTE! If the gem you are testing defines a .gemspec file,
7
7
  # then this approach may be eliminated by instead
8
- # running the following command in the project root (thank you, Rob Kidd):
8
+ # running the following command in the project root (thank you, Robb Kidd):
9
9
 
10
10
  # bundle exec ruby -e "require 'my_gem_name'"
11
11
 
@@ -1,3 +1,3 @@
1
1
  module TrickBag
2
- VERSION = '0.66.0'
2
+ VERSION = '0.67.0'
3
3
  end
@@ -1,5 +1,5 @@
1
- require_relative '../spec_helper'
2
- require 'trick_bag/core_types'
1
+ require_relative '../../spec_helper'
2
+ require_relative '../../../lib/trick_bag/core_types/core_types'
3
3
 
4
4
  module TrickBag
5
5
 
@@ -5,6 +5,7 @@ require 'trick_bag/functional/functional'
5
5
 
6
6
 
7
7
  module TrickBag
8
+ module Functional
8
9
 
9
10
  describe 'Composite predicates' do
10
11
 
@@ -17,15 +18,15 @@ module TrickBag
17
18
  context "none?" do
18
19
 
19
20
  specify "returns true when all are false" do
20
- expect(TrickBag.none_with_object?(all_false_funcs, 1)).to eq(true)
21
+ expect(TrickBag::Functional.none_with_object?(all_false_funcs, 1)).to eq(true)
21
22
  end
22
23
 
23
24
  specify "returns false when all are true" do
24
- expect(TrickBag.none_with_object?(all_true_funcs, 1)).to eq(false)
25
+ expect(TrickBag::Functional.none_with_object?(all_true_funcs, 1)).to eq(false)
25
26
  end
26
27
 
27
28
  specify "returns false when some are false and some are true" do
28
- expect(TrickBag.none_with_object?(mixed_true_false_funcs, 1)).to eq(false)
29
+ expect(TrickBag::Functional.none_with_object?(mixed_true_false_funcs, 1)).to eq(false)
29
30
  end
30
31
  end
31
32
 
@@ -33,15 +34,15 @@ module TrickBag
33
34
  context "any?" do
34
35
 
35
36
  specify "returns false when all are false" do
36
- expect(TrickBag.any_with_object?(all_false_funcs, 1)).to eq(false)
37
+ expect(TrickBag::Functional.any_with_object?(all_false_funcs, 1)).to eq(false)
37
38
  end
38
39
 
39
40
  specify "returns true when all are true" do
40
- expect(TrickBag.any_with_object?(all_true_funcs, 1)).to eq(true)
41
+ expect(TrickBag::Functional.any_with_object?(all_true_funcs, 1)).to eq(true)
41
42
  end
42
43
 
43
44
  specify "returns true when some are false and some are true" do
44
- expect(TrickBag.any_with_object?(mixed_true_false_funcs, 1)).to eq(true)
45
+ expect(TrickBag::Functional.any_with_object?(mixed_true_false_funcs, 1)).to eq(true)
45
46
  end
46
47
  end
47
48
 
@@ -49,16 +50,17 @@ module TrickBag
49
50
  context "all?" do
50
51
 
51
52
  specify "returns false when all are false" do
52
- expect(TrickBag.all_with_object?(all_false_funcs, 1)).to eq(false)
53
+ expect(TrickBag::Functional.all_with_object?(all_false_funcs, 1)).to eq(false)
53
54
  end
54
55
 
55
56
  specify "returns true when all are true" do
56
- expect(TrickBag.all_with_object?(all_true_funcs, 1)).to eq(true)
57
+ expect(TrickBag::Functional.all_with_object?(all_true_funcs, 1)).to eq(true)
57
58
  end
58
59
 
59
60
  specify "returns false when some are false and some are true" do
60
- expect(TrickBag.all_with_object?(mixed_true_false_funcs, 1)).to eq(false)
61
+ expect(TrickBag::Functional.all_with_object?(mixed_true_false_funcs, 1)).to eq(false)
61
62
  end
62
63
  end
63
64
  end
64
65
  end
66
+ 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.66.0
4
+ version: 0.67.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: 2017-09-24 00:00:00.000000000 Z
11
+ date: 2017-09-25 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: os
@@ -140,7 +140,7 @@ files:
140
140
  - lib/trick_bag.rb
141
141
  - lib/trick_bag/collections/collection_access.rb
142
142
  - lib/trick_bag/collections/linked_list.rb
143
- - lib/trick_bag/core_types.rb
143
+ - lib/trick_bag/core_types/core_types.rb
144
144
  - lib/trick_bag/enumerables/buffered_enumerable.rb
145
145
  - lib/trick_bag/enumerables/compound_enumerable.rb
146
146
  - lib/trick_bag/enumerables/endless_last_enumerable.rb
@@ -174,7 +174,7 @@ files:
174
174
  - spec/spec_helper.rb
175
175
  - spec/trick_bag/collections/collection_access_spec.rb
176
176
  - spec/trick_bag/collections/linked_list_spec.rb
177
- - spec/trick_bag/core_types_spec.rb
177
+ - spec/trick_bag/core_types/core_types_spec.rb
178
178
  - spec/trick_bag/enumerables/buffered_enumerable_spec.rb
179
179
  - spec/trick_bag/enumerables/compound_enumerable_spec.rb
180
180
  - spec/trick_bag/enumerables/endless_last_enumerable_spec.rb
@@ -231,7 +231,7 @@ test_files:
231
231
  - spec/spec_helper.rb
232
232
  - spec/trick_bag/collections/collection_access_spec.rb
233
233
  - spec/trick_bag/collections/linked_list_spec.rb
234
- - spec/trick_bag/core_types_spec.rb
234
+ - spec/trick_bag/core_types/core_types_spec.rb
235
235
  - spec/trick_bag/enumerables/buffered_enumerable_spec.rb
236
236
  - spec/trick_bag/enumerables/compound_enumerable_spec.rb
237
237
  - spec/trick_bag/enumerables/endless_last_enumerable_spec.rb