diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..d7e9a07 --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +.DS_Store +html +pkg \ No newline at end of file diff --git a/CHANGELOG.rdoc b/CHANGELOG.rdoc new file mode 100644 index 0000000..9d32b81 --- /dev/null +++ b/CHANGELOG.rdoc @@ -0,0 +1,5 @@ +=== 0.0.1 / 2012-02-23 + +* Initial commit, copied from: + http://github.com/raggi/async_sinatra + http://libraggi.rubyforge.org/async_sinatra diff --git a/README.rdoc b/README.rdoc new file mode 100644 index 0000000..ebbabf3 --- /dev/null +++ b/README.rdoc @@ -0,0 +1,63 @@ += async_rack_test + +https://github.com/thoughtless/async_rack_test + +Inspired by async_sinatra: +http://github.com/raggi/async_sinatra +http://libraggi.rubyforge.org/async_sinatra + +== DESCRIPTION: + +Extends rack-test to make working with EventMachine easier. + +== SYNOPSIS: + +A quick example: + + require 'spec_helper' + require 'async_rack_test' + + describe MyAsyncApp, :type => :request do + include AsyncRackTest::Methods + let(:app) { MyAsyncApp.new } + + it 'should be successful' do + apost "/some_url", "some data" + + last_response.should be_ok + end + end + + +== REQUIREMENTS: + +TODO + +== INSTALL: + +TODO + +== LICENSE: + +(The MIT License) + +Copyright (c) 2012 Paul Cortens + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +'Software'), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/async_rack_test.gemspec b/async_rack_test.gemspec new file mode 100644 index 0000000..1e88f00 --- /dev/null +++ b/async_rack_test.gemspec @@ -0,0 +1,23 @@ +# -*- encoding: utf-8 -*- +$LOAD_PATH.unshift File.expand_path("../lib", __FILE__) +require "async_rack_test/version" + +Gem::Specification.new do |s| + s.name = "async_rack_test" + s.version = AsyncRackTest::Version::STRING + s.platform = Gem::Platform::RUBY + s.authors = ["Paul Cortens"] + s.email = "paul@thoughtless.ca" + s.homepage = "http://github.com/thoughtless/async_rack_test" + s.summary = "async_rack_test-#{AsyncRackTest::Version::STRING}" + s.description = "Extends rack-test to make working with EventMachine easier." + + s.files = `git ls-files`.split("\n") + s.test_files = `git ls-files -- {spec,features}/*`.split("\n") + s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) } + s.extra_rdoc_files = [ 'README.rdoc', 'CHANGELOG.rdoc'] + s.rdoc_options = ["--charset=UTF-8"] + s.require_path = "lib" + + # TODO: Add rack-test as a dependency +end diff --git a/lib/async_rack_test.rb b/lib/async_rack_test.rb new file mode 100644 index 0000000..a071047 --- /dev/null +++ b/lib/async_rack_test.rb @@ -0,0 +1,33 @@ +require 'rack/test' +require 'async_rack_test/resync_app' + + +# Adds aget, apost, etc. which treat an asynchronous rack-app as synchronous. +module AsyncRackTest + module Methods + include Rack::Test::Methods + + def sync_app + self.class.instance_eval { alias_method :async_app, :app } unless self.respond_to?(:async_app) + ResyncApp.new(async_app) + end + + def use_sync + self.instance_eval { alias :app :sync_app } + end + def use_async + self.instance_eval { alias :app :async_app } + end + + %w(get put post delete head options).each do |m| + eval <<-RUBY, binding, __FILE__, __LINE__ + 1 + def a#{m}(*args) + use_sync + #{m}(*args) + use_async + end + RUBY + end + + end +end diff --git a/lib/async_rack_test/resync_app.rb b/lib/async_rack_test/resync_app.rb new file mode 100644 index 0000000..3cb4869 --- /dev/null +++ b/lib/async_rack_test/resync_app.rb @@ -0,0 +1,34 @@ +# Turns an async rack app into a sync one. This let's you test the app with +# rack-test as if it were synchronous. +module AsyncRackTest + class ResyncApp + attr_reader :app + def initialize(app) + @app = app + end + + def call(env) + result = nil + env['async.callback'] = method(:write_async_response) + EM.run do + response = app.call(env) + if response[0] == -1 + EM.add_periodic_timer(0.1) do + unless @async_response.nil? + result = @async_response + EM.stop + end + end + else + result = response + EM.stop + end + end + result + end + + def write_async_response(response) + @async_response = response + end + end +end diff --git a/lib/async_rack_test/version.rb b/lib/async_rack_test/version.rb new file mode 100644 index 0000000..928978e --- /dev/null +++ b/lib/async_rack_test/version.rb @@ -0,0 +1,5 @@ +module AsyncRackTest # :nodoc: + module Version + STRING = '0.0.1' + end +end diff --git a/spec/async_rack_test_spec.rb b/spec/async_rack_test_spec.rb new file mode 100644 index 0000000..a4b40eb --- /dev/null +++ b/spec/async_rack_test_spec.rb @@ -0,0 +1,4 @@ +require 'async_rack_test' + + +# TODO: Make this useful.