watchdog 0.1.0 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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