inactive_support 1.0.0 → 1.1.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.
data/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # InactiveSupport
2
2
 
3
- A collection of utilities for ruby projects.
3
+ A collection of utilities for ruby projects.
4
4
 
5
5
  ## Installation
6
6
 
@@ -21,22 +21,22 @@ Or install it yourself as:
21
21
  ### Object
22
22
  #### #identity
23
23
  returns self
24
-
24
+
25
25
  [1,2,3,3,4,5,5].group_by(&:identity)
26
26
  # => [[1], [2], [3,3], [4], [5,5]]
27
-
27
+
28
28
  #### #try
29
29
  send a message to the receiver and if it doesn't respond to the message, return nil
30
30
 
31
31
  "".try(:some_method)
32
32
  # => nil
33
-
33
+
34
34
  #### #ctry
35
35
  chained try, for methods with no arguments
36
36
 
37
37
  "Somestring".ctry(:mb_chars, :downcase, :some_method)
38
38
  # => nil
39
-
39
+
40
40
  ### Hash
41
41
  #### #delete_blank
42
42
  Deletes all key/value pairs where the value is an empty string/array/hash or nil.
@@ -50,7 +50,7 @@ groups objects by an attribute that is consecutive
50
50
 
51
51
  [1,2,3,5,6,8,9].consecutive_by(&:identity)
52
52
  # => [[1,2,3],[5,6],[8,9]]
53
-
53
+
54
54
 
55
55
  ## Contributing
56
56
 
@@ -0,0 +1,38 @@
1
+ # encoding: utf-8
2
+ module Enumerable
3
+ def consecutive_by
4
+ sorted = sort { |a, b| _ordinal(yield(a)) <=> _ordinal(yield(b)) }
5
+
6
+ prev = sorted.first
7
+
8
+ sorted.slice_before do |cur|
9
+ prev, prev2 = cur, prev
10
+ _ordinal(yield(prev2)) + 1 != _ordinal(yield(prev))
11
+ end.to_a
12
+ end
13
+
14
+ def consecutive?(&block)
15
+ if block_given?
16
+ consecutive_by(&block).count == 1 && self.sorted?(&block)
17
+ else
18
+ consecutive_by(&:identity).count == 1 && self.sorted?(&block)
19
+ end
20
+ end
21
+
22
+ def sorted?
23
+ if block_given?
24
+ each_cons(2).all? do |a, b|
25
+ (_ordinal(yield(a)) <=> _ordinal(yield(b))) <= 0
26
+ end
27
+ else
28
+ each_cons(2).all? do |a, b|
29
+ (_ordinal(a).to_i <=> _ordinal(b).to_i) <= 0
30
+ end
31
+ end
32
+ end
33
+
34
+ private
35
+ def _ordinal(string)
36
+ string.to_s.gsub(/[a-zA-Z]/) { |c| c.ord }.to_i
37
+ end
38
+ end
@@ -0,0 +1 @@
1
+ require 'inactive_support/enumerable/consecutive_by'
@@ -1,8 +1,15 @@
1
1
  class Hash
2
- # Deletes all key/value pairs where the value is empty string/array/hash or nil.
2
+ # Deletes all key/value pairs where the value is empty string/array/hash or nil.
3
3
  def delete_blank
4
- delete_if do |k, v|
5
- (v.blank? && v != false) or v.instance_of?(Hash) && v.delete_blank.empty?
4
+ delete_if do |_, v|
5
+ (v.blank? && v != false)
6
+ end
7
+ end
8
+
9
+ # Recursively deletes all key/value pairs where the value is empty string/array/hash or nil.
10
+ def deep_delete_blank
11
+ delete_if do |_, v|
12
+ (v.blank? && v != false) || v.instance_of?(Hash) && v.deep_delete_blank.empty?
6
13
  end
7
14
  end
8
15
  end
@@ -1,20 +1,20 @@
1
+ # A more precise rounding. ~4 times slower than simple round
2
+ #
3
+ # 3.904605.round(2)
4
+ # # => 3.9
5
+ # 3.904605.precision(2)
6
+ # # => 3.91
7
+ #
8
+ # 37.9945.round(2)
9
+ # # => 37.99
10
+ # 37.9945.precision(2)
11
+ # # => 38.0
1
12
  class Numeric
2
- # A more precise rounding. ~4 times slower than simple round
3
- #
4
- # 3.904605.round(2)
5
- # # => 3.9
6
- # 3.904605.precision(2)
7
- # # => 3.91
8
- #
9
- # 37.9945.round(2)
10
- # # => 37.99
11
- # 37.9945.precision(2)
12
- # # => 38.0
13
13
  def precision(precision = 0)
14
- power = 10 ** precision
14
+ power = 10**precision
15
15
 
16
16
  if precision == 0
17
- self.round
17
+ round
18
18
  else
19
19
  powered = self * power
20
20
 
@@ -3,7 +3,7 @@ class Object
3
3
  #
4
4
  # ==== Examples
5
5
  #
6
- # [1,2,3,5,7].consecutive_by(:identity)
6
+ # [1,2,3,5,7].consecutive_by(&:identity)
7
7
  # => [[1, 2, 3], [5], [7]]
8
8
  def identity
9
9
  if block_given?
@@ -13,5 +13,3 @@ class Object
13
13
  end
14
14
  end
15
15
  end
16
-
17
-
@@ -1,5 +1,4 @@
1
1
  class Object
2
-
3
2
  # Credit goes to the active_support contributors
4
3
  # https://github.com/rails/rails/blob/master/activesupport/lib/active_support/core_ext/object/try.rb
5
4
  #
@@ -14,25 +13,23 @@ class Object
14
13
  end
15
14
  end
16
15
 
17
-
18
16
  # Chained try allows writing
19
17
  #
20
18
  # str.ctry(:mb_chars, :downcase, :dasherize)
21
19
  #
22
20
  # instead of
23
- #
21
+ #
24
22
  # str.try(:mb_chars).try(:downcase).try(:dasherize)
25
23
  #
26
- # Only works for methods that don't take arguments.
24
+ # Only works for methods that don't take any arguments.
27
25
  def ctry(*args)
28
26
  first, *rest = args
29
27
  if rest.any?
30
- self.try(first).ctry(*rest)
28
+ try(first).ctry(*rest)
31
29
  else
32
- self.try(first)
30
+ try(first)
33
31
  end
34
32
  end
35
-
36
33
  end
37
34
 
38
35
  class NilClass
@@ -43,5 +40,4 @@ class NilClass
43
40
  def ctry(*args)
44
41
  nil
45
42
  end
46
-
47
43
  end
@@ -1,3 +1,3 @@
1
1
  module InactiveSupport
2
- VERSION = "1.0.0"
2
+ VERSION = "1.1.0"
3
3
  end
@@ -0,0 +1,77 @@
1
+ require 'spec_helper'
2
+ require 'inactive_support/enumerable'
3
+
4
+ describe Enumerable do
5
+ let(:simple_man) { Struct.new(:name, :age) }
6
+ let(:mitko) { simple_man.new('Mitko', 10) }
7
+ let(:goshko) { simple_man.new('Goshko', 11) }
8
+ let(:krasi) { simple_man.new('Krasi', 13) }
9
+ let(:dedo) { simple_man.new('Dedo', 15) }
10
+
11
+ describe '.consecutive_by' do
12
+ it 'partitions lists by consecutive attribute' do
13
+ simple_people = [mitko, goshko, krasi, dedo]
14
+
15
+ simple_people.consecutive_by(&:age).should eq [[mitko, goshko], [krasi], [dedo]]
16
+ end
17
+
18
+ it 'sorts by the given method before partitioning' do
19
+ simple_people = [goshko, krasi, dedo, mitko]
20
+
21
+ simple_people.consecutive_by(&:age).should eq [[mitko, goshko], [krasi], [dedo]]
22
+ end
23
+
24
+ it 'works on bare arrays' do
25
+ ary = [1, 2, 3, 5, 7, 8, 11, 12]
26
+
27
+ ary.consecutive_by(&:identity).should eq [[1, 2, 3], [5], [7, 8], [11, 12]]
28
+ end
29
+
30
+ describe 'with letters somewhere in the number' do
31
+
32
+ it 'works if the letter is in the beginning' do
33
+ ary = %w(A1 A2 A3 A5 A6)
34
+ expected = [%w(A1 A2 A3), %w(A5 A6)]
35
+
36
+ expect(ary.consecutive_by(&:identity)).to eq expected
37
+ end
38
+
39
+ it 'works if the letter is in the middle' do
40
+ ary = %w(12A12 12A13 12A14 12A16 12A17)
41
+ expected = [%w(12A12 12A13 12A14), %w(12A16 12A17)]
42
+
43
+ expect(ary.consecutive_by(&:identity)).to eq expected
44
+ end
45
+
46
+ it 'differentiates letters' do
47
+ ary = %w(A1 B2 A3 A5 A6)
48
+ expected = [%w(A1), %w(A3), %w(A5 A6), %w(B2)]
49
+
50
+ expect(ary.consecutive_by(&:identity)).to eq expected
51
+ end
52
+
53
+ end
54
+
55
+ end
56
+
57
+ describe '.consecutive?' do
58
+
59
+ it 'returns true if the objects are consecutive by the given key' do
60
+ consecutive_people = [mitko, goshko]
61
+ non_consecutive_people = [mitko, goshko, krasi]
62
+
63
+ consecutive_people.consecutive?(&:age).should be_true
64
+
65
+ non_consecutive_people.consecutive?(&:age).should be_false
66
+ end
67
+
68
+ it 'uses identity on the objects if no key is given' do
69
+ [1, 2, 3, 4].consecutive?.should be_true
70
+ [1, 2, 3, 5].consecutive?.should be_false
71
+ [2, 1, 3, 5].consecutive?.should be_false
72
+ [].consecutive?.should be_false
73
+ end
74
+
75
+ end
76
+
77
+ end
@@ -74,4 +74,104 @@ describe Hash do
74
74
 
75
75
  end
76
76
 
77
+ describe "#deep_delete_blank" do
78
+
79
+ it 'deletes nils' do
80
+ initial = {
81
+ id: 1,
82
+ name: {
83
+ first: nil,
84
+ middle: "Peter"
85
+ }
86
+ }
87
+
88
+ expected = {
89
+ id: 1,
90
+ name: {
91
+ middle: "Peter"
92
+ }
93
+ }
94
+
95
+ initial.deep_delete_blank.should eq expected
96
+ end
97
+
98
+ it 'deletes empty strings' do
99
+ initial = {
100
+ id: 1,
101
+ name: {
102
+ first: "",
103
+ middle: "Peter"
104
+ }
105
+ }
106
+
107
+ expected = {
108
+ id: 1,
109
+ name: {
110
+ middle: "Peter"
111
+ }
112
+ }
113
+
114
+ initial.deep_delete_blank.should eq expected
115
+ end
116
+
117
+ it 'preserves false values' do
118
+ initial = {
119
+ id: 1,
120
+ name: {
121
+ first: false,
122
+ middle: "Peter"
123
+ }
124
+ }
125
+
126
+ expected = {
127
+ id: 1,
128
+ name: {
129
+ first: false,
130
+ middle: "Peter"
131
+ }
132
+ }
133
+
134
+ initial.deep_delete_blank.should eq expected
135
+ end
136
+
137
+ it 'deletes empty arrays' do
138
+ initial = {
139
+ id: 1,
140
+ name: {
141
+ addresses: [],
142
+ middle: "Peter"
143
+ }
144
+ }
145
+
146
+ expected = {
147
+ id: 1,
148
+ name: {
149
+ middle: "Peter"
150
+ }
151
+ }
152
+
153
+ initial.deep_delete_blank.should eq expected
154
+
155
+ end
156
+ it 'deletes empty hashes' do
157
+ initial = {
158
+ id: 1,
159
+ name: {
160
+ children: {},
161
+ middle: "Peter"
162
+ }
163
+ }
164
+
165
+ expected = {
166
+ id: 1,
167
+ name: {
168
+ middle: "Peter"
169
+ }
170
+ }
171
+
172
+ initial.deep_delete_blank.should eq expected
173
+ end
174
+
175
+ end
176
+
77
177
  end
metadata CHANGED
@@ -1,55 +1,62 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: inactive_support
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 1.1.0
5
+ prerelease:
5
6
  platform: ruby
6
7
  authors:
7
8
  - gmitrev
8
9
  autorequire:
9
10
  bindir: bin
10
11
  cert_chain: []
11
- date: 2014-04-26 00:00:00.000000000 Z
12
+ date: 2015-05-07 00:00:00.000000000 Z
12
13
  dependencies:
13
14
  - !ruby/object:Gem::Dependency
14
15
  name: bundler
15
16
  requirement: !ruby/object:Gem::Requirement
17
+ none: false
16
18
  requirements:
17
- - - "~>"
19
+ - - ~>
18
20
  - !ruby/object:Gem::Version
19
21
  version: '1.3'
20
22
  type: :development
21
23
  prerelease: false
22
24
  version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
23
26
  requirements:
24
- - - "~>"
27
+ - - ~>
25
28
  - !ruby/object:Gem::Version
26
29
  version: '1.3'
27
30
  - !ruby/object:Gem::Dependency
28
31
  name: rake
29
32
  requirement: !ruby/object:Gem::Requirement
33
+ none: false
30
34
  requirements:
31
- - - ">="
35
+ - - ! '>='
32
36
  - !ruby/object:Gem::Version
33
37
  version: '0'
34
38
  type: :development
35
39
  prerelease: false
36
40
  version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
37
42
  requirements:
38
- - - ">="
43
+ - - ! '>='
39
44
  - !ruby/object:Gem::Version
40
45
  version: '0'
41
46
  - !ruby/object:Gem::Dependency
42
47
  name: rspec
43
48
  requirement: !ruby/object:Gem::Requirement
49
+ none: false
44
50
  requirements:
45
- - - "~>"
51
+ - - ~>
46
52
  - !ruby/object:Gem::Version
47
53
  version: '2.6'
48
54
  type: :development
49
55
  prerelease: false
50
56
  version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
51
58
  requirements:
52
- - - "~>"
59
+ - - ~>
53
60
  - !ruby/object:Gem::Version
54
61
  version: '2.6'
55
62
  description: A collection of utilities and extensions
@@ -59,14 +66,16 @@ executables: []
59
66
  extensions: []
60
67
  extra_rdoc_files: []
61
68
  files:
62
- - ".gitignore"
63
- - ".rspec"
69
+ - .gitignore
70
+ - .rspec
64
71
  - Gemfile
65
72
  - LICENSE.txt
66
73
  - README.md
67
74
  - Rakefile
68
75
  - inactive_support.gemspec
69
76
  - lib/inactive_support.rb
77
+ - lib/inactive_support/enumerable.rb
78
+ - lib/inactive_support/enumerable/consecutive_by.rb
70
79
  - lib/inactive_support/hash.rb
71
80
  - lib/inactive_support/hash/delete_blank.rb
72
81
  - lib/inactive_support/numeric.rb
@@ -76,6 +85,7 @@ files:
76
85
  - lib/inactive_support/object/identity.rb
77
86
  - lib/inactive_support/object/try.rb
78
87
  - lib/inactive_support/version.rb
88
+ - spec/lib/enumerable_spec.rb
79
89
  - spec/lib/hash_spec.rb
80
90
  - spec/lib/numeric_spec.rb
81
91
  - spec/lib/object_spec.rb
@@ -83,28 +93,36 @@ files:
83
93
  homepage: ''
84
94
  licenses:
85
95
  - MIT
86
- metadata: {}
87
96
  post_install_message:
88
97
  rdoc_options: []
89
98
  require_paths:
90
99
  - lib
91
100
  required_ruby_version: !ruby/object:Gem::Requirement
101
+ none: false
92
102
  requirements:
93
- - - ">="
103
+ - - ! '>='
94
104
  - !ruby/object:Gem::Version
95
105
  version: '0'
106
+ segments:
107
+ - 0
108
+ hash: -4215888734430273764
96
109
  required_rubygems_version: !ruby/object:Gem::Requirement
110
+ none: false
97
111
  requirements:
98
- - - ">="
112
+ - - ! '>='
99
113
  - !ruby/object:Gem::Version
100
114
  version: '0'
115
+ segments:
116
+ - 0
117
+ hash: -4215888734430273764
101
118
  requirements: []
102
119
  rubyforge_project:
103
- rubygems_version: 2.2.2
120
+ rubygems_version: 1.8.23
104
121
  signing_key:
105
- specification_version: 4
122
+ specification_version: 3
106
123
  summary: Snippets and useful stuff extracted from my projects
107
124
  test_files:
125
+ - spec/lib/enumerable_spec.rb
108
126
  - spec/lib/hash_spec.rb
109
127
  - spec/lib/numeric_spec.rb
110
128
  - spec/lib/object_spec.rb
checksums.yaml DELETED
@@ -1,7 +0,0 @@
1
- ---
2
- SHA1:
3
- metadata.gz: 4fb7998869a0bba3ac1bb5605f625f65f2684c5d
4
- data.tar.gz: 649925baa3a002f3d57f40b59d2d6c034ae061ac
5
- SHA512:
6
- metadata.gz: 74563eae66da697c6689860fa20beb6dffbda7e19295c6006443193b958e3f201488713de146afdfb1c8f27b34ef3d42a0c0e7bbdacd00d88ba1c31d46330a33
7
- data.tar.gz: becbcbaa2fbbe33510ee8d9b6726e2d7efa37474c90edf5c30c19686d37ed1446406da7e2654e5514b4a195f00af359711ebc2aff93bf0ea4af1ed9800b06613