attr_bitwise 0.0.1 → 0.0.2

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: 1c7bc7f15d2c51cdaa8e8fc01987c4b3e500d89a
4
- data.tar.gz: fe4fbf205f6c998ea684a45f56e61a833623e1fc
3
+ metadata.gz: 0fe35e1015d6b3d56fad87e17480767740a23dd0
4
+ data.tar.gz: c0ca410c937a40d73eab1b8dac53087cd93c4ab2
5
5
  SHA512:
6
- metadata.gz: 5aaa7af4fc47354187a8c654f296642d7a0699ebac3676d5ef6891895b730da09b674f8dba5f639d9b7e003605d85f5a87fb780da880f29e8531a562dc809866
7
- data.tar.gz: b70fcaf5b88f2eaea060277a4860c1e018a714002ddcf7fb76f5d33fb4a5a99e5c30a08f42acad45ce4b2c44cb6c7ca50a613c61b7a1d07a9f207e2da5460f83
6
+ metadata.gz: ddb05f9230a5a78c3f4534422eb8ec36c1ccabea059ce52a0b8fbc03456e468e59a64c3c7104afe9adfc5134c339223d94042d980d9e958359ed27fe96065927
7
+ data.tar.gz: 29bc9ace8d2e82f5459802ebd7e69d3a4978ef9712b6814a6742de4bd0606f0e78a1a2d2fdf3841aa2cd141dbda74646ba6baf9e106c977ac85a363ca353311f
data/Gemfile CHANGED
@@ -1,3 +1,5 @@
1
1
  source 'https://rubygems.org'
2
2
 
3
+ ruby '2.1.1'
4
+
3
5
  gemspec
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- attr_bitwise (0.0.1)
4
+ attr_bitwise (0.0.2)
5
5
  activesupport
6
6
 
7
7
  GEM
@@ -43,3 +43,6 @@ DEPENDENCIES
43
43
  bundler (~> 1.6)
44
44
  rake
45
45
  rspec
46
+
47
+ BUNDLED WITH
48
+ 1.10.6
data/README.md CHANGED
@@ -1,36 +1,12 @@
1
- # `attr_bitwise`
1
+ # `attr_bitwise` ![https://circleci.com/gh/wittydeveloper/attr_bitwise.png?circle-token=7f58370c3b13faaf1954b9e8fe6c7b1fb329daf2](https://circleci.com/gh/wittydeveloper/attr_bitwise.png?circle-token=7f58370c3b13faaf1954b9e8fe6c7b1fb329daf2) [![Gem Version](https://badge.fury.io/rb/attr_bitwise.svg)](https://badge.fury.io/rb/attr_bitwise)
2
2
  Bitwise attribute for ruby class and Rails model
3
3
 
4
- ```ruby
5
- # Helper to define a bits based value on a Rails model attribute
6
- # this helper expose a set of methods to make bitwise operations
7
- #
8
- #
9
- # Usage :
10
- # attr_bitwise :<name>, [column_name: <column_name>,] mapping: <values_sym>
11
- #
12
- # Example
13
- # class MyModel < ActiveRecord::Base
14
- # include BitwiseUtils
15
- #
16
- # attr_bitwise :payment_types, mapping: [:slots, :credits]
17
- # end
18
- #
19
- # Will define the following high-level methods :
20
- # - Class#payment_types => [<Symbol>, ...]
21
- # - Class#payment_type?(value_or_sym) => Boolean
22
- # - Class#add_payment_type(value_or_sym) => Fixnum
23
- # - Class#remove_payment_type(value_or_sym) => Fixnum
24
- #
25
- # Will define the following low-level methods :
26
- # - Class.to_bitwise_values(object, name) => [<Fixnum>, ...]
27
- # - Class#payment_types_union([Fixnum, ..]) => [Fixnum, ..]
28
- # - Class.bitwise_union([Fixnum, ..], name) => [Fixnum, ..]
29
- # - Class#payment_types_intersection([Fixnum, ..]) => [Fixnum, ..]
30
- # - Class.bitwise_intersection([Fixnum, ..], name) => [Fixnum, ..]
31
- # - Class#payment_types_mapping => Hash
32
- #
33
- ```
4
+ ## Features
5
+
6
+ - bitwise attribute + helpers, useful for storing multiple states in one place
7
+ - ActiveRecord compatible
8
+
9
+ [Please read this article for some concrete examples](https://medium.com/jobteaser-dev-team/rails-bitwise-enum-with-super-powers-5030bda5dbab)
34
10
 
35
11
 
36
12
  ## Install
@@ -38,12 +14,230 @@ Bitwise attribute for ruby class and Rails model
38
14
 
39
15
  ### Inline
40
16
 
41
- - `gem install bitwise_attr`
17
+ - `gem install attr_bitwise`
42
18
 
43
19
  ### Gemfile
44
20
 
45
- - `gem 'bitwise_attr'`
21
+ - `gem 'attr_bitwise'`
22
+
23
+
24
+ ## Usage
25
+
26
+ ```ruby
27
+ attr_bitwise :<name>, mapping: <values_sym> [, column_name: <column_name>]
28
+ ```
29
+
30
+ ## Example
31
+
32
+ You have a website with many locales (English, French, German...) with specific content in each locale. You want your users to be able to chose which content they want to see and you want to be able to query the users by the locales they have choosen.
33
+
34
+ Start with migration
35
+ ```ruby
36
+ class CreateUsers < ActiveRecord::Migration
37
+ def change
38
+ create_table :users do |t|
39
+ # [...]
40
+ t.integer :locales_value
41
+ end
42
+ end
43
+ end
44
+ ```
45
+
46
+ Model
47
+ ```ruby
48
+
49
+ class User < ActiveRecord::Base
50
+ include AttrBitwise
51
+
52
+ attr_bitwise :locales, mapping: [:en, :fr, :de]
53
+
54
+ scope :with_any_locales, lambda { |*locales_sym|
55
+ where(locales_value: bitwise_union(*locales_sym, 'locales'))
56
+ }
57
+
58
+ scope :with_all_locales, lambda { |*locales_sym|
59
+ where(locales_value: bitwise_intersection(*locales_sym, 'locales'))
60
+ }
61
+
62
+ end
63
+
64
+ ###
65
+
66
+ # return all users who can see at least english or french content
67
+ User.with_any_locales(:en, :fr)
68
+
69
+ # return all users who can see english and french content
70
+ User.with_all_locales(:en, :fr)
71
+
72
+ ```
73
+
74
+
75
+ ## API
76
+
77
+ **Examples with <code>name = 'locales'</code>**
78
+
79
+ ### High level methods
80
+ <table>
81
+ <tr>
82
+ <th>Method</th>
83
+ <th>Return</th>
84
+ <th>Description</th>
85
+ </tr>
86
+ <tr>
87
+ <td>
88
+ <code>Class#locales</code>
89
+ </td>
90
+ <td>
91
+ <code>[<Symbol>, ...]</code>
92
+ </td>
93
+ <td>
94
+ Return values as symbols
95
+ </td>
96
+ </tr>
97
+ <tr>
98
+ <td>
99
+ <code>Class#locales=([value_or_sym, ..])</code>
100
+ </td>
101
+ <td>
102
+ <code>[<Symbol>, ...]</code>
103
+ </td>
104
+ <td>
105
+ Given an array of values (Fixnum or Symbol) or single value (Fixnum or Symbol) add them to value.
106
+ </td>
107
+ </tr>
108
+ <tr>
109
+ <td>
110
+ <code>Class#locale == fixnum_or_sym</code>
111
+ </td>
112
+ <td>
113
+ <code>Boolean</code>
114
+ </td>
115
+ <td>
116
+ Return true if value contains only Fixnum or Symbol
117
+ </td>
118
+ </tr>
119
+ <tr>
120
+ <td>
121
+ <code>Class#locale?(fixnum_or_sym)</code>
122
+ </td>
123
+ <td>
124
+ <code>Boolean</code>
125
+ </td>
126
+ <td>
127
+ Return true if value contains Fixnum or Symbol
128
+ </td>
129
+ </tr>
130
+ <tr>
131
+ <td>
132
+ <code>Class#add_locale(value_or_sym)</code>
133
+ </td>
134
+ <td>
135
+ <code>Fixnum</code>
136
+ </td>
137
+ <td>
138
+ Add Fixnum or Symbol to value
139
+ </td>
140
+ </tr>
141
+ <tr>
142
+ <td>
143
+ <code>Class#remove_locale(value_or_sym)</code>
144
+ </td>
145
+ <td>
146
+ <code>Fixnum</code>
147
+ </td>
148
+ <td>
149
+ Remove Fixnum or Symbol to value
150
+ </td>
151
+ </tr>
152
+ <tr>
153
+ <td>
154
+ <code>Class#locales_union([value_or_sym, ..])</code>
155
+ </td>
156
+ <td>
157
+ <code>[Fixnum, ..]</code>
158
+ </td>
159
+ <td>
160
+ Given an array of values (Fixnum or Symbol), return bitwise union computation <br>
161
+ Return all possible values (mask) for an union of given values
162
+ </td>
163
+ </tr>
164
+ <tr>
165
+ <td>
166
+ <code>Class#locales_intersection([value_or_sym, ..])</code>
167
+ </td>
168
+ <td>
169
+ <code>[Fixnum, ..]</code>
170
+ </td>
171
+ <td>
172
+ Given an array of values (Fixnum or Symbol), return bitwise intersection computation <br>
173
+ Return all possible values (mask) for an intersection of given values
174
+ </td>
175
+ </tr>
176
+ <tr>
177
+ <td>
178
+ <code>Class#locales_mapping</code>
179
+ </td>
180
+ <td>
181
+ <code>Hash</code>
182
+ </td>
183
+ <td>
184
+ Return <code>Symbol</code> -> <code>Fixnum</code> mapping
185
+ </td>
186
+ </tr>
187
+
188
+
189
+ </table>
190
+
191
+
192
+ ### Low level methods
193
+
194
+ *Theses methods are static, so a <code>name</code> parameters is mandatory in order to fetch mapping*
195
+
196
+
197
+ <table>
198
+ <tr>
199
+ <th>Method</th>
200
+ <th>Return</th>
201
+ <th>Description</th>
202
+ </tr>
203
+ <tr>
204
+ <td>
205
+ <code>Class.to_bitwise_values(object, name)</code>
206
+ </td>
207
+ <td>
208
+ <code>[Fixnum, ...]</code>
209
+ </td>
210
+ <td>
211
+ Given an Object and a attribute name, return Fixnum value depending on mapping
212
+ </td>
213
+ </tr>
214
+ <tr>
215
+ <td>
216
+ <code>Class.bitwise_union([Fixnum, ..], name)</code>
217
+ </td>
218
+ <td>
219
+ <code>[Fixnum, ..]</code>
220
+ </td>
221
+ <td>
222
+ Given an array of values (Fixnum or Symbol) and a attribute name, return bitwise union computation <br>
223
+ Return all possible values (mask) for an union of given values
224
+ </td>
225
+ </tr>
226
+ <tr>
227
+ <td>
228
+ <code>Class.bitwise_intersection([Fixnum, ..], name)</code>
229
+ </td>
230
+ <td>
231
+ <code>[Fixnum, ..]</code>
232
+ </td>
233
+ <td>
234
+ Given an array of values (Fixnum or Symbol) and a attribute name, return bitwise intersection computation <br>
235
+ Return all possible values (mask) for an intersection of given values
236
+ </td>
237
+ </tr>
238
+
239
+ </table>
46
240
 
47
241
 
48
242
  ----------------------------------------
49
- Maintainers : @wittydeveloper and @FSevaistre
243
+ Maintainers : [@wittydeveloper](https://github.com/wittydeveloper) and [@FSevaistre](https://github.com/FSevaistre)
data/circle.yml ADDED
@@ -0,0 +1,3 @@
1
+ machine:
2
+ ruby:
3
+ version: 2.1.1
@@ -1,3 +1,3 @@
1
1
  module AttrBitwise
2
- VERSION = "0.0.1"
2
+ VERSION = "0.0.2"
3
3
  end
data/lib/attr_bitwise.rb CHANGED
@@ -12,7 +12,7 @@ require "attr_bitwise/version"
12
12
  #
13
13
  # Example
14
14
  # class MyModel < ActiveRecord::Base
15
- # include BitwiseUtils
15
+ # include AttrBitwise
16
16
  #
17
17
  # attr_bitwise :payment_types, mapping: [:slots, :credits]
18
18
  # end
@@ -35,6 +35,21 @@ require "attr_bitwise/version"
35
35
  module AttrBitwise
36
36
  extend ActiveSupport::Concern
37
37
 
38
+
39
+ # Custom class that allow to use shortcut :
40
+ # my_column == :banana
41
+ # instead of
42
+ # my_column == [:banana]
43
+ class ComparableSymbolsArray < Array
44
+ def ==(other_object)
45
+ if other_object.is_a?(Symbol)
46
+ self.size == 1 && self.first == other_object
47
+ else
48
+ super(other_object)
49
+ end
50
+ end
51
+ end
52
+
38
53
  # ClassMethods
39
54
  module ClassMethods
40
55
  ######################
@@ -59,10 +74,7 @@ module AttrBitwise
59
74
  define_method("#{name}") { send(:value_getter, bitwise_mapping) }
60
75
 
61
76
  define_method("#{name}=") do |values_or_symbols_array|
62
- unless values_or_symbols_array.is_a?(Array)
63
- values_or_symbols_array = [values_or_symbols_array]
64
- end
65
- send(:value_setter, values_or_symbols_array, bitwise_mapping)
77
+ send(:value_setter, Array(values_or_symbols_array), bitwise_mapping)
66
78
  end
67
79
 
68
80
  # masks symbol presence
@@ -199,8 +211,10 @@ module AttrBitwise
199
211
  # Return current value to symbols array
200
212
  # Ex : 011 => :slots, :credits
201
213
  def value_getter(mapping)
202
- mapping.values.select { |pv| (value & pv) != 0 }.
203
- map { |v| value_to_sym(v, mapping) }
214
+ ComparableSymbolsArray.new(
215
+ mapping.values.select { |pv| (value & pv) != 0 }.
216
+ map { |v| value_to_sym(v, mapping) }
217
+ )
204
218
  end
205
219
 
206
220
  # Set current values from values array
@@ -7,12 +7,12 @@ describe AttrBitwise do
7
7
 
8
8
  include AttrBitwise
9
9
 
10
- attr_accessor :payment_types_value
10
+ attr_accessor :fruits_value
11
11
 
12
- attr_bitwise :payment_types, mapping: [:slots, :credits]
12
+ attr_bitwise :fruits, mapping: [:banana, :apple]
13
13
 
14
14
  def initialize
15
- @payment_types_value = 0
15
+ @fruits_value = 0
16
16
  end
17
17
 
18
18
  end
@@ -26,10 +26,10 @@ describe AttrBitwise do
26
26
  expect(
27
27
  TestClass.to_bitwise_values(
28
28
  {
29
- a: :credits,
30
- b: :slots
29
+ a: :apple,
30
+ b: :banana
31
31
  },
32
- 'payment_types'
32
+ 'fruits'
33
33
  )
34
34
  ).to eq [2, 1]
35
35
  end
@@ -38,101 +38,121 @@ describe AttrBitwise do
38
38
  context 'with Array argument' do
39
39
  it do
40
40
  expect(TestClass.to_bitwise_values(
41
- [:credits, :slots],
42
- 'payment_types'
41
+ [:apple, :banana],
42
+ 'fruits'
43
43
  )).to eq [2, 1]
44
44
  end
45
45
  end
46
46
 
47
47
  context 'with Fixnum argument' do
48
48
  it do
49
- expect(TestClass.to_bitwise_values(1, 'payment_types')).to eq 1
49
+ expect(TestClass.to_bitwise_values(1, 'fruits')).to eq 1
50
50
  end
51
51
  end
52
52
 
53
53
  end
54
54
 
55
- context 'with `payment_types` attribute_name' do
55
+ context 'with `fruits` attribute_name' do
56
56
 
57
- context '#payment_types=' do
57
+ context '#fruits=' do
58
58
 
59
- before { subject.payment_types = [:slots, :credits] }
59
+ before { subject.fruits = [:banana, :apple] }
60
60
 
61
61
  it 'should set proper value' do
62
- expect(subject.payment_types_value).to eq 3
63
- expect(subject.payment_types).to eq [:slots, :credits]
62
+ expect(subject.fruits_value).to eq 3
63
+ expect(subject.fruits).to eq [:banana, :apple]
64
64
  end
65
65
 
66
66
  end
67
67
 
68
- context 'with `payment_types_value` = 0' do
69
- context '#payment_types' do
68
+ context '#fruits==' do
69
+
70
+ context 'when value is incorrect' do
71
+ before { subject.fruits = [:banana, :apple] }
72
+
73
+ it do
74
+ expect(subject.fruits == :banana).to eq false
75
+ end
76
+ end
77
+
78
+ context 'when value is correct' do
79
+ before { subject.fruits = [:banana] }
80
+
81
+ it do
82
+ expect(subject.fruits == :banana).to eq true
83
+ end
84
+ end
85
+
86
+ end
87
+
88
+ context 'with `fruits_value` = 0' do
89
+ context '#fruits' do
70
90
 
71
91
  it do
72
- expect(subject.payment_types).to eq []
92
+ expect(subject.fruits).to eq []
73
93
  end
74
94
 
75
95
  end
76
96
 
77
- context '#add_payment_type' do
97
+ context '#add_fruit' do
78
98
 
79
99
  it do
80
- subject.add_payment_type(:slots)
81
- expect(subject.payment_types).to eq [:slots]
100
+ subject.add_fruit(:banana)
101
+ expect(subject.fruits).to eq [:banana]
82
102
  end
83
103
 
84
104
  context 'when called twice, each type remains unique' do
85
105
  it do
86
- subject.add_payment_type(:slots)
87
- subject.add_payment_type(:slots)
88
- expect(subject.payment_types).to eq [:slots]
106
+ subject.add_fruit(:banana)
107
+ subject.add_fruit(:banana)
108
+ expect(subject.fruits).to eq [:banana]
89
109
  end
90
110
  end
91
111
 
92
112
  end
93
113
 
94
- context '#payment_type?(:slots)' do
114
+ context '#fruit?(:banana)' do
95
115
 
96
116
  it do
97
- expect(subject.payment_type?(:slots)).to eq false
117
+ expect(subject.fruit?(:banana)).to eq false
98
118
  end
99
119
 
100
120
  end
101
121
  end
102
122
 
103
- context 'with `payment_types_value` = 3' do
123
+ context 'with `fruits_value` = 3' do
104
124
 
105
- before { subject.payment_types_value = 3 }
125
+ before { subject.fruits_value = 3 }
106
126
 
107
- context '#payment_types' do
127
+ context '#fruits' do
108
128
 
109
129
  it do
110
- expect(subject.payment_types).to eq [:slots, :credits]
130
+ expect(subject.fruits).to eq [:banana, :apple]
111
131
  end
112
132
 
113
133
  end
114
134
 
115
- context '#payment_type?(:slots)' do
135
+ context '#fruit?(:banana)' do
116
136
 
117
137
  it do
118
- expect(subject.payment_type?(:slots)).to eq true
138
+ expect(subject.fruit?(:banana)).to eq true
119
139
  end
120
140
 
121
141
  end
122
142
 
123
- context '#remove_payment_type' do
143
+ context '#remove_fruit' do
124
144
 
125
145
  it do
126
- subject.remove_payment_type(:slots)
127
- expect(subject.payment_types).to eq [:credits]
146
+ subject.remove_fruit(:banana)
147
+ expect(subject.fruits).to eq [:apple]
128
148
  end
129
149
 
130
150
  end
131
151
 
132
- context '#payment_types_union' do
152
+ context '#fruits_union' do
133
153
 
134
154
  it do
135
- expect(subject.payment_types_union(1, 2)).to eq [1, 3, 2]
155
+ expect(subject.fruits_union(1, 2)).to eq [1, 3, 2]
136
156
  end
137
157
 
138
158
  end
@@ -141,7 +161,7 @@ describe AttrBitwise do
141
161
 
142
162
  it do
143
163
  expect(
144
- TestClass.bitwise_union(1, 2, 'payment_types')
164
+ TestClass.bitwise_union(1, 2, 'fruits')
145
165
  ).to eq [1, 3, 2]
146
166
  end
147
167
 
@@ -151,7 +171,7 @@ describe AttrBitwise do
151
171
 
152
172
  it do
153
173
  expect(
154
- TestClass.bitwise_intersection(1, 2, 'payment_types')
174
+ TestClass.bitwise_intersection(1, 2, 'fruits')
155
175
  ).to eq [3]
156
176
  end
157
177
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: attr_bitwise
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Charly POLY
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-02-24 00:00:00.000000000 Z
11
+ date: 2016-04-01 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -80,6 +80,7 @@ files:
80
80
  - README.md
81
81
  - Rakefile
82
82
  - attr_bitwise.gemspec
83
+ - circle.yml
83
84
  - lib/attr_bitwise.rb
84
85
  - lib/attr_bitwise/version.rb
85
86
  - spec/attr_bitwise_spec.rb
@@ -103,7 +104,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
103
104
  version: '0'
104
105
  requirements: []
105
106
  rubyforge_project:
106
- rubygems_version: 2.2.2
107
+ rubygems_version: 2.4.8
107
108
  signing_key:
108
109
  specification_version: 4
109
110
  summary: Bitwise attribute for ruby class and Rails model