js_spec 0.3.1 → 0.3.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (72) hide show
  1. data/CHANGES +3 -0
  2. data/Rakefile +3 -2
  3. data/vendor/js-test-core/CHANGES +15 -0
  4. data/vendor/js-test-core/README +12 -0
  5. data/vendor/js-test-core/Rakefile +72 -0
  6. data/vendor/js-test-core/lib/js_test_core.rb +38 -0
  7. data/vendor/js-test-core/lib/js_test_core/client.rb +114 -0
  8. data/vendor/js-test-core/lib/js_test_core/extensions.rb +3 -0
  9. data/vendor/js-test-core/lib/js_test_core/extensions/time.rb +6 -0
  10. data/vendor/js-test-core/lib/js_test_core/rack.rb +2 -0
  11. data/vendor/js-test-core/lib/js_test_core/rack/commonlogger.rb +5 -0
  12. data/vendor/js-test-core/lib/js_test_core/rails_server.rb +22 -0
  13. data/vendor/js-test-core/lib/js_test_core/resources.rb +10 -0
  14. data/vendor/js-test-core/lib/js_test_core/resources/dir.rb +67 -0
  15. data/vendor/js-test-core/lib/js_test_core/resources/file.rb +40 -0
  16. data/vendor/js-test-core/lib/js_test_core/resources/file_not_found.rb +11 -0
  17. data/vendor/js-test-core/lib/js_test_core/resources/runner.rb +105 -0
  18. data/vendor/js-test-core/lib/js_test_core/resources/specs/spec_dir.rb +46 -0
  19. data/vendor/js-test-core/lib/js_test_core/resources/specs/spec_file.rb +17 -0
  20. data/vendor/js-test-core/lib/js_test_core/resources/suite.rb +40 -0
  21. data/vendor/js-test-core/lib/js_test_core/resources/suite_finish.rb +17 -0
  22. data/vendor/js-test-core/lib/js_test_core/resources/web_root.rb +63 -0
  23. data/vendor/js-test-core/lib/js_test_core/selenium.rb +2 -0
  24. data/vendor/js-test-core/lib/js_test_core/selenium/selenium_driver.rb +5 -0
  25. data/vendor/js-test-core/lib/js_test_core/selenium_server_configuration.rb +48 -0
  26. data/vendor/js-test-core/lib/js_test_core/server.rb +50 -0
  27. data/vendor/js-test-core/lib/js_test_core/thin.rb +3 -0
  28. data/vendor/js-test-core/lib/js_test_core/thin/backends/js_test_core_server.rb +9 -0
  29. data/vendor/js-test-core/lib/js_test_core/thin/js_test_core_connection.rb +8 -0
  30. data/vendor/js-test-core/spec/example_core/JsTestCore.css +0 -0
  31. data/vendor/js-test-core/spec/example_core/JsTestCore.js +0 -0
  32. data/vendor/js-test-core/spec/example_public/favicon.ico +0 -0
  33. data/vendor/js-test-core/spec/example_public/javascripts/foo.js +3 -0
  34. data/vendor/js-test-core/spec/example_public/javascripts/large_file.js +59 -0
  35. data/vendor/js-test-core/spec/example_public/javascripts/subdir/bar.js +1 -0
  36. data/vendor/js-test-core/spec/example_public/robots.txt +0 -0
  37. data/vendor/js-test-core/spec/example_public/stylesheets/example.css +3 -0
  38. data/vendor/js-test-core/spec/example_specs/failing_spec.js +5 -0
  39. data/vendor/js-test-core/spec/example_specs/foo/failing_spec.js +6 -0
  40. data/vendor/js-test-core/spec/example_specs/foo/passing_spec.js +6 -0
  41. data/vendor/js-test-core/spec/spec_suite.rb +2 -0
  42. data/vendor/js-test-core/spec/specs/failing_spec.js +0 -0
  43. data/vendor/js-test-core/spec/unit/js_test_core/client_spec.rb +166 -0
  44. data/vendor/js-test-core/spec/unit/js_test_core/rails_server_spec.rb +45 -0
  45. data/vendor/js-test-core/spec/unit/js_test_core/resources/dir_spec.rb +52 -0
  46. data/vendor/js-test-core/spec/unit/js_test_core/resources/file_not_found_spec.rb +16 -0
  47. data/vendor/js-test-core/spec/unit/js_test_core/resources/file_spec.rb +90 -0
  48. data/vendor/js-test-core/spec/unit/js_test_core/resources/runners/runner_spec.rb +283 -0
  49. data/vendor/js-test-core/spec/unit/js_test_core/resources/specs/spec_dir_spec.rb +105 -0
  50. data/vendor/js-test-core/spec/unit/js_test_core/resources/specs/spec_file_spec.rb +42 -0
  51. data/vendor/js-test-core/spec/unit/js_test_core/resources/suite_finish_spec.rb +82 -0
  52. data/vendor/js-test-core/spec/unit/js_test_core/resources/suite_spec.rb +86 -0
  53. data/vendor/js-test-core/spec/unit/js_test_core/resources/web_root_spec.rb +32 -0
  54. data/vendor/js-test-core/spec/unit/js_test_core/selenium_server_configuration_spec.rb +49 -0
  55. data/vendor/js-test-core/spec/unit/js_test_core/server_spec.rb +117 -0
  56. data/vendor/js-test-core/spec/unit/thin/js_test_core_connection_spec.rb +6 -0
  57. data/vendor/js-test-core/spec/unit/unit_spec_helper.rb +134 -0
  58. data/vendor/js-test-core/spec/unit_suite.rb +10 -0
  59. data/vendor/js-test-core/vendor/thin-rest/CHANGES +2 -0
  60. data/vendor/js-test-core/vendor/thin-rest/README +0 -0
  61. data/vendor/js-test-core/vendor/thin-rest/lib/thin_rest.rb +9 -0
  62. data/vendor/js-test-core/vendor/thin-rest/lib/thin_rest/connection.rb +116 -0
  63. data/vendor/js-test-core/vendor/thin-rest/lib/thin_rest/extensions.rb +3 -0
  64. data/vendor/js-test-core/vendor/thin-rest/lib/thin_rest/extensions/object.rb +21 -0
  65. data/vendor/js-test-core/vendor/thin-rest/lib/thin_rest/resource.rb +104 -0
  66. data/vendor/js-test-core/vendor/thin-rest/lib/thin_rest/resource_invalid.rb +4 -0
  67. data/vendor/js-test-core/vendor/thin-rest/lib/thin_rest/routing_error.rb +5 -0
  68. data/vendor/js-test-core/vendor/thin-rest/spec/spec_suite.rb +5 -0
  69. data/vendor/js-test-core/vendor/thin-rest/spec/thin_rest/connection_spec.rb +207 -0
  70. data/vendor/js-test-core/vendor/thin-rest/spec/thin_rest/resource_spec.rb +127 -0
  71. data/vendor/js-test-core/vendor/thin-rest/spec/thin_rest_spec_helper.rb +124 -0
  72. metadata +120 -17
@@ -0,0 +1,11 @@
1
+ module JsTestCore
2
+ module Resources
3
+ class FileNotFound < ThinRest::Resource
4
+ property :name
5
+ def get
6
+ connection.send_head(404)
7
+ connection.send_body("")
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,105 @@
1
+ module JsTestCore
2
+ module Resources
3
+ class Runner < ThinRest::Resource
4
+ class Collection < ThinRest::Resource
5
+ property :selenium_browser_start_command
6
+ route 'firefox' do |env, name|
7
+ self.selenium_browser_start_command = "*firefox"
8
+ self
9
+ end
10
+ route 'iexplore' do |env, name|
11
+ self.selenium_browser_start_command = "*iexplore"
12
+ self
13
+ end
14
+
15
+ def after_initialize
16
+ super
17
+ self.selenium_browser_start_command = rack_request['selenium_browser_start_command']
18
+ end
19
+
20
+ def post
21
+ spec_url = rack_request['spec_url'].to_s == "" ? spec_suite_url : rack_request['spec_url']
22
+ parsed_spec_url = URI.parse(spec_url)
23
+ selenium_host = rack_request['selenium_host'].to_s == "" ? 'localhost' : rack_request['selenium_host'].to_s
24
+ selenium_port = rack_request['selenium_port'].to_s == "" ? 4444 : Integer(rack_request['selenium_port'])
25
+ http_address = "#{parsed_spec_url.scheme}://#{parsed_spec_url.host}:#{parsed_spec_url.port}"
26
+ driver = Selenium::SeleniumDriver.new(
27
+ selenium_host,
28
+ selenium_port,
29
+ selenium_browser_start_command,
30
+ http_address
31
+ )
32
+ begin
33
+ driver.start
34
+ rescue Errno::ECONNREFUSED => e
35
+ raise Errno::ECONNREFUSED, "Cannot connect to Selenium Server at #{http_address}. To start the selenium server, run `selenium`."
36
+ end
37
+ Thread.start do
38
+ driver.open(spec_url)
39
+ end
40
+ runner = Runner.new(:driver => driver)
41
+ Runner.register(runner)
42
+ connection.send_head
43
+ connection.send_body("suite_id=#{runner.suite_id}")
44
+ end
45
+
46
+ protected
47
+ def spec_suite_url
48
+ "#{Server.root_url}/specs"
49
+ end
50
+ end
51
+
52
+ class << self
53
+ def find(id)
54
+ instances[id.to_s]
55
+ end
56
+
57
+ def finalize(suite_id, text)
58
+ if runner = find(suite_id)
59
+ runner.finalize(text)
60
+ end
61
+ end
62
+
63
+ def register(runner)
64
+ instances[runner.suite_id] = runner
65
+ end
66
+
67
+ protected
68
+ def instances
69
+ @instances ||= {}
70
+ end
71
+ end
72
+
73
+ include FileUtils
74
+ property :driver
75
+ attr_reader :profile_dir, :suite_run_result
76
+
77
+ def after_initialize
78
+ profile_base = "#{::Dir.tmpdir}/js_test_core/#{self.class.name}"
79
+ mkdir_p profile_base
80
+ @profile_dir = "#{profile_base}/#{Time.now.to_i}"
81
+ end
82
+
83
+ def finalize(suite_run_result)
84
+ driver.stop
85
+ @suite_run_result = suite_run_result
86
+ end
87
+
88
+ def running?
89
+ suite_run_result.nil?
90
+ end
91
+
92
+ def successful?
93
+ !running? && suite_run_result.empty?
94
+ end
95
+
96
+ def failed?
97
+ !running? && !successful?
98
+ end
99
+
100
+ def suite_id
101
+ driver.session_id
102
+ end
103
+ end
104
+ end
105
+ end
@@ -0,0 +1,46 @@
1
+ module JsTestCore
2
+ module Resources
3
+ module Specs
4
+ class SpecDirSuperclass < ::JsTestCore::Resources::Dir
5
+ def get
6
+ raise NotImplementedError, "#{self.class}#get needs to be implemented"
7
+ end
8
+ end
9
+
10
+ class SpecDir < SpecDirSuperclass
11
+ def spec_files
12
+ glob("/**/*_spec.js")
13
+ end
14
+
15
+ route ANY do |env, name|
16
+ if result = (file(name) || subdir(name) || spec_file(name))
17
+ result
18
+ else
19
+ base_path = "#{relative_path}/#{name}"
20
+ raise "No file or directory found at #{base_path} or spec found at #{base_path}.js."
21
+ end
22
+ end
23
+
24
+ protected
25
+
26
+ def subdir(name)
27
+ absolute_path, relative_path = determine_child_paths(name)
28
+ if ::File.directory?(absolute_path)
29
+ SpecDir.new(env.merge(:absolute_path => absolute_path, :relative_path => relative_path))
30
+ else
31
+ nil
32
+ end
33
+ end
34
+
35
+ def spec_file(name)
36
+ absolute_path, relative_path = determine_child_paths("#{name}.js")
37
+ if ::File.exists?(absolute_path) && !::File.directory?(absolute_path)
38
+ SpecFile.new(env.merge(:absolute_path => absolute_path, :relative_path => relative_path))
39
+ else
40
+ nil
41
+ end
42
+ end
43
+ end
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,17 @@
1
+ module JsTestCore
2
+ module Resources
3
+ module Specs
4
+ class SpecFileSuperclass < ::JsTestCore::Resources::File
5
+ def get
6
+ raise NotImplementedError, "#{self.class}#get needs to be implemented"
7
+ end
8
+ end
9
+
10
+ class SpecFile < SpecFileSuperclass
11
+ def spec_files
12
+ [self]
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,40 @@
1
+ module JsTestCore
2
+ module Resources
3
+ class Suite < ThinRest::Resource
4
+ class Collection < ThinRest::Resource
5
+ route ANY do |env, id|
6
+ Suite.new(env.merge(:id => id))
7
+ end
8
+ end
9
+
10
+ RUNNING = 'running'
11
+ SUCCESSFUL_COMPLETION = 'success'
12
+ FAILURE_COMPLETION = 'failure'
13
+
14
+ property :id
15
+
16
+ def get
17
+ runner = Runner.find(id)
18
+ if runner
19
+ connection.send_head
20
+ if runner.running?
21
+ connection.send_body("status=#{RUNNING}")
22
+ else
23
+ if runner.successful?
24
+ connection.send_body("status=#{SUCCESSFUL_COMPLETION}")
25
+ else
26
+ connection.send_body("status=#{FAILURE_COMPLETION}&reason=#{runner.suite_run_result}")
27
+ end
28
+ end
29
+ else
30
+ connection.send_head(404)
31
+ connection.send_body("")
32
+ end
33
+ end
34
+
35
+ route 'finish' do |env, name|
36
+ SuiteFinish.new(env.merge(:suite => self))
37
+ end
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,17 @@
1
+ module JsTestCore
2
+ module Resources
3
+ class SuiteFinish < ThinRest::Resource
4
+ property :suite
5
+
6
+ def post
7
+ if suite.id == 'user'
8
+ STDOUT.puts rack_request['text']
9
+ else
10
+ Runner.finalize(suite.id, rack_request['text'])
11
+ end
12
+ connection.send_head
13
+ connection.send_body("")
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,63 @@
1
+ module JsTestCore
2
+ module Resources
3
+ class WebRoot < ThinRest::Resource
4
+ route "" do |env, name|
5
+ self
6
+ end
7
+ route "core" do |env, name|
8
+ Resources::Dir.new(env.merge(
9
+ :absolute_path => JsTestCore::Server.core_path,
10
+ :relative_path => "/core"
11
+ ))
12
+ end
13
+ route "implementations" do |env, name|
14
+ Resources::Dir.new(env.merge(
15
+ :absolute_path => JsTestCore::Server.implementation_root_path,
16
+ :relative_path => "/implementations"
17
+ ))
18
+ end
19
+ route "suites", "JsTestCore::Resources::Suite::Collection"
20
+ route "runners", "JsTestCore::Resources::Runner::Collection"
21
+ route "specs" do |env, name|
22
+ if self.class.dispatch_strategy == :specs
23
+ Resources::Specs::SpecDir.new(env.merge(
24
+ :absolute_path => JsTestCore::Server.spec_root_path,
25
+ :relative_path => "/specs"
26
+ ))
27
+ else
28
+ Resources::FileNotFound.new(env.merge(:name => name))
29
+ end
30
+ end
31
+ route ANY do |env, name|
32
+ potential_file_in_public_path = "#{public_path}/#{name}"
33
+ if ::File.directory?(potential_file_in_public_path)
34
+ Resources::Dir.new(env.merge(
35
+ :absolute_path => potential_file_in_public_path,
36
+ :relative_path => "/#{name}"
37
+ ))
38
+ elsif ::File.exists?(potential_file_in_public_path)
39
+ Resources::File.new(env.merge(
40
+ :absolute_path => potential_file_in_public_path,
41
+ :relative_path => "/#{name}"
42
+ ))
43
+ else
44
+ Resources::FileNotFound.new(env.merge(:name => name))
45
+ end
46
+ end
47
+
48
+ class << self
49
+ attr_accessor :dispatch_strategy
50
+ def dispatch_specs
51
+ self.dispatch_strategy = :specs
52
+ end
53
+ end
54
+
55
+ property :public_path
56
+
57
+ def get
58
+ connection.send_head(301, :Location => "/#{self.class.dispatch_strategy}")
59
+ connection.send_body("<script type='text/javascript'>window.location.href='/specs';</script>")
60
+ end
61
+ end
62
+ end
63
+ end
@@ -0,0 +1,2 @@
1
+ dir = File.dirname(__FILE__)
2
+ require "#{dir}/selenium/selenium_driver"
@@ -0,0 +1,5 @@
1
+ module Selenium
2
+ class SeleniumDriver
3
+ attr_reader :session_id
4
+ end
5
+ end
@@ -0,0 +1,48 @@
1
+ module JsTestCore
2
+ class SeleniumServerConfiguration
3
+ attr_reader :parameters
4
+
5
+ class << self
6
+ def query_string_from(*args, &block)
7
+ new(*args, &block).query_string
8
+ end
9
+ end
10
+
11
+ def initialize(parameters={})
12
+ @parameters = parameters
13
+ end
14
+
15
+
16
+ def query_string
17
+ parts = [selenium_browser_start_command, selenium_host, selenium_port]
18
+ parts << spec_url if url
19
+ parts.join('&')
20
+ end
21
+
22
+ private
23
+
24
+ def selenium_browser_start_command
25
+ "selenium_browser_start_command=#{parameter_or_default_for(:selenium_browser_start_command, '*firefox')}"
26
+ end
27
+
28
+ def selenium_host
29
+ "selenium_host=#{parameter_or_default_for(:selenium_host, 'localhost')}"
30
+ end
31
+
32
+ def selenium_port
33
+ "selenium_port=#{parameter_or_default_for(:selenium_port, 4444)}"
34
+ end
35
+
36
+ def spec_url
37
+ "spec_url=#{url}"
38
+ end
39
+
40
+ def url
41
+ parameters[:spec_url]
42
+ end
43
+
44
+ def parameter_or_default_for(parameter_name, default = nil)
45
+ CGI.escape((parameters[parameter_name] || default).to_s)
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,50 @@
1
+ module JsTestCore
2
+ class Server
3
+ class << self
4
+ attr_accessor :instance
5
+
6
+ def run(spec_root_path, implementation_root_path, public_path, server_options = {})
7
+ server_options[:Host] ||= DEFAULT_HOST
8
+ server_options[:Port] ||= DEFAULT_PORT
9
+ @instance = new(spec_root_path, implementation_root_path, public_path, server_options[:Host], server_options[:Port])
10
+ instance.run server_options
11
+ end
12
+
13
+ def spec_root_path; instance.spec_root_path; end
14
+ def implementation_root_path; instance.implementation_root_path; end
15
+ def public_path; instance.public_path; end
16
+ def core_path; instance.core_path; end
17
+ def request; instance.request; end
18
+ def response; instance.response; end
19
+ def root_url; instance.root_url; end
20
+ end
21
+
22
+ attr_reader :host, :port, :spec_root_path, :implementation_root_path, :public_path
23
+
24
+ def initialize(spec_root_path, implementation_root_path, public_path, host=DEFAULT_HOST, port=DEFAULT_PORT)
25
+ dir = ::File.dirname(__FILE__)
26
+ @spec_root_path = ::File.expand_path(spec_root_path)
27
+ @implementation_root_path = ::File.expand_path(implementation_root_path)
28
+ @public_path = ::File.expand_path(public_path)
29
+ @host = host
30
+ @port = port
31
+ end
32
+
33
+ def run(options)
34
+ server = ::Thin::Server.new(options[:Host], options[:Port]) do
35
+ use Rack::CommonLogger
36
+ end
37
+ server.backend = ::Thin::Backends::JsTestCoreServer.new(options[:Host], options[:Port])
38
+ server.backend.server = server
39
+ server.start!
40
+ end
41
+
42
+ def root_url
43
+ "http://#{host}:#{port}"
44
+ end
45
+
46
+ def core_path
47
+ JsTestCore.core_path
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,3 @@
1
+ dir = File.dirname(__FILE__)
2
+ require "#{dir}/thin/js_test_core_connection"
3
+ require "#{dir}/thin/backends/js_test_core_server"
@@ -0,0 +1,9 @@
1
+ module Thin
2
+ module Backends
3
+ class JsTestCoreServer < TcpServer
4
+ def connect
5
+ @signature = EventMachine.start_server(@host, @port, JsTestCoreConnection, &method(:initialize_connection))
6
+ end
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,8 @@
1
+ module Thin
2
+ class JsTestCoreConnection < ThinRest::Connection
3
+ protected
4
+ def root_resource
5
+ ::JsTestCore::Resources::WebRoot.new(:connection => self, :public_path => ::JsTestCore::Server.public_path)
6
+ end
7
+ end
8
+ end