tarantula 0.0.8.1 → 0.1.4

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.
Files changed (55) hide show
  1. data/README.rdoc +80 -51
  2. data/Rakefile +33 -44
  3. data/VERSION.yml +4 -0
  4. data/examples/example_helper.rb +50 -0
  5. data/{test/relevance/core_extensions/ellipsize_test.rb → examples/relevance/core_extensions/ellipsize_example.rb} +1 -1
  6. data/{test/relevance/core_extensions/file_test.rb → examples/relevance/core_extensions/file_example.rb} +1 -1
  7. data/{test/relevance/core_extensions/response_test.rb → examples/relevance/core_extensions/response_example.rb} +5 -5
  8. data/{test/relevance/core_extensions/test_case_test.rb → examples/relevance/core_extensions/test_case_example.rb} +3 -3
  9. data/{test/relevance/tarantula/attack_form_submission_test.rb → examples/relevance/tarantula/attack_form_submission_example.rb} +1 -1
  10. data/{test/relevance/tarantula/attack_handler_test.rb → examples/relevance/tarantula/attack_handler_example.rb} +1 -1
  11. data/{test/relevance/tarantula/crawler_test.rb → examples/relevance/tarantula/crawler_example.rb} +3 -3
  12. data/{test/relevance/tarantula/form_test.rb → examples/relevance/tarantula/form_example.rb} +1 -1
  13. data/{test/relevance/tarantula/form_submission_test.rb → examples/relevance/tarantula/form_submission_example.rb} +1 -1
  14. data/{test/relevance/tarantula/html_document_handler_test.rb → examples/relevance/tarantula/html_document_handler_example.rb} +1 -1
  15. data/{test/relevance/tarantula/html_report_helper_test.rb → examples/relevance/tarantula/html_report_helper_example.rb} +1 -1
  16. data/{test/relevance/tarantula/html_reporter_test.rb → examples/relevance/tarantula/html_reporter_example.rb} +3 -3
  17. data/{test/relevance/tarantula/invalid_html_handler_test.rb → examples/relevance/tarantula/invalid_html_handler_example.rb} +1 -1
  18. data/{test/relevance/tarantula/io_reporter_test.rb → examples/relevance/tarantula/io_reporter_example.rb} +2 -2
  19. data/{test/relevance/tarantula/link_test.rb → examples/relevance/tarantula/link_example.rb} +21 -15
  20. data/{test/relevance/tarantula/log_grabber_test.rb → examples/relevance/tarantula/log_grabber_example.rb} +1 -1
  21. data/{test/relevance/tarantula/rails_init_test.rb → examples/relevance/tarantula/rails_init_example.rb} +3 -3
  22. data/{test/relevance/tarantula/rails_integration_proxy_test.rb → examples/relevance/tarantula/rails_integration_proxy_example.rb} +6 -12
  23. data/{test/relevance/tarantula/result_test.rb → examples/relevance/tarantula/result_example.rb} +2 -2
  24. data/{test/relevance/tarantula/tidy_handler_test.rb → examples/relevance/tarantula/tidy_handler_example.rb} +1 -1
  25. data/{test/relevance/tarantula/transform_test.rb → examples/relevance/tarantula/transform_example.rb} +2 -3
  26. data/{test/relevance/tarantula_test.rb → examples/relevance/tarantula_example.rb} +3 -3
  27. data/laf/v2/detail.html +23 -5
  28. data/laf/v2/index.html +1 -1
  29. data/laf/v2/stylesheets/tarantula.v2.css +77 -5
  30. data/lib/relevance/core_extensions/metaclass.rb +78 -0
  31. data/lib/relevance/tarantula.rb +1 -4
  32. data/lib/relevance/tarantula/link.rb +1 -1
  33. data/lib/relevance/tarantula/rails_integration_proxy.rb +1 -3
  34. data/template/tarantula_test.rb +12 -2
  35. metadata +54 -190
  36. data/init.rb +0 -1
  37. data/install.rb +0 -1
  38. data/manifest.txt +0 -102
  39. data/rails/init.rb +0 -4
  40. data/tarantula.gemspec +0 -56
  41. data/test/test_helper.rb +0 -34
  42. data/uninstall.rb +0 -1
  43. data/vendor/xss-shield/MIT-LICENSE +0 -20
  44. data/vendor/xss-shield/README +0 -76
  45. data/vendor/xss-shield/init.rb +0 -16
  46. data/vendor/xss-shield/lib/xss_shield.rb +0 -6
  47. data/vendor/xss-shield/lib/xss_shield/erb_hacks.rb +0 -111
  48. data/vendor/xss-shield/lib/xss_shield/haml_hacks.rb +0 -42
  49. data/vendor/xss-shield/lib/xss_shield/safe_string.rb +0 -47
  50. data/vendor/xss-shield/lib/xss_shield/secure_helpers.rb +0 -40
  51. data/vendor/xss-shield/test/test_actionview_integration.rb +0 -40
  52. data/vendor/xss-shield/test/test_erb.rb +0 -44
  53. data/vendor/xss-shield/test/test_haml.rb +0 -43
  54. data/vendor/xss-shield/test/test_helpers.rb +0 -25
  55. data/vendor/xss-shield/test/test_safe_string.rb +0 -55
@@ -1,4 +1,4 @@
1
- require File.join(File.dirname(__FILE__), "..", "..", "test_helper.rb")
1
+ require File.join(File.dirname(__FILE__), "..", "..", "example_helper.rb")
2
2
 
3
3
  describe "Relevance::Tarantula::InvalidHtmlHandler" do
4
4
  before do
@@ -1,4 +1,4 @@
1
- require File.join(File.dirname(__FILE__), "..", "..", "test_helper.rb")
1
+ require File.join(File.dirname(__FILE__), "..", "..", "example_helper.rb")
2
2
 
3
3
  describe 'Relevance::Tarantula::IOReporter' do
4
4
  it "reports errors to stderr and then raises" do
@@ -6,6 +6,6 @@ describe 'Relevance::Tarantula::IOReporter' do
6
6
  reporter.report stub(:code => "404", :url => "/uh-oh", :success => false)
7
7
  $stderr.expects(:puts).with("****** FAILURES")
8
8
  $stderr.expects(:puts).with("404: /uh-oh")
9
- lambda {reporter.finish_report("test_user_pages")}.should.raise RuntimeError
9
+ lambda {reporter.finish_report("test_user_pages")}.should raise_error(RuntimeError)
10
10
  end
11
11
  end
@@ -1,42 +1,48 @@
1
- require File.join(File.dirname(__FILE__), "..", "..", "test_helper.rb")
1
+ require File.join(File.dirname(__FILE__), "..", "..", "example_helper.rb")
2
2
 
3
3
  describe "Relevance::Tarantula::Link" do
4
4
  include ActionView::Helpers::UrlHelper
5
5
 
6
+ it "does not raise an error when initializing without href attribtue" do
7
+ link = Relevance::Tarantula::Link.new(Hpricot('<a="/foo">foo</a>').at('a'))
8
+ link.href.should == nil
9
+ link.method.should == :get
10
+ end
11
+
6
12
  it "parses anchor tags" do
7
13
  link = Relevance::Tarantula::Link.new(Hpricot('<a href="/foo">foo</a>').at('a'))
8
- assert_equal "/foo", link.href
9
- assert_equal :get, link.method
14
+ link.href.should == '/foo'
15
+ link.method.should == :get
10
16
  end
11
17
 
12
18
  it "parses anchor tags with POST 'method'" do
13
19
  link = Relevance::Tarantula::Link.new(Hpricot(%Q{<a href="/foo" onclick="#{method_javascript_function(:post)}">foo</a>}).at('a'))
14
- assert_equal "/foo", link.href
15
- assert_equal :post, link.method
20
+ link.href.should == '/foo'
21
+ link.method.should == :post
16
22
  end
17
23
 
18
24
  it "parses anchor tags with PUT 'method'" do
19
25
  link = Relevance::Tarantula::Link.new(Hpricot(%Q{<a href="/foo" onclick="#{method_javascript_function(:put)}">foo</a>}).at('a'))
20
- assert_equal "/foo", link.href
21
- assert_equal :put, link.method
26
+ link.href.should == '/foo'
27
+ link.method.should == :put
22
28
  end
23
29
 
24
30
  it "parses anchor tags with DELETE 'method'" do
25
31
  link = Relevance::Tarantula::Link.new(Hpricot(%Q{<a href="/foo" onclick="#{method_javascript_function(:delete)}">foo</a>}).at('a'))
26
- assert_equal "/foo", link.href
27
- assert_equal :delete, link.method
32
+ link.href.should == '/foo'
33
+ link.method.should == :delete
28
34
  end
29
35
 
30
36
  it "parses link tags with text" do
31
37
  link = Relevance::Tarantula::Link.new(Hpricot('<link href="/bar">bar</a>').at('link'))
32
- assert_equal "/bar", link.href
33
- assert_equal :get, link.method
38
+ link.href.should == '/bar'
39
+ link.method.should == :get
34
40
  end
35
41
 
36
42
  it "parses link tags without text" do
37
43
  link = Relevance::Tarantula::Link.new(Hpricot('<link href="/bar" />').at('link'))
38
- assert_equal "/bar", link.href
39
- assert_equal :get, link.method
44
+ link.href.should == '/bar'
45
+ link.method.should == :get
40
46
  end
41
47
 
42
48
  # method_javascript_function needs this method
@@ -48,14 +54,14 @@ end
48
54
 
49
55
  describe "possible conflict when user has an AR model named Link" do
50
56
  it "does not taint Object with Relevance::Tarantula" do
51
- Object.ancestors.should.not.include Relevance::Tarantula
57
+ Object.ancestors.should_not include(Relevance::Tarantula)
52
58
  end
53
59
 
54
60
  it "doesnt break with a Link model" do
55
61
  lambda {
56
62
  class Link < ActiveRecord::Base
57
63
  end
58
- }.should.not.raise
64
+ }.should_not raise_error
59
65
  end
60
66
 
61
67
  end
@@ -1,4 +1,4 @@
1
- require File.join(File.dirname(__FILE__), "..", "..", "test_helper.rb")
1
+ require File.join(File.dirname(__FILE__), "..", "..", "example_helper.rb")
2
2
 
3
3
  describe 'Relevance::Tarantula::LogGrabber' do
4
4
  before do
@@ -1,9 +1,9 @@
1
- require File.join(File.dirname(__FILE__), "../..", "test_helper.rb")
1
+ require File.join(File.dirname(__FILE__), "../..", "example_helper.rb")
2
2
 
3
3
  describe "Rails init.rb" do
4
- teardown { ENV.delete "RAILS_ENV" }
4
+ after { ENV.delete "RAILS_ENV" }
5
5
 
6
- xit "requires main tarantula file if in test environment" do
6
+ pending "requires main tarantula file if in test environment" do
7
7
  ENV["RAILS_ENV"] = "test"
8
8
  path = File.expand_path(File.join(File.dirname(__FILE__), *%w[.. .. .. lib relevance tarantula]))
9
9
  Object.any_instance.expects(:require).with('rake')
@@ -1,4 +1,4 @@
1
- require File.join(File.dirname(__FILE__), "..", "..", "test_helper.rb")
1
+ require File.join(File.dirname(__FILE__), "..", "..", "example_helper.rb")
2
2
 
3
3
  describe "Relevance::Tarantula::RailsIntegrationProxy rails_integration_test" do
4
4
  before {
@@ -23,7 +23,7 @@ describe "Relevance::Tarantula::RailsIntegrationProxy rails_integration_test" do
23
23
 
24
24
  it "has some useful defaults" do
25
25
  crawler = Relevance::Tarantula::RailsIntegrationProxy.rails_integration_test(stub(:host => "foo.com"))
26
- crawler.log_grabber.should.not.be nil
26
+ crawler.log_grabber.should_not be_nil
27
27
  end
28
28
  end
29
29
 
@@ -34,7 +34,7 @@ describe "Relevance::Tarantula::RailsIntegrationProxy" do
34
34
  @rip = Relevance::Tarantula::RailsIntegrationProxy.new(stub)
35
35
  @response = stub({:code => :foo})
36
36
  @rip.integration_test = stub_everything(:response => @response)
37
- @rip.send(http_method, "/url").should.be @response
37
+ @rip.send(http_method, "/url").should == @response
38
38
  end
39
39
  end
40
40
 
@@ -58,18 +58,12 @@ describe "Relevance::Tarantula::RailsIntegrationProxy patching" do
58
58
  @rip = Relevance::Tarantula::RailsIntegrationProxy.new(stub)
59
59
  @rip.stubs(:rails_root).returns("faux_rails_root")
60
60
  @response = stub_everything({:code => "404", :headers => {}, :content_type => "text/html"})
61
- @response.meta.ancestors.should.not.include Relevance::CoreExtensions::Response
61
+ @response.meta.ancestors.should_not include(Relevance::CoreExtensions::Response)
62
62
  @rip.patch_response("/url", @response)
63
- @response.meta.ancestors.should.include Relevance::CoreExtensions::Response
63
+ @response.meta.ancestors.should include(Relevance::CoreExtensions::Response)
64
64
  @response.html?.should == true
65
65
  end
66
-
67
- it "ignores 404s for known static binary types" do
68
- File.expects(:extension).returns("pdf")
69
- @rip.expects(:log).with("Skipping /url (for now)")
70
- @rip.patch_response("/url", @response)
71
- end
72
-
66
+
73
67
  it "replaces 404s with 200s, pulling content from public, for known text types" do
74
68
  File.expects(:extension).returns("html")
75
69
  @rip.expects(:static_content_file).with("/url").returns("File body")
@@ -1,4 +1,4 @@
1
- require File.join(File.dirname(__FILE__), "..", "..", "test_helper.rb")
1
+ require File.join(File.dirname(__FILE__), "..", "..", "example_helper.rb")
2
2
 
3
3
  describe "Relevance::Tarantula::Result" do
4
4
  before do
@@ -77,7 +77,7 @@ describe "Relevance::Tarantula::Result allowed errors" do
77
77
  end
78
78
 
79
79
  it "chains to super method missing" do
80
- lambda{Relevance::Tarantula::Result.allow_xxx_for}.should.raise(NoMethodError)
80
+ lambda{Relevance::Tarantula::Result.allow_xxx_for}.should raise_error(NoMethodError)
81
81
  end
82
82
 
83
83
  end
@@ -1,4 +1,4 @@
1
- require File.join(File.dirname(__FILE__), "..", "..", "test_helper.rb")
1
+ require File.join(File.dirname(__FILE__), "..", "..", "example_helper.rb")
2
2
 
3
3
  if defined?(Tidy) && ENV['TIDY_PATH']
4
4
  describe "Relevance::Tarantula::TidyHandler default" do
@@ -1,4 +1,4 @@
1
- require File.join(File.dirname(__FILE__), "../..", "test_helper.rb")
1
+ require File.join(File.dirname(__FILE__), "../..", "example_helper.rb")
2
2
 
3
3
  describe "Relevance::Tarantula::Transform" do
4
4
  it "can do a simple replace" do
@@ -15,7 +15,6 @@ describe "Relevance::Tarantula::Transform" do
15
15
  it "cannot access groups from a block, despite Ruby docs" do
16
16
  p = Proc.new {|value| $1.upcase}
17
17
  t = Relevance::Tarantula::Transform.new(/([aeiou])/, p)
18
- lambda {t["hello world"]}.should.raise(NoMethodError).message.should ==
19
- "undefined method `upcase' for nil:NilClass"
18
+ lambda {t["hello world"]}.should raise_error(NoMethodError)
20
19
  end
21
20
  end
@@ -1,6 +1,6 @@
1
- require File.join(File.dirname(__FILE__), "..", "test_helper.rb")
1
+ require File.join(File.dirname(__FILE__), "..", "example_helper.rb")
2
2
 
3
- describe "Relevance::Tarantula" do
3
+ describe Relevance::Tarantula do
4
4
  include Relevance::Tarantula
5
5
  attr_accessor :verbose
6
6
 
@@ -17,7 +17,7 @@ describe "Relevance::Tarantula" do
17
17
  end
18
18
 
19
19
  it "puts RAILS_ROOT behind a method call" do
20
- lambda{rails_root}.should.raise(NameError).message.should == "uninitialized constant RAILS_ROOT"
20
+ lambda{rails_root}.should raise_error(NameError)
21
21
  end
22
22
  end
23
23
 
@@ -4,7 +4,7 @@
4
4
  <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
5
5
  <head>
6
6
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
7
- <link rel="stylesheet" href="stylesheets/tarantula.v2.css" type="text/css" media="screen" title="no title" charset="utf-8">
7
+ <link rel="stylesheet" href="stylesheets/tarantula.v2.css" type="text/css" media="screen" title="no title" charset="utf-8" />
8
8
 
9
9
  <title>Detail</title>
10
10
 
@@ -22,18 +22,36 @@
22
22
  </div>
23
23
  <div id="page">
24
24
  <ul class="tabs">
25
- <li><a href="index.html">Failures</a></li>
25
+ <li><a href="index.html">&laquo; Failures</a></li>
26
26
  <li><a href="#" class="active">Data</a></li>
27
27
  <li><a href="#">Body</a></li>
28
28
  <li><a href="#">Log</a></li>
29
29
  </ul>
30
30
  <div id="report">
31
31
  <h3>Detail of GET /widgets/1 <em>Generated on Friday January 9, 2009 at 11:01:45am</em></h3>
32
- <p><b>Visit</b> <a href="#">http://localhost:3000/widgets/6</a>
33
- <p><b>Response</b> 500</p>
32
+ <p><b>Resource</b> <a href="#">http://localhost:3000/widgets/6</a></p>
33
+ <p><b>Response</b> <span class="r5">500</span></p>
34
34
  <p><b>Referrer</b> /random/30</p>
35
35
 
36
-
36
+ <table id="output">
37
+ <tbody>
38
+ <tr>
39
+ <th colspan="2">#</th>
40
+ </tr>
41
+ <tr>
42
+ <td class="numbers">
43
+ <span class="line number">1</span>
44
+ <span class="line number">2</span>
45
+ <span class="line number">3</span>
46
+ </td>
47
+ <td class="lines">
48
+ <span class="line">{:param1 => :value, :param2 => :another_value} </span>
49
+ <span class="line">{:param1 => :value, :param2 => :another_value} </span>
50
+ <span class="line">{:param1 => :value, :param2 => :another_value} </span>
51
+ </td>
52
+ </tr>
53
+ </tbody>
54
+ </table>
37
55
  </div>
38
56
  </div>
39
57
  </div>
@@ -26,7 +26,7 @@
26
26
  <li><a href="#">Successes</a></li>
27
27
  </ul>
28
28
 
29
- <table cellspacing="0">
29
+ <table id="list" cellspacing="0">
30
30
  <caption>4 Failures</caption>
31
31
  <thead>
32
32
  <tr>
@@ -158,14 +158,15 @@ div#page ul.tabs {
158
158
  left: 7px;
159
159
  }
160
160
 
161
- div#page table {
161
+ #list {
162
162
  width: 100%;
163
163
  }
164
164
 
165
- div#page table th, div #page th a, div#page tfoot td {
165
+ #list th, #list th a, #list tfoot td {
166
166
  background: #b9b9a9;
167
167
  color: #463c38;
168
168
  text-decoration: none;
169
+
169
170
  }
170
171
 
171
172
  .sort {
@@ -176,14 +177,14 @@ div#page table th, div #page th a, div#page tfoot td {
176
177
  opacity: 0.5;
177
178
  }
178
179
 
179
- div#page table th, div #page th a:hover span {
180
+ #list th, #list th a:hover span {
180
181
  filter:alpha(opacity=100);
181
182
  -moz-opacity:1;
182
183
  -khtml-opacity: 1;
183
184
  opacity: 1;
184
185
  }
185
186
 
186
- div#page table td, div#page table th {
187
+ #list td, #list th {
187
188
  text-align: center;
188
189
  padding: 4px;
189
190
  font-size: 14px;
@@ -202,12 +203,18 @@ div#page table caption {
202
203
  padding: 7px;
203
204
  background: #d0d0c4;
204
205
  border-bottom: 2px solid #aba7a1;
206
+ -moz-border-radius-topleft: 2px;
207
+ -moz-border-radius-topright: 2px;
205
208
  }
206
209
 
207
- div#page table tbody td {
210
+ #list tbody td {
208
211
  background: #f2f2eb;
209
212
  }
210
213
 
214
+ #list tfoot td {
215
+ line-height: 18px;
216
+ }
217
+
211
218
  tr.even td {
212
219
  background: #e9e9e2 !important;
213
220
  }
@@ -250,3 +257,68 @@ span.r5 {
250
257
  background-color: #c40000;
251
258
  border: 1px solid #dc0000;
252
259
  }
260
+
261
+ /* Detail */
262
+ #report h3 {
263
+ background: #D0D0C4; font-weight: normal;
264
+ border-bottom: 2px solid #ABA7A1;
265
+ -moz-border-radius-topleft: 2px; -moz-border-radius-topright: 2px;
266
+ -webkit-border-top-left-radius: 2px; -webkit-border-top-right-radius: 2px;
267
+ }
268
+
269
+ #report h3,
270
+ #report p {
271
+ width: 50%;
272
+ padding:6px 8px;
273
+ margin: 1px 0;
274
+ }
275
+
276
+ #report a {
277
+ color: #70B1CA
278
+ }
279
+
280
+ #report a:hover {
281
+ text-decoration: none;
282
+ }
283
+
284
+ #report p b {
285
+ color: #050505;
286
+ font-weight: normal;
287
+ }
288
+
289
+ #report p {
290
+ color: #463C38;
291
+ background: #f2f2eb;
292
+ line-height: 22px;
293
+ }
294
+
295
+ #report p span {
296
+ display: inline-block;
297
+ display: -moz-inline-block;
298
+ margin: 0;
299
+ padding: 2px 6px;
300
+ line-height: 16px;
301
+ }
302
+
303
+ #report h3 em {
304
+ display: block;
305
+ font-family: Consolas, Lucida Console, Monaco, monospace;
306
+ font-size: 75%;
307
+ font-style: normal;
308
+ font-weight: normal;
309
+ color: #463C38;
310
+ line-height: 22px;
311
+ }
312
+
313
+ /* Output */
314
+ #output {margin: 10px 0; width: 100%; font-size: 82.5%;}
315
+ #output th { background: #b9b9a9; text-align: left; padding-left: 2.25em; font-weight: normal; line-height: 18px; color: #463C38; border-bottom: 1px solid #fff;
316
+ -moz-border-radius-topleft: 2px; -moz-border-radius-topright: 2px;
317
+ -webkit-border-top-left-radius: 2px; -webkit-border-top-right-radius: 2px;
318
+ }
319
+ #output td { background: #f2f2eb; padding: 1px; line-height: 18px; }
320
+ #output { font-family: Consolas, Lucida Console, Monaco, monospace; }
321
+ #output .numbers { width: 3em; text-align: right; border-right: 1px solid #fff;}
322
+ #output .lines { width: auto; text-align: left;}
323
+ #output .line { display: block; text-align: left; padding: 1px 4px;}
324
+ #output .line.number { text-align: right; color: #585850; }
@@ -0,0 +1,78 @@
1
+ # This is a direct copy of the facets library metaclass stuff.
2
+ # used by Tarantula pulling in all of Facets doesn't make sense here.
3
+
4
+ # From lib/core/facets/metaid.rb
5
+ module Kernel
6
+ def meta_alias(*args)
7
+ meta_class do
8
+ alias_method(*args)
9
+ end
10
+ end
11
+
12
+ def meta_eval(str=nil, &blk)
13
+ if str
14
+ meta_class.instance_eval(str)
15
+ else
16
+ meta_class.instance_eval(&blk)
17
+ end
18
+ end
19
+
20
+ def meta_def( name, &block )
21
+ meta_class do
22
+ define_method( name, &block )
23
+ end
24
+ end
25
+
26
+ def meta_class(&block)
27
+ if block_given?
28
+ (class << self; self; end).class_eval(&block)
29
+ else
30
+ (class << self; self; end)
31
+ end
32
+ end
33
+
34
+ alias_method :metaclass, :meta_class
35
+
36
+ def eigenclass
37
+ (class << self; self; end)
38
+ end
39
+ end
40
+
41
+ class Module
42
+ def class_def name, &blk
43
+ class_eval { define_method name, &blk }
44
+ end
45
+
46
+ protected :attr
47
+ protected :attr_reader
48
+ protected :attr_writer
49
+ protected :attr_accessor
50
+ protected :remove_method
51
+ protected :undef_method
52
+ end
53
+
54
+ # From /lib/more/facets/kernel/meta.rb
55
+ module Kernel
56
+ def meta
57
+ @_meta_functor ||= Functor.new do |op,*args|
58
+ (class << self; self; end).send(op,*args)
59
+ end
60
+ end
61
+ end
62
+
63
+ # From /lib/core/facets/functor.rb
64
+ class Functor
65
+ private(*instance_methods.select { |m| m !~ /(^__|^binding$)/ })
66
+
67
+ def initialize(&function)
68
+ @function = function
69
+ end
70
+
71
+ def to_proc
72
+ @function
73
+ end
74
+
75
+ def method_missing(op, *args, &blk)
76
+ @function.call(op, *args, &blk)
77
+ end
78
+ end