yarn 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (74) hide show
  1. data/.gitignore +1 -0
  2. data/Gemfile +0 -3
  3. data/README.md +25 -1
  4. data/bin/yarn +6 -4
  5. data/features/concurrency.feature +4 -4
  6. data/features/dynamic_request.feature +6 -1
  7. data/features/rack.feature +5 -8
  8. data/features/static_request.feature +2 -2
  9. data/features/step_definitions/rack_steps.rb +13 -0
  10. data/features/step_definitions/server_steps.rb +5 -5
  11. data/features/step_definitions/web_steps.rb +8 -0
  12. data/lib/rack/handler/yarn.rb +4 -3
  13. data/lib/yarn/error_page.rb +2 -1
  14. data/lib/yarn/logging.rb +1 -1
  15. data/lib/yarn/parslet_parser.rb +9 -24
  16. data/lib/yarn/rack_handler.rb +11 -9
  17. data/lib/yarn/request_handler.rb +21 -12
  18. data/lib/yarn/server.rb +39 -30
  19. data/lib/yarn/version.rb +1 -1
  20. data/spec/helpers.rb +16 -8
  21. data/spec/rack/handler/yarn_spec.rb +21 -0
  22. data/spec/spec_helper.rb +1 -4
  23. data/spec/yarn/directory_lister_spec.rb +0 -5
  24. data/spec/yarn/logging_spec.rb +3 -2
  25. data/spec/yarn/parslet_parser_spec.rb +26 -0
  26. data/spec/yarn/rack_handler_spec.rb +15 -4
  27. data/spec/yarn/request_handler_spec.rb +17 -7
  28. data/spec/yarn/server_spec.rb +49 -8
  29. data/test_objects/.gitignore +1 -0
  30. data/test_objects/app.rb +0 -2
  31. data/test_objects/config.ru +1 -49
  32. data/test_objects/rails_test/.gitignore +5 -0
  33. data/test_objects/rails_test/Gemfile +34 -0
  34. data/test_objects/rails_test/README +261 -0
  35. data/test_objects/rails_test/Rakefile +7 -0
  36. data/test_objects/rails_test/app/assets/images/rails.png +0 -0
  37. data/test_objects/rails_test/app/assets/javascripts/application.js +6 -0
  38. data/test_objects/rails_test/app/assets/stylesheets/application.css +7 -0
  39. data/test_objects/rails_test/app/assets/stylesheets/scaffolds.css.scss +56 -0
  40. data/test_objects/rails_test/app/mailers/.gitkeep +0 -0
  41. data/test_objects/rails_test/app/models/.gitkeep +0 -0
  42. data/test_objects/rails_test/app/views/layouts/application.html.erb +15 -0
  43. data/test_objects/rails_test/app/views/posts/_form.html.erb +25 -0
  44. data/test_objects/rails_test/app/views/posts/edit.html.erb +6 -0
  45. data/test_objects/rails_test/app/views/posts/index.html.erb +20 -0
  46. data/test_objects/rails_test/app/views/posts/new.html.erb +5 -0
  47. data/test_objects/rails_test/app/views/posts/show.html.erb +15 -0
  48. data/test_objects/rails_test/config.ru +4 -0
  49. data/test_objects/rails_test/config/database.yml +25 -0
  50. data/test_objects/rails_test/config/locales/en.yml +5 -0
  51. data/test_objects/rails_test/doc/README_FOR_APP +2 -0
  52. data/test_objects/rails_test/lib/assets/.gitkeep +0 -0
  53. data/test_objects/rails_test/lib/tasks/.gitkeep +0 -0
  54. data/test_objects/rails_test/log/.gitkeep +0 -0
  55. data/test_objects/rails_test/public/404.html +26 -0
  56. data/test_objects/rails_test/public/422.html +26 -0
  57. data/test_objects/rails_test/public/500.html +26 -0
  58. data/test_objects/rails_test/public/favicon.ico +0 -0
  59. data/test_objects/rails_test/public/robots.txt +5 -0
  60. data/test_objects/rails_test/script/rails +6 -0
  61. data/test_objects/rails_test/test/fixtures/.gitkeep +0 -0
  62. data/test_objects/rails_test/test/fixtures/posts.yml +9 -0
  63. data/test_objects/rails_test/test/functional/.gitkeep +0 -0
  64. data/test_objects/rails_test/test/integration/.gitkeep +0 -0
  65. data/test_objects/rails_test/test/unit/.gitkeep +0 -0
  66. data/test_objects/rails_test/vendor/assets/stylesheets/.gitkeep +0 -0
  67. data/test_objects/rails_test/vendor/plugins/.gitkeep +0 -0
  68. data/yarn.gemspec +4 -8
  69. metadata +59 -59
  70. data/lib/yarn/worker.rb +0 -19
  71. data/lib/yarn/worker_pool.rb +0 -36
  72. data/spec/yarn/worker_pool_spec.rb +0 -23
  73. data/spec/yarn/worker_spec.rb +0 -26
  74. data/test_objects/simple_rack.rb +0 -12
@@ -1,3 +1,3 @@
1
1
  module Yarn
2
- VERSION = "0.0.1"
2
+ VERSION = "0.0.2"
3
3
  end
@@ -12,22 +12,28 @@ module Helpers
12
12
 
13
13
  def get(url)
14
14
  setup
15
- @connection.get "test_objects#{url}"
15
+ if url == ""
16
+ @connection.get "/"
17
+ else
18
+ @connection.get "test_objects#{url}"
19
+ end
16
20
  end
17
21
 
18
- def post(url, params={})
22
+ def post(url, data)
19
23
  setup
20
- @connection.post url, params
24
+ @connection.post url, data
21
25
  end
22
26
 
23
27
  def stop_server
24
28
  @thread.kill if @thread
29
+ @server.workers.each { |worker_id| Process.kill("INT", worker_id) } if @server and !@server.workers.empty?
25
30
  @server.stop if @server
31
+ sleep 0.1 # enable socket to close before next test
26
32
  end
27
33
 
28
- def start_server(port=3000,handler=:static)
29
- $console = MockIO.new
30
- @server = Yarn::Server.new({ port: port, output: $console })
34
+ def start_server(port=3000,rack="off")
35
+ $console ||= MockIO.new
36
+ @server = Yarn::Server.new({ port: port, output: $console, rack: rack, debug: true })
31
37
  @thread = Thread.new { @server.start }
32
38
  sleep 0.1 until @server.socket # wait for socket to be created
33
39
  end
@@ -49,8 +55,10 @@ module Helpers
49
55
  private
50
56
 
51
57
  def setup
52
- host = URI.parse("http://#{@server.host}:#{@server.port}")
53
- @connection ||= Faraday.new(host)
58
+ host = "127.0.0.1"
59
+ port = "3000"
60
+ uri = URI.parse("http://#{host}:#{port}")
61
+ @connection = Faraday.new(uri)
54
62
  end
55
63
  end
56
64
 
@@ -0,0 +1,21 @@
1
+ require 'spec_helper'
2
+
3
+ module Rack
4
+ module Handler
5
+
6
+ include Helpers
7
+
8
+ # describe Yarn do
9
+ # after do
10
+ # @thread.kill
11
+ # end
12
+
13
+ # it "should start the server" do
14
+ # @thread = Thread.new { Yarn.run("test_objects/config.ru") }
15
+ # response = get("/").body
16
+ # response.gsub(/\n?/,"").should == "Rack works"
17
+ # end
18
+ # end
19
+ end
20
+ end
21
+
@@ -2,21 +2,18 @@ $LOAD_PATH << File.expand_path('../../../lib', __FILE__)
2
2
 
3
3
  require 'rubygems'
4
4
  require 'bundler/setup'
5
- require 'fakefs'
6
5
 
7
6
  # unless /jruby/ =~ `ruby -v`
8
7
  require 'simplecov'
9
8
  SimpleCov.start do
10
- FakeFS.deactivate!
11
9
  add_filter "/spec/"
12
10
  add_filter "lib/yarn/http*"
13
11
  end
14
12
  # end
15
13
 
16
- require 'capybara/rspec'
17
-
18
14
  require 'yarn'
19
15
  require 'helpers'
16
+ require 'pry'
20
17
 
21
18
  RSpec.configure do |config|
22
19
  config.include Helpers
@@ -5,10 +5,6 @@ module Yarn
5
5
 
6
6
  describe DirectoryLister do
7
7
 
8
- before(:each) do
9
- FakeFS.deactivate!
10
- end
11
-
12
8
  describe "#list" do
13
9
  it "returns valid HTML for a directory" do
14
10
  response = DirectoryLister.list("lib")
@@ -17,7 +13,6 @@ module Yarn
17
13
  end
18
14
 
19
15
  it "returns valid HTML a long path" do
20
- FakeFS.deactivate!
21
16
  response = DirectoryLister.list("lib/yarn")
22
17
  response.should_not be_nil
23
18
  valid_html?(response).should be_true
@@ -10,10 +10,10 @@ module Yarn
10
10
 
11
11
  describe "#log" do
12
12
  it "should make the logging methods available" do
13
- @server = Server.new(output: $output)
13
+ @server = Server.new(output: $output, debug: true)
14
14
  @server.should respond_to(:log)
15
15
  @server.should respond_to(:debug)
16
- @server.socket.close
16
+ @server.stop
17
17
  end
18
18
 
19
19
  it "should be available in the handler classes" do
@@ -41,6 +41,7 @@ module Yarn
41
41
 
42
42
  describe "#debug" do
43
43
  it "should invoke the log method with a message" do
44
+ $debug = true
44
45
  test_logger = TestLoggging.new
45
46
  test_logger.should_receive(:log).with("DEBUG: testing").once
46
47
 
@@ -56,6 +56,13 @@ module Yarn
56
56
  puts result
57
57
  result[:uri][:query].should == "param1=1&param2=2"
58
58
  end
59
+
60
+ it "should parse query on rails assets" do
61
+ result = @parser.run("GET assets/application.js?body=0 HTTP/1.1\n")
62
+ puts result
63
+ result[:uri][:query].should == "body=0"
64
+ result[:uri][:path].should == "assets/application.js"
65
+ end
59
66
  end
60
67
 
61
68
  describe "#parse headers" do
@@ -95,5 +102,24 @@ module Yarn
95
102
  end
96
103
  end
97
104
 
105
+ describe "#parse POST body" do
106
+ it "should parse POST body" do
107
+ header = "Cookie: $Version=1; Skin=new;"
108
+ body = "attr=test"
109
+ request = "POST /form HTTP/1.1\r\n#{header}\r\n\r\n#{body}"
110
+ result = @parser.run(request)
111
+ result[:body].should == body
112
+ end
113
+
114
+ it "should parse POST body with added line ending" do
115
+ header = "Cookie: $Version=1; Skin=new;"
116
+ body = "attr=test&attr2=some_other_value&attr3=1231682368125361823"
117
+ request = "POST /form HTTP/1.1\r\n#{header}\r\n\r\n#{body}"
118
+ result = @parser.run(request)
119
+ puts result
120
+ result[:body].should == body
121
+ end
122
+ end
123
+
98
124
  end
99
125
  end
@@ -3,15 +3,26 @@ require 'spec_helper'
3
3
  module Yarn
4
4
  describe RackHandler do
5
5
 
6
+ before(:each) do
7
+ @handler = RackHandler.new(nil)
8
+ @handler.request = @handler.parser.run "GET http://www.hostname.com:8888/some_controller/some_action?param1=1&param2=2 HTTP/1.1"
9
+ end
10
+
6
11
  describe "#prepare_response" do
7
-
12
+ it "should call make_env" do
13
+ @app.stub(:call).and_return([200, {}, []])
14
+ @handler.prepare_response
15
+ @handler.env.should_not be_nil
16
+ end
17
+
18
+ it "should call the rack app" do
19
+ @app.should_receive(:call)
20
+ @handler.prepare_response
21
+ end
8
22
  end
9
23
 
10
24
  describe "#make_env" do
11
-
12
25
  before(:each) do
13
- @handler = RackHandler.new(nil,{})
14
- @handler.request = @handler.parser.run "GET http://www.hostname.com:8888/some_controller/some_action?param1=1&param2=2 HTTP/1.1"
15
26
  @env = @handler.make_env
16
27
  end
17
28
 
@@ -25,6 +25,15 @@ module Yarn
25
25
 
26
26
  @handler.read_request.should == "line1\nline2\nline3"
27
27
  end
28
+
29
+ it "should handle POST body" do
30
+ @req = "POST /app HTTP/1.1\nCookie: $key=value;\nContent-Length: 17;\n\r\nfield1=1&field2=2"
31
+ @handler.unstub!(:read_request)
32
+ @handler.session = StringIO.new
33
+ @handler.session.string = @req
34
+
35
+ @handler.read_request.should == @req
36
+ end
28
37
  end
29
38
 
30
39
  describe "#parse_request" do
@@ -86,22 +95,23 @@ module Yarn
86
95
  @handler = RequestHandler.new
87
96
  @handler.session = @session
88
97
 
89
- FakeFS.activate!
90
98
  @file_content = "<html><body>success!</body></html>"
91
99
  @file = File.open("index.html", 'w') do |file|
92
100
  file.write @file_content
93
101
  end
102
+ Dir.mkdir("testdir") unless Dir.exists?("testdir")
94
103
  end
95
104
 
96
105
  after(:each) do
97
106
  @handler.close_connection
98
- FakeFS.deactivate!
107
+ File.delete("index.html") if File.exists?("index.html")
108
+ File.delete("testdir/index.html") if File.exists?("testdir/index.html")
109
+ Dir.delete("testdir") if Dir.exists?("testdir")
99
110
  end
100
111
 
101
112
  describe "#prepare_response" do
102
113
  it "should handle a directory" do
103
114
  File.delete("index.html")
104
- Dir.mkdir("testdir")
105
115
  @handler.stub(:extract_path).and_return("testdir")
106
116
  @handler.should_receive(:serve_directory).once
107
117
  @handler.prepare_response
@@ -112,6 +122,7 @@ module Yarn
112
122
  @handler.stub(:extract_path).and_return("test.html")
113
123
  @handler.should_receive(:serve_file).once
114
124
  @handler.prepare_response
125
+ File.delete("test.html")
115
126
  end
116
127
 
117
128
  it "handles missing files" do
@@ -130,10 +141,9 @@ module Yarn
130
141
 
131
142
  describe "#serve_directory" do
132
143
  it "should read index file if it exists" do
133
- Dir.mkdir("test")
134
- File.new("test/index.html", "w")
144
+ File.new("testdir/index.html", "w")
135
145
  @handler.should_receive(:read_file).once
136
- @handler.serve_directory("test")
146
+ @handler.serve_directory("testdir")
137
147
  end
138
148
 
139
149
  it "should list a directory" do
@@ -144,7 +154,7 @@ module Yarn
144
154
  end
145
155
 
146
156
  describe "#read_file" do
147
- it "should return the contents of a file it it exists" do
157
+ it "should return the contents of a file" do
148
158
  @handler.response.body.should be_empty
149
159
  @handler.read_file("index.html").should == [@file_content]
150
160
  end
@@ -5,25 +5,66 @@ module Yarn
5
5
 
6
6
  after(:each) do
7
7
  stop_server
8
- @server.stop if @server
8
+ end
9
+
10
+ describe "#new" do
11
+ end
12
+
13
+ describe "#load_rack_app" do
14
+
15
+ before(:each) do
16
+ $console = MockIO.new
17
+ @server = Server.new( output: $console )
18
+ end
19
+
20
+ it "should print a message and exit if the file does not exist" do
21
+ Kernel.should_receive(:exit)
22
+ @server.load_rack_app("non-existing-app.ru")
23
+ $console.should include("non-existing-app.ru does not exist. Exiting.")
24
+ end
25
+
26
+ it "should return a rack app if the file exists" do
27
+ app = @server.load_rack_app("test_objects/config.ru")
28
+ app.class.should == Rack::Builder
29
+ end
9
30
  end
10
31
 
11
32
  describe "#start" do
12
- it "creates a TCP server" do
13
- start_server
14
- @server.socket.should_not be_nil
33
+ it "should creates a TCP server" do
34
+ @server = Server.new
35
+ @server.stub(:init_workers)
36
+ @server.start
37
+
38
+ @server.socket.class.should == TCPServer
15
39
  end
16
40
 
17
- it "starts on the supplied port" do
18
- @server = Server.new(nil,port: 4000)
41
+ it "should listen on the supplied port" do
42
+ @server = Server.new({ port: 4000 })
43
+ @server.stub(:init_workers)
44
+ @server.start
19
45
 
20
46
  @server.socket.addr.should include(4000)
21
47
  end
22
48
  end
23
49
 
50
+ # describe "#start" do
51
+ # it "should start the socket_listener" do
52
+ # @thread = Thread.new do
53
+ # @server = Server.new({ output: $console })
54
+ # @server.start
55
+ # end
56
+ # sleep 2
57
+ # get("/").should be_true
58
+ # @thread.kill
59
+ # end
60
+ # end
61
+
24
62
  describe "#stop" do
25
- it "notifies the server is stopped" do
26
- @server = Server.new(nil,{ output: $console })
63
+ it "should notify the server is stopped" do
64
+ $console = MockIO.new
65
+ @server = Server.new({ output: $console })
66
+ @server.stub(:init_workers)
67
+ @server.start
27
68
  @server.stop
28
69
 
29
70
  $console.should include("Server stopped")
@@ -7,3 +7,4 @@ pkg/*
7
7
  doc/*
8
8
  rails_app
9
9
  rails_app/*
10
+ *.rb
@@ -1,5 +1,3 @@
1
- #!/bin/ruby
2
-
3
1
  puts "<h1>Dynamic script: #{__FILE__}</h1>"
4
2
  puts "2^8 = #{2**8}"
5
3
  puts "<br>"
@@ -1,54 +1,6 @@
1
1
  require 'rubygems'
2
2
  require 'rack'
3
3
 
4
- # The root of our app
5
- @root = File.expand_path(File.dirname(__FILE__))
6
-
7
4
  run Proc.new { |env|
8
- # Extract the requested path from the request
9
- path = Rack::Utils.unescape(env['PATH_INFO'])
10
- index_file = @root + "#{path}/index.html"
11
-
12
- if File.exists?(index_file)
13
- # Return the index
14
- [200, {'Content-Type' => get_mime_type(index_file)}, read_file(index_file)]
15
- elsif File.exists?(path) && !File.directory?(path)
16
- # Return the file
17
- [200, {'Content-Type' => get_mime_type(path)}, read_file(path)]
18
- else
19
- # Return a directory listing
20
- Rack::Directory.new(@root).call(env)
21
- end
5
+ [200, {'Content-Type' => "text/plain"}, ["Rack works"]]
22
6
  }
23
-
24
- def read_file(path)
25
- file_contents = []
26
- File.open(path, "r") do |file|
27
- while (line = file.gets) do
28
- file_contents << line
29
- end
30
- end
31
- file_contents
32
- end
33
-
34
-
35
- def get_mime_type(path)
36
- return false unless path.include? '.'
37
- filetype = path.split('.').last
38
-
39
- return case
40
- when ["html", "htm"].include?(filetype)
41
- "text/html"
42
- when "txt" == filetype
43
- "text/plain"
44
- when "css" == filetype
45
- "text/css"
46
- when "js" == filetype
47
- "text/javascript"
48
- when ["png", "jpg", "jpeg", "gif", "tiff"].include?(filetype)
49
- "image/#{filetype}"
50
- when ["zip","pdf","postscript","x-tar","x-dvi"].include?(filetype)
51
- "application/#{filetype}"
52
- else false
53
- end
54
- end
@@ -0,0 +1,5 @@
1
+ .bundle
2
+ db/*.sqlite3
3
+ log/*.log
4
+ tmp/
5
+ .sass-cache/
@@ -0,0 +1,34 @@
1
+ source 'http://rubygems.org'
2
+
3
+ gem 'rails', '3.1.0'
4
+
5
+ # Bundle edge Rails instead:
6
+ # gem 'rails', :git => 'git://github.com/rails/rails.git'
7
+
8
+ gem 'sqlite3'
9
+ gem 'yarn'
10
+ gem 'pry'
11
+
12
+ # Gems used only for assets and not required
13
+ # in production environments by default.
14
+ group :assets do
15
+ gem 'sass-rails', " ~> 3.1.0"
16
+ gem 'coffee-rails', "~> 3.1.0"
17
+ gem 'uglifier'
18
+ end
19
+
20
+ gem 'jquery-rails'
21
+
22
+ # Use unicorn as the web server
23
+ # gem 'unicorn'
24
+
25
+ # Deploy with Capistrano
26
+ # gem 'capistrano'
27
+
28
+ # To use debugger
29
+ # gem 'ruby-debug19', :require => 'ruby-debug'
30
+
31
+ group :test do
32
+ # Pretty printed test output
33
+ gem 'turn', :require => false
34
+ end