shenanigans 1.0.10 → 1.0.15
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 +5 -5
- data/Gemfile +2 -1
- data/lib/shenanigans/array/caret.rb +3 -2
- data/lib/shenanigans/array/random_subarray.rb +7 -5
- data/lib/shenanigans/array/reductions.rb +13 -10
- data/lib/shenanigans/array/zip_with.rb +9 -12
- data/lib/shenanigans/array.rb +3 -3
- data/lib/shenanigans/hash/extract.rb +5 -4
- data/lib/shenanigans/hash/has_shape_pred.rb +6 -7
- data/lib/shenanigans/hash/to_ostruct.rb +8 -9
- data/lib/shenanigans/hash.rb +3 -3
- data/lib/shenanigans/integer/divisible_by.rb +13 -0
- data/lib/shenanigans/integer/string_length.rb +13 -0
- data/lib/shenanigans/integer.rb +2 -0
- data/lib/shenanigans/kernel/fn.rb +6 -5
- data/lib/shenanigans/kernel/prompt.rb +6 -7
- data/lib/shenanigans/kernel/require_optional.rb +7 -7
- data/lib/shenanigans/kernel/with.rb +3 -2
- data/lib/shenanigans/kernel.rb +4 -4
- data/lib/shenanigans/module/private_accessor.rb +5 -5
- data/lib/shenanigans/module.rb +1 -1
- data/lib/shenanigans/object/display.rb +5 -4
- data/lib/shenanigans/object.rb +1 -2
- data/lib/shenanigans/string/cmpi.rb +9 -0
- data/lib/shenanigans/string/in_groups_of.rb +4 -6
- data/lib/shenanigans/string.rb +2 -1
- data/lib/shenanigans.rb +7 -7
- data/test/array/caret_test.rb +9 -0
- data/test/array/{test_random_subarray.rb → random_subarray_test.rb} +3 -3
- data/test/array/reductions_test.rb +27 -0
- data/test/array/zip_with_test.rb +14 -0
- data/test/hash/extract_test.rb +11 -0
- data/test/hash/{test_has_shape_pred.rb → has_shape_pred_test.rb} +3 -3
- data/test/hash/{test_to_ostruct.rb → to_ostruct_test.rb} +3 -3
- data/test/integer/divisible_by_test.rb +16 -0
- data/test/integer/string_length_test.rb +16 -0
- data/test/kernel/fn_test.rb +14 -0
- data/test/kernel/{test_prompt.rb → prompt_test.rb} +4 -4
- data/test/kernel/require_optional_test.rb +15 -0
- data/test/kernel/with_test.rb +12 -0
- data/test/module/{test_private_accessor.rb → private_accessor_test.rb} +3 -3
- data/test/object/{test_display.rb → display_test.rb} +4 -5
- data/test/string/cmpi_test.rb +10 -0
- data/test/string/in_groups_of_test.rb +11 -0
- metadata +40 -62
- data/doc/Array.html +0 -518
- data/doc/Fixnum.html +0 -214
- data/doc/Hash.html +0 -415
- data/doc/Kernel.html +0 -462
- data/doc/Module.html +0 -236
- data/doc/Object.html +0 -284
- data/doc/String.html +0 -226
- data/doc/_index.html +0 -188
- data/doc/class_list.html +0 -54
- data/doc/css/common.css +0 -1
- data/doc/css/full_list.css +0 -57
- data/doc/css/style.css +0 -338
- data/doc/file.README.html +0 -162
- data/doc/file_list.html +0 -56
- data/doc/frames.html +0 -26
- data/doc/index.html +0 -162
- data/doc/js/app.js +0 -219
- data/doc/js/full_list.js +0 -178
- data/doc/js/jquery.js +0 -4
- data/doc/method_list.html +0 -149
- data/doc/top-level-namespace.html +0 -114
- data/lib/shenanigans/fixnum/string_length.rb +0 -14
- data/lib/shenanigans/fixnum.rb +0 -1
- data/lib/shenanigans/object/it.rb +0 -9
- data/test/array/test_caret.rb +0 -9
- data/test/array/test_reductions.rb +0 -27
- data/test/array/test_zip_with.rb +0 -14
- data/test/fixnum/test_string_length.rb +0 -16
- data/test/hash/test_extract.rb +0 -11
- data/test/kernel/test_fn.rb +0 -14
- data/test/kernel/test_require_optional.rb +0 -17
- data/test/kernel/test_with.rb +0 -12
- data/test/object/test_it.rb +0 -10
- data/test/string/test_display.rb +0 -36
- data/test/string/test_in_groups_of.rb +0 -11
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 6b59ed384b8df1b8998e226ae092c61983fcbb926f52d825f77ca4cc6ffd455f
|
4
|
+
data.tar.gz: 36030c324aadae0a3f8ac00a5d2b0283dff3fa9e65ab682a7e3d6073da2472a6
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 5ace930024d466feb40bdb52dde54effb61182f3c2dcf13d4a8f34ed9cfcae8aec8509fdb04fee40317a1072640682af1e26b82a1759e1066b6cf2a91d58ebd3
|
7
|
+
data.tar.gz: d04dcb70b2565d320cf971864199e8f038c3fe0e609fb507adcab68000d271bad646e6f78f42b41095101930f5c9bf3ad402c2fac9a0c84411e5088c5eefa133
|
data/Gemfile
CHANGED
@@ -2,15 +2,17 @@ class Array
|
|
2
2
|
# Generates random subarrays. Uses random numbers and
|
3
3
|
# bit-fiddling to assure performant uniform distributions
|
4
4
|
# even for large arrays.
|
5
|
+
#
|
6
|
+
# @example
|
5
7
|
# a = *1..5
|
6
|
-
# a.random_subarray(3)
|
7
|
-
# #=> [[1, 3, 5], [2, 4], [1, 3, 4, 5]]
|
8
|
+
# a.random_subarray(3) #=> [[1, 3, 5], [2, 4], [1, 3, 4, 5]]
|
8
9
|
|
9
|
-
def random_subarray(n=1)
|
10
|
+
def random_subarray(n = 1)
|
10
11
|
raise ArgumentError, "negative argument" if n < 0
|
12
|
+
|
11
13
|
(1..n).map do
|
12
|
-
r = rand(2**
|
13
|
-
|
14
|
+
r = rand(2**size)
|
15
|
+
select.with_index { |_, i| r[i] == 1 }
|
14
16
|
end
|
15
17
|
end
|
16
18
|
end
|
@@ -1,13 +1,16 @@
|
|
1
1
|
class Array
|
2
|
-
# Similar to +reduce+/+inject+, but also returns intermediate values. Has the
|
2
|
+
# Similar to +reduce+/+inject+, but also returns intermediate values. Has the
|
3
|
+
# same interface as +reduce+/+inject+, so an initial value, an operator or
|
4
|
+
# both can be supplied. This method may eventually be moved to the
|
5
|
+
# +Enumerable+ module.
|
3
6
|
#
|
4
|
-
#
|
5
|
-
# a
|
6
|
-
# #=> 10
|
7
|
-
#
|
8
|
-
# #=> 60
|
9
|
-
#
|
10
|
-
# #=> ["a", "ab", "abc"]
|
7
|
+
# @example Symbol argument
|
8
|
+
# a = (1..4).to_a
|
9
|
+
# a.reductions(:+) #=> 10
|
10
|
+
# @example Initial value and symbol argument
|
11
|
+
# a.reductions(50, :+) #=> 60
|
12
|
+
# @example Block argument
|
13
|
+
# %w(a b c).reductions { |s1, s2| s1+s2 } #=> ["a", "ab", "abc"]
|
11
14
|
def reductions(*args, &block)
|
12
15
|
arr = dup
|
13
16
|
|
@@ -21,9 +24,9 @@ class Array
|
|
21
24
|
|
22
25
|
initial ||= arr.shift
|
23
26
|
|
24
|
-
arr.inject([initial, [initial]])
|
27
|
+
arr.inject([initial, [initial]]) { |(acc, result), el|
|
25
28
|
val = op ? acc.send(op, el) : yield(acc, el)
|
26
29
|
[val, result << val]
|
27
|
-
|
30
|
+
}.last
|
28
31
|
end
|
29
32
|
end
|
@@ -1,21 +1,18 @@
|
|
1
1
|
class Array
|
2
|
-
|
3
2
|
# Zip <tt>self</tt> with <tt>other</tt>, combining the elements
|
4
3
|
# with the provided block or symbol.
|
5
4
|
# The resulting array will be as long as the shorter of
|
6
5
|
# the two arrays.
|
7
|
-
#
|
8
|
-
# #=> [7, 7, 7]
|
9
|
-
# %w(a b).zip_with(%w(c d), :+)
|
10
|
-
#
|
11
|
-
#
|
12
|
-
# For more complex combinations, a block can be provided:
|
13
|
-
#
|
14
|
-
# [1,2,3].zip_with([6,5,4]) { |a,b| 3*a+2*b }
|
6
|
+
# @example With a symbol
|
7
|
+
# [1,2,3].zip_with([6,5,4], :+) #=> [7, 7, 7]
|
8
|
+
# %w(a b).zip_with(%w(c d), :+) #=> ["ac", "bd"]
|
9
|
+
# @example With a block
|
10
|
+
# [1,2,3].zip_with([6,5,4]) { |a,b| 3 * a + 2 * b }
|
15
11
|
# #=> [15, 16, 17]
|
16
|
-
def zip_with(other, op=nil)
|
17
|
-
return [] if
|
18
|
-
|
12
|
+
def zip_with(other, op = nil)
|
13
|
+
return [] if empty? || other.empty?
|
14
|
+
|
15
|
+
clipped = self[0..other.length - 1]
|
19
16
|
zipped = clipped.zip(other)
|
20
17
|
|
21
18
|
if op
|
data/lib/shenanigans/array.rb
CHANGED
@@ -1,3 +1,3 @@
|
|
1
|
-
require_relative
|
2
|
-
require_relative
|
3
|
-
require_relative
|
1
|
+
require_relative "array/caret"
|
2
|
+
require_relative "array/random_subarray"
|
3
|
+
require_relative "array/zip_with"
|
@@ -1,10 +1,11 @@
|
|
1
1
|
class Hash
|
2
2
|
# Returns a new hash only with the specified keys (if present).
|
3
|
+
#
|
4
|
+
# @example Key order does not matter
|
3
5
|
# hash = { a: 1, b: 2, c: 3 }
|
4
|
-
# hash.extract(:b, :a)
|
5
|
-
#
|
6
|
-
# hash.extract(:a, :d)
|
7
|
-
# #=> { a: 1}
|
6
|
+
# hash.extract(:b, :a) #=> { a: 1, b: 2 }
|
7
|
+
# @example Missing keys are ignored
|
8
|
+
# hash.extract(:a, :d) #=> { a: 1}
|
8
9
|
def extract(*ks)
|
9
10
|
existing = keys & ks
|
10
11
|
Hash[existing.zip(values_at(*existing))]
|
@@ -1,15 +1,14 @@
|
|
1
1
|
class Hash
|
2
2
|
# Checks if a hash has a certain structure.
|
3
|
+
#
|
4
|
+
# @example Simple hash
|
3
5
|
# h = { k1: 1, k2: "1" }
|
4
|
-
# h.has_shape?(k1:
|
5
|
-
# #=>
|
6
|
-
#
|
7
|
-
# #=> false
|
8
|
-
# It also works with compound data structures.
|
6
|
+
# h.has_shape?(k1: Integer, k2: String) #=> true
|
7
|
+
# h.has_shape?(k1: Class, k2: String) #=> false
|
8
|
+
# @example Nested hashes
|
9
9
|
# h = { k1: [], k2: { k3: Struct.new("Foo") } }
|
10
10
|
# shape = { k1: Array, k2: { k3: Module } }
|
11
|
-
# h.has_shape?(shape)
|
12
|
-
# #=> true
|
11
|
+
# h.has_shape?(shape) #=> true
|
13
12
|
def has_shape?(shape)
|
14
13
|
all? do |k, v|
|
15
14
|
Hash === v ? v.has_shape?(shape[k]) : shape[k] === v
|
@@ -1,8 +1,10 @@
|
|
1
|
-
require
|
1
|
+
require "ostruct"
|
2
2
|
|
3
3
|
class Hash
|
4
4
|
# Recursively converts a <tt>Hash</tt> and all nested <tt>Hash</tt>es to
|
5
5
|
# <tt>OpenStruct</tt>s. Especially useful for parsing YAML.
|
6
|
+
#
|
7
|
+
# @example
|
6
8
|
# yaml=<<EOY
|
7
9
|
# subject: Programming Languages
|
8
10
|
# languages:
|
@@ -14,14 +16,11 @@ class Hash
|
|
14
16
|
# creator : Larry Wall
|
15
17
|
# EOY
|
16
18
|
# struct = YAML.load(yaml).to_ostruct
|
17
|
-
# struct.subject
|
18
|
-
# #=> "
|
19
|
-
# struct.languages.first
|
20
|
-
# #=> #<OpenStruct name="Ruby", creator="Matz">
|
21
|
-
# struct.languages.first.creator
|
22
|
-
# #=> "Matz"
|
19
|
+
# struct.subject #=> "Programming Languages"
|
20
|
+
# struct.languages.first #=> #<OpenStruct name="Ruby", creator="Matz">
|
21
|
+
# struct.languages.first.creator #=> "Matz"
|
23
22
|
def to_ostruct
|
24
|
-
arr = map
|
23
|
+
arr = map { |k, v|
|
25
24
|
case v
|
26
25
|
when Hash
|
27
26
|
[k, v.to_ostruct]
|
@@ -30,7 +29,7 @@ class Hash
|
|
30
29
|
else
|
31
30
|
[k, v]
|
32
31
|
end
|
33
|
-
|
32
|
+
}
|
34
33
|
OpenStruct.new(Hash[arr])
|
35
34
|
end
|
36
35
|
end
|
data/lib/shenanigans/hash.rb
CHANGED
@@ -1,3 +1,3 @@
|
|
1
|
-
require_relative
|
2
|
-
require_relative
|
3
|
-
require_relative
|
1
|
+
require_relative "hash/extract"
|
2
|
+
require_relative "hash/has_shape_pred"
|
3
|
+
require_relative "hash/to_ostruct"
|
@@ -0,0 +1,13 @@
|
|
1
|
+
class Integer
|
2
|
+
# Checks whether the receiver is cleanly divisble by the argument.
|
3
|
+
# @example
|
4
|
+
# 3.divisble_by(0) #=> false
|
5
|
+
# 3.divisble_by(2) #=> false
|
6
|
+
# 9.divisble_bu(3) #=> true
|
7
|
+
def divisible_by(n)
|
8
|
+
return false if n.zero?
|
9
|
+
|
10
|
+
self % n == 0
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
@@ -0,0 +1,13 @@
|
|
1
|
+
class Integer
|
2
|
+
# Returns the length of the number's string representation.
|
3
|
+
# @example
|
4
|
+
# 0.string_length #=> 1
|
5
|
+
# 123.string_length #=> 3
|
6
|
+
# -1.string_length #=> 2
|
7
|
+
def string_length
|
8
|
+
return 1 if zero?
|
9
|
+
|
10
|
+
len = Math.log10(abs).floor.next
|
11
|
+
positive? ? len : len.next
|
12
|
+
end
|
13
|
+
end
|
@@ -1,14 +1,15 @@
|
|
1
1
|
module Kernel
|
2
2
|
# Composes a list of functions.
|
3
3
|
# Functions can be specified as symbols or lambdas.
|
4
|
-
# ["foo bar", "baz qux"].map &fn(:split, :last)
|
5
|
-
# #=> ["bar", "qux"]
|
6
4
|
#
|
7
|
-
#
|
5
|
+
# @example Composing symbols
|
6
|
+
# ["foo bar", "baz qux"].map(&fn(:split, :last)) #=> ["bar", "qux"]
|
7
|
+
# @example Composing symbplds and lambdas
|
8
|
+
# (1..3).map(&fn(:next, -> x { x * x }, -> x { x.to_f / 2 } ))
|
8
9
|
# #=> [2.0, 4.5, 8.0]
|
9
10
|
def fn(*funs)
|
10
|
-
->
|
11
|
-
funs.inject(x) do |v,f|
|
11
|
+
->(x) do
|
12
|
+
funs.inject(x) do |v, f|
|
12
13
|
Proc === f ? f.call(v) : v.send(f)
|
13
14
|
end
|
14
15
|
end
|
@@ -1,5 +1,4 @@
|
|
1
1
|
module Kernel
|
2
|
-
|
3
2
|
# Currently only used by <tt>prompt</tt>:
|
4
3
|
# <tt>:to_i</tt>, <tt>:to_f</tt>, <tt>:to_r</tt>, <tt>:to_sym</tt>, <tt>:to_c</tt>
|
5
4
|
CONVERSIONS = [:to_i, :to_f, :to_r, :to_sym, :to_c]
|
@@ -7,14 +6,14 @@ module Kernel
|
|
7
6
|
# Displays a prompt and returns chomped input.
|
8
7
|
# Modelled after the Python method <tt>raw_input</tt>, but also can
|
9
8
|
# be supplied with an optional conversion method.
|
9
|
+
#
|
10
|
+
# @example A simple prompt
|
10
11
|
# prompt("Prompt> ")
|
11
|
-
# Prompt> 12
|
12
|
-
#
|
13
|
-
#
|
12
|
+
# Prompt> 12 #=> "12"
|
13
|
+
# @example A prompt with conversion
|
14
14
|
# prompt("Prompt> ", :to_f)
|
15
|
-
# Prompt> 12
|
16
|
-
|
17
|
-
def prompt(text='', conversion=nil)
|
15
|
+
# Prompt> 12 #=> 12.0
|
16
|
+
def prompt(text = "", conversion = nil)
|
18
17
|
print text unless text.empty?
|
19
18
|
input = gets.chomp
|
20
19
|
CONVERSIONS.include?(conversion) ? input.send(conversion) : input
|
@@ -2,17 +2,17 @@ module Kernel
|
|
2
2
|
# Optionally require a gem. If it is not available, <tt>nil</tt>
|
3
3
|
# will be returned. Alternatively, a block can be provided with code
|
4
4
|
# to run.
|
5
|
-
# require 'non_existent'
|
6
|
-
# #=> nil
|
7
5
|
#
|
8
|
-
#
|
9
|
-
#
|
10
|
-
#
|
11
|
-
#
|
6
|
+
# @example Without a block
|
7
|
+
# require "non_existent" #=> nil
|
8
|
+
# @example With a custom block
|
9
|
+
# require "non_existent" do
|
10
|
+
# puts "Something went wrong"
|
11
|
+
# end #=> Outputs "Something went wrong"
|
12
12
|
def require_optional(gem, &block)
|
13
13
|
require gem
|
14
14
|
rescue LoadError
|
15
|
-
block
|
15
|
+
block&.call
|
16
16
|
end
|
17
17
|
|
18
18
|
private :require_optional
|
@@ -1,11 +1,12 @@
|
|
1
1
|
module Kernel
|
2
2
|
# A Pascal/ActionScript like <tt>with</tt> method. Yields its
|
3
3
|
# argument to the provided block and then returns it.
|
4
|
+
#
|
5
|
+
# @example
|
4
6
|
# with([]) do |a|
|
5
7
|
# a << "a"
|
6
8
|
# a << "b"
|
7
|
-
# end
|
8
|
-
# #=> ["a", "b"]
|
9
|
+
# end #=> ["a", "b"]
|
9
10
|
def with(o, &blk)
|
10
11
|
o.tap(&blk)
|
11
12
|
end
|
data/lib/shenanigans/kernel.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
require_relative
|
2
|
-
require_relative
|
3
|
-
require_relative
|
4
|
-
require_relative
|
1
|
+
require_relative "kernel/fn"
|
2
|
+
require_relative "kernel/prompt"
|
3
|
+
require_relative "kernel/with"
|
4
|
+
require_relative "kernel/require_optional"
|
@@ -1,7 +1,7 @@
|
|
1
1
|
class Module
|
2
|
-
# Works like <tt>attr_accessor</tt> but generates private
|
3
|
-
#
|
4
|
-
#
|
2
|
+
# Works like <tt>attr_accessor</tt> but generates private getter/setter
|
3
|
+
# methods for class internal use only. Useful for enforcing Smalltalk-style
|
4
|
+
# internal encapsulation.
|
5
5
|
#
|
6
6
|
# For a more complete implementation of a similar feature see {ivar_encapsulation}[https://github.com/citizen428/ivar_encapsulation].
|
7
7
|
def private_accessor(*names)
|
@@ -16,8 +16,8 @@ class Module
|
|
16
16
|
instance_variable_set(instance_var_name, value)
|
17
17
|
end
|
18
18
|
|
19
|
-
|
20
|
-
|
19
|
+
send(:private, name)
|
20
|
+
send(:private, "#{name}=")
|
21
21
|
end
|
22
22
|
nil # like attr_accessor
|
23
23
|
end
|
data/lib/shenanigans/module.rb
CHANGED
@@ -1 +1 @@
|
|
1
|
-
require_relative
|
1
|
+
require_relative "module/private_accessor"
|
@@ -2,16 +2,17 @@ class Object
|
|
2
2
|
# Outputs the object and also returns it.
|
3
3
|
# Will use <tt>puts</tt> if <tt>new_line</tt> is <tt>true</tt> and
|
4
4
|
# <tt>print</tt> otherwise.
|
5
|
+
#
|
6
|
+
# @example
|
5
7
|
# "foo".display
|
6
|
-
# foo
|
7
|
-
# #=> "foo"
|
8
|
+
# foo #=> "foo"
|
8
9
|
#
|
9
10
|
# "foo".display(false)
|
10
11
|
# foo#=> "foo"
|
11
12
|
def display(new_line = true)
|
12
13
|
m = new_line ? :puts : :print
|
13
|
-
|
14
|
+
tap { |o| send(m, o) }
|
14
15
|
end
|
15
16
|
|
16
|
-
alias
|
17
|
+
alias d display
|
17
18
|
end
|
data/lib/shenanigans/object.rb
CHANGED
@@ -1,2 +1 @@
|
|
1
|
-
require_relative
|
2
|
-
require_relative 'object/display'
|
1
|
+
require_relative "object/display"
|
@@ -1,14 +1,12 @@
|
|
1
1
|
class String
|
2
2
|
# Returns an array of the string broken down into groups of
|
3
3
|
# <tt>size</tt> characters.
|
4
|
-
# "aabbcc".in_groups_of(2)
|
5
|
-
# #=> [
|
6
|
-
# "".in_groups_of(
|
7
|
-
# #=> []
|
8
|
-
# "".in_groups_of(0)
|
9
|
-
# #=> ArgumentError
|
4
|
+
# "aabbcc".in_groups_of(2) #=> ['aa', 'bb', 'cc']
|
5
|
+
# "".in_groups_of(2) #=> []
|
6
|
+
# "".in_groups_of(0) #=> ArgumentError
|
10
7
|
def in_groups_of(size)
|
11
8
|
raise ArgumentError, "Size of group must be >= 1" if size < 1
|
9
|
+
|
12
10
|
scan(/.{1,#{size}}/)
|
13
11
|
end
|
14
12
|
end
|
data/lib/shenanigans/string.rb
CHANGED
@@ -1 +1,2 @@
|
|
1
|
-
require_relative
|
1
|
+
require_relative "string/in_groups_of"
|
2
|
+
require_relative "string/cmpi"
|
data/lib/shenanigans.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
|
-
require
|
2
|
-
require
|
3
|
-
require
|
4
|
-
require
|
5
|
-
require
|
6
|
-
require
|
7
|
-
require
|
1
|
+
require "shenanigans/array"
|
2
|
+
require "shenanigans/hash"
|
3
|
+
require "shenanigans/integer"
|
4
|
+
require "shenanigans/kernel"
|
5
|
+
require "shenanigans/module"
|
6
|
+
require "shenanigans/object"
|
7
|
+
require "shenanigans/string"
|
@@ -1,7 +1,7 @@
|
|
1
|
-
require
|
2
|
-
require
|
1
|
+
require "minitest/autorun"
|
2
|
+
require "shenanigans/array/random_subarray"
|
3
3
|
|
4
|
-
class RandomSubarray <
|
4
|
+
class RandomSubarray < Minitest::Test
|
5
5
|
def test_random_subarray
|
6
6
|
result = [*1..5].random_subarray(3)
|
7
7
|
assert result.size == 3
|
@@ -0,0 +1,27 @@
|
|
1
|
+
require "minitest/autorun"
|
2
|
+
require "shenanigans/array/reductions"
|
3
|
+
|
4
|
+
class ArrayReductions < Minitest::Test
|
5
|
+
TEST_ARRAY = [*1..4]
|
6
|
+
|
7
|
+
def test_reductions_without_params_or_block
|
8
|
+
assert_raises(ArgumentError) { TEST_ARRAY.reductions }
|
9
|
+
end
|
10
|
+
|
11
|
+
def test_reductions_operator_only
|
12
|
+
assert TEST_ARRAY.reductions(:+) == [1, 3, 6, 10]
|
13
|
+
end
|
14
|
+
|
15
|
+
def test_reductions_initial_only
|
16
|
+
assert TEST_ARRAY.reductions(50) { |acc, b| acc + b } == [50, 51, 53, 56, 60]
|
17
|
+
end
|
18
|
+
|
19
|
+
def test_reductions_inital_and_operator
|
20
|
+
assert TEST_ARRAY.reductions(50, :+) == [50, 51, 53, 56, 60]
|
21
|
+
end
|
22
|
+
|
23
|
+
def test_reductions_without_params
|
24
|
+
assert TEST_ARRAY.reductions { |acc, b| acc + b } == [1, 3, 6, 10]
|
25
|
+
assert %w[a b c].reductions { |s1, s2| s1 + s2 } == %w[a ab abc]
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
require "minitest/autorun"
|
2
|
+
require "shenanigans/array/zip_with"
|
3
|
+
|
4
|
+
class ZipWith < Minitest::Test
|
5
|
+
def test_zip_with_with_symbol
|
6
|
+
result = [*1..3].zip_with([*1..3], :+)
|
7
|
+
assert result == [2, 4, 6]
|
8
|
+
end
|
9
|
+
|
10
|
+
def test_zip_with_with_block
|
11
|
+
result = [*"a".."c"].zip_with([*"a".."c"]) { |a, b| a * 2 + b.upcase }
|
12
|
+
assert result == %w[aaA bbB ccC]
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
require "minitest/autorun"
|
2
|
+
require "shenanigans/hash/extract"
|
3
|
+
|
4
|
+
class Extract < Minitest::Test
|
5
|
+
def test_extract
|
6
|
+
hash = { a: 1, b: 2, c: 3 }
|
7
|
+
assert_equal hash.extract(:b, :a), { a: 1, b: 2 }
|
8
|
+
assert_equal hash.extract(:a, :d), { a: 1 }
|
9
|
+
assert_equal({}.extract(:a, :c), {})
|
10
|
+
end
|
11
|
+
end
|
@@ -1,7 +1,7 @@
|
|
1
|
-
require
|
2
|
-
require
|
1
|
+
require "minitest/autorun"
|
2
|
+
require "shenanigans/hash/to_ostruct"
|
3
3
|
|
4
|
-
class ToOstruct <
|
4
|
+
class ToOstruct < Minitest::Test
|
5
5
|
def test_simple_hash
|
6
6
|
struct = {a: 1, b: 2}.to_ostruct
|
7
7
|
assert struct.a == 1
|
@@ -0,0 +1,16 @@
|
|
1
|
+
require "minitest/autorun"
|
2
|
+
require "shenanigans/integer/divisible_by"
|
3
|
+
|
4
|
+
class StringLength < Minitest::Test
|
5
|
+
def test_divide_by_zero
|
6
|
+
refute 3.divisible_by(0)
|
7
|
+
end
|
8
|
+
|
9
|
+
def test_not_divisible
|
10
|
+
refute 3.divisible_by(2)
|
11
|
+
end
|
12
|
+
|
13
|
+
def test_divisible
|
14
|
+
assert 9.divisible_by(3)
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
require "minitest/autorun"
|
2
|
+
require "shenanigans/integer/string_length"
|
3
|
+
|
4
|
+
class StringLength < Minitest::Test
|
5
|
+
def test_zero
|
6
|
+
assert 0.string_length == 1
|
7
|
+
end
|
8
|
+
|
9
|
+
def test_positive
|
10
|
+
assert 123.string_length == 3
|
11
|
+
end
|
12
|
+
|
13
|
+
def test_negative
|
14
|
+
assert(-1.string_length) == 2
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
require "minitest/autorun"
|
2
|
+
require "shenanigans/kernel/fn"
|
3
|
+
|
4
|
+
class Fn < Minitest::Test
|
5
|
+
def test_with_symbols
|
6
|
+
result = ["foo bar", "baz qux"].map(&fn(:split, :last))
|
7
|
+
assert result == ["bar", "qux"]
|
8
|
+
end
|
9
|
+
|
10
|
+
def test_with_symbols_and_lambdas
|
11
|
+
result = (1..3).map(&fn(:next, ->(x) { x * x }, ->(x) { x.to_f / 2 }))
|
12
|
+
assert result == [2.0, 4.5, 8.0]
|
13
|
+
end
|
14
|
+
end
|
@@ -1,8 +1,8 @@
|
|
1
|
-
require
|
2
|
-
require
|
3
|
-
require
|
1
|
+
require "minitest/autorun"
|
2
|
+
require "shenanigans/kernel/prompt"
|
3
|
+
require "stringio"
|
4
4
|
|
5
|
-
class Prompt <
|
5
|
+
class Prompt < Minitest::Test
|
6
6
|
def setup
|
7
7
|
@orig_stdin = $stderr
|
8
8
|
@orig_stdout = $stdout
|