microscope 1.0.1 → 1.1.0

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: 1282869f83f7716bed7b98f51ffbf10ac549af20
4
- data.tar.gz: ce43d2a660b015851ff0a336f7aa68e3dbe853d4
3
+ metadata.gz: 8c8857057897b00e46c32f958bf65363f463a97a
4
+ data.tar.gz: 276f72506b52623fd611587a69a742c566a8859f
5
5
  SHA512:
6
- metadata.gz: 1aac23cb4ae88a3177eec3a41d2d2a59de034ab8ccea6374293f22e9f286b7c12d89d7adf41e263d8ceb23743d0b81c092bada433415eec66009b1cc7e0b5f78
7
- data.tar.gz: b4602d97dde4ce2404e088ec64d7c79890e345f48623510b127e8f5f0f88b85bcc16d17fd392057dfc6c69ca0b4dcf550b830f7509239e13db43ebcf30345226
6
+ metadata.gz: e4af246cd67dd81ff7afd01ff2ab4ba5341e914502f6f7ae466bbbf541d0fa5825e06a13bb243de58c377087934ad266737cecfaaaf44462195ba731f6cc8f61
7
+ data.tar.gz: 91cfb56993cd8e86db4a2ac721966a0917501bc911f981803e7fa59e1e559b4272afe1f28141a25ae0c7b5e28da1f4eda9554f3809731efbfc911e946958eeee
@@ -1,19 +1,23 @@
1
1
  language: ruby
2
2
  sudo: false
3
3
 
4
- rvm:
5
- - 2.0
6
- - 2.1
7
- - 2.2
4
+ rvm: 2.3
8
5
 
9
6
  gemfile:
10
7
  - gemfiles/Gemfile.activerecord-4.1
8
+ - gemfiles/Gemfile.activerecord-4.2
9
+ - gemfiles/Gemfile.activerecord-5.1
10
+ - gemfiles/Gemfile.activerecord-5.2
11
11
 
12
12
  env:
13
13
  - DB_ADAPTER=sqlite3
14
14
  - DB_ADAPTER=mysql2
15
15
  - DB_ADAPTER=postgresql
16
16
 
17
+ before_install:
18
+ - gem update --system
19
+ - gem install bundler
20
+
17
21
  before_script:
18
22
  - mysql -e 'create database microscope_test;'
19
23
  - psql -c 'create database microscope_test;' -U postgres
@@ -21,11 +25,3 @@ before_script:
21
25
  script:
22
26
  - 'echo "Checking code style" && bundle exec phare'
23
27
  - 'echo "Running tests" && bundle exec rake spec'
24
-
25
- notifications:
26
- hipchat:
27
- rooms:
28
- secure: cJWiEh3XNWrEkoeaZd5Kyx3igwOJto+B8jPiyr38Kfv8Z2WLINkHbMQXcd37/tIubX6w9VWjWJ2TuX5cK2H07EraPDDYAHJlnoR/WIPoYwQoXGUWqGH26O2LdBiLs9JcBQ9rKT8K8wmQuxf2rTpY7lN2RoKMjjEjcleWJwQG/3w=
29
- template:
30
- - '%{repository}#%{build_number} (%{branch} - %{commit} : %{author}): %{message} (<a href="%{build_url}">Build</a>/<a href="%{compare_url}">Changes</a>)'
31
- format: 'html'
data/LICENSE.md CHANGED
@@ -1,4 +1,4 @@
1
- Copyright (c) 2013-2015, Mirego
1
+ Copyright (c) 2013-2019, Mirego
2
2
  All rights reserved.
3
3
 
4
4
  Redistribution and use in source and binary forms, with or without
data/README.md CHANGED
@@ -1,15 +1,11 @@
1
- <p align="center">
2
- <a href="https://github.com/mirego/microscope">
3
- <img src="http://i.imgur.com/JMcAStM.png" alt="Microscope" />
4
- </a>
5
- <br />
6
- Microscope adds useful scopes targeting ActiveRecord <code>boolean</code>, <code>date</code> and <code>datetime</code> fields.
7
- <br /><br />
8
- <a href="https://rubygems.org/gems/microscope"><img src="http://img.shields.io/gem/v/microscope.svg" /></a>
9
- <a href="https://codeclimate.com/github/mirego/microscope"><img src="http://img.shields.io/codeclimate/github/mirego/microscope.svg" /></a>
10
- <a href='https://gemnasium.com/mirego/microscope'><img src="http://img.shields.io/gemnasium/mirego/microscope.svg" /></a>
11
- <a href="https://travis-ci.org/mirego/microscope"><img src="http://img.shields.io/travis/mirego/microscope.svg" /></a>
12
- </p>
1
+ <div align="center">
2
+ <img src="https://user-images.githubusercontent.com/11348/55957273-e1a0a580-5c33-11e9-9eb7-edb896fbbeaf.png" width="600" alt="Microscope" />
3
+ <p><br />Microscope adds useful scopes targeting ActiveRecord <code>boolean</code>, <code>date</code> and <code>datetime</code> attributes.</p>
4
+ <p>
5
+ <a href="https://travis-ci.com/mirego/microscope"><img src="https://travis-ci.com/mirego/microscope.svg?branch=master" /></a>
6
+ <a href="https://rubygems.org/gems/microscope"><img src="https://img.shields.io/gem/v/microscope.svg" /></a>
7
+ </p>
8
+ </div>
13
9
 
14
10
  ---
15
11
 
@@ -31,7 +27,7 @@ create_table "events" do |t|
31
27
  t.date "archived_on"
32
28
  end
33
29
 
34
- class Event < ActiveRecord::Base
30
+ class Event < ApplicationRecord
35
31
  acts_as_microscope
36
32
  end
37
33
 
@@ -106,12 +102,12 @@ event.archived_at # => 2013-07-05 15:43:42
106
102
  You can also use a few options when calling `acts_as_microscope`:
107
103
 
108
104
  ```ruby
109
- class Event < ActiveRecord::Base
110
- acts_as_microscope, only: [:created_at]
105
+ class Event < ApplicationRecord
106
+ acts_as_microscope only: [:created_at]
111
107
  end
112
108
 
113
- class User < ActiveRecord::Base
114
- acts_as_microscope, except: [:created_at]
109
+ class User < ApplicationRecord
110
+ acts_as_microscope except: [:created_at]
115
111
  end
116
112
 
117
113
  Event.created_before(2.months.ago) # works!
@@ -121,14 +117,62 @@ User.created_before(2.months.ago) # NoMethodError
121
117
  User.updated_before(2.months.ago) # works!
122
118
  ```
123
119
 
120
+ ### Date and time attributes and forms
121
+
122
+ When using Microscope on a `date` or `datetime` attribute, you’ll probably want
123
+ avoid dealing with those values in forms and only expose a checkbox to the
124
+ user.
125
+
126
+ Setting a Microscope-enabled attribute to a [_truthy_ value](https://github.com/mirego/microscope/blob/master/lib/microscope/utils.rb#L5)
127
+ will correctly cast the attribute to the right value (`Date.today` or `Time.now`, respectively). Otherwise the attribute will
128
+ be set to `nil`.
129
+
130
+ #### Model
131
+
132
+ ```
133
+ class Event < ApplicationRecord
134
+ acts_as_microscope
135
+ end
136
+ ```
137
+
138
+ #### View
139
+
140
+ ```erb
141
+ <% form_for @event do |form| %>
142
+ <%= form.text_field :name %>
143
+ <%= form.check_box :archived? %>
144
+
145
+ <%= submit_tag %>
146
+ <% end %>
147
+ ```
148
+
149
+ #### Controller
150
+
151
+ ```ruby
152
+ class EventsController < ApplicationController
153
+ def new
154
+ @event = Event.new
155
+ end
156
+
157
+ def create
158
+ @event = Event.new(event_params)
159
+ @event.save
160
+ end
161
+
162
+ def event_params
163
+ params.require(:event).permit(:name, :archived)
164
+ end
165
+ end
166
+ ```
167
+
124
168
  ## License
125
169
 
126
- `Microscope` is © 2013-2015 [Mirego](http://www.mirego.com) and may be freely distributed under the [New BSD license](http://opensource.org/licenses/BSD-3-Clause). See the [`LICENSE.md`](https://github.com/mirego/microscope/blob/master/LICENSE.md) file.
170
+ `Microscope` is © 2013-2019 [Mirego](http://www.mirego.com) and may be freely distributed under the [New BSD license](http://opensource.org/licenses/BSD-3-Clause). See the [`LICENSE.md`](https://github.com/mirego/microscope/blob/master/LICENSE.md) file.
127
171
 
128
172
  The microscope logo is based on [this lovely icon](http://thenounproject.com/noun/microscope/#icon-No9056) by [Scott Lewis](http://thenounproject.com/iconify), from The Noun Project. Used under a [Creative Commons BY 3.0](http://creativecommons.org/licenses/by/3.0/) license.
129
173
 
130
174
  ## About Mirego
131
175
 
132
- [Mirego](http://mirego.com) is a team of passionate people who believe that work is a place where you can innovate and have fun. We're a team of [talented people](http://life.mirego.com) who imagine and build beautiful Web and mobile applications. We come together to share ideas and [change the world](http://mirego.org).
176
+ [Mirego](https://www.mirego.com) is a team of passionate people who believe that work is a place where you can innovate and have fun. We're a team of [talented people](https://life.mirego.com) who imagine and build beautiful Web and mobile applications. We come together to share ideas and [change the world](https://www.mirego.org).
133
177
 
134
- We also [love open-source software](http://open.mirego.com) and we try to give back to the community as much as we can.
178
+ We also [love open-source software](https://open.mirego.com) and we try to give back to the community as much as we can.
@@ -3,3 +3,6 @@ source 'https://rubygems.org'
3
3
  gemspec path: '../'
4
4
 
5
5
  gem 'activerecord', '~> 4.1.0'
6
+ gem 'sqlite3', '~> 1.3.6'
7
+ gem 'mysql2', '~> 0.3.0'
8
+ gem 'pg', '~> 0.15.0'
@@ -0,0 +1,8 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gemspec path: '../'
4
+
5
+ gem 'activerecord', '~> 4.2.0'
6
+ gem 'sqlite3', '~> 1.3.6'
7
+ gem 'mysql2', '~> 0.4.0'
8
+ gem 'pg', '~> 0.15.0'
@@ -0,0 +1,8 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gemspec path: '../'
4
+
5
+ gem 'activerecord', '~> 5.1.0'
6
+ gem 'sqlite3', '~> 1.3.6'
7
+ gem 'mysql2', '~> 0.4.0'
8
+ gem 'pg', '~> 0.18.0'
@@ -0,0 +1,8 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gemspec path: '../'
4
+
5
+ gem 'activerecord', '~> 5.2.0'
6
+ gem 'sqlite3', '~> 1.3.6'
7
+ gem 'mysql2', '~> 0.4.0'
8
+ gem 'pg', '~> 0.18.0'
@@ -17,6 +17,11 @@ require 'microscope/instance_method/datetime_instance_method'
17
17
  require 'microscope/instance_method/date_instance_method'
18
18
 
19
19
  module Microscope
20
+ # Constants
21
+ BlacklistedColumnsErrorMessage = 'The `%s` column cannot be used with Microscope because it’s on ActiveRecord’s method name blacklist.'.freeze
22
+
23
+ # Errors
24
+ BlacklistedColumnsError = Class.new(StandardError)
20
25
  end
21
26
 
22
27
  module ActiveRecord
@@ -33,6 +38,8 @@ module ActiveRecord
33
38
 
34
39
  Microscope::Scope.inject_scopes(self, model_columns, options)
35
40
  Microscope::InstanceMethod.inject_instance_methods(self, model_columns, options)
41
+ rescue ActiveRecord::NoDatabaseError
42
+ nil
36
43
  end
37
44
  end
38
45
  end
@@ -22,5 +22,17 @@ module Microscope
22
22
  "Microscope::Scope::#{scope}".constantize.new(model, field).apply if const_defined?(scope)
23
23
  end
24
24
  end
25
+
26
+ protected
27
+
28
+ def blacklisted_fields
29
+ return [] unless defined? ActiveRecord::AttributeMethods::BLACKLISTED_CLASS_METHODS
30
+
31
+ ActiveRecord::AttributeMethods::BLACKLISTED_CLASS_METHODS
32
+ end
33
+
34
+ def validate_field_name!(cropped_field_name, field_name)
35
+ raise Microscope::BlacklistedColumnsError, Microscope::BlacklistedColumnsErrorMessage % field_name if blacklisted_fields.include?(cropped_field_name)
36
+ end
25
37
  end
26
38
  end
@@ -2,6 +2,8 @@ module Microscope
2
2
  class Scope
3
3
  class BooleanScope < Scope
4
4
  def apply
5
+ validate_field_name!(@field.name, @field.name)
6
+
5
7
  model.class_eval <<-RUBY, __FILE__, __LINE__ + 1
6
8
  scope "#{@field.name}", lambda { where("#{@field.name}" => true) }
7
9
  scope "not_#{@field.name}", lambda { where("#{@field.name}" => false) }
@@ -12,7 +12,10 @@ module Microscope
12
12
  end
13
13
 
14
14
  def apply
15
- model.class_eval(apply_scopes) if @field.name =~ @cropped_field_regex
15
+ return unless @field.name =~ @cropped_field_regex
16
+
17
+ validate_field_name!(cropped_field, @field.name)
18
+ model.class_eval(apply_scopes)
16
19
  end
17
20
 
18
21
  private
@@ -1,3 +1,3 @@
1
1
  module Microscope
2
- VERSION = '1.0.1'
2
+ VERSION = '1.1.0'
3
3
  end
@@ -8,7 +8,7 @@ Gem::Specification.new do |spec|
8
8
  spec.version = Microscope::VERSION
9
9
  spec.authors = ['Simon Prévost', 'Rémi Prévost', 'Samuel Garneau']
10
10
  spec.email = ['sprevost@mirego.com', 'rprevost@mirego.com', 'sgarneau@mirego.com']
11
- spec.description = 'Microscope adds useful scopes targeting ActiveRecord boolean and datetime fields.'
11
+ spec.description = 'Microscope adds useful scopes targeting ActiveRecord boolean and datetime attributes.'
12
12
  spec.summary = spec.description
13
13
  spec.homepage = 'https://github.com/mirego/microscope'
14
14
  spec.license = 'BSD 3-Clause'
@@ -18,15 +18,12 @@ Gem::Specification.new do |spec|
18
18
  spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
19
  spec.require_paths = ['lib']
20
20
 
21
- spec.add_dependency 'activesupport', '>= 3.0.0'
22
- spec.add_dependency 'activerecord', '>= 3.0.0'
21
+ spec.add_dependency 'activesupport', '>= 4.1.0'
22
+ spec.add_dependency 'activerecord', '>= 4.1.0'
23
23
 
24
- spec.add_development_dependency 'bundler', '~> 1.3'
24
+ spec.add_development_dependency 'bundler', '~> 2.0'
25
25
  spec.add_development_dependency 'rake'
26
26
  spec.add_development_dependency 'rspec', '~> 3.1'
27
- spec.add_development_dependency 'sqlite3'
28
- spec.add_development_dependency 'pg'
29
- spec.add_development_dependency 'mysql2', '~> 0.3.13'
30
27
  spec.add_development_dependency 'rubocop', '0.29'
31
28
  spec.add_development_dependency 'phare'
32
29
  end
@@ -42,7 +42,7 @@ describe Microscope::InstanceMethod::DatetimeInstanceMethod do
42
42
 
43
43
  context 'with present argument, twice' do
44
44
  let(:event) { Event.create(started_at: time) }
45
- let(:time) { 2.months.ago }
45
+ let(:time) { 2.months.ago.beginning_of_hour }
46
46
  let(:value) { '1' }
47
47
 
48
48
  it { expect(event.started_at).to eql time }
@@ -1,36 +1,50 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe Microscope::Scope::BooleanScope do
4
- before do
5
- run_migration do
6
- create_table(:oh_users, force: true) do |t|
7
- t.boolean :active, default: false
4
+ describe 'for a valid column name' do
5
+ before do
6
+ run_migration do
7
+ create_table(:oh_users, force: true) do |t|
8
+ t.boolean :active, default: false
9
+ end
8
10
  end
9
- end
10
11
 
11
- microscope 'User' do
12
- self.table_name = 'oh_users'
12
+ microscope 'User' do
13
+ self.table_name = 'oh_users'
14
+ end
13
15
  end
14
- end
15
16
 
16
- describe 'positive scope' do
17
- before do
18
- @user1 = User.create(active: true)
19
- @user2 = User.create(active: false)
17
+ describe 'positive scope' do
18
+ before do
19
+ @user1 = User.create(active: true)
20
+ @user2 = User.create(active: false)
21
+ end
22
+
23
+ it { expect(User.active.length).to eql 1 }
24
+ it { expect(User.active).to include(@user1) }
20
25
  end
21
26
 
22
- it { expect(User.active.length).to eql 1 }
23
- it { expect(User.active).to include(@user1) }
27
+ describe 'negative scope' do
28
+ before do
29
+ @user1 = User.create(active: false)
30
+ @user2 = User.create(active: true)
31
+ end
32
+
33
+ it { expect(User.not_active.length).to eql 1 }
34
+ it { expect(User.not_active).to include(@user1) }
35
+ it { expect(User.unactive.to_a).to eql User.not_active.to_a }
36
+ end
24
37
  end
25
38
 
26
- describe 'negative scope' do
39
+ describe 'for a invalid column name' do
27
40
  before do
28
- @user1 = User.create(active: false)
29
- @user2 = User.create(active: true)
41
+ run_migration do
42
+ create_table(:users, force: true) do |t|
43
+ t.boolean :public, default: false
44
+ end
45
+ end
30
46
  end
31
47
 
32
- it { expect(User.not_active.length).to eql 1 }
33
- it { expect(User.not_active).to include(@user1) }
34
- it { expect(User.unactive.to_a).to eql User.not_active.to_a }
48
+ it { expect { microscope 'User' }.to raise_error(Microscope::BlacklistedColumnsError) }
35
49
  end
36
50
  end
@@ -1,150 +1,164 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe Microscope::Scope::DateScope do
4
- before do
5
- run_migration do
6
- create_table(:events, force: true) do |t|
7
- t.date :started_on, default: nil
8
- t.date :published_date, default: nil
4
+ describe 'for a valid column name' do
5
+ before do
6
+ run_migration do
7
+ create_table(:events, force: true) do |t|
8
+ t.date :started_on, default: nil
9
+ t.date :published_date, default: nil
10
+ end
9
11
  end
12
+
13
+ microscope 'Event'
10
14
  end
11
15
 
12
- microscope 'Event'
13
- end
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
14
21
 
15
- describe 'before scope' do
16
- before do
17
- @event = Event.create(started_on: 2.months.ago)
18
- Event.create(started_on: 1.month.from_now)
22
+ it { expect(Event.started_before(1.month.ago).to_a).to eql [@event] }
19
23
  end
20
24
 
21
- it { expect(Event.started_before(1.month.ago).to_a).to eql [@event] }
22
- end
25
+ describe 'before_or_on scope' do
26
+ let(:date) { 2.months.ago }
23
27
 
24
- describe 'before_or_on scope' do
25
- let(:date) { 2.months.ago }
28
+ before do
29
+ @event1 = Event.create(started_on: date)
30
+ @event2 = Event.create(started_on: date - 1.day)
31
+ Event.create(started_on: 1.month.from_now)
32
+ end
26
33
 
27
- before do
28
- @event1 = Event.create(started_on: date)
29
- @event2 = Event.create(started_on: date - 1.day)
30
- Event.create(started_on: 1.month.from_now)
34
+ it { expect(Event.started_before_or_on(date).to_a).to eql [@event1, @event2] }
31
35
  end
32
36
 
33
- it { expect(Event.started_before_or_on(date).to_a).to eql [@event1, @event2] }
34
- end
37
+ describe 'before_or_now scope' do
38
+ let(:stubbed_date) { Date.parse('2020-03-18 08:00:00') }
39
+ before { allow(Date).to receive(:today).and_return(stubbed_date) }
35
40
 
36
- describe 'before_or_now scope' do
37
- let(:stubbed_date) { Date.parse('2020-03-18 08:00:00') }
38
- before { allow(Date).to receive(:today).and_return(stubbed_date) }
41
+ before do
42
+ @event1 = Event.create(started_on: stubbed_date)
43
+ @event2 = Event.create(started_on: stubbed_date - 1.day)
44
+ Event.create(started_on: stubbed_date + 1.week)
45
+ end
39
46
 
40
- before do
41
- @event1 = Event.create(started_on: stubbed_date)
42
- @event2 = Event.create(started_on: stubbed_date - 1.day)
43
- Event.create(started_on: stubbed_date + 1.week)
47
+ it { expect(Event.started_before_or_today.to_a).to eql [@event1, @event2] }
44
48
  end
45
49
 
46
- it { expect(Event.started_before_or_today.to_a).to eql [@event1, @event2] }
47
- end
50
+ describe 'before_today scope' do
51
+ before do
52
+ @event = Event.create(started_on: 2.months.ago)
53
+ Event.create(started_on: 1.month.from_now)
54
+ end
48
55
 
49
- describe 'before_today scope' do
50
- before do
51
- @event = Event.create(started_on: 2.months.ago)
52
- Event.create(started_on: 1.month.from_now)
56
+ it { expect(Event.started_before_today.to_a).to eql [@event] }
53
57
  end
54
58
 
55
- it { expect(Event.started_before_today.to_a).to eql [@event] }
56
- end
59
+ describe 'after scope' do
60
+ before do
61
+ @event = Event.create(started_on: 2.months.from_now)
62
+ Event.create(started_on: 1.month.ago)
63
+ end
57
64
 
58
- describe 'after scope' do
59
- before do
60
- @event = Event.create(started_on: 2.months.from_now)
61
- Event.create(started_on: 1.month.ago)
65
+ it { expect(Event.started_after(1.month.from_now).to_a).to eql [@event] }
62
66
  end
63
67
 
64
- it { expect(Event.started_after(1.month.from_now).to_a).to eql [@event] }
65
- end
68
+ describe 'after_or_on scope' do
69
+ let(:date) { 2.months.from_now }
66
70
 
67
- describe 'after_or_on scope' do
68
- let(:date) { 2.months.from_now }
71
+ before do
72
+ @event1 = Event.create(started_on: date)
73
+ @event2 = Event.create(started_on: date + 1.day)
74
+ Event.create(started_on: 1.month.ago)
75
+ end
69
76
 
70
- before do
71
- @event1 = Event.create(started_on: date)
72
- @event2 = Event.create(started_on: date + 1.day)
73
- Event.create(started_on: 1.month.ago)
77
+ it { expect(Event.started_after_or_on(date).to_a).to eql [@event1, @event2] }
74
78
  end
75
79
 
76
- it { expect(Event.started_after_or_on(date).to_a).to eql [@event1, @event2] }
77
- end
80
+ describe 'after_or_now scope' do
81
+ let(:stubbed_date) { Date.parse('2020-03-18 08:00:00') }
82
+ before { allow(Date).to receive(:today).and_return(stubbed_date) }
78
83
 
79
- describe 'after_or_now scope' do
80
- let(:stubbed_date) { Date.parse('2020-03-18 08:00:00') }
81
- before { allow(Date).to receive(:today).and_return(stubbed_date) }
84
+ before do
85
+ @event1 = Event.create(started_on: stubbed_date)
86
+ @event2 = Event.create(started_on: stubbed_date + 1.day)
87
+ Event.create(started_on: 1.month.ago)
88
+ end
82
89
 
83
- before do
84
- @event1 = Event.create(started_on: stubbed_date)
85
- @event2 = Event.create(started_on: stubbed_date + 1.day)
86
- Event.create(started_on: 1.month.ago)
90
+ it { expect(Event.started_after_or_today.to_a).to eql [@event1, @event2] }
87
91
  end
88
92
 
89
- it { expect(Event.started_after_or_today.to_a).to eql [@event1, @event2] }
90
- end
93
+ describe 'after_today scope' do
94
+ before do
95
+ @event = Event.create(started_on: 2.months.from_now)
96
+ Event.create(started_on: 1.month.ago)
97
+ end
91
98
 
92
- describe 'after_today scope' do
93
- before do
94
- @event = Event.create(started_on: 2.months.from_now)
95
- Event.create(started_on: 1.month.ago)
99
+ it { expect(Event.started_after_today.to_a).to eql [@event] }
96
100
  end
97
101
 
98
- it { expect(Event.started_after_today.to_a).to eql [@event] }
99
- end
102
+ describe 'between scope' do
103
+ before do
104
+ Event.create(started_on: 1.month.ago)
105
+ @event = Event.create(started_on: 3.months.ago)
106
+ Event.create(started_on: 5.month.ago)
107
+ end
100
108
 
101
- describe 'between scope' do
102
- before do
103
- Event.create(started_on: 1.month.ago)
104
- @event = Event.create(started_on: 3.months.ago)
105
- Event.create(started_on: 5.month.ago)
109
+ it { expect(Event.started_between(4.months.ago..2.months.ago).to_a).to eql [@event] }
106
110
  end
107
111
 
108
- it { expect(Event.started_between(4.months.ago..2.months.ago).to_a).to eql [@event] }
109
- end
112
+ describe 'super-boolean positive scope' do
113
+ before do
114
+ @event1 = Event.create(started_on: 1.month.ago)
115
+ @event2 = Event.create(started_on: 3.months.ago)
116
+ Event.create(started_on: 2.months.from_now)
117
+ Event.create(started_on: nil)
118
+ end
110
119
 
111
- describe 'super-boolean positive scope' do
112
- before do
113
- @event1 = Event.create(started_on: 1.month.ago)
114
- @event2 = Event.create(started_on: 3.months.ago)
115
- Event.create(started_on: 2.months.from_now)
116
- Event.create(started_on: nil)
120
+ it { expect(Event.started.to_a).to eql [@event1, @event2] }
117
121
  end
118
122
 
119
- it { expect(Event.started.to_a).to eql [@event1, @event2] }
120
- end
123
+ describe 'super-boolean negative scope' do
124
+ before do
125
+ Event.create(started_on: 1.month.ago)
126
+ Event.create(started_on: 3.months.ago)
127
+ @event1 = Event.create(started_on: 2.months.from_now)
128
+ @event2 = Event.create(started_on: nil)
129
+ end
121
130
 
122
- describe 'super-boolean negative scope' do
123
- before do
124
- Event.create(started_on: 1.month.ago)
125
- Event.create(started_on: 3.months.ago)
126
- @event1 = Event.create(started_on: 2.months.from_now)
127
- @event2 = Event.create(started_on: nil)
131
+ it { expect(Event.not_started.to_a).to eql [@event1, @event2] }
132
+ it { expect(Event.unstarted.to_a).to eql Event.not_started.to_a }
128
133
  end
129
134
 
130
- it { expect(Event.not_started.to_a).to eql [@event1, @event2] }
131
- it { expect(Event.unstarted.to_a).to eql Event.not_started.to_a }
132
- end
135
+ describe 'boolean instance method' do
136
+ context 'for positive record' do
137
+ let(:event) { Event.create(started_on: 3.months.ago) }
138
+ it { expect(event).to be_started }
139
+ end
133
140
 
134
- describe 'boolean instance method' do
135
- context 'for positive record' do
136
- let(:event) { Event.create(started_on: 3.months.ago) }
137
- it { expect(event).to be_started }
141
+ context 'for negative record' do
142
+ let(:event) { Event.create(started_on: 2.months.from_now) }
143
+ it { expect(event).to_not be_started }
144
+ end
138
145
  end
139
146
 
140
- context 'for negative record' do
141
- let(:event) { Event.create(started_on: 2.months.from_now) }
142
- it { expect(event).to_not be_started }
147
+ context 'for field that does not match the pattern' do
148
+ it { expect(Event).to_not respond_to(:published_date) }
149
+ it { expect(Event).to_not respond_to(:not_published_date) }
143
150
  end
144
151
  end
145
152
 
146
- context 'for field that does not match the pattern' do
147
- it { expect(Event).to_not respond_to(:published_date) }
148
- it { expect(Event).to_not respond_to(:not_published_date) }
153
+ describe 'for a invalid column name' do
154
+ before do
155
+ run_migration do
156
+ create_table(:events, force: true) do |t|
157
+ t.date :public_on, default: nil
158
+ end
159
+ end
160
+ end
161
+
162
+ it { expect { microscope 'Event' }.to raise_error(Microscope::BlacklistedColumnsError) }
149
163
  end
150
164
  end
@@ -1,150 +1,164 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe Microscope::Scope::DatetimeScope do
4
- before do
5
- run_migration do
6
- create_table(:events, force: true) do |t|
7
- t.datetime :started_at, default: nil
8
- t.datetime :published_date, default: nil
4
+ describe 'for a valid column name' do
5
+ before do
6
+ run_migration do
7
+ create_table(:events, force: true) do |t|
8
+ t.datetime :started_at, default: nil
9
+ t.datetime :published_date, default: nil
10
+ end
9
11
  end
12
+
13
+ microscope 'Event'
10
14
  end
11
15
 
12
- microscope 'Event'
13
- end
16
+ describe 'before scope' do
17
+ before do
18
+ @event = Event.create(started_at: 2.months.ago)
19
+ Event.create(started_at: 1.month.from_now)
20
+ end
14
21
 
15
- describe 'before scope' do
16
- before do
17
- @event = Event.create(started_at: 2.months.ago)
18
- Event.create(started_at: 1.month.from_now)
22
+ it { expect(Event.started_before(1.month.ago).to_a).to eql [@event] }
19
23
  end
20
24
 
21
- it { expect(Event.started_before(1.month.ago).to_a).to eql [@event] }
22
- end
25
+ describe 'before_or_at scope' do
26
+ let(:datetime) { 1.month.ago }
23
27
 
24
- describe 'before_or_at scope' do
25
- let(:datetime) { 1.month.ago }
28
+ before do
29
+ @event1 = Event.create(started_at: datetime)
30
+ @event2 = Event.create(started_at: datetime - 1.second)
31
+ Event.create(started_at: 1.month.from_now)
32
+ end
26
33
 
27
- before do
28
- @event1 = Event.create(started_at: datetime)
29
- @event2 = Event.create(started_at: datetime - 1.second)
30
- Event.create(started_at: 1.month.from_now)
34
+ it { expect(Event.started_before_or_at(datetime).to_a).to eql [@event1, @event2] }
31
35
  end
32
36
 
33
- it { expect(Event.started_before_or_at(datetime).to_a).to eql [@event1, @event2] }
34
- end
37
+ describe 'before_or_now scope' do
38
+ let(:stubbed_date) { Time.parse('2020-03-18 08:00:00') }
39
+ before { allow(Time).to receive(:now).and_return(stubbed_date) }
35
40
 
36
- describe 'before_or_now scope' do
37
- let(:stubbed_date) { Time.parse('2020-03-18 08:00:00') }
38
- before { allow(Time).to receive(:now).and_return(stubbed_date) }
41
+ before do
42
+ @event1 = Event.create(started_at: stubbed_date)
43
+ @event2 = Event.create(started_at: stubbed_date - 1.second)
44
+ Event.create(started_at: 1.month.from_now)
45
+ end
39
46
 
40
- before do
41
- @event1 = Event.create(started_at: stubbed_date)
42
- @event2 = Event.create(started_at: stubbed_date - 1.second)
43
- Event.create(started_at: 1.month.from_now)
47
+ it { expect(Event.started_before_or_now.to_a).to eql [@event1, @event2] }
44
48
  end
45
49
 
46
- it { expect(Event.started_before_or_now.to_a).to eql [@event1, @event2] }
47
- end
50
+ describe 'before_now scope' do
51
+ before do
52
+ @event = Event.create(started_at: 2.months.ago)
53
+ Event.create(started_at: 1.month.from_now)
54
+ end
48
55
 
49
- describe 'before_now scope' do
50
- before do
51
- @event = Event.create(started_at: 2.months.ago)
52
- Event.create(started_at: 1.month.from_now)
56
+ it { expect(Event.started_before_now.to_a).to eql [@event] }
53
57
  end
54
58
 
55
- it { expect(Event.started_before_now.to_a).to eql [@event] }
56
- end
59
+ describe 'after scope' do
60
+ before do
61
+ @event = Event.create(started_at: 2.months.from_now)
62
+ Event.create(started_at: 1.month.ago)
63
+ end
57
64
 
58
- describe 'after scope' do
59
- before do
60
- @event = Event.create(started_at: 2.months.from_now)
61
- Event.create(started_at: 1.month.ago)
65
+ it { expect(Event.started_after(1.month.from_now).to_a).to eql [@event] }
62
66
  end
63
67
 
64
- it { expect(Event.started_after(1.month.from_now).to_a).to eql [@event] }
65
- end
68
+ describe 'after_or_at scope' do
69
+ let(:datetime) { 1.month.from_now.beginning_of_hour }
66
70
 
67
- describe 'after_or_at scope' do
68
- let(:datetime) { 1.month.from_now }
71
+ before do
72
+ @event1 = Event.create(started_at: datetime)
73
+ @event2 = Event.create(started_at: datetime + 1.second)
74
+ Event.create(started_at: 1.month.ago)
75
+ end
69
76
 
70
- before do
71
- @event1 = Event.create(started_at: datetime)
72
- @event2 = Event.create(started_at: datetime + 1.second)
73
- Event.create(started_at: 1.month.ago)
77
+ it { expect(Event.started_after_or_at(datetime).to_a).to eql [@event1, @event2] }
74
78
  end
75
79
 
76
- it { expect(Event.started_after_or_at(datetime).to_a).to eql [@event1, @event2] }
77
- end
80
+ describe 'after_or_now scope' do
81
+ let(:stubbed_date) { Time.parse('2020-03-18 08:00:00') }
82
+ before { allow(Time).to receive(:now).and_return(stubbed_date) }
78
83
 
79
- describe 'after_or_now scope' do
80
- let(:stubbed_date) { Time.parse('2020-03-18 08:00:00') }
81
- before { allow(Time).to receive(:now).and_return(stubbed_date) }
84
+ before do
85
+ @event1 = Event.create(started_at: stubbed_date)
86
+ @event2 = Event.create(started_at: stubbed_date + 1.second)
87
+ Event.create(started_at: 1.month.ago)
88
+ end
82
89
 
83
- before do
84
- @event1 = Event.create(started_at: stubbed_date)
85
- @event2 = Event.create(started_at: stubbed_date + 1.second)
86
- Event.create(started_at: 1.month.ago)
90
+ it { expect(Event.started_after_or_now.to_a).to eql [@event1, @event2] }
87
91
  end
88
92
 
89
- it { expect(Event.started_after_or_now.to_a).to eql [@event1, @event2] }
90
- end
93
+ describe 'after_now scope' do
94
+ before do
95
+ @event = Event.create(started_at: 2.months.from_now)
96
+ Event.create(started_at: 1.month.ago)
97
+ end
91
98
 
92
- describe 'after_now scope' do
93
- before do
94
- @event = Event.create(started_at: 2.months.from_now)
95
- Event.create(started_at: 1.month.ago)
99
+ it { expect(Event.started_after_now.to_a).to eql [@event] }
96
100
  end
97
101
 
98
- it { expect(Event.started_after_now.to_a).to eql [@event] }
99
- end
102
+ describe 'between scope' do
103
+ before do
104
+ Event.create(started_at: 1.month.ago)
105
+ @event = Event.create(started_at: 3.months.ago)
106
+ Event.create(started_at: 5.month.ago)
107
+ end
100
108
 
101
- describe 'between scope' do
102
- before do
103
- Event.create(started_at: 1.month.ago)
104
- @event = Event.create(started_at: 3.months.ago)
105
- Event.create(started_at: 5.month.ago)
109
+ it { expect(Event.started_between(4.months.ago..2.months.ago).to_a).to eql [@event] }
106
110
  end
107
111
 
108
- it { expect(Event.started_between(4.months.ago..2.months.ago).to_a).to eql [@event] }
109
- end
112
+ describe 'super-boolean positive scope', focus: true do
113
+ before do
114
+ @event1 = Event.create(started_at: 1.month.ago)
115
+ @event2 = Event.create(started_at: 3.months.ago)
116
+ Event.create(started_at: 2.months.from_now)
117
+ Event.create(started_at: nil)
118
+ end
110
119
 
111
- describe 'super-boolean positive scope', focus: true do
112
- before do
113
- @event1 = Event.create(started_at: 1.month.ago)
114
- @event2 = Event.create(started_at: 3.months.ago)
115
- Event.create(started_at: 2.months.from_now)
116
- Event.create(started_at: nil)
120
+ it { expect(Event.started.to_a).to eql [@event1, @event2] }
117
121
  end
118
122
 
119
- it { expect(Event.started.to_a).to eql [@event1, @event2] }
120
- end
123
+ describe 'super-boolean negative scope' do
124
+ before do
125
+ Event.create(started_at: 1.month.ago)
126
+ Event.create(started_at: 3.months.ago)
127
+ @event1 = Event.create(started_at: 2.months.from_now)
128
+ @event2 = Event.create(started_at: nil)
129
+ end
121
130
 
122
- describe 'super-boolean negative scope' do
123
- before do
124
- Event.create(started_at: 1.month.ago)
125
- Event.create(started_at: 3.months.ago)
126
- @event1 = Event.create(started_at: 2.months.from_now)
127
- @event2 = Event.create(started_at: nil)
131
+ it { expect(Event.not_started.to_a).to eql [@event1, @event2] }
132
+ it { expect(Event.unstarted.to_a).to eql Event.not_started.to_a }
128
133
  end
129
134
 
130
- it { expect(Event.not_started.to_a).to eql [@event1, @event2] }
131
- it { expect(Event.unstarted.to_a).to eql Event.not_started.to_a }
132
- end
135
+ describe 'boolean instance method' do
136
+ context 'for positive record' do
137
+ let(:event) { Event.create(started_at: 3.months.ago) }
138
+ it { expect(event).to be_started }
139
+ end
133
140
 
134
- describe 'boolean instance method' do
135
- context 'for positive record' do
136
- let(:event) { Event.create(started_at: 3.months.ago) }
137
- it { expect(event).to be_started }
141
+ context 'for negative record' do
142
+ let(:event) { Event.create(started_at: 2.months.from_now) }
143
+ it { expect(event).to_not be_started }
144
+ end
138
145
  end
139
146
 
140
- context 'for negative record' do
141
- let(:event) { Event.create(started_at: 2.months.from_now) }
142
- it { expect(event).to_not be_started }
147
+ context 'for field that does not match the pattern' do
148
+ it { expect(Event).to_not respond_to(:published_date) }
149
+ it { expect(Event).to_not respond_to(:not_published_date) }
143
150
  end
144
151
  end
145
152
 
146
- context 'for field that does not match the pattern' do
147
- it { expect(Event).to_not respond_to(:published_date) }
148
- it { expect(Event).to_not respond_to(:not_published_date) }
153
+ describe 'for a invalid column name' do
154
+ before do
155
+ run_migration do
156
+ create_table(:events, force: true) do |t|
157
+ t.datetime :public_at, default: nil
158
+ end
159
+ end
160
+ end
161
+
162
+ it { expect { microscope 'Event' }.to raise_error(Microscope::BlacklistedColumnsError) }
149
163
  end
150
164
  end
@@ -1,6 +1,17 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe Microscope do
4
+ describe :acts_as_microscope_without_database do
5
+ specify do
6
+ adapter = ENV['DB_ADAPTER'] || 'sqlite3'
7
+ setup_database(adapter: adapter, database: 'microscope_test_that_does_not_exist')
8
+
9
+ class User < ActiveRecord::Base
10
+ acts_as_microscope
11
+ end
12
+ end
13
+ end
14
+
4
15
  describe :acts_as_microscope do
5
16
  before do
6
17
  run_migration do
@@ -12,5 +12,7 @@ class Mysql2Adapter < DatabaseAdapter
12
12
 
13
13
  def reset_database!
14
14
  ActiveRecord::Base.connection.execute("SELECT concat('DROP TABLE IF EXISTS ', table_name, ';') FROM information_schema.tables WHERE table_schema = '#{@database}';")
15
+ rescue ActiveRecord::NoDatabaseError
16
+ nil
15
17
  end
16
18
  end
@@ -13,5 +13,7 @@ class PostgresqlAdapter < DatabaseAdapter
13
13
  def reset_database!
14
14
  ActiveRecord::Base.connection.execute('drop schema public cascade;')
15
15
  ActiveRecord::Base.connection.execute('create schema public;')
16
+ rescue ActiveRecord::NoDatabaseError
17
+ nil
16
18
  end
17
19
  end
@@ -2,7 +2,11 @@ module DatabaseMacros
2
2
  # Run migrations in the test database
3
3
  def run_migration(&block)
4
4
  # Create a new migration class
5
- klass = Class.new(ActiveRecord::Migration)
5
+ if ActiveRecord.version >= Gem::Version.new('5.0')
6
+ klass = Class.new(ActiveRecord::Migration[ActiveRecord.version.to_s.to_f])
7
+ else
8
+ klass = Class.new(ActiveRecord::Migration)
9
+ end
6
10
 
7
11
  # Create a new `up` that executes the argument
8
12
  klass.send(:define_method, :up) { instance_exec(&block) }
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: 1.0.1
4
+ version: 1.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Simon Prévost
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2015-03-27 00:00:00.000000000 Z
13
+ date: 2019-04-11 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: activesupport
@@ -18,42 +18,42 @@ dependencies:
18
18
  requirements:
19
19
  - - ">="
20
20
  - !ruby/object:Gem::Version
21
- version: 3.0.0
21
+ version: 4.1.0
22
22
  type: :runtime
23
23
  prerelease: false
24
24
  version_requirements: !ruby/object:Gem::Requirement
25
25
  requirements:
26
26
  - - ">="
27
27
  - !ruby/object:Gem::Version
28
- version: 3.0.0
28
+ version: 4.1.0
29
29
  - !ruby/object:Gem::Dependency
30
30
  name: activerecord
31
31
  requirement: !ruby/object:Gem::Requirement
32
32
  requirements:
33
33
  - - ">="
34
34
  - !ruby/object:Gem::Version
35
- version: 3.0.0
35
+ version: 4.1.0
36
36
  type: :runtime
37
37
  prerelease: false
38
38
  version_requirements: !ruby/object:Gem::Requirement
39
39
  requirements:
40
40
  - - ">="
41
41
  - !ruby/object:Gem::Version
42
- version: 3.0.0
42
+ version: 4.1.0
43
43
  - !ruby/object:Gem::Dependency
44
44
  name: bundler
45
45
  requirement: !ruby/object:Gem::Requirement
46
46
  requirements:
47
47
  - - "~>"
48
48
  - !ruby/object:Gem::Version
49
- version: '1.3'
49
+ version: '2.0'
50
50
  type: :development
51
51
  prerelease: false
52
52
  version_requirements: !ruby/object:Gem::Requirement
53
53
  requirements:
54
54
  - - "~>"
55
55
  - !ruby/object:Gem::Version
56
- version: '1.3'
56
+ version: '2.0'
57
57
  - !ruby/object:Gem::Dependency
58
58
  name: rake
59
59
  requirement: !ruby/object:Gem::Requirement
@@ -82,48 +82,6 @@ dependencies:
82
82
  - - "~>"
83
83
  - !ruby/object:Gem::Version
84
84
  version: '3.1'
85
- - !ruby/object:Gem::Dependency
86
- name: sqlite3
87
- requirement: !ruby/object:Gem::Requirement
88
- requirements:
89
- - - ">="
90
- - !ruby/object:Gem::Version
91
- version: '0'
92
- type: :development
93
- prerelease: false
94
- version_requirements: !ruby/object:Gem::Requirement
95
- requirements:
96
- - - ">="
97
- - !ruby/object:Gem::Version
98
- version: '0'
99
- - !ruby/object:Gem::Dependency
100
- name: pg
101
- requirement: !ruby/object:Gem::Requirement
102
- requirements:
103
- - - ">="
104
- - !ruby/object:Gem::Version
105
- version: '0'
106
- type: :development
107
- prerelease: false
108
- version_requirements: !ruby/object:Gem::Requirement
109
- requirements:
110
- - - ">="
111
- - !ruby/object:Gem::Version
112
- version: '0'
113
- - !ruby/object:Gem::Dependency
114
- name: mysql2
115
- requirement: !ruby/object:Gem::Requirement
116
- requirements:
117
- - - "~>"
118
- - !ruby/object:Gem::Version
119
- version: 0.3.13
120
- type: :development
121
- prerelease: false
122
- version_requirements: !ruby/object:Gem::Requirement
123
- requirements:
124
- - - "~>"
125
- - !ruby/object:Gem::Version
126
- version: 0.3.13
127
85
  - !ruby/object:Gem::Dependency
128
86
  name: rubocop
129
87
  requirement: !ruby/object:Gem::Requirement
@@ -153,7 +111,7 @@ dependencies:
153
111
  - !ruby/object:Gem::Version
154
112
  version: '0'
155
113
  description: Microscope adds useful scopes targeting ActiveRecord boolean and datetime
156
- fields.
114
+ attributes.
157
115
  email:
158
116
  - sprevost@mirego.com
159
117
  - rprevost@mirego.com
@@ -172,6 +130,9 @@ files:
172
130
  - Rakefile
173
131
  - UPGRADE.md
174
132
  - gemfiles/Gemfile.activerecord-4.1
133
+ - gemfiles/Gemfile.activerecord-4.2
134
+ - gemfiles/Gemfile.activerecord-5.1
135
+ - gemfiles/Gemfile.activerecord-5.2
175
136
  - lib/microscope.rb
176
137
  - lib/microscope/instance_method.rb
177
138
  - lib/microscope/instance_method/boolean_instance_method.rb
@@ -218,11 +179,11 @@ required_rubygems_version: !ruby/object:Gem::Requirement
218
179
  version: '0'
219
180
  requirements: []
220
181
  rubyforge_project:
221
- rubygems_version: 2.2.2
182
+ rubygems_version: 2.5.2.3
222
183
  signing_key:
223
184
  specification_version: 4
224
185
  summary: Microscope adds useful scopes targeting ActiveRecord boolean and datetime
225
- fields.
186
+ attributes.
226
187
  test_files:
227
188
  - spec/microscope/instance_method/boolean_instance_method_spec.rb
228
189
  - spec/microscope/instance_method/date_instance_method_spec.rb