predef 0.8.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,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: aa5c7ec0741fd0fec34e209fcc67873076662c02
4
+ data.tar.gz: 3e5262dd0fb9da3b0d97fdef139c19c5bf7926df
5
+ SHA512:
6
+ metadata.gz: 7eefc89fdba544c33660e14769df1625752bc7b4f2f52fdc2ad5cb1652556b79e0c9b065fc0adc424c517adb1ac985f3752e5d6d0ede2482e784eb5aa4f53c2f
7
+ data.tar.gz: 36b57795b4426a4ac59943c60e8cfd9bf62cb0821dfbf916d4b2ad531abf5ea1e37a8ec1219c28180ac701b34eb3028bdbdefadc099e1566349d4aa4da53715e
@@ -0,0 +1,14 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
10
+ *.bundle
11
+ *.so
12
+ *.o
13
+ *.a
14
+ mkmf.log
@@ -0,0 +1,20 @@
1
+ language: ruby
2
+ install:
3
+ - gem install bundler
4
+ - bundle
5
+ rvm:
6
+ - ruby-head
7
+ - 2.2.2
8
+ - 2.1.6
9
+ - 2.0.0
10
+ script:
11
+ - bundle exec ruby test/example.rb
12
+ notifications:
13
+ email:
14
+ recipients:
15
+ - whosekiteneverfly@gmail.com
16
+ on_success: never
17
+ on_failure: never
18
+ matrix:
19
+ allow_failures:
20
+ - rvm: ruby-head
@@ -0,0 +1,3 @@
1
+ # 0.8.0 (2015-06-04)
2
+
3
+ - Initial release. I think *all* of the features are complete. After trying it in my job for a while, release 1.0.0.
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in predef.gemspec
4
+ gemspec
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2015 Yuji Yamamoto
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,114 @@
1
+ # Predef
2
+
3
+ Shortcut for prepend-ing Module. Maybe useful for debugging.
4
+
5
+ [![Build Status](https://travis-ci.org/igrep/predef.svg?branch=master)](https://travis-ci.org/igrep/predef)
6
+
7
+ ## Installation
8
+
9
+ Add this line to your application's Gemfile:
10
+
11
+ ```ruby
12
+ gem 'predef'
13
+ ```
14
+
15
+ And then execute:
16
+
17
+ $ bundle
18
+
19
+ Or install it yourself as:
20
+
21
+ $ gem install predef
22
+
23
+ ## Usage
24
+
25
+ ### Example: Collect All Queries Executed in a Test
26
+
27
+ Given you're using some third-party database client library like this...
28
+
29
+ ```ruby
30
+ class HogeSQL::Connection
31
+ def execute query
32
+ # ...
33
+ end
34
+
35
+ # ...
36
+ end
37
+ ```
38
+
39
+ Imagine you want to see all `SELECT` queries and the stacktrace when executed, without any change of `HogeSQL::Connection`.
40
+
41
+ ```ruby
42
+ require 'predef'
43
+
44
+ Predef.predef HogeSQL::Connection, :execute do|query|
45
+ if query.include? 'SELECT'
46
+ puts query
47
+ pp caller
48
+ end
49
+ super # call the original query method.
50
+ end
51
+
52
+ # ... your app or some test code ...
53
+ ```
54
+
55
+ Then you'd get...
56
+
57
+ ```ruby
58
+ SELECT * from your_apps_table WHERE ...
59
+ ["/path/to/your_app/app/models/foo.rb:355:in `some_method_in_model'",
60
+ "/path/to/your_app/app/controllers/foo_controller.rb:355:in `some_action_in_controller'",
61
+ ...]
62
+
63
+ ...
64
+ ```
65
+
66
+ This is just a shortcut for:
67
+
68
+ ```ruby
69
+ module SomeWrapper
70
+ def execute
71
+ if query.include? 'SELECT'
72
+ puts query
73
+ pp caller
74
+ end
75
+ super # call the original execute method.
76
+ end
77
+ end
78
+
79
+ HogeSQL::Connection.__send__(:prepend, SomeWrapper)
80
+ ```
81
+
82
+ So you can more quickly inspect code you don't want to change directly!
83
+
84
+ ### More Ruby-ish Way
85
+
86
+ Or would you like `using` this way?
87
+ Though it's a bit more verbose to prepend only one method.
88
+
89
+ ```ruby
90
+ using Predef::Refinements
91
+
92
+ HogeSQL::Connection.predef :execute do|query|
93
+ # same here with the last example...
94
+ end
95
+ ```
96
+
97
+ ## For more methods:
98
+
99
+ See and/or execute [test/example.rb](test/example.rb):
100
+
101
+ ```bash
102
+ $ git clone git@github.com:igrep/predef.git
103
+ $ cd predef
104
+ $ bundle
105
+ $ bundle exec ruby test/example.rb
106
+ ```
107
+
108
+ ## Contributing
109
+
110
+ 1. Fork it ( https://github.com/igrep/predef/fork )
111
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
112
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
113
+ 4. Push to the branch (`git push origin my-new-feature`)
114
+ 5. Create a new Pull Request
@@ -0,0 +1,2 @@
1
+ require "bundler/gem_tasks"
2
+
@@ -0,0 +1,72 @@
1
+ class Predef < Module
2
+ VERSION = '0.8.0'
3
+
4
+ private_class_method :new
5
+
6
+ def self.predef klass, method_name, &definition
7
+ unless klass.public_method_defined? method_name
8
+ raise ::Predef::Error, "#{klass}##{method_name} is not defined! Use `Predef.predef!` if you want to define a new method."
9
+ end
10
+
11
+ predef! klass, method_name, &definition
12
+ end
13
+
14
+ def self.predef! klass, method_name, &definition
15
+ if defined? klass.__PREDEF__
16
+ instance = klass.__PREDEF__
17
+ else
18
+ instance = new(klass)
19
+
20
+ singleton_class = class << klass; self ; end
21
+ singleton_class.class_eval do
22
+ define_method(:__PREDEF__) { instance }
23
+ end
24
+ end
25
+
26
+ instance.module_eval do
27
+ define_method(method_name, &definition)
28
+ end
29
+ method_name
30
+ end
31
+
32
+ def self.unpredef klass, method_name
33
+ if !(defined? klass.__PREDEF__) || !(klass.__PREDEF__.public_method_defined? method_name)
34
+ raise ::Predef::Error, "#{klass}##{method_name} has never been predef-ed!"
35
+ end
36
+ self.unpredef! klass, method_name
37
+ end
38
+
39
+ def self.unpredef! klass, method_name
40
+ klass.__PREDEF__.module_eval do
41
+ remove_method method_name
42
+ end
43
+ end
44
+
45
+ def initialize klass
46
+ prepend_features klass
47
+ end
48
+
49
+ module Refinements
50
+ refine Class do
51
+ def predef method_name, &block
52
+ ::Predef.predef(self, method_name, &block)
53
+ end
54
+
55
+ def predef! method_name, &block
56
+ ::Predef.predef!(self, method_name, &block)
57
+ end
58
+
59
+ def unpredef method_name
60
+ ::Predef.unpredef(self, method_name)
61
+ end
62
+
63
+ def unpredef! method_name
64
+ ::Predef.unpredef!(self, method_name)
65
+ end
66
+ end
67
+ end
68
+
69
+ class Error < ::Exception
70
+ end
71
+
72
+ end
@@ -0,0 +1,25 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'predef'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "predef"
8
+ spec.version = Predef::VERSION
9
+ spec.authors = ["Yuji Yamamoto"]
10
+ spec.email = ["whosekiteneverfly@gmail.com"]
11
+ spec.summary = %q{Shortcut for prepend-ing Module.}
12
+ spec.description = %q{Shortcut for prepend-ing Module. Maybe useful for debugging.}
13
+ spec.homepage = "https://github.com/igrep/predef"
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files -z`.split("\x0")
17
+ spec.executables = []
18
+ spec.test_files = ["test/example.rb"]
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_development_dependency "bundler", "~> 1.9"
22
+ spec.add_development_dependency "rake", "~> 10.0"
23
+
24
+ spec.required_ruby_version = '>= 2.0'
25
+ end
@@ -0,0 +1,135 @@
1
+ require_relative 'test_helper'
2
+
3
+ class Hoge
4
+ def foo arg
5
+ 'bar ' + arg
6
+ end
7
+ def foo2
8
+ 'original foo2'
9
+ end
10
+ def foo3
11
+ end
12
+ def never_predef_ed
13
+ end
14
+
15
+ def self.singleton_method arg
16
+ 'singleton_bar ' + arg
17
+ end
18
+ end
19
+
20
+ example 'Predef.predef overrides a method of a class' do
21
+
22
+ note 'overridden method can use super.'
23
+ Predef.predef Hoge, :foo do|arg|
24
+ super(arg) + ' baz'
25
+ end
26
+
27
+ actual = Hoge.new.foo('arg')
28
+ expected = 'bar arg baz'
29
+ test(
30
+ (actual == expected),
31
+ "Expected #{actual.inspect} to equal to #{expected.inspect}."
32
+ )
33
+ end
34
+
35
+ example 'Predef.predef overrides a singleton method of a object' do
36
+
37
+ Predef.predef Hoge.singleton_class, :singleton_method do|arg|
38
+ super(arg) + ' baz'
39
+ end
40
+
41
+ actual = Hoge.singleton_method('arg')
42
+ expected = 'singleton_bar arg baz'
43
+ test(
44
+ (actual == expected),
45
+ "Expected #{actual.inspect} to equal to #{expected.inspect}."
46
+ )
47
+ end
48
+
49
+ example 'Predef.predef overrides another method of the class' do
50
+ Predef.predef Hoge, :foo2 do
51
+ 'baz2'
52
+ end
53
+
54
+ actual = Hoge.new.foo2
55
+ expected = 'baz2'
56
+ test(
57
+ (actual == expected),
58
+ "Expected #{actual.inspect} to equal to #{expected.inspect}."
59
+ )
60
+ end
61
+
62
+ example 'Predef.predef raises an error given an undefined method.' do
63
+ actual = error_of do
64
+ Predef.predef Hoge, :non_defined do
65
+ end
66
+ end
67
+ expected = ::Predef::Error
68
+ test(
69
+ (actual.instance_of? expected),
70
+ "Expected an instance of #{actual.class} to be an instance of #{expected}."
71
+ )
72
+ end
73
+
74
+ example 'Predef.predef! does NOT raise an error given even an undefined method.' do
75
+ actual = error_of do
76
+ Predef.predef! Hoge, :non_defined do
77
+ end
78
+ end
79
+ test(actual.nil?, "Expected an instance of #{actual.inspect} to nil.")
80
+ end
81
+
82
+ example 'Predef.unpredef gets back orignal method.' do
83
+ Predef.unpredef Hoge, :foo2
84
+
85
+ actual = Hoge.new.foo2
86
+ expected = 'original foo2'
87
+ test(
88
+ (actual == expected),
89
+ "Expected #{actual.inspect} to equal to #{expected.inspect}."
90
+ )
91
+ end
92
+
93
+ example 'Predef.unpredef raises an error given a non predef-ed class.' do
94
+ class AnotherClass
95
+ def foo
96
+ end
97
+ end
98
+
99
+ actual = error_of { Predef.unpredef AnotherClass, :foo }
100
+ expected = ::Predef::Error
101
+ test(
102
+ (actual.instance_of? expected),
103
+ "Expected an instance of #{actual.class} to be an instance of #{expected}."
104
+ )
105
+ end
106
+
107
+ example 'Predef.unpredef raises an error given a non predef-ed method.' do
108
+ actual = error_of { Predef.unpredef Hoge, :never_predef_ed }
109
+ expected = ::Predef::Error
110
+ test(
111
+ (actual.instance_of? expected),
112
+ "Expected an instance of #{actual.class} to be an instance of #{expected}."
113
+ )
114
+ end
115
+
116
+ example 'Hoge.predef raises a NoMethodError without using Predef::Refinements' do
117
+ actual = error_of { Hoge.predef(:foo3){ :foo3 } }
118
+ expected = ::NoMethodError
119
+ test(
120
+ (actual.instance_of? expected),
121
+ "Expected an instance of #{actual.class} to be an instance of #{expected}."
122
+ )
123
+ end
124
+
125
+ using ::Predef::Refinements
126
+
127
+ example "Hoge.predef doesn't raise an error by using Predef::Refinements" do
128
+ Hoge.predef(:foo3){ :foo3 }
129
+ actual = Hoge.new.foo3
130
+ expected = :foo3
131
+ test(
132
+ (actual == expected),
133
+ "Expected #{actual.inspect} to equal to #{expected.inspect}."
134
+ )
135
+ end
@@ -0,0 +1,25 @@
1
+ def example description, &block
2
+ puts "- #{description}"
3
+ block.call
4
+ puts
5
+ end
6
+
7
+ def note content
8
+ puts "-- # #{content}"
9
+ end
10
+
11
+ def test boolean_expression, on_failure
12
+ if boolean_expression
13
+ puts '=> OK'.freeze
14
+ else
15
+ fail "Assertion failed.\n\n ==> #{on_failure}\n\n"
16
+ end
17
+ end
18
+
19
+ def error_of &block
20
+ block.call
21
+ rescue ::Exception => e
22
+ return e
23
+ else
24
+ return nil
25
+ end
metadata ADDED
@@ -0,0 +1,85 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: predef
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.8.0
5
+ platform: ruby
6
+ authors:
7
+ - Yuji Yamamoto
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-06-04 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.9'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.9'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '10.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '10.0'
41
+ description: Shortcut for prepend-ing Module. Maybe useful for debugging.
42
+ email:
43
+ - whosekiteneverfly@gmail.com
44
+ executables: []
45
+ extensions: []
46
+ extra_rdoc_files: []
47
+ files:
48
+ - ".gitignore"
49
+ - ".travis.yml"
50
+ - ChangeLog.md
51
+ - Gemfile
52
+ - LICENSE.txt
53
+ - README.md
54
+ - Rakefile
55
+ - lib/predef.rb
56
+ - predef.gemspec
57
+ - test/example.rb
58
+ - test/test_helper.rb
59
+ homepage: https://github.com/igrep/predef
60
+ licenses:
61
+ - MIT
62
+ metadata: {}
63
+ post_install_message:
64
+ rdoc_options: []
65
+ require_paths:
66
+ - lib
67
+ required_ruby_version: !ruby/object:Gem::Requirement
68
+ requirements:
69
+ - - ">="
70
+ - !ruby/object:Gem::Version
71
+ version: '2.0'
72
+ required_rubygems_version: !ruby/object:Gem::Requirement
73
+ requirements:
74
+ - - ">="
75
+ - !ruby/object:Gem::Version
76
+ version: '0'
77
+ requirements: []
78
+ rubyforge_project:
79
+ rubygems_version: 2.2.2
80
+ signing_key:
81
+ specification_version: 4
82
+ summary: Shortcut for prepend-ing Module.
83
+ test_files:
84
+ - test/example.rb
85
+ has_rdoc: