shenanigans 1.0.10 → 1.0.15
Sign up to get free protection for your applications and to get access to all the features.
- 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
|