akephalos 0.0.4 → 0.0.5

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.
data/TODO.txt CHANGED
@@ -1,7 +1,11 @@
1
1
  0.0.5
2
2
  =======================================================================================
3
- * DRb server should never shut down prematurely -- missing methods, 500 errors,
4
- even java errors (NPE error from bad javascript).
3
+ * Upgrade to htmlunit-2.7
4
+ * Fix DRb recycled object errors
5
+ * Define NativeException on ruby side so that uncaught exceptions are displayed with
6
+ a proper backtrace.
7
+ * Add Akephalos.filter() for enabling FakeWeb style request/response mocking in the
8
+ HtmlUnit browser.
5
9
 
6
10
  0.0.4
7
11
  =======================================================================================
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.0.4
1
+ 0.0.5
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{akephalos}
8
- s.version = "0.0.4"
8
+ s.version = "0.0.5"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Bernerd Schaefer"]
12
- s.date = %q{2010-06-15}
12
+ s.date = %q{2010-06-24}
13
13
  s.default_executable = %q{akephalos}
14
14
  s.description = %q{}
15
15
  s.email = %q{bj.schaefer@gmail.com}
@@ -28,14 +28,19 @@ Gem::Specification.new do |s|
28
28
  "lib/akephalos.rb",
29
29
  "lib/akephalos/capybara.rb",
30
30
  "lib/akephalos/client.rb",
31
+ "lib/akephalos/client/filter.rb",
32
+ "lib/akephalos/client/listener.rb",
33
+ "lib/akephalos/configuration.rb",
31
34
  "lib/akephalos/console.rb",
32
35
  "lib/akephalos/cucumber.rb",
33
36
  "lib/akephalos/htmlunit.rb",
37
+ "lib/akephalos/htmlunit/ext/http_method.rb",
34
38
  "lib/akephalos/node.rb",
35
39
  "lib/akephalos/page.rb",
36
40
  "lib/akephalos/remote_client.rb",
37
41
  "lib/akephalos/server.rb",
38
42
  "spec/driver/akephalos_driver_spec.rb",
43
+ "spec/filter_spec.rb",
39
44
  "spec/session/akephalos_session_spec.rb",
40
45
  "spec/slow_page_loads_spec.rb",
41
46
  "spec/spec.opts",
@@ -47,10 +52,10 @@ Gem::Specification.new do |s|
47
52
  "src/commons-lang-2.4.jar",
48
53
  "src/commons-logging-1.1.1.jar",
49
54
  "src/cssparser-0.9.5.jar",
50
- "src/htmlunit-2.6.jar",
51
- "src/htmlunit-core-js-2.6.jar",
55
+ "src/htmlunit-2.7.jar",
56
+ "src/htmlunit-core-js-2.7.jar",
52
57
  "src/jruby-complete-1.5.0.jar",
53
- "src/nekohtml-1.9.13.jar",
58
+ "src/nekohtml-1.9.14.jar",
54
59
  "src/sac-1.3.jar",
55
60
  "src/serializer-2.7.1.jar",
56
61
  "src/xalan-2.7.1.jar",
@@ -64,6 +69,7 @@ Gem::Specification.new do |s|
64
69
  s.summary = %q{}
65
70
  s.test_files = [
66
71
  "spec/driver/akephalos_driver_spec.rb",
72
+ "spec/filter_spec.rb",
67
73
  "spec/session/akephalos_session_spec.rb",
68
74
  "spec/slow_page_loads_spec.rb",
69
75
  "spec/spec_helper.rb"
@@ -92,7 +92,9 @@ class Capybara::Driver::Akephalos < Capybara::Driver::Base
92
92
  private
93
93
 
94
94
  def all_unfiltered(selector)
95
- node.find(selector).map { |node| Node.new(driver, node) }
95
+ nodes = []
96
+ node.find(selector).each { |node| nodes << Node.new(driver, node) }
97
+ nodes
96
98
  end
97
99
 
98
100
  def type
@@ -129,7 +131,9 @@ class Capybara::Driver::Akephalos < Capybara::Driver::Base
129
131
  end
130
132
 
131
133
  def find(selector)
132
- page.find(selector).map { |node| Node.new(self, node) }
134
+ nodes = []
135
+ page.find(selector).each { |node| nodes << Node.new(self, node) }
136
+ nodes
133
137
  end
134
138
 
135
139
  def evaluate_script(script)
@@ -1,44 +1,45 @@
1
+ require 'akephalos/configuration'
2
+
1
3
  if RUBY_PLATFORM != "java"
2
4
  require 'akephalos/remote_client'
3
5
  Akephalos::Client = Akephalos::RemoteClient
4
6
  else
5
7
  require 'akephalos/htmlunit'
8
+ require 'akephalos/htmlunit/ext/http_method'
9
+
6
10
  require 'akephalos/page'
7
11
  require 'akephalos/node'
8
12
 
13
+ require 'akephalos/client/filter'
14
+ require 'akephalos/client/listener'
15
+
9
16
  module Akephalos
10
17
  class Client
18
+ java_import 'com.gargoylesoftware.htmlunit.NicelyResynchronizingAjaxController'
19
+ java_import 'com.gargoylesoftware.htmlunit.SilentCssErrorHandler'
20
+
11
21
  attr_reader :page
12
22
 
13
23
  def initialize
14
- @_client = WebClient.new
15
-
16
- @_client.setAjaxController(com.gargoylesoftware.htmlunit.NicelyResynchronizingAjaxController.new)
24
+ @_client = java.util.concurrent.FutureTask.new do
25
+ client = WebClient.new
17
26
 
18
- listener = Class.new do
19
- include com.gargoylesoftware.htmlunit.WebWindowListener
27
+ Filter.new(client)
28
+ client.addWebWindowListener(Listener.new(self))
29
+ client.setAjaxController(NicelyResynchronizingAjaxController.new)
30
+ client.setCssErrorHandler(SilentCssErrorHandler.new)
20
31
 
21
- def initialize(client)
22
- @client = client
23
- end
24
-
25
- def webWindowContentChanged(event)
26
- @client.page = event.getNewPage
27
- if latch = Thread.current[:latch]
28
- latch.countDown
29
- Thread.current[:latch] = nil
30
- end
31
- end
32
+ client
32
33
  end
34
+ Thread.new { @_client.run }
35
+ end
33
36
 
34
- @_client.addWebWindowListener(listener.new(self))
35
- @_client.setCssErrorHandler(com.gargoylesoftware.htmlunit.SilentCssErrorHandler.new)
37
+ def configuration=(config)
38
+ Akephalos.configuration = config
36
39
  end
37
40
 
38
41
  def visit(url)
39
- self.class.wait_for_result do
40
- @_client.getPage(url)
41
- end
42
+ client.getPage(url)
42
43
  end
43
44
 
44
45
  def page=(_page)
@@ -48,16 +49,10 @@ else
48
49
  @page
49
50
  end
50
51
 
51
- def self.wait_for_result(timeout = 3)
52
- latch = java.util.concurrent.CountDownLatch.new(1)
53
- Thread.new do
54
- Thread.current[:latch] = latch
55
- yield
56
- end.join
57
- start = Time.now
58
- latch.await(timeout, java.util.concurrent.TimeUnit::SECONDS)
52
+ private
53
+ def client
54
+ @client ||= @_client.get
59
55
  end
60
-
61
56
  end
62
57
  end
63
58
  end
@@ -0,0 +1,82 @@
1
+ module Akephalos
2
+ class Client
3
+ class Filter < WebConnectionWrapper
4
+ java_import 'com.gargoylesoftware.htmlunit.util.NameValuePair'
5
+ java_import 'com.gargoylesoftware.htmlunit.WebResponseData'
6
+ java_import 'com.gargoylesoftware.htmlunit.WebResponseImpl'
7
+
8
+ def filter(request)
9
+ if filter = Akephalos.filters.find { |filter| request.http_method === filter[:method] && request.url.to_s =~ filter[:filter] }
10
+ start_time = Time.now
11
+ headers = filter[:headers].map { |name, value| NameValuePair.new(name.to_s, value.to_s) }
12
+ response = WebResponseData.new(filter[:body].to_s.to_java_bytes, filter[:status], HTTP_STATUS_CODES.fetch(filter[:status], "Unknown"), headers)
13
+ WebResponseImpl.new(response, request, Time.now - start_time)
14
+ end
15
+ end
16
+
17
+ def getResponse(request)
18
+ filter(request) || super
19
+ end
20
+
21
+ HTTP_STATUS_CODES = {
22
+ 100 => "Continue",
23
+ 101 => "Switching Protocols",
24
+ 102 => "Processing",
25
+ 200 => "OK",
26
+ 201 => "Created",
27
+ 202 => "Accepted",
28
+ 203 => "Non-Authoritative Information",
29
+ 204 => "No Content",
30
+ 205 => "Reset Content",
31
+ 206 => "Partial Content",
32
+ 207 => "Multi-Status",
33
+ 300 => "Multiple Choices",
34
+ 301 => "Moved Permanently",
35
+ 302 => "Found",
36
+ 303 => "See Other",
37
+ 304 => "Not Modified",
38
+ 305 => "Use Proxy",
39
+ 306 => "Switch Proxy",
40
+ 307 => "Temporary Redirect",
41
+ 400 => "Bad Request",
42
+ 401 => "Unauthorized",
43
+ 402 => "Payment Required",
44
+ 403 => "Forbidden",
45
+ 404 => "Not Found",
46
+ 405 => "Method Not Allowed",
47
+ 406 => "Not Acceptable",
48
+ 407 => "Proxy Authentication Required",
49
+ 408 => "Request Timeout",
50
+ 409 => "Conflict",
51
+ 410 => "Gone",
52
+ 411 => "Length Required",
53
+ 412 => "Precondition Failed",
54
+ 413 => "Request Entity Too Large",
55
+ 414 => "Request-URI Too Long",
56
+ 415 => "Unsupported Media Type",
57
+ 416 => "Requested Range Not Satisfiable",
58
+ 417 => "Expectation Failed",
59
+ 418 => "I'm a teapot",
60
+ 421 => "There are too many connections from your internet address",
61
+ 422 => "Unprocessable Entity",
62
+ 423 => "Locked",
63
+ 424 => "Failed Dependency",
64
+ 425 => "Unordered Collection",
65
+ 426 => "Upgrade Required",
66
+ 449 => "Retry With",
67
+ 450 => "Blocked by Windows Parental Controls",
68
+ 500 => "Internal Server Error",
69
+ 501 => "Not Implemented",
70
+ 502 => "Bad Gateway",
71
+ 503 => "Service Unavailable",
72
+ 504 => "Gateway Timeout",
73
+ 505 => "HTTP Version Not Supported",
74
+ 506 => "Variant Also Negotiates",
75
+ 507 => "Insufficient Storage",
76
+ 509 => "Bandwidth Limit Exceeded",
77
+ 510 => "Not Extended",
78
+ 530 => "User access denied"
79
+ }.freeze
80
+ end
81
+ end
82
+ end
@@ -0,0 +1,18 @@
1
+ module Akephalos
2
+ class Client
3
+ class Listener
4
+ include com.gargoylesoftware.htmlunit.WebWindowListener
5
+
6
+ def initialize(client)
7
+ @client = client
8
+ end
9
+
10
+ def webWindowClosed(event)
11
+ end
12
+
13
+ def webWindowContentChanged(event)
14
+ @client.page = event.getNewPage
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,22 @@
1
+ module Akephalos
2
+ def self.configuration
3
+ @configuration ||= {}
4
+ end
5
+
6
+ def self.configuration=(config)
7
+ @configuration = config
8
+ end
9
+
10
+ module Filters
11
+ def filters
12
+ configuration[:filters] ||= []
13
+ end
14
+
15
+ def filter(method, regex, options = {})
16
+ regex = Regexp.new(Regexp.escape(regex)) if regex.is_a?(String)
17
+ filters << {:method => method, :filter => regex, :status => 200, :body => "", :headers => {}}.merge!(options)
18
+ end
19
+ end
20
+
21
+ extend Filters
22
+ end
@@ -9,20 +9,23 @@ require "commons-io-1.4.jar"
9
9
  require "commons-lang-2.4.jar"
10
10
  require "commons-logging-1.1.1.jar"
11
11
  require "cssparser-0.9.5.jar"
12
- require "htmlunit-2.6.jar"
13
- require "htmlunit-core-js-2.6.jar"
14
- require "nekohtml-1.9.13.jar"
12
+ require "htmlunit-2.7.jar"
13
+ require "htmlunit-core-js-2.7.jar"
14
+ require "nekohtml-1.9.14.jar"
15
15
  require "sac-1.3.jar"
16
16
  require "serializer-2.7.1.jar"
17
17
  require "xalan-2.7.1.jar"
18
18
  require "xercesImpl-2.9.1.jar"
19
19
  require "xml-apis-1.3.04.jar"
20
20
 
21
- logger = org.apache.commons.logging.LogFactory.getLog('com.gargoylesoftware.htmlunit')
22
- logger.getLogger().setLevel(java.util.logging.Level::SEVERE)
21
+ java.lang.System.setProperty("org.apache.commons.logging.Log", "org.apache.commons.logging.impl.SimpleLog")
22
+ java.lang.System.setProperty("org.apache.commons.logging.simplelog.defaultlog", "fatal")
23
+ java.lang.System.setProperty("org.apache.commons.logging.simplelog.showdatetime", "true")
23
24
 
24
25
  java_import "com.gargoylesoftware.htmlunit.WebClient"
26
+ java_import "com.gargoylesoftware.htmlunit.util.WebConnectionWrapper"
27
+ java_import 'com.gargoylesoftware.htmlunit.HttpMethod'
25
28
 
26
29
  com.gargoylesoftware.htmlunit.BrowserVersion.setDefault(
27
- com.gargoylesoftware.htmlunit.BrowserVersion::FIREFOX_3
30
+ com.gargoylesoftware.htmlunit.BrowserVersion::FIREFOX_3
28
31
  )
@@ -0,0 +1,18 @@
1
+ class HttpMethod
2
+ def ===(other)
3
+ case other
4
+ when HttpMethod
5
+ super
6
+ when :any
7
+ true
8
+ when :get
9
+ self == self.class::GET
10
+ when :post
11
+ self == self.class::POST
12
+ when :put
13
+ self == self.class::PUT
14
+ when :delete
15
+ self == self.class::DELETE
16
+ end
17
+ end
18
+ end
@@ -1,6 +1,7 @@
1
1
  module Akephalos
2
2
  class Node
3
3
  def initialize(node)
4
+ @nodes = []
4
5
  @_node = node
5
6
  end
6
7
 
@@ -64,7 +65,9 @@ module Akephalos
64
65
  end
65
66
 
66
67
  def find(selector)
67
- @_node.getByXPath(selector).map { |node| Node.new(node) }
68
+ nodes = @_node.getByXPath(selector).map { |node| Node.new(node) }
69
+ @nodes << nodes
70
+ nodes
68
71
  end
69
72
  end
70
73
  end
@@ -1,5 +1,7 @@
1
1
  require 'drb/drb'
2
2
 
3
+ class NativeException < StandardError; end
4
+
3
5
  module Akephalos
4
6
  class RemoteClient
5
7
  @socket_file = "/tmp/akephalos.#{Process.pid}.sock"
@@ -17,7 +19,9 @@ module Akephalos
17
19
  def self.new
18
20
  start!
19
21
  DRb.start_service
20
- DRbObject.new_with_uri("drbunix://#{@socket_file}")
22
+ client = DRbObject.new_with_uri("drbunix://#{@socket_file}")
23
+ client.configuration = Akephalos.configuration.extend(DRbUndumped)
24
+ client
21
25
  end
22
26
  end
23
27
  end
@@ -0,0 +1,24 @@
1
+ require 'spec_helper'
2
+
3
+ describe "Filters" do
4
+ before do
5
+ @session = Capybara::Session.new(:akephalos, TestApp)
6
+ end
7
+
8
+ context "with no filter" do
9
+ it "returns the page's source" do
10
+ @session.visit "/"
11
+ @session.source.should == "Hello world!"
12
+ end
13
+ end
14
+
15
+ context "with a filter" do
16
+ after { Akephalos.filters.clear }
17
+
18
+ it "returns the filter's source" do
19
+ Akephalos.filter :get, %r{.*}, :body => "Howdy!"
20
+ @session.visit "/"
21
+ @session.source.should == "Howdy!"
22
+ end
23
+ end
24
+ end
Binary file
Binary file
metadata CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
5
5
  segments:
6
6
  - 0
7
7
  - 0
8
- - 4
9
- version: 0.0.4
8
+ - 5
9
+ version: 0.0.5
10
10
  platform: ruby
11
11
  authors:
12
12
  - Bernerd Schaefer
@@ -14,7 +14,7 @@ autorequire:
14
14
  bindir: bin
15
15
  cert_chain: []
16
16
 
17
- date: 2010-06-15 00:00:00 -05:00
17
+ date: 2010-06-24 00:00:00 -05:00
18
18
  default_executable: akephalos
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency
@@ -76,14 +76,19 @@ files:
76
76
  - lib/akephalos.rb
77
77
  - lib/akephalos/capybara.rb
78
78
  - lib/akephalos/client.rb
79
+ - lib/akephalos/client/filter.rb
80
+ - lib/akephalos/client/listener.rb
81
+ - lib/akephalos/configuration.rb
79
82
  - lib/akephalos/console.rb
80
83
  - lib/akephalos/cucumber.rb
81
84
  - lib/akephalos/htmlunit.rb
85
+ - lib/akephalos/htmlunit/ext/http_method.rb
82
86
  - lib/akephalos/node.rb
83
87
  - lib/akephalos/page.rb
84
88
  - lib/akephalos/remote_client.rb
85
89
  - lib/akephalos/server.rb
86
90
  - spec/driver/akephalos_driver_spec.rb
91
+ - spec/filter_spec.rb
87
92
  - spec/session/akephalos_session_spec.rb
88
93
  - spec/slow_page_loads_spec.rb
89
94
  - spec/spec.opts
@@ -95,10 +100,10 @@ files:
95
100
  - src/commons-lang-2.4.jar
96
101
  - src/commons-logging-1.1.1.jar
97
102
  - src/cssparser-0.9.5.jar
98
- - src/htmlunit-2.6.jar
99
- - src/htmlunit-core-js-2.6.jar
103
+ - src/htmlunit-2.7.jar
104
+ - src/htmlunit-core-js-2.7.jar
100
105
  - src/jruby-complete-1.5.0.jar
101
- - src/nekohtml-1.9.13.jar
106
+ - src/nekohtml-1.9.14.jar
102
107
  - src/sac-1.3.jar
103
108
  - src/serializer-2.7.1.jar
104
109
  - src/xalan-2.7.1.jar
@@ -136,6 +141,7 @@ specification_version: 3
136
141
  summary: ""
137
142
  test_files:
138
143
  - spec/driver/akephalos_driver_spec.rb
144
+ - spec/filter_spec.rb
139
145
  - spec/session/akephalos_session_spec.rb
140
146
  - spec/slow_page_loads_spec.rb
141
147
  - spec/spec_helper.rb
Binary file
Binary file
Binary file