act_as_time_as_boolean 0.4.0 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore CHANGED
@@ -17,3 +17,4 @@ Gemfile.lock
17
17
  .yardoc
18
18
  _yardoc
19
19
  doc/
20
+ *.sqlite
data/.travis.yml CHANGED
@@ -1,4 +1,7 @@
1
1
  language: ruby
2
+ cache: bundler
2
3
  rvm:
3
- - 1.9.2
4
4
  - 1.9.3
5
+ - 2.0.0
6
+ - 2.1.0
7
+ - 2.1.1
data/CONTRIBUTING.md ADDED
@@ -0,0 +1,7 @@
1
+ # Contributing
2
+
3
+ 1. Fork repository
4
+ 2. Create a branch following a [successfull branching model](http://nvie.com/posts/a-successful-git-branching-model/)
5
+ 3. Write your feature/fix
6
+ 4. Write tests
7
+ 5. Pull request
data/README.md CHANGED
@@ -10,20 +10,22 @@ _Add time_as_boolean feature to your ruby classes_
10
10
 
11
11
  ## Installation
12
12
 
13
- ```shell
14
- gem install act_as_time_as_boolean
13
+ ### Ruby 1.9.3+, 2+
14
+
15
+ ```ruby
16
+ gem 'act_as_time_as_boolean'
15
17
  ```
16
18
 
17
- Or in your Gemfile:
19
+ ### Ruby 1.9.2
18
20
 
19
21
  ```ruby
20
- gem 'act_as_time_as_boolean'
22
+ gem 'act_as_time_as_boolean', '~> 0.4.0'
21
23
  ```
22
24
 
23
25
  ## Usage
24
26
 
25
27
  ```ruby
26
- class Item
28
+ class Item < ActiveRecord::Base
27
29
  include ActAsTimeAsBoolean
28
30
 
29
31
  attr_accessor :active_at
@@ -46,11 +48,7 @@ item.active?
46
48
 
47
49
  item.inactive?
48
50
  #=> false
49
- ```
50
-
51
- #### On a rails app
52
51
 
53
- ```ruby
54
52
  Item.active
55
53
  #=> #<ActiveRecord::Relation [...]>
56
54
 
@@ -60,11 +58,7 @@ Item.inactive
60
58
 
61
59
  ## Contributing
62
60
 
63
- 1. Fork repository
64
- 2. Create a branch following a [successfull branching model](http://nvie.com/posts/a-successful-git-branching-model/)
65
- 3. Write your feature/fix
66
- 4. Write tests
67
- 5. Pull request
61
+ [Contributors](https://github.com/caedes/act_as_time_as_boolean/graphs/contributors) and [CONTRIBUTING](https://github.com/caedes/act_as_time_as_boolean/blob/master/CONTRIBUTING.md)
68
62
 
69
63
  ## Licence
70
64
 
@@ -6,15 +6,20 @@ Gem::Specification.new do |s|
6
6
  s.authors = ['caedes']
7
7
  s.email = ['laurentromain@gmail.com']
8
8
  s.homepage = 'https://github.com/caedes/act_as_time_as_boolean'
9
- s.summary = 'Add time_as_boolean feature to your ruby classes'
9
+ s.summary = 'Add time_as_boolean feature to ActiveRecord classes'
10
10
  s.description = s.summary
11
11
 
12
12
  s.files = `git ls-files`.split("\n")
13
13
 
14
14
  s.require_path = 'lib'
15
15
 
16
+ s.add_dependency 'activesupport', '>= 3.2'
17
+
16
18
  s.add_development_dependency 'rake'
17
- s.add_development_dependency 'rspec', '~> 2.13'
18
19
  s.add_development_dependency 'coveralls', '~> 0.6'
19
20
  s.add_development_dependency 'json', '~> 1.7.7'
21
+ s.add_development_dependency 'combustion', '~> 0.5.1'
22
+ s.add_development_dependency 'rspec-rails', '~> 2.14'
23
+ s.add_development_dependency 'sqlite3', '~> 1.3.3'
24
+ s.add_development_dependency 'activerecord', '~> 4.0.4'
20
25
  end
@@ -0,0 +1,50 @@
1
+ require 'active_support/concern'
2
+
3
+ module ActAsTimeAsBoolean
4
+ extend ActiveSupport::Concern
5
+
6
+ module ClassMethods
7
+ def time_as_boolean(field, options = {})
8
+ define_method field do
9
+ !send(:"#{field}_at").nil?
10
+ end
11
+ send :alias_method, :"#{field}?", :"#{field}"
12
+
13
+ define_method :"#{field}=" do |value|
14
+ value = value && value.to_s != '0'
15
+ if value && !send(field)
16
+ send :"#{field}_at=", Time.now
17
+ true
18
+ elsif !value && send(field)
19
+ send :"#{field}_at=", nil
20
+ end
21
+ end
22
+
23
+ define_method :"#{field}!" do
24
+ send :"#{field}=", true
25
+ save!
26
+ end
27
+
28
+ if options[:opposite]
29
+ opposite = options[:opposite]
30
+ define_method :"#{opposite}" do
31
+ send(:"#{field}_at").nil?
32
+ end
33
+ send :alias_method, :"#{opposite}?", :"#{opposite}"
34
+
35
+ define_method :"#{opposite}!" do
36
+ send :"#{field}=", false
37
+ save!
38
+ end
39
+
40
+ scope opposite, -> {
41
+ where "#{table_name}.#{field}_at IS NULL OR #{table_name}.#{field}_at > ?", Time.current
42
+ }
43
+ end
44
+
45
+ scope field, -> {
46
+ where "#{table_name}.#{field}_at IS NOT NULL AND #{table_name}.#{field}_at <= ?", Time.current
47
+ }
48
+ end
49
+ end
50
+ end
@@ -1,3 +1,3 @@
1
1
  module ActAsTimeAsBoolean
2
- VERSION = '0.4.0'
2
+ VERSION = '1.0.0'
3
3
  end
@@ -1,2 +1,2 @@
1
1
  require 'act_as_time_as_boolean/version'
2
- require 'act_as_time_as_boolean/base'
2
+ require 'act_as_time_as_boolean/concern'
@@ -0,0 +1,5 @@
1
+ class Article < ActiveRecord::Base
2
+ include ActAsTimeAsBoolean
3
+
4
+ time_as_boolean :active
5
+ end
@@ -0,0 +1,5 @@
1
+ class ArticleWithOpposite < ActiveRecord::Base
2
+ include ActAsTimeAsBoolean
3
+
4
+ time_as_boolean :active, opposite: :inactive
5
+ end
@@ -0,0 +1,3 @@
1
+ test:
2
+ adapter: sqlite3
3
+ database: db/combustion_test.sqlite
@@ -0,0 +1,3 @@
1
+ Rails.application.routes.draw do
2
+ #
3
+ end
@@ -0,0 +1,9 @@
1
+ ActiveRecord::Schema.define do
2
+ create_table :articles, force: true do |t|
3
+ t.datetime :active_at
4
+ end
5
+
6
+ create_table :article_with_opposites, force: true do |t|
7
+ t.datetime :active_at
8
+ end
9
+ end
@@ -0,0 +1 @@
1
+ *.log
File without changes
@@ -1,66 +1,15 @@
1
- require_relative '../spec_helper'
2
-
3
- class SimpleTimeAsBooleanModel
4
- include ActAsTimeAsBoolean
5
-
6
- attr_accessor :active_at
7
-
8
- time_as_boolean :active
9
- end
10
-
11
- class TimeAsBooleanWithOppositeModel
12
- include ActAsTimeAsBoolean
13
-
14
- attr_accessor :active_at
15
-
16
- def initialize(options = {})
17
- @active_at = options[:active_at] || nil
18
- end
19
-
20
- time_as_boolean :active, opposite: :inactive
21
- end
22
-
23
- # Awesome mock to test scope
24
- class ActiveRecord
25
- end
26
-
27
- class ActiveRecord::Base
28
- def self.scope(name, body, &block)
29
- define_singleton_method name do
30
- # Nothing to do here, just a mock
31
- end
32
- end
33
-
34
- def save!
35
- end
36
- end
37
-
38
- class InheritedModel < ActiveRecord::Base
39
- include ActAsTimeAsBoolean
40
-
41
- attr_accessor :active_at
42
-
43
- time_as_boolean :active
44
- end
45
-
46
- class InheritedModelWithOpposite < ActiveRecord::Base
47
- include ActAsTimeAsBoolean
48
-
49
- attr_accessor :active_at
50
-
51
- time_as_boolean :active, opposite: :inactive
52
- end
1
+ require 'spec_helper'
53
2
 
54
3
  describe ActAsTimeAsBoolean do
55
4
  it 'defines time_as_boolean class method' do
56
- SimpleTimeAsBooleanModel.singleton_methods.should include(:time_as_boolean)
5
+ Article.singleton_methods.should include(:time_as_boolean)
57
6
  end
58
7
 
59
8
  describe 'calling time_as_boolean' do
60
9
  describe 'without param' do
61
10
  it 'raises an ArgumentError' do
62
11
  expect do
63
- class NoParamTimeAsBooleanModel
12
+ class Article < ActiveRecord::Base
64
13
  include ActAsTimeAsBoolean
65
14
 
66
15
  time_as_boolean
@@ -70,7 +19,7 @@ describe ActAsTimeAsBoolean do
70
19
  end
71
20
 
72
21
  describe 'with :active param' do
73
- subject { SimpleTimeAsBooleanModel.new.methods }
22
+ subject { Article.new.methods }
74
23
 
75
24
  it 'defines active method' do
76
25
  subject.should include(:active)
@@ -84,7 +33,7 @@ describe ActAsTimeAsBoolean do
84
33
  end
85
34
 
86
35
  describe 'with :active and opposite param' do
87
- subject { TimeAsBooleanWithOppositeModel.new.methods }
36
+ subject { ArticleWithOpposite.new.methods }
88
37
 
89
38
  it 'defines active method' do
90
39
  subject.should include(:active)
@@ -103,9 +52,9 @@ describe ActAsTimeAsBoolean do
103
52
  end
104
53
  end
105
54
 
106
- describe 'on a rails app' do
55
+ describe 'scopes' do
107
56
  describe 'with :active param' do
108
- subject { InheritedModel.new }
57
+ subject { Article.new }
109
58
 
110
59
  it 'define active scope' do
111
60
  subject.class.methods.should include(:active)
@@ -117,7 +66,7 @@ describe ActAsTimeAsBoolean do
117
66
  end
118
67
 
119
68
  describe 'with :active and opposite param' do
120
- subject { InheritedModelWithOpposite.new }
69
+ subject { ArticleWithOpposite.new }
121
70
 
122
71
  it 'define active scope' do
123
72
  subject.class.methods.should include(:active)
@@ -137,7 +86,7 @@ describe ActAsTimeAsBoolean do
137
86
  describe 'using ActAsTimeAsBoolean' do
138
87
  describe 'with an active instance' do
139
88
  let(:time) { Time.now }
140
- subject { TimeAsBooleanWithOppositeModel.new active_at: time }
89
+ subject { ArticleWithOpposite.new active_at: time }
141
90
 
142
91
  describe 'calling active' do
143
92
  it { subject.active.should be_true }
@@ -180,10 +129,22 @@ describe ActAsTimeAsBoolean do
180
129
  describe 'calling inactive?' do
181
130
  it { subject.inactive?.should be_false }
182
131
  end
132
+
133
+ describe 'calling active!' do
134
+ before { subject.active! }
135
+
136
+ it { subject.active?.should be_true }
137
+ end
138
+
139
+ describe 'calling inactive!' do
140
+ before { subject.inactive! }
141
+
142
+ it { subject.active?.should be_false }
143
+ end
183
144
  end
184
145
 
185
146
  describe 'with an inactive instance' do
186
- subject { TimeAsBooleanWithOppositeModel.new }
147
+ subject { ArticleWithOpposite.new }
187
148
 
188
149
  describe 'calling active' do
189
150
  it { subject.active.should be_false }
@@ -198,7 +159,7 @@ describe ActAsTimeAsBoolean do
198
159
  describe "with #{value}" do
199
160
  before { subject.active = value }
200
161
 
201
- it { subject.active_at.class.should == Time }
162
+ it { subject.active_at.class.should == ActiveSupport::TimeWithZone }
202
163
  end
203
164
  end
204
165
 
@@ -218,20 +179,6 @@ describe ActAsTimeAsBoolean do
218
179
  describe 'calling inactive?' do
219
180
  it { subject.inactive?.should be_true }
220
181
  end
221
- end
222
-
223
- describe 'with an ActiveRecord inherited instance' do
224
- subject { InheritedModel.new }
225
-
226
- describe 'calling active!' do
227
- before { subject.active! }
228
-
229
- it { subject.active?.should be_true }
230
- end
231
- end
232
-
233
- describe 'with an ActiveRecord inherited with opposite instance' do
234
- subject { InheritedModelWithOpposite.new }
235
182
 
236
183
  describe 'calling active!' do
237
184
  before { subject.active! }
data/spec/spec_helper.rb CHANGED
@@ -2,3 +2,8 @@ require 'coveralls'
2
2
  Coveralls.wear!
3
3
 
4
4
  require 'act_as_time_as_boolean'
5
+ require 'combustion'
6
+
7
+ Combustion.initialize! :active_record
8
+
9
+ require 'rspec/rails'
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: act_as_time_as_boolean
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.0
4
+ version: 1.0.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,40 +9,40 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2014-02-11 00:00:00.000000000 Z
12
+ date: 2014-03-20 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
- name: rake
15
+ name: activesupport
16
16
  requirement: !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ! '>='
20
20
  - !ruby/object:Gem::Version
21
- version: '0'
22
- type: :development
21
+ version: '3.2'
22
+ type: :runtime
23
23
  prerelease: false
24
24
  version_requirements: !ruby/object:Gem::Requirement
25
25
  none: false
26
26
  requirements:
27
27
  - - ! '>='
28
28
  - !ruby/object:Gem::Version
29
- version: '0'
29
+ version: '3.2'
30
30
  - !ruby/object:Gem::Dependency
31
- name: rspec
31
+ name: rake
32
32
  requirement: !ruby/object:Gem::Requirement
33
33
  none: false
34
34
  requirements:
35
- - - ~>
35
+ - - ! '>='
36
36
  - !ruby/object:Gem::Version
37
- version: '2.13'
37
+ version: '0'
38
38
  type: :development
39
39
  prerelease: false
40
40
  version_requirements: !ruby/object:Gem::Requirement
41
41
  none: false
42
42
  requirements:
43
- - - ~>
43
+ - - ! '>='
44
44
  - !ruby/object:Gem::Version
45
- version: '2.13'
45
+ version: '0'
46
46
  - !ruby/object:Gem::Dependency
47
47
  name: coveralls
48
48
  requirement: !ruby/object:Gem::Requirement
@@ -75,7 +75,71 @@ dependencies:
75
75
  - - ~>
76
76
  - !ruby/object:Gem::Version
77
77
  version: 1.7.7
78
- description: Add time_as_boolean feature to your ruby classes
78
+ - !ruby/object:Gem::Dependency
79
+ name: combustion
80
+ requirement: !ruby/object:Gem::Requirement
81
+ none: false
82
+ requirements:
83
+ - - ~>
84
+ - !ruby/object:Gem::Version
85
+ version: 0.5.1
86
+ type: :development
87
+ prerelease: false
88
+ version_requirements: !ruby/object:Gem::Requirement
89
+ none: false
90
+ requirements:
91
+ - - ~>
92
+ - !ruby/object:Gem::Version
93
+ version: 0.5.1
94
+ - !ruby/object:Gem::Dependency
95
+ name: rspec-rails
96
+ requirement: !ruby/object:Gem::Requirement
97
+ none: false
98
+ requirements:
99
+ - - ~>
100
+ - !ruby/object:Gem::Version
101
+ version: '2.14'
102
+ type: :development
103
+ prerelease: false
104
+ version_requirements: !ruby/object:Gem::Requirement
105
+ none: false
106
+ requirements:
107
+ - - ~>
108
+ - !ruby/object:Gem::Version
109
+ version: '2.14'
110
+ - !ruby/object:Gem::Dependency
111
+ name: sqlite3
112
+ requirement: !ruby/object:Gem::Requirement
113
+ none: false
114
+ requirements:
115
+ - - ~>
116
+ - !ruby/object:Gem::Version
117
+ version: 1.3.3
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ none: false
122
+ requirements:
123
+ - - ~>
124
+ - !ruby/object:Gem::Version
125
+ version: 1.3.3
126
+ - !ruby/object:Gem::Dependency
127
+ name: activerecord
128
+ requirement: !ruby/object:Gem::Requirement
129
+ none: false
130
+ requirements:
131
+ - - ~>
132
+ - !ruby/object:Gem::Version
133
+ version: 4.0.4
134
+ type: :development
135
+ prerelease: false
136
+ version_requirements: !ruby/object:Gem::Requirement
137
+ none: false
138
+ requirements:
139
+ - - ~>
140
+ - !ruby/object:Gem::Version
141
+ version: 4.0.4
142
+ description: Add time_as_boolean feature to ActiveRecord classes
79
143
  email:
80
144
  - laurentromain@gmail.com
81
145
  executables: []
@@ -84,6 +148,7 @@ extra_rdoc_files: []
84
148
  files:
85
149
  - .gitignore
86
150
  - .travis.yml
151
+ - CONTRIBUTING.md
87
152
  - Gemfile
88
153
  - LICENSE.md
89
154
  - README.md
@@ -91,8 +156,15 @@ files:
91
156
  - act_as_time_as_boolean.gemspec
92
157
  - init.rb
93
158
  - lib/act_as_time_as_boolean.rb
94
- - lib/act_as_time_as_boolean/base.rb
159
+ - lib/act_as_time_as_boolean/concern.rb
95
160
  - lib/act_as_time_as_boolean/version.rb
161
+ - spec/internal/app/models/article.rb
162
+ - spec/internal/app/models/article_with_opposite.rb
163
+ - spec/internal/config/database.yml
164
+ - spec/internal/config/routes.rb
165
+ - spec/internal/db/schema.rb
166
+ - spec/internal/log/.gitignore
167
+ - spec/internal/public/favicon.ico
96
168
  - spec/lib/act_as_time_as_boolean_spec.rb
97
169
  - spec/spec_helper.rb
98
170
  homepage: https://github.com/caedes/act_as_time_as_boolean
@@ -118,5 +190,5 @@ rubyforge_project:
118
190
  rubygems_version: 1.8.26
119
191
  signing_key:
120
192
  specification_version: 3
121
- summary: Add time_as_boolean feature to your ruby classes
193
+ summary: Add time_as_boolean feature to ActiveRecord classes
122
194
  test_files: []
@@ -1,103 +0,0 @@
1
- module ActAsTimeAsBoolean
2
- def self.included(base)
3
- @base = base
4
-
5
- base.define_singleton_method(:time_as_boolean) do |field, options = {}|
6
- ActAsTimeAsBoolean.time_as_boolean_method field, options
7
- end
8
- end
9
-
10
- protected
11
-
12
- def self.time_as_boolean_method(field, options)
13
- field = field.to_sym
14
-
15
- ActAsTimeAsBoolean.field_getter_method field
16
- ActAsTimeAsBoolean.field_setter_method field
17
-
18
- if options[:opposite]
19
- ActAsTimeAsBoolean.opposite_getter_method field, options[:opposite]
20
- end
21
-
22
- if ActAsTimeAsBoolean.has_scope_method?
23
- ActAsTimeAsBoolean.field_scope field
24
-
25
- if options[:opposite]
26
- ActAsTimeAsBoolean.opposite_field_scope field, options[:opposite]
27
- end
28
- end
29
-
30
- if ActAsTimeAsBoolean.is_active_record_inherited?
31
- ActAsTimeAsBoolean.field_bang_method field
32
-
33
- if options[:opposite]
34
- ActAsTimeAsBoolean.opposite_bang_method field, options[:opposite]
35
- end
36
- end
37
- end
38
-
39
- def self.field_getter_method(field)
40
- send :define_method, field do
41
- !send(:"#{field}_at").nil?
42
- end
43
-
44
- send :alias_method, :"#{field}?", :"#{field}"
45
- end
46
-
47
- def self.field_setter_method(field)
48
- send :define_method, :"#{field}=" do |value|
49
- value = value && value.to_s != '0'
50
- if value && !send(field)
51
- send :"#{field}_at=", Time.now
52
- true
53
- elsif !value && send(field)
54
- send :"#{field}_at=", nil
55
- end
56
- end
57
- end
58
-
59
- def self.field_bang_method(field)
60
- send :define_method, :"#{field}!" do
61
- send :"#{field}=", true
62
- save!
63
- end
64
- end
65
-
66
- def self.opposite_getter_method(field, opposite)
67
- send :define_method, :"#{opposite}" do
68
- send(:"#{field}_at").nil?
69
- end
70
-
71
- send :alias_method, :"#{opposite}?", :"#{opposite}"
72
- end
73
-
74
- def self.opposite_bang_method(field, opposite)
75
- send :define_method, :"#{opposite}!" do
76
- send :"#{field}=", false
77
- save!
78
- end
79
- end
80
-
81
- def self.field_scope(field)
82
- @base.send :scope, field, -> {
83
- @base.send :where, [ "#{field}_at IS NOT NULL AND #{field}_at <= ?", Time.current]
84
- }
85
- end
86
-
87
- def self.opposite_field_scope(field, opposite)
88
- @base.send :scope, opposite, -> {
89
- @base.send :where, [ "#{field}_at IS NULL OR #{field}_at > ?", Time.current]
90
- }
91
- end
92
-
93
- def self.is_active_record_inherited?
94
- defined?(ActiveRecord::Base) &&
95
- ActiveRecord::Base.is_a?(Class) &&
96
- @base < ActiveRecord::Base
97
- end
98
-
99
- def self.has_scope_method?
100
- is_active_record_inherited? &&
101
- ActiveRecord::Base.methods.include?(:scope)
102
- end
103
- end