watchdog 0.1.0 → 0.2.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,6 @@
1
+ == 0.2.0
2
+ * Fix multiple guards per extended class
3
+ * Fix guarding for subclasses of extended classes
4
+
5
+ == 0.1.0
6
+ * Initial release
data/README.md CHANGED
@@ -68,4 +68,4 @@ Thanks to Wegowise for open-source time to make this possible!
68
68
  License
69
69
  =======
70
70
 
71
- See LICENSE file
71
+ See LICENSE.txt
@@ -3,12 +3,14 @@ require 'watchdog/german_shepard'
3
3
  require 'watchdog/version'
4
4
 
5
5
  module Watchdog
6
- # Maps objects or modules to their extension modules
7
- class <<self; attr_accessor :extensions; end
8
- self.extensions = {}
6
+ class <<self; attr_accessor :extensions, :subclasses; end
7
+ self.extensions, self.subclasses = {}, []
9
8
 
10
9
  # Guards extension methods from being overwritten
11
10
  def self.guard(obj, meth)
11
+ return if subclasses.include?(obj)
12
+ return subclasses << obj if !extensions.key?(obj) && extensions.keys.
13
+ any? {|e| e.is_a?(Module) && e > obj }
12
14
  if extensions[obj].instance_methods.map(&:to_sym).include?(meth)
13
15
  raise ExtensionMethodExistsError.new(meth, obj, extensions[obj])
14
16
  end
@@ -1,6 +1,11 @@
1
1
  module Watchdog
2
2
  module GermanShepard
3
+ class << self; attr_accessor :created; end
4
+ self.created = []
5
+
3
6
  def self.create_guard(meth, obj)
7
+ return if created.include?([meth, obj])
8
+ created << [meth, obj]
4
9
  meta = class <<obj; self end
5
10
  original = meta.instance_method(meth)
6
11
  meta.send(:define_method, meth) do |m|
@@ -14,8 +19,9 @@ module Watchdog
14
19
  create_guard :method_added, obj
15
20
  elsif obj.respond_to? :singleton_method_added
16
21
  create_guard :singleton_method_added, obj
22
+ else
23
+ super
17
24
  end
18
- super
19
25
  end
20
26
 
21
27
  [:singleton_method_added, :method_added].each do |m|
@@ -1,3 +1,3 @@
1
1
  module Watchdog
2
- VERSION = '0.1.0'
2
+ VERSION = '0.2.0'
3
3
  end
@@ -53,17 +53,17 @@ describe Watchdog do
53
53
 
54
54
  context "new extension method" do
55
55
  it "doesn't raise error if no existing methods conflict" do
56
- existing = Module.new
56
+ existing = Class.new
57
57
  lambda { existing.send :include, extensions }.should_not raise_error
58
58
  end
59
59
 
60
60
  it "raises error if existing public methods conflict" do
61
- existing = create_methods Module.new, :blah
61
+ existing = create_methods Class.new, :blah
62
62
  lambda { existing.send :include, extensions }.should raise_error(Watchdog::MethodExistsError, /#blah/)
63
63
  end
64
64
 
65
65
  it "raises error if existing private methods conflict" do
66
- existing = create_methods Module.new, :blah
66
+ existing = create_methods Class.new, :blah
67
67
  existing.send :private, :blah
68
68
  lambda { existing.send :include, extensions }.should raise_error(Watchdog::MethodExistsError)
69
69
  end
@@ -71,24 +71,37 @@ describe Watchdog do
71
71
 
72
72
  context "new method" do
73
73
  it "doesn't raise error if it doesn't redefine extension methods" do
74
- existing = Module.new.send :include, extensions
74
+ existing = Class.new.send :include, extensions
75
75
  lambda { existing.send(:define_method, :bling) { } }.should_not raise_error
76
76
  end
77
77
 
78
78
  it "raises error if it redefines extension methods" do
79
- existing = Module.new.send :include, extensions
79
+ existing = Class.new.send :include, extensions
80
80
  lambda {
81
81
  existing.send(:define_method, :blah) { }
82
82
  }.should raise_error(Watchdog::ExtensionMethodExistsError)
83
83
  end
84
84
 
85
85
  it "raises error if it redefines extension methods for module with method_added" do
86
- existing = Module.new { def self.method_added(meth); end }
87
- existing.send :include, extensions
86
+ existing = Class.new { def self.method_added(meth); end }.send :include, extensions
88
87
  lambda {
89
88
  existing.send(:define_method, :blah) { }
90
89
  }.should raise_error(Watchdog::ExtensionMethodExistsError)
91
90
  end
92
91
  end
92
+
93
+ it "doesn't guard if subclass of extended class" do
94
+ existing = Class.new.send :include, extensions
95
+ subclass = Class.new(existing)
96
+ lambda { subclass.send(:define_method, :blah) { } }.should_not raise_error
97
+ end
98
+
99
+ it "creates one method_added guard per extended class" do
100
+ Watchdog::GermanShepard.created = []
101
+ existing = Class.new { def self.method_added(meth); end }.send :include, extensions
102
+ another_extensions = Module.new.extend(Watchdog)
103
+ existing.send :include, another_extensions
104
+ Watchdog::GermanShepard.created.size.should == 1
105
+ end
93
106
  end
94
107
  end
@@ -11,6 +11,7 @@ Gem::Specification.new do |s|
11
11
  s.summary = "Watches over your extensions and monkey patches"
12
12
  s.description = "Watchdog ensures your extensions and monkey patches don't redefine existing methods as well as get redefined by others."
13
13
  s.required_rubygems_version = ">= 1.3.6"
14
+ s.add_development_dependency 'rspec', '~> 2.5'
14
15
  s.files = Dir.glob(%w[{lib,spec}/**/*.rb [A-Z]*.{txt,rdoc,md} *.gemspec]) + %w{Rakefile}
15
16
  s.extra_rdoc_files = ["README.md", "LICENSE.txt"]
16
17
  s.license = 'MIT'
metadata CHANGED
@@ -2,7 +2,7 @@
2
2
  name: watchdog
3
3
  version: !ruby/object:Gem::Version
4
4
  prerelease:
5
- version: 0.1.0
5
+ version: 0.2.0
6
6
  platform: ruby
7
7
  authors:
8
8
  - Gabriel Horner
@@ -10,10 +10,20 @@ autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
12
 
13
- date: 2011-04-16 00:00:00 -04:00
13
+ date: 2011-04-17 00:00:00 -04:00
14
14
  default_executable:
15
- dependencies: []
16
-
15
+ dependencies:
16
+ - !ruby/object:Gem::Dependency
17
+ name: rspec
18
+ prerelease: false
19
+ requirement: &id001 !ruby/object:Gem::Requirement
20
+ none: false
21
+ requirements:
22
+ - - ~>
23
+ - !ruby/object:Gem::Version
24
+ version: "2.5"
25
+ type: :development
26
+ version_requirements: *id001
17
27
  description: Watchdog ensures your extensions and monkey patches don't redefine existing methods as well as get redefined by others.
18
28
  email: ghorner@wegowise.com
19
29
  executables: []
@@ -29,6 +39,7 @@ files:
29
39
  - lib/watchdog/version.rb
30
40
  - lib/watchdog.rb
31
41
  - spec/watchdog_spec.rb
42
+ - CHANGELOG.txt
32
43
  - LICENSE.txt
33
44
  - README.md
34
45
  - watchdog.gemspec