microscope 0.3 → 0.4

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -1,6 +1,7 @@
1
1
  # Microscope
2
2
 
3
3
  [![Gem Version](https://badge.fury.io/rb/microscope.png)](https://rubygems.org/gems/microscope)
4
+ [![Code Climate](https://codeclimate.com/github/mirego/microscope.png)](https://codeclimate.com/github/mirego/microscope)
4
5
  [![Build Status](https://travis-ci.org/mirego/microscope.png?branch=master)](https://travis-ci.org/mirego/microscope)
5
6
 
6
7
  Microscope adds useful scopes targeting ActiveRecord boolean, date and datetime fields.
@@ -61,6 +62,16 @@ Event.not_started
61
62
  # SELECT * FROM `events` where `events`.`started_at` IS NULL OR `events`.`started_at` > '2013-07-05 15:43:42'
62
63
  ```
63
64
 
65
+ Microscope also adds two instance methods to the model per scope.
66
+
67
+ ```ruby
68
+ event = Event.started.first
69
+ # SELECT * FROM `events` where `events`.`started_at` IS NOT NULL AND `events`.`started_at` <= '2013-07-05 15:43:42' LIMIT 1
70
+
71
+ event.started? # => true
72
+ event.not_started? # => false
73
+ ```
74
+
64
75
  ### Options
65
76
 
66
77
  You can use a few options when calling `acts_as_microscope`:
@@ -0,0 +1,16 @@
1
+ module Microscope
2
+ class InstanceMethod
3
+ class DateInstanceMethod < InstanceMethod
4
+ def apply
5
+ cropped_field = field.name.gsub(/_on$/, '')
6
+
7
+ model.class_eval <<-RUBY, __FILE__, __LINE__ + 1
8
+ define_method "#{cropped_field}?" do
9
+ value = send("#{field.name}")
10
+ !value.nil? && value <= Date.today
11
+ end
12
+ RUBY
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,16 @@
1
+ module Microscope
2
+ class InstanceMethod
3
+ class DatetimeInstanceMethod < InstanceMethod
4
+ def apply
5
+ cropped_field = field.name.gsub(/_at$/, '')
6
+
7
+ model.class_eval <<-RUBY, __FILE__, __LINE__ + 1
8
+ define_method "#{cropped_field}?" do
9
+ value = send("#{field.name}")
10
+ !value.nil? && value <= Time.now
11
+ end
12
+ RUBY
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,14 @@
1
+ module Microscope
2
+ class InstanceMethod < Struct.new(:model, :field)
3
+ # Inject ActiveRecord scopes into a model
4
+ def self.inject_instance_methods(model, fields, options = {})
5
+ fields.each do |field|
6
+ scope = "#{field.type.to_s.camelize}InstanceMethod"
7
+
8
+ if Microscope::InstanceMethod.const_defined?(scope)
9
+ "Microscope::InstanceMethod::#{scope}".constantize.new(model, field).apply
10
+ end
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,12 @@
1
+ module Microscope
2
+ class Scope
3
+ class BooleanScope < Scope
4
+ def apply
5
+ model.class_eval <<-RUBY, __FILE__, __LINE__ + 1
6
+ scope "#{field.name}", lambda { where("#{field.name}" => true) }
7
+ scope "not_#{field.name}", lambda { where("#{field.name}" => false) }
8
+ RUBY
9
+ end
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,13 @@
1
+ module Microscope
2
+ class Scope
3
+ class DateScope < DatetimeScope
4
+ def initialize(*args)
5
+ super
6
+
7
+ @now = 'Date.today'
8
+ @now_suffix = '_today'
9
+ @cropped_field_regex = /_on$/
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,55 @@
1
+ module Microscope
2
+ class Scope
3
+ class DatetimeScope < Scope
4
+ def initialize(*args)
5
+ super
6
+
7
+ @now = 'Time.now'
8
+ @now_suffix = '_now'
9
+ @cropped_field_regex = /_at$/
10
+ end
11
+
12
+ def apply
13
+ @cropped_field = field.name.gsub(@cropped_field_regex, '')
14
+
15
+ model.class_eval <<-RUBY, __FILE__, __LINE__ + 1
16
+ #{before_scopes}
17
+ #{after_scopes}
18
+ #{between_scopes}
19
+ #{boolean_scopes}
20
+ RUBY
21
+ end
22
+
23
+ private
24
+
25
+ def before_scopes
26
+ <<-RUBY
27
+ scope "#{@cropped_field}_before", lambda { |time| where("#{field.name} < ?", time) }
28
+ scope "#{@cropped_field}_before_or_at", lambda { |time| where("#{field.name} <= ?", time) }
29
+ scope "#{@cropped_field}_before#{@now_suffix}", lambda { where("#{field.name} < ?", #{@now}) }
30
+ RUBY
31
+ end
32
+
33
+ def after_scopes
34
+ <<-RUBY
35
+ scope "#{@cropped_field}_after", lambda { |time| where("#{field.name} > ?", time) }
36
+ scope "#{@cropped_field}_after_or_at", lambda { |time| where("#{field.name} >= ?", time) }
37
+ scope "#{@cropped_field}_after#{@now_suffix}", lambda { where("#{field.name} > ?", #{@now}) }
38
+ RUBY
39
+ end
40
+
41
+ def between_scopes
42
+ <<-RUBY
43
+ scope "#{@cropped_field}_between", lambda { |range| where("#{field.name}" => range) }
44
+ RUBY
45
+ end
46
+
47
+ def boolean_scopes
48
+ <<-RUBY
49
+ scope "#{@cropped_field}", lambda { where("#{field.name} IS NOT NULL AND #{field.name} <= ?", #{@now}) }
50
+ scope "not_#{@cropped_field}", lambda { where("#{field.name} IS NULL OR #{field.name} > ?", #{@now}) }
51
+ RUBY
52
+ end
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,14 @@
1
+ module Microscope
2
+ class Scope < Struct.new(:model, :field)
3
+ # Inject ActiveRecord scopes into a model
4
+ def self.inject_scopes(model, fields, options = {})
5
+ fields.each do |field|
6
+ scope = "#{field.type.to_s.camelize}Scope"
7
+
8
+ if Microscope::Scope.const_defined?(scope)
9
+ "Microscope::Scope::#{scope}".constantize.new(model, field).apply
10
+ end
11
+ end
12
+ end
13
+ end
14
+ end
@@ -1,3 +1,3 @@
1
1
  module Microscope
2
- VERSION = "0.3"
2
+ VERSION = "0.4"
3
3
  end
data/lib/microscope.rb CHANGED
@@ -3,17 +3,31 @@ require "microscope/version"
3
3
  require 'active_record'
4
4
  require 'active_support'
5
5
 
6
- require "microscope/mixin"
6
+ require "microscope/scope"
7
+ require "microscope/scope/boolean_scope"
8
+ require "microscope/scope/datetime_scope"
9
+ require "microscope/scope/date_scope"
10
+
11
+ require "microscope/instance_method"
12
+ require "microscope/instance_method/datetime_instance_method"
13
+ require "microscope/instance_method/date_instance_method"
7
14
 
8
15
  module Microscope
9
16
  def self.inject_into_active_record
10
- @inject_into_active_record ||= Proc.new do
17
+ Proc.new do
11
18
  def self.acts_as_microscope(options = {})
12
- @microscope_options = options
13
- include Microscope::Mixin
19
+ except = options[:except] || []
20
+ model_columns = columns.dup.reject { |c| except.include?(c.name.to_sym) }
21
+
22
+ if only = options[:only]
23
+ model_columns = model_columns.select { |c| only.include?(c.name.to_sym) }
24
+ end
25
+
26
+ Microscope::Scope.inject_scopes(self, model_columns, options)
27
+ Microscope::InstanceMethod.inject_instance_methods(self, model_columns, options)
14
28
  end
15
29
  end
16
30
  end
17
31
  end
18
32
 
19
- require 'microscope/railtie' if defined?(Rails) && Rails::VERSION::MAJOR >= 3
33
+ ActiveRecord::Base.class_eval(&Microscope.inject_into_active_record)
@@ -0,0 +1,31 @@
1
+ require 'spec_helper'
2
+
3
+ describe Microscope::Scope::BooleanScope do
4
+ subject { User }
5
+
6
+ before do
7
+ run_migration do
8
+ create_table(:users, force: true) do |t|
9
+ t.boolean :active, default: false
10
+ end
11
+ end
12
+
13
+ microscope 'User'
14
+ end
15
+
16
+ describe 'positive scope' do
17
+ before { @user1 = User.create(active: true) }
18
+
19
+ its(:active) { should have(1).items }
20
+ its(:active) { should include(@user1) }
21
+ its(:not_active) { should be_empty }
22
+ end
23
+
24
+ describe 'negative scope' do
25
+ before { @user1 = User.create(active: false) }
26
+
27
+ its(:not_active) { should have(1).items }
28
+ its(:not_active) { should include(@user1) }
29
+ its(:active) { should be_empty }
30
+ end
31
+ end
@@ -0,0 +1,95 @@
1
+ require 'spec_helper'
2
+
3
+ describe Microscope::Scope::DateScope do
4
+ subject { Event }
5
+
6
+ before do
7
+ run_migration do
8
+ create_table(:events, force: true) do |t|
9
+ t.date :started_on, default: nil
10
+ end
11
+ end
12
+
13
+ microscope 'Event'
14
+ end
15
+
16
+ describe 'before scope' do
17
+ before do
18
+ @event = Event.create(started_on: 2.months.ago)
19
+ Event.create(started_on: 1.month.from_now)
20
+ end
21
+
22
+ it { expect(Event.started_before(1.month.ago).to_a).to eql [@event] }
23
+ end
24
+
25
+ describe 'before_today scope' do
26
+ before do
27
+ @event = Event.create(started_on: 2.months.ago)
28
+ Event.create(started_on: 1.month.from_now)
29
+ end
30
+
31
+ it { expect(Event.started_before_today.to_a).to eql [@event] }
32
+ end
33
+
34
+ describe 'after scope' do
35
+ before do
36
+ @event = Event.create(started_on: 2.months.from_now)
37
+ Event.create(started_on: 1.month.ago)
38
+ end
39
+
40
+ it { expect(Event.started_after(1.month.from_now).to_a).to eql [@event] }
41
+ end
42
+
43
+ describe 'after_today scope' do
44
+ before do
45
+ @event = Event.create(started_on: 2.months.from_now)
46
+ Event.create(started_on: 1.month.ago)
47
+ end
48
+
49
+ it { expect(Event.started_after_today.to_a).to eql [@event] }
50
+ end
51
+
52
+ describe 'between scope' do
53
+ before do
54
+ Event.create(started_on: 1.month.ago)
55
+ @event = Event.create(started_on: 3.months.ago)
56
+ Event.create(started_on: 5.month.ago)
57
+ end
58
+
59
+ it { expect(Event.started_between(4.months.ago..2.months.ago).to_a).to eql [@event] }
60
+ end
61
+
62
+ describe 'super-boolean positive scope' do
63
+ before do
64
+ @event1 = Event.create(started_on: 1.month.ago)
65
+ @event2 = Event.create(started_on: 3.months.ago)
66
+ Event.create(started_on: 2.months.from_now)
67
+ Event.create(started_on: nil)
68
+ end
69
+
70
+ it { expect(Event.started.to_a).to eql [@event1, @event2] }
71
+ end
72
+
73
+ describe 'super-boolean negative scope' do
74
+ before do
75
+ Event.create(started_on: 1.month.ago)
76
+ Event.create(started_on: 3.months.ago)
77
+ @event1 = Event.create(started_on: 2.months.from_now)
78
+ @event2 = Event.create(started_on: nil)
79
+ end
80
+
81
+ it { expect(Event.not_started.to_a).to eql [@event1, @event2] }
82
+ end
83
+
84
+ describe 'boolean instance method' do
85
+ context 'for positive record' do
86
+ subject { Event.create(started_on: 3.months.ago) }
87
+ it { should be_started }
88
+ end
89
+
90
+ context 'for negative record' do
91
+ subject { Event.create(started_on: 2.months.from_now) }
92
+ it { should_not be_started }
93
+ end
94
+ end
95
+ end
@@ -0,0 +1,93 @@
1
+ describe Microscope::Scope::DatetimeScope do
2
+ subject { Event }
3
+
4
+ before do
5
+ run_migration do
6
+ create_table(:events, force: true) do |t|
7
+ t.datetime :started_at, default: nil
8
+ end
9
+ end
10
+
11
+ microscope 'Event'
12
+ end
13
+
14
+ describe 'before scope' do
15
+ before do
16
+ @event = Event.create(started_at: 2.months.ago)
17
+ Event.create(started_at: 1.month.from_now)
18
+ end
19
+
20
+ it { expect(Event.started_before(1.month.ago).to_a).to eql [@event] }
21
+ end
22
+
23
+ describe 'before_now scope' do
24
+ before do
25
+ @event = Event.create(started_at: 2.months.ago)
26
+ Event.create(started_at: 1.month.from_now)
27
+ end
28
+
29
+ it { expect(Event.started_before_now.to_a).to eql [@event] }
30
+ end
31
+
32
+ describe 'after scope' do
33
+ before do
34
+ @event = Event.create(started_at: 2.months.from_now)
35
+ Event.create(started_at: 1.month.ago)
36
+ end
37
+
38
+ it { expect(Event.started_after(1.month.from_now).to_a).to eql [@event] }
39
+ end
40
+
41
+ describe 'after_now scope' do
42
+ before do
43
+ @event = Event.create(started_at: 2.months.from_now)
44
+ Event.create(started_at: 1.month.ago)
45
+ end
46
+
47
+ it { expect(Event.started_after_now.to_a).to eql [@event] }
48
+ end
49
+
50
+ describe 'between scope' do
51
+ before do
52
+ Event.create(started_at: 1.month.ago)
53
+ @event = Event.create(started_at: 3.months.ago)
54
+ Event.create(started_at: 5.month.ago)
55
+ end
56
+
57
+ it { expect(Event.started_between(4.months.ago..2.months.ago).to_a).to eql [@event] }
58
+ end
59
+
60
+ describe 'super-boolean positive scope', focus: true do
61
+ before do
62
+ @event1 = Event.create(started_at: 1.month.ago)
63
+ @event2 = Event.create(started_at: 3.months.ago)
64
+ Event.create(started_at: 2.months.from_now)
65
+ Event.create(started_at: nil)
66
+ end
67
+
68
+ it { expect(Event.started.to_a).to eql [@event1, @event2] }
69
+ end
70
+
71
+ describe 'super-boolean negative scope' do
72
+ before do
73
+ Event.create(started_at: 1.month.ago)
74
+ Event.create(started_at: 3.months.ago)
75
+ @event1 = Event.create(started_at: 2.months.from_now)
76
+ @event2 = Event.create(started_at: nil)
77
+ end
78
+
79
+ it { expect(Event.not_started.to_a).to eql [@event1, @event2] }
80
+ end
81
+
82
+ describe 'boolean instance method' do
83
+ context 'for positive record' do
84
+ subject { Event.create(started_at: 3.months.ago) }
85
+ it { should be_started }
86
+ end
87
+
88
+ context 'for negative record' do
89
+ subject { Event.create(started_at: 2.months.from_now) }
90
+ it { should_not be_started }
91
+ end
92
+ end
93
+ end
@@ -0,0 +1,56 @@
1
+ require 'spec_helper'
2
+
3
+ describe Microscope::Scope do
4
+ describe :inject_scopes do
5
+ subject { User }
6
+
7
+ before do
8
+ run_migration do
9
+ create_table(:users, force: true) do |t|
10
+ t.boolean :active, default: false
11
+ t.boolean :admin, default: false
12
+ t.boolean :moderator, default: false
13
+ end
14
+ end
15
+ end
16
+
17
+ describe :except do
18
+ before do
19
+ microscope 'User', except: [:admin]
20
+ end
21
+
22
+ it { should respond_to :active }
23
+ it { should respond_to :not_active }
24
+ it { should respond_to :moderator }
25
+ it { should respond_to :not_moderator }
26
+ it { should_not respond_to :admin }
27
+ it { should_not respond_to :not_admin }
28
+ end
29
+
30
+ describe :only do
31
+ before do
32
+ microscope 'User', only: [:admin]
33
+ end
34
+
35
+ it { should_not respond_to :active }
36
+ it { should_not respond_to :not_active }
37
+ it { should_not respond_to :moderator }
38
+ it { should_not respond_to :not_moderator }
39
+ it { should respond_to :admin }
40
+ it { should respond_to :not_admin }
41
+ end
42
+
43
+ describe 'except and only' do
44
+ before do
45
+ microscope 'User', only: [:admin], except: [:active]
46
+ end
47
+
48
+ it { should_not respond_to :active }
49
+ it { should_not respond_to :not_active }
50
+ it { should_not respond_to :moderator }
51
+ it { should_not respond_to :not_moderator }
52
+ it { should respond_to :admin }
53
+ it { should respond_to :not_admin }
54
+ end
55
+ end
56
+ end
data/spec/spec_helper.rb CHANGED
@@ -8,9 +8,6 @@ require 'microscope'
8
8
  # Require our macros and extensions
9
9
  Dir[File.expand_path('../../spec/support/macros/*.rb', __FILE__)].map(&method(:require))
10
10
 
11
- # Inject our methods into ActiveRecord (like our railtie does)
12
- ActiveRecord::Base.class_eval(&Microscope.inject_into_active_record)
13
-
14
11
  RSpec.configure do |config|
15
12
  # Include our macros
16
13
  config.include DatabaseMacros
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: microscope
3
3
  version: !ruby/object:Gem::Version
4
- version: '0.3'
4
+ version: '0.4'
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2013-08-08 00:00:00.000000000 Z
13
+ date: 2013-08-13 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: activesupport
@@ -127,11 +127,19 @@ files:
127
127
  - gemfiles/Gemfile.activerecord-3.2.x
128
128
  - gemfiles/Gemfile.activerecord-4.0
129
129
  - lib/microscope.rb
130
- - lib/microscope/mixin.rb
131
- - lib/microscope/railtie.rb
130
+ - lib/microscope/instance_method.rb
131
+ - lib/microscope/instance_method/date_instance_method.rb
132
+ - lib/microscope/instance_method/datetime_instance_method.rb
133
+ - lib/microscope/scope.rb
134
+ - lib/microscope/scope/boolean_scope.rb
135
+ - lib/microscope/scope/date_scope.rb
136
+ - lib/microscope/scope/datetime_scope.rb
132
137
  - lib/microscope/version.rb
133
138
  - microscope.gemspec
134
- - spec/microscope/mixin_spec.rb
139
+ - spec/microscope/scope/boolean_scope_spec.rb
140
+ - spec/microscope/scope/date_scope_spec.rb
141
+ - spec/microscope/scope/datetime_scope_spec.rb
142
+ - spec/microscope/scope_spec.rb
135
143
  - spec/spec_helper.rb
136
144
  - spec/support/macros/database_macros.rb
137
145
  - spec/support/macros/model_macros.rb
@@ -150,7 +158,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
150
158
  version: '0'
151
159
  segments:
152
160
  - 0
153
- hash: -1281633982724090897
161
+ hash: 2193329954126245792
154
162
  required_rubygems_version: !ruby/object:Gem::Requirement
155
163
  none: false
156
164
  requirements:
@@ -159,7 +167,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
159
167
  version: '0'
160
168
  segments:
161
169
  - 0
162
- hash: -1281633982724090897
170
+ hash: 2193329954126245792
163
171
  requirements: []
164
172
  rubyforge_project:
165
173
  rubygems_version: 1.8.23
@@ -168,7 +176,10 @@ specification_version: 3
168
176
  summary: Microscope adds useful scopes targeting ActiveRecord boolean and datetime
169
177
  fields.
170
178
  test_files:
171
- - spec/microscope/mixin_spec.rb
179
+ - spec/microscope/scope/boolean_scope_spec.rb
180
+ - spec/microscope/scope/date_scope_spec.rb
181
+ - spec/microscope/scope/datetime_scope_spec.rb
182
+ - spec/microscope/scope_spec.rb
172
183
  - spec/spec_helper.rb
173
184
  - spec/support/macros/database_macros.rb
174
185
  - spec/support/macros/model_macros.rb
@@ -1,62 +0,0 @@
1
- module Microscope
2
- module Mixin
3
- extend ActiveSupport::Concern
4
-
5
- included do
6
- define_microscrope_scopes
7
- end
8
-
9
- module ClassMethods
10
- def define_microscrope_scopes
11
- except = @microscope_options[:except] || []
12
- model_columns = self.columns.dup.reject { |c| except.include?(c.name.to_sym) }
13
-
14
- if only = @microscope_options[:only]
15
- model_columns = model_columns.select { |c| only.include?(c.name.to_sym) }
16
- end
17
-
18
- boolean_fields = model_columns.select { |c| c.type == :boolean }.map(&:name)
19
- boolean_fields.each do |field|
20
- scope field, lambda { where(field => true) }
21
- scope "not_#{field}", lambda { where(field => false) }
22
- end
23
-
24
- datetime_fields = model_columns.select { |c| c.type == :datetime }.map(&:name)
25
- datetime_fields.each do |field|
26
- cropped_field = field.gsub(/_at$/, '')
27
-
28
- scope "#{cropped_field}_before", lambda { |time| where("#{field} < ?", time) }
29
- scope "#{cropped_field}_before_or_at", lambda { |time| where("#{field} <= ?", time) }
30
- scope "#{cropped_field}_before_now", lambda { where("#{field} < ?", Time.now) }
31
-
32
- scope "#{cropped_field}_after", lambda { |time| where("#{field} > ?", time) }
33
- scope "#{cropped_field}_after_or_at", lambda { |time| where("#{field} >= ?", time) }
34
- scope "#{cropped_field}_after_now", lambda { where("#{field} > ?", Time.now) }
35
-
36
- scope "#{cropped_field}_between", lambda { |range| where(field => range) }
37
-
38
- scope "#{cropped_field}", lambda { where("#{field} IS NOT NULL AND #{field} <= ?", Time.now) }
39
- scope "not_#{cropped_field}", lambda { where("#{field} IS NULL OR #{field} > ?", Time.now) }
40
- end
41
-
42
- date_fields = model_columns.select { |c| c.type == :date }.map(&:name)
43
- date_fields.each do |field|
44
- cropped_field = field.gsub(/_on$/, '')
45
-
46
- scope "#{cropped_field}_before", lambda { |time| where("#{field} < ?", time) }
47
- scope "#{cropped_field}_before_or_on", lambda { |time| where("#{field} <= ?", time) }
48
- scope "#{cropped_field}_before_today", lambda { where("#{field} < ?", Date.today) }
49
-
50
- scope "#{cropped_field}_after", lambda { |time| where("#{field} > ?", time) }
51
- scope "#{cropped_field}_after_or_at", lambda { |time| where("#{field} >= ?", time) }
52
- scope "#{cropped_field}_after_today", lambda { where("#{field} > ?", Date.today) }
53
-
54
- scope "#{cropped_field}_between", lambda { |range| where(field => range) }
55
-
56
- scope "#{cropped_field}", lambda { where("#{field} IS NOT NULL AND #{field} <= ?", Date.today) }
57
- scope "not_#{cropped_field}", lambda { where("#{field} IS NULL OR #{field} > ?", Date.today) }
58
- end
59
- end
60
- end
61
- end
62
- end
@@ -1,10 +0,0 @@
1
- require 'microscope'
2
- require 'rails'
3
-
4
- module Microscope
5
- class Railtie < Rails::Railtie
6
- initializer 'microscope.active_record' do |app|
7
- ActiveSupport.on_load :active_record, {}, &Microscope.inject_into_active_record
8
- end
9
- end
10
- end
@@ -1,250 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe Microscope::Mixin do
4
- describe :acts_as_microscope do
5
- subject { User }
6
-
7
- before do
8
- run_migration do
9
- create_table(:users, force: true) do |t|
10
- t.boolean :active, default: false
11
- t.boolean :admin, default: false
12
- t.boolean :moderator, default: false
13
- end
14
- end
15
- end
16
-
17
- describe :except do
18
- before do
19
- microscope 'User', except: [:admin]
20
- end
21
-
22
- it { should respond_to :active }
23
- it { should respond_to :not_active }
24
- it { should respond_to :moderator }
25
- it { should respond_to :not_moderator }
26
- it { should_not respond_to :admin }
27
- it { should_not respond_to :not_admin }
28
- end
29
-
30
- describe :only do
31
- before do
32
- microscope 'User', only: [:admin]
33
- end
34
-
35
- it { should_not respond_to :active }
36
- it { should_not respond_to :not_active }
37
- it { should_not respond_to :moderator }
38
- it { should_not respond_to :not_moderator }
39
- it { should respond_to :admin }
40
- it { should respond_to :not_admin }
41
- end
42
-
43
- describe 'except and only' do
44
- before do
45
- microscope 'User', only: [:admin], except: [:active]
46
- end
47
-
48
- it { should_not respond_to :active }
49
- it { should_not respond_to :not_active }
50
- it { should_not respond_to :moderator }
51
- it { should_not respond_to :not_moderator }
52
- it { should respond_to :admin }
53
- it { should respond_to :not_admin }
54
- end
55
- end
56
-
57
- describe 'Boolean scopes' do
58
- subject { User }
59
-
60
- before do
61
- run_migration do
62
- create_table(:users, force: true) do |t|
63
- t.boolean :active, default: false
64
- end
65
- end
66
-
67
- microscope 'User'
68
- end
69
-
70
- describe 'positive scope' do
71
- before { @user1 = User.create(active: true) }
72
-
73
- its(:active) { should have(1).items }
74
- its(:active) { should include(@user1) }
75
- its(:not_active) { should be_empty }
76
- end
77
-
78
- describe 'negative scope' do
79
- before { @user1 = User.create(active: false) }
80
-
81
- its(:not_active) { should have(1).items }
82
- its(:not_active) { should include(@user1) }
83
- its(:active) { should be_empty }
84
- end
85
- end
86
-
87
- describe 'DateTime scopes' do
88
- subject { Event }
89
-
90
- before do
91
- run_migration do
92
- create_table(:events, force: true) do |t|
93
- t.datetime :started_at, default: nil
94
- end
95
- end
96
-
97
- microscope 'Event'
98
- end
99
-
100
- describe 'before scope' do
101
- before do
102
- @event = Event.create(started_at: 2.months.ago)
103
- Event.create(started_at: 1.month.from_now)
104
- end
105
-
106
- it { expect(Event.started_before(1.month.ago).to_a).to eql [@event] }
107
- end
108
-
109
- describe 'before_now scope' do
110
- before do
111
- @event = Event.create(started_at: 2.months.ago)
112
- Event.create(started_at: 1.month.from_now)
113
- end
114
-
115
- it { expect(Event.started_before_now.to_a).to eql [@event] }
116
- end
117
-
118
- describe 'after scope' do
119
- before do
120
- @event = Event.create(started_at: 2.months.from_now)
121
- Event.create(started_at: 1.month.ago)
122
- end
123
-
124
- it { expect(Event.started_after(1.month.from_now).to_a).to eql [@event] }
125
- end
126
-
127
- describe 'after_now scope' do
128
- before do
129
- @event = Event.create(started_at: 2.months.from_now)
130
- Event.create(started_at: 1.month.ago)
131
- end
132
-
133
- it { expect(Event.started_after_now.to_a).to eql [@event] }
134
- end
135
-
136
- describe 'between scope' do
137
- before do
138
- Event.create(started_at: 1.month.ago)
139
- @event = Event.create(started_at: 3.months.ago)
140
- Event.create(started_at: 5.month.ago)
141
- end
142
-
143
- it { expect(Event.started_between(4.months.ago..2.months.ago).to_a).to eql [@event] }
144
- end
145
-
146
- describe 'super-boolean positive scope', focus: true do
147
- before do
148
- @event1 = Event.create(started_at: 1.month.ago)
149
- @event2 = Event.create(started_at: 3.months.ago)
150
- Event.create(started_at: 2.months.from_now)
151
- Event.create(started_at: nil)
152
- end
153
-
154
- it { expect(Event.started.to_a).to eql [@event1, @event2] }
155
- end
156
-
157
- describe 'super-boolean negative scope' do
158
- before do
159
- Event.create(started_at: 1.month.ago)
160
- Event.create(started_at: 3.months.ago)
161
- @event1 = Event.create(started_at: 2.months.from_now)
162
- @event2 = Event.create(started_at: nil)
163
- end
164
-
165
- it { expect(Event.not_started.to_a).to eql [@event1, @event2] }
166
- end
167
- end
168
-
169
- describe 'Date scopes' do
170
- subject { Event }
171
-
172
- before do
173
- run_migration do
174
- create_table(:events, force: true) do |t|
175
- t.date :started_on, default: nil
176
- end
177
- end
178
-
179
- microscope 'Event'
180
- end
181
-
182
- describe 'before scope' do
183
- before do
184
- @event = Event.create(started_on: 2.months.ago)
185
- Event.create(started_on: 1.month.from_now)
186
- end
187
-
188
- it { expect(Event.started_before(1.month.ago).to_a).to eql [@event] }
189
- end
190
-
191
- describe 'before_today scope' do
192
- before do
193
- @event = Event.create(started_on: 2.months.ago)
194
- Event.create(started_on: 1.month.from_now)
195
- end
196
-
197
- it { expect(Event.started_before_today.to_a).to eql [@event] }
198
- end
199
-
200
- describe 'after scope' do
201
- before do
202
- @event = Event.create(started_on: 2.months.from_now)
203
- Event.create(started_on: 1.month.ago)
204
- end
205
-
206
- it { expect(Event.started_after(1.month.from_now).to_a).to eql [@event] }
207
- end
208
-
209
- describe 'after_today scope' do
210
- before do
211
- @event = Event.create(started_on: 2.months.from_now)
212
- Event.create(started_on: 1.month.ago)
213
- end
214
-
215
- it { expect(Event.started_after_today.to_a).to eql [@event] }
216
- end
217
-
218
- describe 'between scope' do
219
- before do
220
- Event.create(started_on: 1.month.ago)
221
- @event = Event.create(started_on: 3.months.ago)
222
- Event.create(started_on: 5.month.ago)
223
- end
224
-
225
- it { expect(Event.started_between(4.months.ago..2.months.ago).to_a).to eql [@event] }
226
- end
227
-
228
- describe 'super-boolean positive scope' do
229
- before do
230
- @event1 = Event.create(started_on: 1.month.ago)
231
- @event2 = Event.create(started_on: 3.months.ago)
232
- Event.create(started_on: 2.months.from_now)
233
- Event.create(started_on: nil)
234
- end
235
-
236
- it { expect(Event.started.to_a).to eql [@event1, @event2] }
237
- end
238
-
239
- describe 'super-boolean negative scope' do
240
- before do
241
- Event.create(started_on: 1.month.ago)
242
- Event.create(started_on: 3.months.ago)
243
- @event1 = Event.create(started_on: 2.months.from_now)
244
- @event2 = Event.create(started_on: nil)
245
- end
246
-
247
- it { expect(Event.not_started.to_a).to eql [@event1, @event2] }
248
- end
249
- end
250
- end