activerecord_null_object 0.2.0 → 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 8e814ba60434b9563a80ed56708733bcce37ac810148403ce512eede9006e0dc
4
+ data.tar.gz: 7a79cb743fb799deb9ed2b899357fbbd34c71eeda7468cdd3e00737a1f1c3329
5
+ SHA512:
6
+ metadata.gz: 5c3d744c96242745bfd230f952de637728e2e8788407b72a5f95ca08d3fa4bbc1e804fbbc5953bde4cca15f5450e14f1e53499aafe37907e6f353b8c937958fc
7
+ data.tar.gz: 95e60bb581a2f19dee479161bcad3a6dda3048986521f31228a2ff344e2808ccde837724b5724362b8d339447b64109499ff1574b6ef3592c622db93d906dbd1
@@ -0,0 +1,6 @@
1
+ version: 2
2
+ updates:
3
+ - package-ecosystem: "bundler"
4
+ directory: "/"
5
+ schedule:
6
+ interval: "daily"
@@ -0,0 +1,59 @@
1
+ name: Release
2
+
3
+ on:
4
+ push:
5
+ tags:
6
+ - "v*"
7
+
8
+ jobs:
9
+ build:
10
+ name: Build
11
+ runs-on: ubuntu-latest
12
+ steps:
13
+ - name: Checkout
14
+ uses: actions/checkout@v2
15
+ - uses: ruby/setup-ruby@v1
16
+ with:
17
+ bundler-cache: true
18
+ - run: bundle exec rake
19
+
20
+ release:
21
+ needs: build
22
+ name: Release
23
+ runs-on: ubuntu-latest
24
+ steps:
25
+ - name: Checkout
26
+ uses: actions/checkout@v2
27
+
28
+ - name: Generate Changelog
29
+ run: |
30
+ # Get version from github ref (remove 'refs/tags/' and prefix 'v')
31
+ version="${GITHUB_REF#refs/tags/v}"
32
+ npx changelog-parser CHANGELOG.md | jq -cr ".versions | .[] | select(.version == \"$version\") | .body" > ${{ github.workflow }}-CHANGELOG.txt
33
+
34
+ - name: Release
35
+ uses: softprops/action-gh-release@v1
36
+ with:
37
+ body_path: ${{ github.workflow }}-CHANGELOG.txt
38
+ env:
39
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
40
+
41
+ publish:
42
+ needs: [build, release]
43
+ name: Publish
44
+ runs-on: ubuntu-latest
45
+
46
+ steps:
47
+ - uses: actions/checkout@v2
48
+ - uses: ruby/setup-ruby@v1
49
+
50
+ - name: Publish to RubyGems
51
+ run: |
52
+ mkdir -p $HOME/.gem
53
+ touch $HOME/.gem/credentials
54
+ chmod 0600 $HOME/.gem/credentials
55
+ printf -- "---\n:rubygems_api_key: ${GEM_HOST_API_KEY}\n" > $HOME/.gem/credentials
56
+ gem build *.gemspec
57
+ gem push *.gem
58
+ env:
59
+ GEM_HOST_API_KEY: "${{secrets.RUBYGEMS_AUTH_TOKEN}}"
@@ -0,0 +1,24 @@
1
+ name: Build and Test
2
+ on: [push, pull_request]
3
+ jobs:
4
+ test:
5
+ strategy:
6
+ fail-fast: false
7
+ matrix:
8
+ gemfile: [rails60, rails61, rails70]
9
+ ruby: ["2.7", "3.0", "3.1"]
10
+ runs-on: ubuntu-latest
11
+ env:
12
+ BUNDLE_GEMFILE: gemfiles/${{ matrix.gemfile }}.gemfile
13
+ steps:
14
+ - uses: actions/checkout@v2
15
+ - uses: ruby/setup-ruby@v1
16
+ with:
17
+ ruby-version: ${{ matrix.ruby }}
18
+ bundler-cache: true
19
+ - run: bundle exec rake
20
+ - name: Coveralls
21
+ uses: coverallsapp/github-action@master
22
+ with:
23
+ github-token: ${{ secrets.GITHUB_TOKEN }}
24
+ path-to-lcov: coverage/lcov.info
data/.gitignore CHANGED
@@ -1,3 +1,5 @@
1
- .DS_Store
2
- test.db
3
1
  pkg
2
+ coverage
3
+ Gemfile.lock
4
+ tmp
5
+ vendor
data/.ruby-version ADDED
@@ -0,0 +1 @@
1
+ 3.1.0
data/CHANGELOG.md ADDED
@@ -0,0 +1,14 @@
1
+ # Change Log
2
+
3
+ ## 0.6.0
4
+
5
+ - [PLAT-183] Ruby 3.0, Rails 7 and coveralls github action
6
+
7
+ ## 0.5.0
8
+
9
+ - [TT-8620] Update to build with github actions / ruby 3.0 / Rails 6.1
10
+
11
+ ## 0.4.0
12
+
13
+ * Use coverage kit to enforce maximum coverage
14
+ * [TT-6631] Fix present? and blank? checks on Rails6
data/Gemfile ADDED
@@ -0,0 +1,2 @@
1
+ source 'http://rubygems.org'
2
+ gemspec
data/README.md ADDED
@@ -0,0 +1,25 @@
1
+ ActiveRecord Null Object
2
+ ========================
3
+
4
+ [![Gem Version](https://badge.fury.io/rb/activerecord_null_object.svg)](http://badge.fury.io/rb/activerecord_null_object)
5
+ [![Build Status](https://github.com/sealink/activerecord_null_object/workflows/Build%20and%20Test/badge.svg?branch=master)](https://github.com/sealink/activerecord_null_object/actions)
6
+ [![Coverage Status](https://coveralls.io/repos/sealink/activerecord_null_object/badge.png)](https://coveralls.io/r/sealink/activerecord_null_object)
7
+ [![Code Climate](https://codeclimate.com/github/sealink/activerecord_null_object.png)](https://codeclimate.com/github/sealink/activerecord_null_object)
8
+
9
+ # DESCRIPTION
10
+
11
+ Implements the Null Object Pattern for nil values in ActiveRecord associations.
12
+
13
+ # RELEASE
14
+
15
+ To publish a new version of this gem the following steps must be taken.
16
+
17
+ * Update the version in the following files
18
+ ```
19
+ CHANGELOG.md
20
+ lib/activerecord_null_object/version.rb
21
+ ````
22
+ * Create a tag using the format v0.1.0
23
+ * Follow build progress in GitHub actions
24
+
25
+ Copyright (c) 2009 West Arete Computing, Inc., released under the MIT license
data/Rakefile CHANGED
@@ -1,25 +1,12 @@
1
- require 'spec'
2
- require 'spec/rake/spectask'
3
- require 'init'
1
+ require "bundler/gem_tasks"
4
2
 
5
3
  desc 'Default: run specs.'
6
4
  task :default => :spec
7
5
 
8
- Spec::Rake::SpecTask.new do |t|
9
- t.spec_opts = ['--options', "\"#{File.dirname(__FILE__)}/spec/spec.opts\""]
10
- t.spec_files = FileList['spec/**/*_spec.rb']
11
- end
6
+ require 'rspec/core/rake_task'
12
7
 
13
- begin
14
- require 'jeweler'
15
- Jeweler::Tasks.new do |s|
16
- s.name = %q{activerecord_null_object}
17
- s.summary = %q{Implements the Null Object Pattern for nil values in ActiveRecord associations.}
18
- s.email = %q{info@westarete.com}
19
- s.homepage = %q{http://github.com/westarete/activerecord_null_object/}
20
- s.description = ""
21
- s.authors = ["Scott Woods"]
22
- end
23
- rescue LoadError
24
- puts "Jeweler not available. Install it with: sudo gem install technicalpickles-jeweler -s http://gems.github.com"
8
+ desc "Run specs"
9
+ RSpec::Core::RakeTask.new do |t|
10
+ t.pattern = "./spec/**/*_spec.rb" # don't need this, it's default.
11
+ # Put spec opts in a file named .rspec in root
25
12
  end
@@ -1,54 +1,30 @@
1
- # -*- encoding: utf-8 -*-
1
+ # frozen_string_literal: true
2
2
 
3
- Gem::Specification.new do |s|
4
- s.name = %q{activerecord_null_object}
5
- s.version = "0.2.0"
3
+ require File.expand_path('lib/activerecord_null_object/version', __dir__)
6
4
 
7
- s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
8
- s.authors = ["Scott Woods"]
9
- s.date = %q{2009-09-02}
10
- s.description = %q{}
11
- s.email = %q{info@westarete.com}
12
- s.extra_rdoc_files = [
13
- "README"
14
- ]
15
- s.files = [
16
- ".gitignore",
17
- "MIT-LICENSE",
18
- "README",
19
- "Rakefile",
20
- "VERSION",
21
- "activerecord_null_object.gemspec",
22
- "init.rb",
23
- "lib/activerecord_null_object.rb",
24
- "lib/null_object.rb",
25
- "spec/belongs_to_spec.rb",
26
- "spec/database.yml",
27
- "spec/null_object_spec.rb",
28
- "spec/schema.rb",
29
- "spec/spec.opts",
30
- "spec/spec_helper.rb"
31
- ]
32
- s.has_rdoc = true
33
- s.homepage = %q{http://github.com/westarete/activerecord_null_object/}
34
- s.rdoc_options = ["--charset=UTF-8"]
35
- s.require_paths = ["lib"]
36
- s.rubygems_version = %q{1.3.1}
37
- s.summary = %q{Implements the Null Object Pattern for nil values in ActiveRecord associations.}
38
- s.test_files = [
39
- "spec/belongs_to_spec.rb",
40
- "spec/null_object_spec.rb",
41
- "spec/schema.rb",
42
- "spec/spec_helper.rb"
43
- ]
5
+ Gem::Specification.new do |spec|
6
+ spec.name = "activerecord_null_object"
7
+ spec.version = ActiveRecordNullObject::VERSION
8
+ spec.authors = ["Scott Woods", "Alessandro Berardi"]
9
+ spec.email = ["support@travellink.com.au"]
10
+ spec.description = %q{Implements the Null Object Pattern for nil values in ActiveRecord associations.}
11
+ spec.summary = %q{Implements the Null Object Pattern for nil values in ActiveRecord associations.}
12
+ spec.homepage = 'http://github.com/sealink/activerecord_null_object'
44
13
 
45
- if s.respond_to? :specification_version then
46
- current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
47
- s.specification_version = 2
14
+ spec.license = "MIT"
48
15
 
49
- if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
50
- else
51
- end
52
- else
53
- end
16
+ spec.files = `git ls-files`.split($/)
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_runtime_dependency "activesupport", ">= 6.0", "< 8"
22
+ spec.add_runtime_dependency "activerecord", ">= 6.0", "< 8"
23
+ spec.add_development_dependency "bundler"
24
+ spec.add_development_dependency "rake"
25
+ spec.add_development_dependency "rspec"
26
+ spec.add_development_dependency "rspec-its"
27
+ spec.add_development_dependency "coverage-kit"
28
+ spec.add_development_dependency 'sqlite3'
29
+ spec.add_development_dependency 'pry-byebug'
54
30
  end
@@ -0,0 +1,8 @@
1
+ source :rubygems
2
+ gemspec :path => '../'
3
+
4
+ group :development, :test do
5
+ gem 'activesupport', '~> 6.0'
6
+ gem 'activerecord', '~> 6.0'
7
+ gem 'actionpack', '~> 6.0'
8
+ end
@@ -0,0 +1,8 @@
1
+ source :rubygems
2
+ gemspec :path => '../'
3
+
4
+ group :development, :test do
5
+ gem 'activesupport', '~> 6.1'
6
+ gem 'activerecord', '~> 6.1'
7
+ gem 'actionpack', '~> 6.1'
8
+ end
@@ -0,0 +1,8 @@
1
+ source :rubygems
2
+ gemspec :path => '../'
3
+
4
+ group :development, :test do
5
+ gem 'activesupport', '~> 7.0'
6
+ gem 'activerecord', '~> 7.0'
7
+ gem 'actionpack', '~> 7.0'
8
+ end
@@ -0,0 +1,36 @@
1
+ require 'active_support/concern'
2
+
3
+ module ActiveRecordNullObject
4
+ module NullObject
5
+ extend ActiveSupport::Concern
6
+
7
+ included do
8
+ validate :unsavable
9
+ end
10
+
11
+ def id
12
+ nil
13
+ end
14
+
15
+ def nil?
16
+ true
17
+ end
18
+
19
+ def empty?
20
+ true
21
+ end
22
+
23
+ def blank?
24
+ true
25
+ end
26
+
27
+ def present?
28
+ false
29
+ end
30
+
31
+ def unsavable
32
+ errors.add(:base, "is a null object and can't be saved")
33
+ end
34
+
35
+ end
36
+ end
@@ -0,0 +1,64 @@
1
+ require 'active_support/concern'
2
+
3
+ module ActiveRecordNullObject
4
+ module NullObjectSupport
5
+ extend ActiveSupport::Concern
6
+
7
+ module ClassMethods
8
+
9
+ # Add null object support to the given accessor method.
10
+ def add_null_object_support(name, options = {}) #:nodoc:
11
+ # Determine the class of the association.
12
+ association_class_name = options[:class_name] || name.to_s.classify
13
+ association_class = association_class_name.constantize
14
+ null_class_name = "Null" + association_class_name
15
+
16
+ # Determine the null class for this association.
17
+ null_class = options[:null_object].to_s.classify.safe_constantize || null_class_name.safe_constantize
18
+
19
+ unless null_class
20
+ # Define the null class as an ancestor of the association class.
21
+ null_class = Object.const_set(null_class_name, Class.new(association_class))
22
+ null_class.class_eval do
23
+ include ::Singleton
24
+ include ::ActiveRecordNullObject::NullObject
25
+ end
26
+ end
27
+
28
+ # Modify the "getter" of the relationship to return an
29
+ # instance of the association's null object instead of returning nil.
30
+ class_eval do
31
+ define_method("#{name}".to_sym) do |*args|
32
+ super(*args) || null_class.instance
33
+ end
34
+ end
35
+ end
36
+
37
+ # Add a :null_object option to belongs_to.
38
+ def belongs_to(name, scope = nil, **options)
39
+ # args << options.except(:null_object)
40
+ # Call the real belongs_to so that the association gets defined.
41
+ super(name, scope, **options.except(:null_object))
42
+
43
+ # Modify the association if need be.
44
+ if options[:null_object]
45
+ add_null_object_support(name, options)
46
+ end
47
+ end
48
+
49
+ # Add a :null_object option to has_one.
50
+ def has_one(name, scope = nil, **options)
51
+ # args = options.except(:null_object)
52
+
53
+ # Call the real belongs_to so that the association gets defined.
54
+ super(name, scope, **options.except(:null_object))
55
+
56
+ # Modify the association if need be.
57
+ if options[:null_object]
58
+ add_null_object_support(name, options)
59
+ end
60
+ end
61
+
62
+ end
63
+ end
64
+ end
@@ -0,0 +1,3 @@
1
+ module ActiveRecordNullObject
2
+ VERSION = '0.6.0'
3
+ end
@@ -1,58 +1,7 @@
1
- module ActiveRecord
2
- module Associations
3
- module ClassMethods
4
-
5
- # Add null object support to the given accessor method.
6
- def add_null_object_support(association_id, options = {}) #:nodoc:
7
- # Determine the class of the association.
8
- association_class_name = options[:class_name] || association_id.to_s.classify
9
- association_class = association_class_name.constantize
1
+ require 'active_record'
10
2
 
11
- # Determine the null class for this association.
12
- null_class_name = "Null" + association_class_name
13
- if Object.const_defined?(null_class_name)
14
- null_class = Object.const_get(null_class_name.to_sym)
15
- else
16
- # Define the null class as an ancestor of the association class.
17
- null_class = Object.const_set(null_class_name, Class.new(association_class))
18
- null_class.class_eval do
19
- include Singleton
20
- include ActiveRecordNullObject::NullObject
21
- end
22
- end
3
+ require 'activerecord_null_object/version'
4
+ require 'activerecord_null_object/null_object'
5
+ require 'activerecord_null_object/null_object_support'
23
6
 
24
- # Modify the "getter" of the relationship to return an
25
- # instance of the association's null object instead of returning nil.
26
- class_eval do
27
- define_method("#{association_id}_with_null_object".to_sym) do
28
- send("#{association_id}_without_null_object".to_sym) || null_class.instance
29
- end
30
- alias_method_chain association_id, :null_object
31
- end
32
- end
33
-
34
- # Add a boolean :null_object option to belongs_to.
35
- def belongs_to_with_null_object(association_id, options = {}) #:nodoc:
36
- # Extract our custom option.
37
- use_null_object = options.delete(:null_object)
38
- # Call the real belongs_to so that the association gets defined.
39
- belongs_to_without_null_object(association_id, options)
40
- # Modify the association if need be.
41
- add_null_object_support(association_id, options) if use_null_object
42
- end
43
- alias_method_chain :belongs_to, :null_object
44
-
45
- # Add a boolean :null_object option to has_one.
46
- def has_one_with_null_object(association_id, options = {}) #:nodoc:
47
- # Extract our custom option.
48
- use_null_object = options.delete(:null_object)
49
- # Call the real has_one so that the association gets defined.
50
- has_one_without_null_object(association_id, options)
51
- # Modify the association if need be.
52
- add_null_object_support(association_id, options) if use_null_object
53
- end
54
- alias_method_chain :has_one, :null_object
55
-
56
- end
57
- end
58
- end
7
+ ActiveRecord::Base.send :include, ActiveRecordNullObject::NullObjectSupport
@@ -1,93 +1,61 @@
1
1
  require File.dirname(__FILE__) + '/spec_helper'
2
2
 
3
3
  describe Comment do
4
- before(:each) do
5
- @comment = Comment.create!(:body => 'The body.')
6
- end
7
-
8
- it "should contain a body" do
9
- @comment.body.should == 'The body.'
10
- end
4
+ subject(:comment) { Comment.create!(:body => 'The body.') }
11
5
 
12
- describe "without an author" do
13
- it "should return a null object for the author" do
14
- @comment.author.kind_of?(NullAuthor).should be_true
15
- end
16
-
17
- it "should be nil" do
18
- @comment.author.should be_nil
19
- end
20
-
21
- it "should return true for comment.author.nil?" do
22
- @comment.author.nil?.should be_true
23
- end
24
-
25
- it "should return false for comment.author.present?" do
26
- @comment.author.present?.should be_false
27
- end
28
-
29
- it "should return nil for the author's name" do
30
- @comment.author.name.should be_nil
31
- end
32
- end
33
-
34
- describe "with an author" do
35
- before(:each) do
36
- @comment.author = Author.create!(:name => 'James Baker')
37
- end
38
-
39
- it "should return the author object" do
40
- @comment.author.kind_of?(Author).should be_true
41
- @comment.author.kind_of?(NullAuthor).should_not be_true
42
- end
43
-
44
- it "should return false for comment.author.nil?" do
45
- @comment.author.nil?.should be_false
46
- end
47
-
48
- it "should return true for comment.author.present?" do
49
- @comment.author.present?.should be_true
50
- end
51
-
52
- it "should return the author's name" do
53
- @comment.author.name.should == 'James Baker'
6
+ its(:body) { should == 'The body.' }
7
+
8
+ context "its author" do
9
+ subject(:author) { comment.author }
10
+
11
+ context "when not present" do
12
+ it { should be_kind_of NullAuthor }
13
+ it { should be_nil }
14
+ it { should_not be_present }
15
+ its(:name) { should be_nil }
54
16
  end
55
-
56
- it "should revert to a null object if assigned nil" do
57
- @comment.author = nil
58
- @comment.author.name.should be_nil
17
+
18
+ context "when present" do
19
+ before { comment.create_author!(:name => 'James Baker') }
20
+
21
+ it { should be_kind_of Author }
22
+ it { should_not be_kind_of NullAuthor }
23
+ it { should_not be_nil }
24
+ it { should be_present }
25
+ its(:name) { should == 'James Baker' }
26
+
27
+ context "when removed" do
28
+ before { comment.author = nil }
29
+ its(:name) { should be_nil }
30
+ end
59
31
  end
60
32
  end
61
33
  end
62
34
 
63
35
  describe Post do
64
- before(:each) do
65
- @post = Post.create!(:body => 'The body.')
66
- end
67
-
68
- it "should contain a body" do
69
- @post.body.should == 'The body.'
70
- end
71
-
72
- it "should not have null object support for the author" do
73
- @post.author.should be_nil
74
- @post.author.kind_of?(Author).should be_false
75
- @post.author.respond_to?(:name).should be_false
36
+ subject(:post) { Post.create!(:body => 'The body.') }
37
+
38
+ its(:body) { should == 'The body.' }
39
+
40
+ context "without null object support for the author" do
41
+ subject(:author) { post.author }
42
+
43
+ it { should be_nil }
44
+ it { should_not be_kind_of Author }
45
+ it { should_not respond_to :name }
76
46
  end
77
47
  end
78
48
 
79
49
  describe Session do
80
- before(:each) do
81
- @session = Session.create!(:description => 'The description.')
82
- end
83
-
84
- it "should contain a description" do
85
- @session.description.should == 'The description.'
86
- end
87
-
88
- it "should not have null object support for the author" do
89
- @session.author.should be_nil
90
- @session.author.kind_of?(Author).should be_false
91
- @session.author.respond_to?(:name).should be_false
50
+ subject(:session) { Session.create!(:description => 'The description.') }
51
+
52
+ its(:description) { should == 'The description.' }
53
+
54
+ context "without null object support for the author" do
55
+ subject(:author) { session.author }
56
+
57
+ it { should be_nil }
58
+ it { should_not be_kind_of Author }
59
+ it { should_not respond_to :name }
92
60
  end
93
61
  end
@@ -0,0 +1,70 @@
1
+ require File.dirname(__FILE__) + '/spec_helper'
2
+
3
+ describe Author do
4
+ subject(:author) { Author.create!(:name => 'James Madison') }
5
+
6
+ context "its profile" do
7
+ subject(:profile) { author.profile }
8
+
9
+ context "when not present" do
10
+ context "without null object support for the profile" do
11
+ it { should be_nil }
12
+ it { should_not be_kind_of Profile }
13
+ it { should_not respond_to :age }
14
+ end
15
+ end
16
+
17
+ context "when present" do
18
+ before { author.create_profile!(:age => 56) }
19
+
20
+ its(:age) { should == 56 }
21
+ end
22
+ end
23
+
24
+ context "its account" do
25
+ subject(:account) { author.account }
26
+
27
+ context "when not present" do
28
+ context "without null object support for the account" do
29
+ it { should be_nil }
30
+ it { should_not be_kind_of Account }
31
+ it { should_not respond_to :password }
32
+ end
33
+ end
34
+
35
+ context "when present" do
36
+ before { author.create_account!(:password => 'secret') }
37
+
38
+ its(:password) { should == 'secret' }
39
+ end
40
+ end
41
+
42
+
43
+ context "its address" do
44
+ subject(:address) { author.address }
45
+
46
+ context "when not present" do
47
+ it { should be_kind_of NullAddress }
48
+ it { should be_nil }
49
+ it { should_not be_present }
50
+ its(:street) { should be_nil }
51
+ end
52
+
53
+ context "when present" do
54
+ before { author.create_address!(:street => '1600 Pennsylvania Ave') }
55
+
56
+ it { should be_kind_of Address }
57
+ it { should_not be_kind_of NullAddress }
58
+ it { should_not be_nil }
59
+ it { should be_present }
60
+ its(:street) { should == '1600 Pennsylvania Ave' }
61
+
62
+ context "when the address is removed" do
63
+ before { author.address = nil }
64
+ its(:street) { should be_nil }
65
+ end
66
+ end
67
+
68
+ end
69
+
70
+ end
@@ -1,99 +1,67 @@
1
1
  require File.dirname(__FILE__) + '/spec_helper'
2
2
 
3
3
  describe NullAuthor do
4
-
5
- before(:each) do
6
- @null_author = Comment.new.author
7
- end
8
-
9
- it "should be a kind of Author" do
10
- @null_author.kind_of?(Author).should be_true
11
- end
4
+
5
+ subject(:null_author) { Comment.new.author }
6
+
7
+ it { should be_kind_of Author }
12
8
 
13
9
  it "should be a singleton" do
14
- lambda { NullAuthor.new }.should raise_error(NoMethodError)
15
- end
16
-
17
- it "should be nil" do
18
- @null_author.nil?.should be_true
19
- @null_author.should be_nil
20
- end
21
-
22
- it "should be empty" do
23
- @null_author.empty?.should be_true
24
- end
25
-
26
- it "should be blank" do
27
- @null_author.blank?.should be_true
28
- end
29
-
30
- it "should not be present" do
31
- @null_author.present?.should be_false
10
+ expect { NullAuthor.new }.to raise_error(NoMethodError)
32
11
  end
33
12
 
34
- describe "#id" do
35
- it "should return nil" do
36
- @null_author.id.should be_nil
37
- end
38
- end
39
-
40
- describe "#new_record?" do
41
- it "should return true" do
42
- @null_author.new_record?.should be_true
43
- end
44
- end
45
-
46
- describe "#save" do
47
- it "should return false" do
48
- @null_author.save.should be_false
49
- end
50
-
13
+ it { should be_nil }
14
+ it { should be_empty }
15
+ it { should be_blank }
16
+ it { should_not be_present }
17
+ its(:id) { should be_nil }
18
+ it { should be_new_record }
19
+
20
+ context "when saving with save" do
21
+ its(:save) { should be false }
22
+
51
23
  it "should not create a new record" do
52
- lambda { @null_author.save }.should_not change { NullAuthor.count }
24
+ expect { null_author.save }.to_not change { NullAuthor.count }
53
25
  end
54
-
26
+
55
27
  it "should add an error" do
56
- @null_author.errors.on(:base).should == "is a null object and can't be saved"
28
+ expect(null_author.errors[:base]).to eq ["is a null object and can't be saved"]
57
29
  end
58
30
  end
59
-
60
- describe "#save!" do
31
+
32
+ context "when saving with save!" do
61
33
  it "should raise an exception" do
62
- lambda { @null_author.save! }.should raise_error(ActiveRecord::RecordInvalid)
34
+ expect { null_author.save! }.to raise_error(ActiveRecord::RecordInvalid)
63
35
  end
64
-
36
+
65
37
  it "should not create a new record" do
66
- lambda {
38
+ expect {
67
39
  begin
68
- @null_author.save!
40
+ null_author.save!
69
41
  rescue ActiveRecord::RecordInvalid
70
42
  end
71
- }.should_not change { NullAuthor.count }
43
+ }.to_not change { NullAuthor.count }
72
44
  end
73
45
 
74
46
  it "should add an error" do
75
- @null_author.errors.on(:base).should == "is a null object and can't be saved"
47
+ expect(null_author.errors[:base]).to eq ["is a null object and can't be saved"]
76
48
  end
77
49
  end
78
50
 
79
- describe "#update_attributes" do
51
+ context "when updating attributes" do
80
52
  it "should return false" do
81
- @null_author.update_attributes({}).should be_false
53
+ expect(null_author.update({})).to be false
82
54
  end
83
-
55
+
84
56
  it "should not create a new record" do
85
- lambda { @null_author.update_attributes({}) }.should_not change { NullAuthor.count }
57
+ expect { null_author.update({}) }.to_not change { NullAuthor.count }
86
58
  end
87
59
 
88
60
  it "should add an error" do
89
- @null_author.errors.on(:base).should == "is a null object and can't be saved"
90
- end
91
- end
92
-
93
- describe "#name" do
94
- it "should return nil" do
95
- @null_author.name.should be_nil
61
+ expect(null_author.errors[:base]).to eq ["is a null object and can't be saved"]
96
62
  end
97
63
  end
98
-
99
- end
64
+
65
+ its(:name) { should be_nil }
66
+
67
+ end
data/spec/spec_helper.rb CHANGED
@@ -1,19 +1,29 @@
1
1
  require 'rubygems'
2
+ require 'bundler/setup'
2
3
  require 'active_record'
3
4
  require 'yaml'
4
- require 'spec'
5
- require File.dirname(__FILE__) + '/../init.rb'
5
+ require 'rspec'
6
+ require 'rspec/its'
6
7
 
7
- # Establish database connection.
8
- config = YAML::load(File.open(File.dirname(__FILE__) + '/database.yml'))
9
- ActiveRecord::Base.establish_connection(config['test'])
10
- load(File.dirname(__FILE__) + "/schema.rb")
8
+ I18n.enforce_available_locales = true if I18n.respond_to? :enforce_available_locales=
9
+
10
+ require 'support/coverage_loader'
11
+
12
+ require 'activerecord_null_object'
11
13
 
12
14
  # Fixes 'address'.singularize # => 'addres'
13
15
  ActiveSupport::Inflector.inflections do |inflect|
14
16
  inflect.singular(/ess$/i, 'ess')
15
17
  end
16
18
 
19
+ DB_FILE = 'tmp/test_db'
20
+ FileUtils.mkdir_p File.dirname(DB_FILE)
21
+ FileUtils.rm_f DB_FILE
22
+
23
+ ActiveRecord::Base.establish_connection :adapter => 'sqlite3', :database => DB_FILE
24
+
25
+ load('spec/schema.rb')
26
+
17
27
  class Account < ActiveRecord::Base
18
28
  end
19
29
 
@@ -29,12 +39,20 @@ class Author < ActiveRecord::Base
29
39
  has_many :comments
30
40
  has_many :sessions
31
41
  has_one :profile
32
- has_one :account, :null_object => false
42
+ if ::ActiveRecord::VERSION::MAJOR == 4
43
+ has_one :account, -> {order :created_at}, :null_object => false
44
+ else
45
+ has_one :account, :null_object => false
46
+ end
33
47
  has_one :address, :null_object => true
34
48
  end
35
49
 
36
50
  class Comment < ActiveRecord::Base
37
- belongs_to :author, :null_object => true
51
+ if ::ActiveRecord::VERSION::MAJOR == 4
52
+ belongs_to :author, -> {order :name}, :null_object => true
53
+ else
54
+ belongs_to :author, :null_object => true
55
+ end
38
56
  end
39
57
 
40
58
  class Post < ActiveRecord::Base
@@ -45,3 +63,6 @@ class Session < ActiveRecord::Base
45
63
  belongs_to :author
46
64
  end
47
65
 
66
+ RSpec.configure do |config|
67
+ config.raise_errors_for_deprecations!
68
+ end
@@ -0,0 +1,3 @@
1
+ require 'coverage/kit'
2
+
3
+ Coverage::Kit.setup(minimum_coverage: 100)
metadata CHANGED
@@ -1,72 +1,215 @@
1
- --- !ruby/object:Gem::Specification
1
+ --- !ruby/object:Gem::Specification
2
2
  name: activerecord_null_object
3
- version: !ruby/object:Gem::Version
4
- version: 0.2.0
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.6.0
5
5
  platform: ruby
6
- authors:
6
+ authors:
7
7
  - Scott Woods
8
+ - Alessandro Berardi
8
9
  autorequire:
9
10
  bindir: bin
10
11
  cert_chain: []
11
-
12
- date: 2009-09-02 00:00:00 -04:00
13
- default_executable:
14
- dependencies: []
15
-
16
- description: ""
17
- email: info@westarete.com
12
+ date: 2022-01-25 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: activesupport
16
+ requirement: !ruby/object:Gem::Requirement
17
+ requirements:
18
+ - - ">="
19
+ - !ruby/object:Gem::Version
20
+ version: '6.0'
21
+ - - "<"
22
+ - !ruby/object:Gem::Version
23
+ version: '8'
24
+ type: :runtime
25
+ prerelease: false
26
+ version_requirements: !ruby/object:Gem::Requirement
27
+ requirements:
28
+ - - ">="
29
+ - !ruby/object:Gem::Version
30
+ version: '6.0'
31
+ - - "<"
32
+ - !ruby/object:Gem::Version
33
+ version: '8'
34
+ - !ruby/object:Gem::Dependency
35
+ name: activerecord
36
+ requirement: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '6.0'
41
+ - - "<"
42
+ - !ruby/object:Gem::Version
43
+ version: '8'
44
+ type: :runtime
45
+ prerelease: false
46
+ version_requirements: !ruby/object:Gem::Requirement
47
+ requirements:
48
+ - - ">="
49
+ - !ruby/object:Gem::Version
50
+ version: '6.0'
51
+ - - "<"
52
+ - !ruby/object:Gem::Version
53
+ version: '8'
54
+ - !ruby/object:Gem::Dependency
55
+ name: bundler
56
+ requirement: !ruby/object:Gem::Requirement
57
+ requirements:
58
+ - - ">="
59
+ - !ruby/object:Gem::Version
60
+ version: '0'
61
+ type: :development
62
+ prerelease: false
63
+ version_requirements: !ruby/object:Gem::Requirement
64
+ requirements:
65
+ - - ">="
66
+ - !ruby/object:Gem::Version
67
+ version: '0'
68
+ - !ruby/object:Gem::Dependency
69
+ name: rake
70
+ requirement: !ruby/object:Gem::Requirement
71
+ requirements:
72
+ - - ">="
73
+ - !ruby/object:Gem::Version
74
+ version: '0'
75
+ type: :development
76
+ prerelease: false
77
+ version_requirements: !ruby/object:Gem::Requirement
78
+ requirements:
79
+ - - ">="
80
+ - !ruby/object:Gem::Version
81
+ version: '0'
82
+ - !ruby/object:Gem::Dependency
83
+ name: rspec
84
+ requirement: !ruby/object:Gem::Requirement
85
+ requirements:
86
+ - - ">="
87
+ - !ruby/object:Gem::Version
88
+ version: '0'
89
+ type: :development
90
+ prerelease: false
91
+ version_requirements: !ruby/object:Gem::Requirement
92
+ requirements:
93
+ - - ">="
94
+ - !ruby/object:Gem::Version
95
+ version: '0'
96
+ - !ruby/object:Gem::Dependency
97
+ name: rspec-its
98
+ requirement: !ruby/object:Gem::Requirement
99
+ requirements:
100
+ - - ">="
101
+ - !ruby/object:Gem::Version
102
+ version: '0'
103
+ type: :development
104
+ prerelease: false
105
+ version_requirements: !ruby/object:Gem::Requirement
106
+ requirements:
107
+ - - ">="
108
+ - !ruby/object:Gem::Version
109
+ version: '0'
110
+ - !ruby/object:Gem::Dependency
111
+ name: coverage-kit
112
+ requirement: !ruby/object:Gem::Requirement
113
+ requirements:
114
+ - - ">="
115
+ - !ruby/object:Gem::Version
116
+ version: '0'
117
+ type: :development
118
+ prerelease: false
119
+ version_requirements: !ruby/object:Gem::Requirement
120
+ requirements:
121
+ - - ">="
122
+ - !ruby/object:Gem::Version
123
+ version: '0'
124
+ - !ruby/object:Gem::Dependency
125
+ name: sqlite3
126
+ requirement: !ruby/object:Gem::Requirement
127
+ requirements:
128
+ - - ">="
129
+ - !ruby/object:Gem::Version
130
+ version: '0'
131
+ type: :development
132
+ prerelease: false
133
+ version_requirements: !ruby/object:Gem::Requirement
134
+ requirements:
135
+ - - ">="
136
+ - !ruby/object:Gem::Version
137
+ version: '0'
138
+ - !ruby/object:Gem::Dependency
139
+ name: pry-byebug
140
+ requirement: !ruby/object:Gem::Requirement
141
+ requirements:
142
+ - - ">="
143
+ - !ruby/object:Gem::Version
144
+ version: '0'
145
+ type: :development
146
+ prerelease: false
147
+ version_requirements: !ruby/object:Gem::Requirement
148
+ requirements:
149
+ - - ">="
150
+ - !ruby/object:Gem::Version
151
+ version: '0'
152
+ description: Implements the Null Object Pattern for nil values in ActiveRecord associations.
153
+ email:
154
+ - support@travellink.com.au
18
155
  executables: []
19
-
20
156
  extensions: []
21
-
22
- extra_rdoc_files:
23
- - README
24
- files:
25
- - .gitignore
157
+ extra_rdoc_files: []
158
+ files:
159
+ - ".github/dependabot.yml"
160
+ - ".github/workflows/release.yml"
161
+ - ".github/workflows/ruby.yml"
162
+ - ".gitignore"
163
+ - ".ruby-version"
164
+ - CHANGELOG.md
165
+ - Gemfile
26
166
  - MIT-LICENSE
27
- - README
167
+ - README.md
28
168
  - Rakefile
29
169
  - VERSION
30
170
  - activerecord_null_object.gemspec
31
- - init.rb
171
+ - gemfiles/rails60.gemfile
172
+ - gemfiles/rails61.gemfile
173
+ - gemfiles/rails70.gemfile
32
174
  - lib/activerecord_null_object.rb
33
- - lib/null_object.rb
175
+ - lib/activerecord_null_object/null_object.rb
176
+ - lib/activerecord_null_object/null_object_support.rb
177
+ - lib/activerecord_null_object/version.rb
34
178
  - spec/belongs_to_spec.rb
35
- - spec/database.yml
179
+ - spec/has_one_spec.rb
36
180
  - spec/null_object_spec.rb
37
181
  - spec/schema.rb
38
182
  - spec/spec.opts
39
183
  - spec/spec_helper.rb
40
- has_rdoc: true
41
- homepage: http://github.com/westarete/activerecord_null_object/
42
- licenses: []
43
-
184
+ - spec/support/coverage_loader.rb
185
+ homepage: http://github.com/sealink/activerecord_null_object
186
+ licenses:
187
+ - MIT
188
+ metadata: {}
44
189
  post_install_message:
45
- rdoc_options:
46
- - --charset=UTF-8
47
- require_paths:
190
+ rdoc_options: []
191
+ require_paths:
48
192
  - lib
49
- required_ruby_version: !ruby/object:Gem::Requirement
50
- requirements:
193
+ required_ruby_version: !ruby/object:Gem::Requirement
194
+ requirements:
51
195
  - - ">="
52
- - !ruby/object:Gem::Version
53
- version: "0"
54
- version:
55
- required_rubygems_version: !ruby/object:Gem::Requirement
56
- requirements:
196
+ - !ruby/object:Gem::Version
197
+ version: '0'
198
+ required_rubygems_version: !ruby/object:Gem::Requirement
199
+ requirements:
57
200
  - - ">="
58
- - !ruby/object:Gem::Version
59
- version: "0"
60
- version:
201
+ - !ruby/object:Gem::Version
202
+ version: '0'
61
203
  requirements: []
62
-
63
- rubyforge_project:
64
- rubygems_version: 1.3.5
204
+ rubygems_version: 3.3.3
65
205
  signing_key:
66
- specification_version: 2
206
+ specification_version: 4
67
207
  summary: Implements the Null Object Pattern for nil values in ActiveRecord associations.
68
- test_files:
208
+ test_files:
69
209
  - spec/belongs_to_spec.rb
210
+ - spec/has_one_spec.rb
70
211
  - spec/null_object_spec.rb
71
212
  - spec/schema.rb
213
+ - spec/spec.opts
72
214
  - spec/spec_helper.rb
215
+ - spec/support/coverage_loader.rb
data/README DELETED
@@ -1,5 +0,0 @@
1
- = ActiveRecordWithNullObject
2
-
3
- Implements the Null Object Pattern for nil values in ActiveRecord associations.
4
-
5
- Copyright (c) 2009 West Arete Computing, Inc., released under the MIT license
data/init.rb DELETED
@@ -1,5 +0,0 @@
1
- require 'rubygems'
2
- require 'active_record'
3
- ActiveRecord::ActiveRecordError # Workaround for loading bug in AR 2.3.2.
4
- require File.dirname(__FILE__) + '/lib/activerecord_null_object'
5
- require File.dirname(__FILE__) + '/lib/null_object'
data/lib/null_object.rb DELETED
@@ -1,21 +0,0 @@
1
- module ActiveRecordNullObject
2
- module NullObject
3
-
4
- def id
5
- nil
6
- end
7
-
8
- def nil?
9
- true
10
- end
11
-
12
- def empty?
13
- true
14
- end
15
-
16
- def validate
17
- errors.add_to_base("is a null object and can't be saved")
18
- end
19
-
20
- end
21
- end
data/spec/database.yml DELETED
@@ -1,3 +0,0 @@
1
- test:
2
- :adapter: sqlite3
3
- :database: test.db