tarantula 0.0.8.1 → 0.1.4

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