yarn 0.0.1 → 0.0.2

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 (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