defined 0.0.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,20 @@
1
+ Copyright (c) 2011 Sean Huber - shuber@huberry.com
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,53 @@
1
+ = defined
2
+
3
+ Calls <tt>Module#defined</tt> after a class or module has been defined or redefined
4
+
5
+
6
+ == Installation
7
+
8
+ gem install defined
9
+
10
+
11
+ == Usage
12
+
13
+ class User
14
+ def self.defined(file, line, method)
15
+ puts " defined by #{file}:#{line} with #{method}"
16
+ end
17
+
18
+ puts 'in original class definition'
19
+ end
20
+
21
+ User.class_eval do
22
+ puts 'in class_eval'
23
+ end
24
+
25
+ class User
26
+ puts 'in class definition again'
27
+ end
28
+
29
+ Class.new(User) do
30
+ puts 'in Class.new'
31
+ end
32
+
33
+ === Outputs
34
+
35
+ in original class definition
36
+ defined by /tmp/untitled.rb:1 with class
37
+ in class_eval
38
+ defined by /tmp/untitled.rb:9 with class_eval
39
+ in class definition again
40
+ defined by /tmp/untitled.rb:13 with class
41
+ in Class.new
42
+ defined by /tmp/untitled.rb:17 with initialize
43
+
44
+ ==== Note the <tt>method</tt> in the last example is <tt>initialize</tt> NOT <tt>new</tt>
45
+
46
+
47
+ == Patches and pull requests
48
+
49
+ * Fork the project.
50
+ * Make your feature addition or bug fix.
51
+ * Add tests for it. This is important so I don't break it in a future version unintentionally.
52
+ * Commit, do not mess with Rakefile, version, or history. (if you want to have your own version, that is fine but bump version in a commit by itself I can ignore when I pull)
53
+ * Send me a pull request. Bonus points for topic branches.
@@ -0,0 +1,50 @@
1
+ # Calls <tt>Module#defined(file, line, method)</tt> after a class or module has been defined or redefined
2
+ module Defined
3
+ autoload :Version, 'defined/version'
4
+
5
+ class << self
6
+ def included(mod) # :nodoc:
7
+ set_trace_func method(:trace_function).to_proc
8
+ end
9
+
10
+ # An array of classes and modules that are currently being defined
11
+ def definitions
12
+ @definitions ||= []
13
+ end
14
+
15
+ protected
16
+
17
+ def definition?(event, method, klass, keyword_event, method_event)
18
+ event == keyword_event || (event == method_event && definition_method?(method, klass))
19
+ end
20
+
21
+ # Checks if the event is the end of a class or module definition
22
+ def definition_end?(event, method, klass)
23
+ !definitions.empty? && definition?(event, method, klass, 'end', 'c-return')
24
+ end
25
+
26
+ # Checks if the event is a call to <tt>Module.new</tt>, <tt>Class.new</tt>, or <tt>/(class|instance|module)_(eval|exec)/</tt>
27
+ def definition_method?(method, klass)
28
+ (method == :initialize && klass.is_a?(Module)) || method.to_s =~ /^(class|instance|module)_(eval|exec)$/
29
+ end
30
+
31
+ # Checks if the event is the start of a class or module definition
32
+ def definition_start?(event, method, klass)
33
+ definition?(event, method, klass, 'class', 'c-call')
34
+ end
35
+
36
+ # Checks if the event is the end of a class or module definition, and if so
37
+ # it calls <tt>Module#defined(file, line, method)</tt> if implemented
38
+ def trace_function(event, file, line, method, binding, klass)
39
+ if definition_start?(event, method, klass)
40
+ definitions << binding.eval('self')
41
+ elsif definition_end?(event, method, klass)
42
+ object = definitions.pop
43
+ method ||= object.class.name.downcase.to_sym
44
+ object.defined(file, line, method) if object.respond_to?(:defined)
45
+ end
46
+ end
47
+ end
48
+ end
49
+
50
+ Module.send(:include, Defined)
@@ -0,0 +1,17 @@
1
+ module Defined
2
+ # Contains information about this gem's version
3
+ module Version
4
+ MAJOR = 0
5
+ MINOR = 0
6
+ PATCH = 0
7
+
8
+ # Returns a version string by joining <tt>MAJOR</tt>, <tt>MINOR</tt>, and <tt>PATCH</tt> with <tt>'.'</tt>
9
+ #
10
+ # Example
11
+ #
12
+ # Version.string # '1.0.2'
13
+ def self.string
14
+ [MAJOR, MINOR, PATCH].join('.')
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,122 @@
1
+ require 'test_helper'
2
+
3
+ class DefinedTest < Test::Unit::TestCase
4
+ module TestMethods
5
+ attr_reader :file, :line, :method, :called
6
+
7
+ def defined(file, line, method)
8
+ @file, @line, @method, @called = file, line, method, true
9
+ end
10
+ end
11
+
12
+ module Mock
13
+ extend TestMethods
14
+ end
15
+
16
+ class Dummy
17
+ extend TestMethods
18
+ end
19
+
20
+ def test_should_match_definition_start_with_keyword
21
+ assert Defined.send(:definition_start?, 'class', false, false)
22
+ end
23
+
24
+ def test_should_not_match_definition_start_with_wrong_keyword
25
+ assert !Defined.send(:definition_start?, 'wrong_keyword', :class_eval, false)
26
+ end
27
+
28
+ def test_should_match_definition_start_with_method
29
+ assert Defined.send(:definition_start?, 'c-call', :class_eval, false)
30
+ end
31
+
32
+ def test_should_not_match_definition_start_with_normal_method
33
+ assert !Defined.send(:definition_start?, 'c-call', :normal_method, false)
34
+ end
35
+
36
+ def test_should_match_definition_start_with_initialize
37
+ assert Defined.send(:definition_start?, 'c-call', :initialize, Module.new)
38
+ end
39
+
40
+ def test_should_not_match_definition_start_with_initialize_if_not_called_on_module_or_class
41
+ assert Defined.send(:definition_start?, 'c-call', :initialize, Dummy)
42
+ end
43
+
44
+ def test_should_match_definition_end_with_keyword
45
+ with_dummy_definition do
46
+ assert Defined.send(:definition_end?, 'end', false, false)
47
+ end
48
+ end
49
+
50
+ def test_should_not_match_definition_end_with_wrong_keyword
51
+ with_dummy_definition do
52
+ assert !Defined.send(:definition_end?, 'wrong_keyword', :class_eval, false)
53
+ end
54
+ end
55
+
56
+ def test_should_match_definition_end_with_method
57
+ with_dummy_definition do
58
+ assert Defined.send(:definition_end?, 'c-return', :class_eval, false)
59
+ end
60
+ end
61
+
62
+ def test_should_not_match_definition_end_with_normal_method
63
+ with_dummy_definition do
64
+ assert !Defined.send(:definition_end?, 'c-return', :normal_method, false)
65
+ end
66
+ end
67
+
68
+ def test_should_match_definition_end_with_initialize
69
+ with_dummy_definition do
70
+ assert Defined.send(:definition_end?, 'c-return', :initialize, Module.new)
71
+ end
72
+ end
73
+
74
+ def test_should_not_match_definition_end_with_initialize_if_not_called_on_module_or_class
75
+ with_dummy_definition do
76
+ assert Defined.send(:definition_end?, 'c-return', :initialize, Dummy)
77
+ end
78
+ end
79
+
80
+ def test_should_not_match_end_without_start
81
+ assert !Defined.send(:definition_end?, 'end', false, false)
82
+ end
83
+
84
+ def test_method_should_be_class_or_module_when_defined_with_keywords
85
+ assert_equal :module, Mock.method
86
+ assert_equal :class, Dummy.method
87
+ end
88
+
89
+ def test_should_not_call_defined_unless_implemented
90
+ mod = Module.new
91
+ assert !mod.respond_to?(:defined)
92
+ end
93
+
94
+ def test_should_call_defined_when_module_is_defined
95
+ assert Mock.called
96
+ end
97
+
98
+ def test_should_call_defined_when_module_is_defined_with_new
99
+ mod = Module.new { extend TestMethods }
100
+ assert mod.called
101
+ assert_equal :initialize, mod.method
102
+ end
103
+
104
+ %w(class instance module).each do |prefix|
105
+ %w(eval exec).each do |suffix|
106
+ method_name = [prefix, suffix].join('_').to_sym
107
+ define_method "test_should_call_defined_when_module_is_defined_with_#{method_name}" do
108
+ Mock.send(method_name) { @called = false }
109
+ assert Mock.called
110
+ assert_equal method_name, Mock.method
111
+ end
112
+ end
113
+ end
114
+
115
+ protected
116
+
117
+ def with_dummy_definition
118
+ Defined.definitions << Dummy
119
+ yield
120
+ Defined.definitions.pop
121
+ end
122
+ end
@@ -0,0 +1,5 @@
1
+ require 'test/unit'
2
+
3
+ $:.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
4
+ $:.unshift(File.dirname(__FILE__))
5
+ require 'defined'
metadata ADDED
@@ -0,0 +1,76 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: defined
3
+ version: !ruby/object:Gem::Version
4
+ hash: 31
5
+ prerelease:
6
+ segments:
7
+ - 0
8
+ - 0
9
+ - 0
10
+ version: 0.0.0
11
+ platform: ruby
12
+ authors:
13
+ - Sean Huber
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2011-02-23 00:00:00 -08:00
19
+ default_executable:
20
+ dependencies: []
21
+
22
+ description: Calls Module#defined whenever a class or module is defined or redefined
23
+ email: shuber@huberry.com
24
+ executables: []
25
+
26
+ extensions: []
27
+
28
+ extra_rdoc_files: []
29
+
30
+ files:
31
+ - lib/defined/version.rb
32
+ - lib/defined.rb
33
+ - MIT-LICENSE
34
+ - README.rdoc
35
+ - test/defined_test.rb
36
+ - test/test_helper.rb
37
+ has_rdoc: true
38
+ homepage: http://github.com/shuber/defined
39
+ licenses: []
40
+
41
+ post_install_message:
42
+ rdoc_options:
43
+ - --line-numbers
44
+ - --inline-source
45
+ - --main
46
+ - README.rdoc
47
+ require_paths:
48
+ - lib
49
+ required_ruby_version: !ruby/object:Gem::Requirement
50
+ none: false
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ hash: 3
55
+ segments:
56
+ - 0
57
+ version: "0"
58
+ required_rubygems_version: !ruby/object:Gem::Requirement
59
+ none: false
60
+ requirements:
61
+ - - ">="
62
+ - !ruby/object:Gem::Version
63
+ hash: 3
64
+ segments:
65
+ - 0
66
+ version: "0"
67
+ requirements: []
68
+
69
+ rubyforge_project:
70
+ rubygems_version: 1.5.0
71
+ signing_key:
72
+ specification_version: 3
73
+ summary: Calls Module#defined whenever a class or module is (re)defined
74
+ test_files:
75
+ - test/defined_test.rb
76
+ - test/test_helper.rb