no_peeping_toms 1.1.0 → 2.1.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.
@@ -0,0 +1,5 @@
1
+ *.gem
2
+ .bundle
3
+ Gemfile.lock
4
+ pkg/*
5
+ spec/debug.log
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in no-peeping-toms.gemspec
4
+ gemspec
@@ -1,3 +1,6 @@
1
+ === Version 2.0.1 / 2011-02-16
2
+ * Supports current Rails 3.x release. No longer supports Rails 2.
3
+
1
4
  === Version 1.1.0 / 2010-01-06
2
5
 
3
6
  * Explicit enable/disable API (Corey Haines & Drew Olson)
@@ -0,0 +1,67 @@
1
+ = no_peeping_toms
2
+
3
+ This plugin disables observers in your specs, so that model specs can run in complete isolation.
4
+
5
+ == Installation
6
+
7
+ Add to your Gemfile:
8
+
9
+ gem 'no_peeping_toms', :git => 'git://github.com/alindeman/no_peeping_toms.git'
10
+
11
+ and run `bundle install`.
12
+
13
+ no_peeping_toms >= 2.0.0 only supports on Rails 3. If you need Rails 2 support, use 1.1.0: `gem install no_peeping_toms -v 1.1.0`
14
+
15
+ == Usage
16
+
17
+ To disable observers, place the following code in your test.rb, or spec_helper.rb, or wherever:
18
+
19
+ ActiveRecord::Observer.disable_observers
20
+
21
+ You can easily reenable observers:
22
+
23
+ ActiveRecord::Observer.enable_observers
24
+
25
+ You can choose to run some code with specific observers turned on. This is useful when spec'ing an observer. For example, if you write the following observer:
26
+
27
+ class PersonObserver < ActiveRecord::Observer
28
+ def before_update(person)
29
+ old_person = Person.find person.id
30
+ if old_person.name != person.name
31
+ NameChange.create! :person => person, :old_name => old_person.name, :new_name => person.name
32
+ end
33
+ end
34
+ end
35
+
36
+ You can spec the Person class in complete isolation.
37
+
38
+ describe Person, " when changing a name" do
39
+ before(:each) do
40
+ @person = Person.create! :name => "Pat Maddox"
41
+ end
42
+
43
+ # By default, don't run any observers
44
+ it "should not register a name change" do
45
+ lambda { @person.update_attribute :name, "Don Juan Demarco" }.should_not change(NameChange, :count)
46
+ end
47
+
48
+ # Run only a portion of code with certain observers turned on
49
+ it "should register a name change with the person observer turned on" do
50
+ ActiveRecord::Observer.with_observers(:person_observer) do
51
+ lambda { @person.update_attribute :name, "Don Juan Demarco" }.should change(NameChange, :count).by(1)
52
+ end
53
+
54
+ lambda { @person.update_attribute :name, "Man Without a Name" }.should_not change(NameChange, :count)
55
+ end
56
+ end
57
+
58
+ == Credits
59
+
60
+ * Brandon Keepers
61
+ * Corey Haines
62
+ * Drew Olson
63
+ * Jeff Siegel
64
+ * Zach Dennis
65
+ * Andy Lindeman
66
+
67
+ Copyright (c) 2007-2011 Pat Maddox, released under the MIT license.
@@ -1,42 +1,77 @@
1
+ require 'active_record'
2
+ require 'active_support/core_ext/class/attribute_accessors'
3
+ require 'active_support/core_ext/string/inflections'
4
+
1
5
  module NoPeepingToms
2
- def self.included(base)
3
- unless base.included_modules.include?(NoPeepingToms::InstanceMethods)
4
- base.send :include, NoPeepingToms::InstanceMethods
5
- base.extend NoPeepingToms::ClassMethods
6
- base.alias_method_chain :update, :neighborhood_watch
7
- base.cattr_accessor :peeping_toms, :default_observers_enabled
8
- base.peeping_toms = [] # toms that are allowed to peep
9
- end
6
+ extend ActiveSupport::Concern
10
7
 
11
- base.enable_observers
12
- end
8
+ included do
9
+ # Define class-level accessors
10
+ cattr_accessor :default_observers_enabled, :observers_enabled
13
11
 
14
- module InstanceMethods
15
- def update_with_neighborhood_watch(*args)
16
- if self.class.default_observers_enabled || self.class.peeping_toms.include?(self)
17
- update_without_neighborhood_watch(*args)
18
- end
19
- end
12
+ # By default, enable all observers
13
+ enable_observers
14
+ self.observers_enabled = []
15
+
16
+ alias_method_chain :define_callbacks, :enabled_check
20
17
  end
21
-
18
+
22
19
  module ClassMethods
20
+ # Enables all observers (default behavior)
21
+ def enable_observers
22
+ self.default_observers_enabled = true
23
+ end
24
+
25
+ # Disables all observers
26
+ def disable_observers
27
+ self.default_observers_enabled = false
28
+ end
29
+
30
+ # Run a block with a specific set of observers enabled
23
31
  def with_observers(*observer_syms)
24
- self.peeping_toms = Array(observer_syms).map do |o|
32
+ self.observers_enabled = Array(observer_syms).map do |o|
25
33
  o.respond_to?(:instance) ? o.instance : o.to_s.classify.constantize.instance
26
34
  end
27
35
  yield
28
36
  ensure
29
- self.peeping_toms.clear
37
+ self.observers_enabled = []
30
38
  end
31
39
 
32
- def disable_observers
33
- self.default_observers_enabled = false
40
+ # Determines whether an observer is enabled. Either:
41
+ # - All observers are enabled OR
42
+ # - The observer is in the whitelist
43
+ def observer_enabled?(observer)
44
+ default_observers_enabled or self.observers_enabled.include?(observer)
34
45
  end
46
+ end
35
47
 
36
- def enable_observers
37
- self.default_observers_enabled = true
48
+ module InstanceMethods
49
+ # Overrides ActiveRecord#define_callbacks so that observers are only called
50
+ # when enabled.
51
+ #
52
+ # This is a bit yuck being a protected method, but appears to be the cleanest
53
+ # way so far
54
+ def define_callbacks_with_enabled_check(klass)
55
+ observer = self
56
+ observer_name = observer.class.name.underscore.gsub('/', '__')
57
+
58
+ ActiveRecord::Callbacks::CALLBACKS.each do |callback|
59
+ next unless respond_to?(callback)
60
+ callback_meth = :"_notify_#{observer_name}_for_#{callback}"
61
+ unless klass.respond_to?(callback_meth)
62
+ klass.send(:define_method, callback_meth) do
63
+ observer.send(callback, self) if observer.observer_enabled?
64
+ end
65
+ klass.send(callback, callback_meth)
66
+ end
67
+ end
68
+ end
69
+
70
+ # Determines whether this observer should be run
71
+ def observer_enabled?
72
+ self.class.observer_enabled?(self)
38
73
  end
39
74
  end
40
75
  end
41
76
 
42
- ActiveRecord::Observer.send :include, NoPeepingToms
77
+ ActiveRecord::Observer.__send__ :include, NoPeepingToms
@@ -0,0 +1,3 @@
1
+ module NoPeepingToms
2
+ VERSION = "2.1.0"
3
+ end
@@ -1,58 +1,26 @@
1
- # Generated by jeweler
2
- # DO NOT EDIT THIS FILE DIRECTLY
3
- # Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
4
1
  # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "no_peeping_toms/version"
5
4
 
6
5
  Gem::Specification.new do |s|
7
- s.name = %q{no_peeping_toms}
8
- s.version = "1.1.0"
9
-
10
- s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
- s.authors = ["Pat Maddox", "Brandon Keepers"]
12
- s.date = %q{2010-01-06}
6
+ s.name = "no_peeping_toms"
7
+ s.version = NoPeepingToms::VERSION
8
+ s.platform = Gem::Platform::RUBY
9
+ s.authors = ["Pat Maddox"]
10
+ s.email = ["pat.maddox@gmail.com"]
11
+ s.homepage = "https://github.com/patmaddox/no_peeping_toms"
12
+ s.summary = %q{Disables observers during testing, allowing you to write model tests that are completely decoupled from the observer.}
13
13
  s.description = %q{Disables observers during testing, allowing you to write model tests that are completely decoupled from the observer.}
14
- s.email = %q{pat.maddox@gmail.com}
15
- s.extra_rdoc_files = [
16
- "README"
17
- ]
18
- s.files = [
19
- "History.rdoc",
20
- "README",
21
- "Rakefile",
22
- "VERSION",
23
- "install.rb",
24
- "lib/no_peeping_toms.rb",
25
- "no_peeping_toms.gemspec",
26
- "spec/db/database.yml",
27
- "spec/db/schema.rb",
28
- "spec/no_peeping_toms_spec.rb",
29
- "spec/spec_helper.rb",
30
- "uninstall.rb"
31
- ]
32
- s.homepage = %q{http://github.com/patmaddox/no-peeping-toms}
33
- s.rdoc_options = ["--charset=UTF-8"]
14
+ s.rubyforge_project = "no_peeping_toms"
15
+
16
+ s.files = `git ls-files`.split("\n")
17
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
18
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
34
19
  s.require_paths = ["lib"]
35
- s.rubygems_version = %q{1.3.5}
36
- s.summary = %q{Disables observers during testing, allowing you to write model tests that are completely decoupled from the observer.}
37
- s.test_files = [
38
- "spec/db",
39
- "spec/db/database.yml",
40
- "spec/db/schema.rb",
41
- "spec/no_peeping_toms_spec.rb",
42
- "spec/spec_helper.rb"
43
- ]
44
20
 
45
- if s.respond_to? :specification_version then
46
- current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
47
- s.specification_version = 3
21
+ s.add_runtime_dependency 'activerecord', '>=3.0.0'
22
+ s.add_runtime_dependency 'activesupport', '>=3.0.0'
48
23
 
49
- if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
50
- s.add_runtime_dependency(%q<activerecord>, [">= 1.1"])
51
- else
52
- s.add_dependency(%q<activerecord>, [">= 1.1"])
53
- end
54
- else
55
- s.add_dependency(%q<activerecord>, [">= 1.1"])
56
- end
24
+ s.add_development_dependency 'rspec', '~>2.5'
25
+ s.add_development_dependency 'sqlite3'
57
26
  end
58
-
@@ -2,12 +2,14 @@ require File.dirname(__FILE__) + '/spec_helper'
2
2
 
3
3
  module NoPeepingTomsSpec
4
4
  class Person < ActiveRecord::Base; end
5
+ class SpecialPerson < Person; end
5
6
 
6
7
  class PersonObserver < ActiveRecord::Observer
7
8
  cattr_accessor :called
8
9
 
9
10
  def before_create(person)
10
- self.class.called = true
11
+ self.class.called ||= 0
12
+ self.class.called += 1
11
13
  end
12
14
  end
13
15
 
@@ -16,10 +18,15 @@ module NoPeepingTomsSpec
16
18
  cattr_accessor :called
17
19
 
18
20
  def before_create(person)
19
- self.class.called = true
21
+ self.class.called ||= 0
22
+ self.class.called += 1
20
23
  end
21
24
  end
22
25
 
26
+ # Register the observers with the host app
27
+ PersonObserver.instance
28
+ AnotherObserver.instance
29
+
23
30
  describe NoPeepingToms, "configuration" do
24
31
  it "enables observers by default" do
25
32
  load 'no_peeping_toms.rb'
@@ -28,16 +35,23 @@ module NoPeepingTomsSpec
28
35
 
29
36
  it "runs default observers when default observers are enabled" do
30
37
  ActiveRecord::Observer.enable_observers
31
- PersonObserver.called = false
38
+ PersonObserver.called = 0
32
39
  Person.create!
33
- PersonObserver.called.should be_true
40
+ PersonObserver.called.should == 1
34
41
  end
35
42
 
36
43
  it "does not run default observers when default observers are disabled" do
37
44
  ActiveRecord::Observer.disable_observers
38
- PersonObserver.called = false
45
+ PersonObserver.called = 0
39
46
  Person.create!
40
- PersonObserver.called.should be_false
47
+ PersonObserver.called.should == 0
48
+ end
49
+
50
+ it "only runs observers once on descendent classes" do
51
+ ActiveRecord::Observer.enable_observers
52
+ PersonObserver.called = 0
53
+ SpecialPerson.create!
54
+ PersonObserver.called.should == 1
41
55
  end
42
56
  end
43
57
 
@@ -68,23 +82,13 @@ module NoPeepingTomsSpec
68
82
  AnotherObserver.called.should be_true
69
83
  end
70
84
 
71
- it "should accept anonymous observers" do
72
- called = false
73
- observer = Class.new(ActiveRecord::Observer) do
74
- observe NoPeepingTomsSpec::Person
75
- define_method(:before_create) {|person| called = true }
76
- end
77
- ActiveRecord::Observer.with_observers(observer) { Person.create! }
78
- called.should be_true
79
- end
80
-
81
85
  it "should ensure peeping toms are reset after raised exception" do
82
86
  lambda {
83
87
  ActiveRecord::Observer.with_observers(NoPeepingTomsSpec::PersonObserver) do
84
88
  raise ArgumentError, "Michael, I've made a huge mistake"
85
89
  end
86
90
  }.should raise_error(ArgumentError)
87
- ActiveRecord::Observer.peeping_toms.should == []
91
+ ActiveRecord::Observer.observers_enabled.should_not include(NoPeepingTomsSpec::PersonObserver)
88
92
  end
89
93
  end
90
94
  end
@@ -1,8 +1,12 @@
1
- require File.expand_path(File.dirname(__FILE__) + '/../../../../spec/spec_helper')
1
+ require 'logger'
2
2
 
3
3
  plugin_spec_dir = File.dirname(__FILE__)
4
- ActiveRecord::Base.logger = Logger.new(plugin_spec_dir + "/debug.log")
4
+ plugin_lib_dir = File.join(plugin_spec_dir, '..', 'lib')
5
+
6
+ require File.join(plugin_lib_dir, 'no_peeping_toms')
5
7
 
8
+ # Setup ActiveRecord
9
+ ActiveRecord::Base.logger = Logger.new(plugin_spec_dir + "/debug.log")
6
10
  databases = YAML::load(IO.read(plugin_spec_dir + "/db/database.yml"))
7
11
  ActiveRecord::Base.establish_connection(databases[ENV["DB"] || "sqlite3"])
8
12
  load(File.join(plugin_spec_dir, "db", "schema.rb"))
metadata CHANGED
@@ -1,74 +1,136 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: no_peeping_toms
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.0
4
+ hash: 11
5
+ prerelease: false
6
+ segments:
7
+ - 2
8
+ - 1
9
+ - 0
10
+ version: 2.1.0
5
11
  platform: ruby
6
12
  authors:
7
13
  - Pat Maddox
8
- - Brandon Keepers
9
14
  autorequire:
10
15
  bindir: bin
11
16
  cert_chain: []
12
17
 
13
- date: 2010-01-06 00:00:00 -08:00
18
+ date: 2011-02-26 00:00:00 -08:00
14
19
  default_executable:
15
20
  dependencies:
16
21
  - !ruby/object:Gem::Dependency
17
22
  name: activerecord
23
+ prerelease: false
24
+ requirement: &id001 !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ">="
28
+ - !ruby/object:Gem::Version
29
+ hash: 7
30
+ segments:
31
+ - 3
32
+ - 0
33
+ - 0
34
+ version: 3.0.0
35
+ type: :runtime
36
+ version_requirements: *id001
37
+ - !ruby/object:Gem::Dependency
38
+ name: activesupport
39
+ prerelease: false
40
+ requirement: &id002 !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ">="
44
+ - !ruby/object:Gem::Version
45
+ hash: 7
46
+ segments:
47
+ - 3
48
+ - 0
49
+ - 0
50
+ version: 3.0.0
18
51
  type: :runtime
19
- version_requirement:
20
- version_requirements: !ruby/object:Gem::Requirement
52
+ version_requirements: *id002
53
+ - !ruby/object:Gem::Dependency
54
+ name: rspec
55
+ prerelease: false
56
+ requirement: &id003 !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ~>
60
+ - !ruby/object:Gem::Version
61
+ hash: 9
62
+ segments:
63
+ - 2
64
+ - 5
65
+ version: "2.5"
66
+ type: :development
67
+ version_requirements: *id003
68
+ - !ruby/object:Gem::Dependency
69
+ name: sqlite3
70
+ prerelease: false
71
+ requirement: &id004 !ruby/object:Gem::Requirement
72
+ none: false
21
73
  requirements:
22
74
  - - ">="
23
75
  - !ruby/object:Gem::Version
24
- version: "1.1"
25
- version:
76
+ hash: 3
77
+ segments:
78
+ - 0
79
+ version: "0"
80
+ type: :development
81
+ version_requirements: *id004
26
82
  description: Disables observers during testing, allowing you to write model tests that are completely decoupled from the observer.
27
- email: pat.maddox@gmail.com
83
+ email:
84
+ - pat.maddox@gmail.com
28
85
  executables: []
29
86
 
30
87
  extensions: []
31
88
 
32
- extra_rdoc_files:
33
- - README
89
+ extra_rdoc_files: []
90
+
34
91
  files:
92
+ - .gitignore
93
+ - Gemfile
35
94
  - History.rdoc
36
- - README
37
- - Rakefile
38
- - VERSION
39
- - install.rb
95
+ - README.rdoc
40
96
  - lib/no_peeping_toms.rb
97
+ - lib/no_peeping_toms/version.rb
41
98
  - no_peeping_toms.gemspec
42
99
  - spec/db/database.yml
43
100
  - spec/db/schema.rb
44
101
  - spec/no_peeping_toms_spec.rb
45
102
  - spec/spec_helper.rb
46
- - uninstall.rb
47
103
  has_rdoc: true
48
- homepage: http://github.com/patmaddox/no-peeping-toms
104
+ homepage: https://github.com/patmaddox/no_peeping_toms
49
105
  licenses: []
50
106
 
51
107
  post_install_message:
52
- rdoc_options:
53
- - --charset=UTF-8
108
+ rdoc_options: []
109
+
54
110
  require_paths:
55
111
  - lib
56
112
  required_ruby_version: !ruby/object:Gem::Requirement
113
+ none: false
57
114
  requirements:
58
115
  - - ">="
59
116
  - !ruby/object:Gem::Version
117
+ hash: 3
118
+ segments:
119
+ - 0
60
120
  version: "0"
61
- version:
62
121
  required_rubygems_version: !ruby/object:Gem::Requirement
122
+ none: false
63
123
  requirements:
64
124
  - - ">="
65
125
  - !ruby/object:Gem::Version
126
+ hash: 3
127
+ segments:
128
+ - 0
66
129
  version: "0"
67
- version:
68
130
  requirements: []
69
131
 
70
- rubyforge_project:
71
- rubygems_version: 1.3.5
132
+ rubyforge_project: no_peeping_toms
133
+ rubygems_version: 1.3.7
72
134
  signing_key:
73
135
  specification_version: 3
74
136
  summary: Disables observers during testing, allowing you to write model tests that are completely decoupled from the observer.
data/README DELETED
@@ -1,58 +0,0 @@
1
- no_peeping_toms
2
- =============
3
-
4
- Originally a plugin, now gemified. 'gem install no_peeping_toms'
5
-
6
- This plugin disables observers in your specs, so that model specs can run in complete isolation.
7
-
8
- To disable observers, place the following code in your test.rb, or spec_helper.rb, or wherever:
9
-
10
- ActiveRecord::Observer.disable_observers
11
-
12
- You can easily reenable observers:
13
-
14
- ActiveRecord::Observer.enable_observers
15
-
16
- You can choose to run some code with specific observers turned on. This is useful when spec'ing an observer. For example, if you write the following observer:
17
-
18
- class PersonObserver < ActiveRecord::Observer
19
- def before_update(person)
20
- old_person = Person.find person.id
21
- if old_person.name != person.name
22
- NameChange.create! :person => person, :old_name => old_person.name, :new_name => person.name
23
- end
24
- end
25
- end
26
-
27
- You can spec the Person class in complete isolation.
28
-
29
- describe Person, " when changing a name" do
30
- before(:each) do
31
- @person = Person.create! :name => "Pat Maddox"
32
- end
33
-
34
- # By default, don't run any observers
35
- it "should not register a name change" do
36
- lambda { @person.update_attribute :name, "Don Juan Demarco" }.should_not change(NameChange, :count)
37
- end
38
-
39
- # Run only a portion of code with certain observers turned on
40
- it "should register a name change with the person observer turned on" do
41
- ActiveRecord::Observer.with_observers(:person_observer) do
42
- lambda { @person.update_attribute :name, "Don Juan Demarco" }.should change(NameChange, :count).by(1)
43
- end
44
-
45
- lambda { @person.update_attribute :name, "Man Without a Name" }.should_not change(NameChange, :count)
46
- end
47
- end
48
-
49
- Cool people who have contributed to NoPeepingToms:
50
- * Brandon Keepers
51
- * Corey Haines
52
- * Jeff Siegel
53
- * Drew Olson
54
- * Zach Dennis
55
-
56
- If you think your name should be here, shoot me an email and I'll add it ASAP.
57
-
58
- Copyright (c) 2007-2010 Pat Maddox, released under the MIT license
data/Rakefile DELETED
@@ -1,25 +0,0 @@
1
- begin
2
- require 'jeweler'
3
- rescue LoadError
4
- puts "Jeweler not available. Install it with: sudo gem install technicalpickles-jeweler -s http://gems.github.com"
5
- exit 1
6
- end
7
- require 'rake/testtask'
8
- require 'rake/rdoctask'
9
- require 'rcov/rcovtask'
10
- require "load_multi_rails_rake_tasks"
11
-
12
- Jeweler::Tasks.new do |s|
13
- s.name = "no_peeping_toms"
14
- s.summary = "Disables observers during testing, allowing you to write model tests that are completely decoupled from the observer."
15
- s.description = s.summary
16
- s.email = "pat.maddox@gmail.com"
17
- s.homepage = "http://github.com/patmaddox/no-peeping-toms"
18
- s.authors = ["Pat Maddox", "Brandon Keepers"]
19
- s.add_dependency "activerecord", ['>= 1.1']
20
- s.files -= ['.gitignore', 'init.rb']
21
- s.test_files = Dir['spec/**/*']
22
- s.test_files -= ['spec/debug.log']
23
- end
24
-
25
- Jeweler::GemcutterTasks.new
data/VERSION DELETED
@@ -1 +0,0 @@
1
- 1.1.0
data/install.rb DELETED
@@ -1 +0,0 @@
1
- # Install hook code here
@@ -1 +0,0 @@
1
- # Uninstall hook code here