stark-rack 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.autotest +23 -0
- data/.gemtest +0 -0
- data/History.txt +6 -0
- data/Manifest.txt +23 -0
- data/README.txt +61 -0
- data/Rakefile +21 -0
- data/lib/stark/rack.rb +94 -0
- data/lib/stark/rack/content_negotiation.rb +34 -0
- data/lib/stark/rack/logging_processor.rb +50 -0
- data/lib/stark/rack/metadata.rb +89 -0
- data/lib/stark/rack/rest.rb +327 -0
- data/lib/stark/rack/verbose_protocol.rb +36 -0
- data/stark-rack.gemspec +42 -0
- data/test/calc-opt.rb +31 -0
- data/test/calc.thrift +13 -0
- data/test/config.ru +19 -0
- data/test/gen-rb/calc.rb +80 -0
- data/test/gen-rb/calc_constants.rb +8 -0
- data/test/gen-rb/calc_types.rb +7 -0
- data/test/helper.rb +60 -0
- data/test/test_metadata.rb +43 -0
- data/test/test_rack.rb +65 -0
- data/test/test_rest.rb +175 -0
- metadata +140 -0
@@ -0,0 +1,36 @@
|
|
1
|
+
class Stark::Rack
|
2
|
+
# Slightly more verbose protocol so that we can get struct and field names
|
3
|
+
# included.
|
4
|
+
class VerboseProtocol < Thrift::BinaryProtocol
|
5
|
+
def write_struct_begin(name)
|
6
|
+
write_string name
|
7
|
+
end
|
8
|
+
|
9
|
+
def read_struct_begin
|
10
|
+
read_string
|
11
|
+
end
|
12
|
+
|
13
|
+
def write_field_begin(name, type, id)
|
14
|
+
write_string name
|
15
|
+
super
|
16
|
+
end
|
17
|
+
|
18
|
+
def write_field_stop
|
19
|
+
write_string ""
|
20
|
+
super
|
21
|
+
end
|
22
|
+
|
23
|
+
def read_field_begin
|
24
|
+
name = read_string
|
25
|
+
result = super
|
26
|
+
result[0] = name unless name.empty?
|
27
|
+
result
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
class VerboseProtocolFactory < Thrift::BinaryProtocolFactory
|
32
|
+
def get_protocol(trans)
|
33
|
+
return VerboseProtocol.new(trans)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
data/stark-rack.gemspec
ADDED
@@ -0,0 +1,42 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
|
3
|
+
Gem::Specification.new do |s|
|
4
|
+
s.name = "stark-rack"
|
5
|
+
s.version = "1.0.0"
|
6
|
+
|
7
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
8
|
+
s.authors = ["Evan Phoenix"]
|
9
|
+
s.date = "2013-05-22"
|
10
|
+
s.description = "Provides middleware for mounting Stark/Thrift services as Rack endpoints."
|
11
|
+
s.email = ["evan@phx.io"]
|
12
|
+
s.extra_rdoc_files = ["History.txt", "Manifest.txt", "README.txt"]
|
13
|
+
s.files = [".autotest", ".gemtest", "History.txt", "Manifest.txt", "README.txt", "Rakefile", "lib/stark/rack.rb", "lib/stark/rack/content_negotiation.rb", "lib/stark/rack/logging_processor.rb", "lib/stark/rack/metadata.rb", "lib/stark/rack/rest.rb", "stark-rack.gemspec", "test/calc-opt.rb", "test/calc.thrift", "test/config.ru", "test/gen-rb/calc.rb", "test/gen-rb/calc_constants.rb", "test/gen-rb/calc_types.rb", "test/helper.rb", "test/test_metadata.rb", "test/test_rack.rb", "test/test_rest.rb"]
|
14
|
+
s.homepage = "https://github.com/evanphx/stark-rack"
|
15
|
+
s.rdoc_options = ["--main", "README.txt"]
|
16
|
+
s.require_paths = ["lib"]
|
17
|
+
s.rubyforge_project = "stark-rack"
|
18
|
+
s.rubygems_version = "1.8.23"
|
19
|
+
s.summary = "Provides middleware for mounting Stark/Thrift services as Rack endpoints."
|
20
|
+
s.test_files = ["test/test_metadata.rb", "test/test_rack.rb", "test/test_rest.rb"]
|
21
|
+
|
22
|
+
if s.respond_to? :specification_version then
|
23
|
+
s.specification_version = 3
|
24
|
+
|
25
|
+
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
26
|
+
s.add_runtime_dependency(%q<stark>, ["< 2.0.0"])
|
27
|
+
s.add_development_dependency(%q<rdoc>, ["~> 4.0"])
|
28
|
+
s.add_development_dependency(%q<rack>, [">= 1.5.0"])
|
29
|
+
s.add_development_dependency(%q<hoe>, ["~> 3.6"])
|
30
|
+
else
|
31
|
+
s.add_dependency(%q<stark>, ["< 2.0.0"])
|
32
|
+
s.add_dependency(%q<rdoc>, ["~> 4.0"])
|
33
|
+
s.add_dependency(%q<rack>, [">= 1.5.0"])
|
34
|
+
s.add_dependency(%q<hoe>, ["~> 3.6"])
|
35
|
+
end
|
36
|
+
else
|
37
|
+
s.add_dependency(%q<stark>, ["< 2.0.0"])
|
38
|
+
s.add_dependency(%q<rdoc>, ["~> 4.0"])
|
39
|
+
s.add_dependency(%q<rack>, [">= 1.5.0"])
|
40
|
+
s.add_dependency(%q<hoe>, ["~> 3.6"])
|
41
|
+
end
|
42
|
+
end
|
data/test/calc-opt.rb
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
module Calc
|
2
|
+
class Client
|
3
|
+
def add(lhs, rhs)
|
4
|
+
op = @oprot
|
5
|
+
op.write_message_begin 'add', ::Thrift::MessageTypes::CALL, 0
|
6
|
+
op.write_struct_begin "add_args"
|
7
|
+
op.write_field_begin 'lhs', ::Thrift::Types::I32, 1
|
8
|
+
op.write_i32 lhs
|
9
|
+
op.write_field_end
|
10
|
+
op.write_field_begin 'rhs', ::Thrift::Types::I32, 2
|
11
|
+
op.write_i32 rhs
|
12
|
+
op.write_field_end
|
13
|
+
op.write_field_stop
|
14
|
+
op.write_struct_end
|
15
|
+
op.write_message_end
|
16
|
+
op.trans.flush
|
17
|
+
ip = @iprot
|
18
|
+
fname, mtype, rseqid = ip.read_message_begin
|
19
|
+
handle_exception mtype
|
20
|
+
ip.read_struct_begin
|
21
|
+
rname, rtype, rid = ip.read_field_begin
|
22
|
+
result = ip.read_i32
|
23
|
+
rname, rtype, rid = ip.read_field_begin
|
24
|
+
fail if rtype != ::Thrift::Types::STOP
|
25
|
+
ip.read_field_end
|
26
|
+
ip.read_struct_end
|
27
|
+
ip.read_message_end
|
28
|
+
return result
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
data/test/calc.thrift
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
struct State {
|
2
|
+
1: i32 last_result
|
3
|
+
2: map<string,i32> vars
|
4
|
+
}
|
5
|
+
|
6
|
+
service Calc {
|
7
|
+
i32 add(1: i32 lhs, 2: i32 rhs)
|
8
|
+
i32 last_result()
|
9
|
+
void store_vars(1: map<string,i32> vars)
|
10
|
+
i32 get_var(1: string name)
|
11
|
+
void set_state(1: State state)
|
12
|
+
State get_state()
|
13
|
+
}
|
data/test/config.ru
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
require 'thrift/rack'
|
2
|
+
|
3
|
+
$:.unshift File.expand_path("../gen-rb", __FILE__)
|
4
|
+
|
5
|
+
require 'calc'
|
6
|
+
|
7
|
+
class CalcImpl
|
8
|
+
def add(lhs, rhs)
|
9
|
+
lhs + rhs
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
impl = CalcImpl.new
|
14
|
+
|
15
|
+
processor = Calc::Processor.new impl
|
16
|
+
|
17
|
+
obj = Thrift::Rack.new processor
|
18
|
+
|
19
|
+
run obj
|
data/test/gen-rb/calc.rb
ADDED
@@ -0,0 +1,80 @@
|
|
1
|
+
#
|
2
|
+
# Autogenerated by Thrift Compiler (0.8.0)
|
3
|
+
#
|
4
|
+
# DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
|
5
|
+
#
|
6
|
+
|
7
|
+
require 'thrift'
|
8
|
+
require 'calc_types'
|
9
|
+
|
10
|
+
module Calc
|
11
|
+
class Client
|
12
|
+
include ::Thrift::Client
|
13
|
+
|
14
|
+
def add(lhs, rhs)
|
15
|
+
send_add(lhs, rhs)
|
16
|
+
return recv_add()
|
17
|
+
end
|
18
|
+
|
19
|
+
def send_add(lhs, rhs)
|
20
|
+
send_message('add', Add_args, :lhs => lhs, :rhs => rhs)
|
21
|
+
end
|
22
|
+
|
23
|
+
def recv_add()
|
24
|
+
result = receive_message(Add_result)
|
25
|
+
return result.success unless result.success.nil?
|
26
|
+
raise ::Thrift::ApplicationException.new(::Thrift::ApplicationException::MISSING_RESULT, 'add failed: unknown result')
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
30
|
+
|
31
|
+
class Processor
|
32
|
+
include ::Thrift::Processor
|
33
|
+
|
34
|
+
def process_add(seqid, iprot, oprot)
|
35
|
+
args = read_args(iprot, Add_args)
|
36
|
+
result = Add_result.new()
|
37
|
+
result.success = @handler.add(args.lhs, args.rhs)
|
38
|
+
write_result(result, oprot, 'add', seqid)
|
39
|
+
end
|
40
|
+
|
41
|
+
end
|
42
|
+
|
43
|
+
# HELPER FUNCTIONS AND STRUCTURES
|
44
|
+
|
45
|
+
class Add_args
|
46
|
+
include ::Thrift::Struct, ::Thrift::Struct_Union
|
47
|
+
LHS = 1
|
48
|
+
RHS = 2
|
49
|
+
|
50
|
+
FIELDS = {
|
51
|
+
LHS => {:type => ::Thrift::Types::I32, :name => 'lhs'},
|
52
|
+
RHS => {:type => ::Thrift::Types::I32, :name => 'rhs'}
|
53
|
+
}
|
54
|
+
|
55
|
+
def struct_fields; FIELDS; end
|
56
|
+
|
57
|
+
def validate
|
58
|
+
end
|
59
|
+
|
60
|
+
::Thrift::Struct.generate_accessors self
|
61
|
+
end
|
62
|
+
|
63
|
+
class Add_result
|
64
|
+
include ::Thrift::Struct, ::Thrift::Struct_Union
|
65
|
+
SUCCESS = 0
|
66
|
+
|
67
|
+
FIELDS = {
|
68
|
+
SUCCESS => {:type => ::Thrift::Types::I32, :name => 'success'}
|
69
|
+
}
|
70
|
+
|
71
|
+
def struct_fields; FIELDS; end
|
72
|
+
|
73
|
+
def validate
|
74
|
+
end
|
75
|
+
|
76
|
+
::Thrift::Struct.generate_accessors self
|
77
|
+
end
|
78
|
+
|
79
|
+
end
|
80
|
+
|
data/test/helper.rb
ADDED
@@ -0,0 +1,60 @@
|
|
1
|
+
module TestHelper
|
2
|
+
class Handler
|
3
|
+
def initialize(n)
|
4
|
+
@state = n::State.new
|
5
|
+
end
|
6
|
+
def add(a,b)
|
7
|
+
@state.last_result = a + b
|
8
|
+
end
|
9
|
+
def last_result
|
10
|
+
@state.last_result
|
11
|
+
end
|
12
|
+
def store_vars(hash)
|
13
|
+
@state.vars ||= {}
|
14
|
+
hash.each do |k,v|
|
15
|
+
@state.vars[k] = v.to_i
|
16
|
+
end
|
17
|
+
end
|
18
|
+
def get_var(name)
|
19
|
+
@state.vars[name]
|
20
|
+
end
|
21
|
+
def get_state
|
22
|
+
@state
|
23
|
+
end
|
24
|
+
def set_state(state)
|
25
|
+
@state = state
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def setup
|
30
|
+
@n = Module.new
|
31
|
+
|
32
|
+
Stark.materialize File.expand_path("../calc.thrift", __FILE__), @n
|
33
|
+
|
34
|
+
@sr, @cw = IO.pipe
|
35
|
+
@cr, @sw = IO.pipe
|
36
|
+
|
37
|
+
@prev_logger = Stark.logger
|
38
|
+
@log_stream = StringIO.new
|
39
|
+
Stark.logger = Logger.new @log_stream
|
40
|
+
|
41
|
+
@client_t = Thrift::IOStreamTransport.new @cr, @cw
|
42
|
+
@client_p = Thrift::BinaryProtocol.new @client_t
|
43
|
+
|
44
|
+
@client = @n::Calc::Client.new @client_p, @client_p
|
45
|
+
@handler = Handler.new(@n)
|
46
|
+
end
|
47
|
+
|
48
|
+
def teardown
|
49
|
+
print @log_stream.string unless passed?
|
50
|
+
Stark.logger = @prev_logger
|
51
|
+
|
52
|
+
@client_t.close
|
53
|
+
@sr.close
|
54
|
+
@sw.close
|
55
|
+
end
|
56
|
+
|
57
|
+
def stark_rack
|
58
|
+
@stark_rack ||= Stark::Rack.new(@n::Calc::Processor.new(@handler), :log => false)
|
59
|
+
end
|
60
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
require "test/unit"
|
2
|
+
require "stark/rack"
|
3
|
+
require "stark/rack/metadata"
|
4
|
+
require "helper"
|
5
|
+
|
6
|
+
class TestMetadata < Test::Unit::TestCase
|
7
|
+
include TestHelper
|
8
|
+
|
9
|
+
def setup
|
10
|
+
super
|
11
|
+
@metadata = { 'version' => '1.0 baby', 'name' => "This is a sweet service" }
|
12
|
+
@rack = Stark::Rack::Metadata.new stark_rack, @metadata
|
13
|
+
end
|
14
|
+
|
15
|
+
def test_call_to_metadata
|
16
|
+
@client = Stark::Rack::Metadata::Client.new @client_p, @client_p
|
17
|
+
st = Thread.new do
|
18
|
+
env = { 'rack.input' => @sr, 'PATH_INFO' => '/metadata', 'REQUEST_METHOD' => 'POST' }
|
19
|
+
code, headers, out = @rack.call env
|
20
|
+
|
21
|
+
out.each do |s|
|
22
|
+
@sw << s
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
assert_equal @metadata, @client.metadata
|
27
|
+
end
|
28
|
+
|
29
|
+
def test_call_add_passes_through_metadata
|
30
|
+
st = Thread.new do
|
31
|
+
env = { 'rack.input' => @sr, 'PATH_INFO' => '/', 'REQUEST_METHOD' => 'POST' }
|
32
|
+
code, headers, out = @rack.call env
|
33
|
+
|
34
|
+
out.each do |s|
|
35
|
+
@sw << s
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
result = @client.add 1, 1
|
40
|
+
assert_equal 2, result
|
41
|
+
end
|
42
|
+
|
43
|
+
end
|
data/test/test_rack.rb
ADDED
@@ -0,0 +1,65 @@
|
|
1
|
+
require "test/unit"
|
2
|
+
require "stark/rack"
|
3
|
+
require "helper"
|
4
|
+
|
5
|
+
class TestRack < Test::Unit::TestCase
|
6
|
+
include TestHelper
|
7
|
+
|
8
|
+
|
9
|
+
def test_call_to_thrift
|
10
|
+
st = Thread.new do
|
11
|
+
env = { 'rack.input' => @sr, 'REQUEST_METHOD' => 'POST' }
|
12
|
+
env['PATH_INFO'] = ''
|
13
|
+
|
14
|
+
code, headers, out = stark_rack.call env
|
15
|
+
|
16
|
+
out.each do |s|
|
17
|
+
@sw << s
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
out = @client.add 3, 4
|
22
|
+
|
23
|
+
assert_equal 7, out
|
24
|
+
end
|
25
|
+
|
26
|
+
def test_json_protocol
|
27
|
+
@client_p = Thrift::JsonProtocol.new @client_t
|
28
|
+
@client = @n::Calc::Client.new @client_p, @client_p
|
29
|
+
|
30
|
+
st = Thread.new do
|
31
|
+
env = { 'rack.input' => @sr, 'REQUEST_METHOD' => 'POST' }
|
32
|
+
env['PATH_INFO'] = ''
|
33
|
+
env['HTTP_CONTENT_TYPE'] = 'application/vnd.thrift+json'
|
34
|
+
|
35
|
+
code, headers, out = stark_rack.call env
|
36
|
+
|
37
|
+
out.each do |s|
|
38
|
+
@sw << s
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
out = @client.add 3, 4
|
43
|
+
|
44
|
+
assert_equal 7, out
|
45
|
+
end
|
46
|
+
|
47
|
+
def test_call_with_wrong_method
|
48
|
+
env = { 'REQUEST_METHOD' => 'GET' }
|
49
|
+
env['PATH_INFO'] = '/'
|
50
|
+
|
51
|
+
code, headers, out = stark_rack.call env
|
52
|
+
|
53
|
+
assert_equal 405, code
|
54
|
+
end
|
55
|
+
|
56
|
+
def test_call_to_undefined_url
|
57
|
+
env = { 'REQUEST_METHOD' => 'POST' }
|
58
|
+
env['PATH_INFO'] = '/blah'
|
59
|
+
|
60
|
+
code, headers, out = stark_rack.call env
|
61
|
+
|
62
|
+
assert_equal 404, code
|
63
|
+
end
|
64
|
+
|
65
|
+
end
|
data/test/test_rest.rb
ADDED
@@ -0,0 +1,175 @@
|
|
1
|
+
require "test/unit"
|
2
|
+
require "stark/rack"
|
3
|
+
require "stark/rack/metadata"
|
4
|
+
require "stark/rack/rest"
|
5
|
+
require "helper"
|
6
|
+
|
7
|
+
class TestREST < Test::Unit::TestCase
|
8
|
+
include TestHelper
|
9
|
+
|
10
|
+
def test_get_last_result
|
11
|
+
rack = Stark::Rack::REST.new stark_rack
|
12
|
+
@handler.add 2, 2
|
13
|
+
|
14
|
+
out = ['']
|
15
|
+
Thread.new do
|
16
|
+
env = {'rack.input' => StringIO.new, 'REQUEST_METHOD' => 'GET',
|
17
|
+
'PATH_INFO' => '/last_result', 'QUERY_STRING' => ''}
|
18
|
+
|
19
|
+
code, headers, out = rack.call env
|
20
|
+
end.join
|
21
|
+
|
22
|
+
json = '{"result":4}'
|
23
|
+
assert_equal json, out.join
|
24
|
+
end
|
25
|
+
|
26
|
+
def test_store_vars_with_single_arg_map
|
27
|
+
rack = Stark::Rack::REST.new stark_rack
|
28
|
+
Thread.new do
|
29
|
+
env = {'rack.input' => StringIO.new, 'REQUEST_METHOD' => 'GET',
|
30
|
+
'PATH_INFO' => '/store_vars', 'QUERY_STRING' => 'a=1&b=2&c=3'}
|
31
|
+
|
32
|
+
code, headers, out = rack.call env
|
33
|
+
end.join
|
34
|
+
|
35
|
+
assert_equal 1, @handler.get_var('a')
|
36
|
+
assert_equal 2, @handler.get_var('b')
|
37
|
+
assert_equal 3, @handler.get_var('c')
|
38
|
+
end
|
39
|
+
|
40
|
+
def test_add_with_arg_map
|
41
|
+
rack = Stark::Rack::REST.new stark_rack
|
42
|
+
@handler.store_vars 'a' => 42
|
43
|
+
out = ['']
|
44
|
+
Thread.new do
|
45
|
+
env = {'rack.input' => StringIO.new, 'REQUEST_METHOD' => 'GET',
|
46
|
+
'PATH_INFO' => '/add', 'QUERY_STRING' => 'arg[1]=1&arg[2]=1'}
|
47
|
+
|
48
|
+
code, headers, out = rack.call env
|
49
|
+
end.join
|
50
|
+
|
51
|
+
json = '{"result":2}'
|
52
|
+
assert_equal json, out.join
|
53
|
+
end
|
54
|
+
|
55
|
+
def test_add_with_arg_map_missing_an_argument
|
56
|
+
rack = Stark::Rack::REST.new stark_rack
|
57
|
+
@handler.store_vars 'a' => 42
|
58
|
+
out = ['']
|
59
|
+
Thread.new do
|
60
|
+
env = {'rack.input' => StringIO.new, 'REQUEST_METHOD' => 'GET',
|
61
|
+
'PATH_INFO' => '/add', 'QUERY_STRING' => 'arg[2]=1'}
|
62
|
+
|
63
|
+
code, headers, out = rack.call env
|
64
|
+
end.join
|
65
|
+
|
66
|
+
json = '{"error":"undefined method `+\' for nil:NilClass (NoMethodError)"}'
|
67
|
+
assert_equal json, out.join
|
68
|
+
end
|
69
|
+
|
70
|
+
def test_get_var_with_arg_map
|
71
|
+
rack = Stark::Rack::REST.new stark_rack
|
72
|
+
@handler.store_vars 'a' => 42
|
73
|
+
out = ['']
|
74
|
+
Thread.new do
|
75
|
+
env = {'rack.input' => StringIO.new, 'REQUEST_METHOD' => 'GET',
|
76
|
+
'PATH_INFO' => '/get_var', 'QUERY_STRING' => 'arg[1]=a'}
|
77
|
+
|
78
|
+
code, headers, out = rack.call env
|
79
|
+
end.join
|
80
|
+
|
81
|
+
json = '{"result":42}'
|
82
|
+
assert_equal json, out.join
|
83
|
+
end
|
84
|
+
|
85
|
+
def test_get_var_with_arg_array
|
86
|
+
rack = Stark::Rack::REST.new stark_rack
|
87
|
+
@handler.store_vars 'a' => 42
|
88
|
+
out = ['']
|
89
|
+
Thread.new do
|
90
|
+
env = {'rack.input' => StringIO.new, 'REQUEST_METHOD' => 'GET',
|
91
|
+
'PATH_INFO' => '/get_var', 'QUERY_STRING' => 'args[]=a'}
|
92
|
+
|
93
|
+
code, headers, out = rack.call env
|
94
|
+
end.join
|
95
|
+
|
96
|
+
json = '{"result":42}'
|
97
|
+
assert_equal json, out.join
|
98
|
+
end
|
99
|
+
|
100
|
+
def test_get_state
|
101
|
+
rack = Stark::Rack::REST.new stark_rack
|
102
|
+
@handler.store_vars 'a' => 42
|
103
|
+
@handler.add 2, 2
|
104
|
+
out = ['']
|
105
|
+
Thread.new do
|
106
|
+
env = {'rack.input' => StringIO.new, 'REQUEST_METHOD' => 'GET',
|
107
|
+
'PATH_INFO' => '/get_state', 'QUERY_STRING' => ''}
|
108
|
+
|
109
|
+
code, headers, out = rack.call env
|
110
|
+
end.join
|
111
|
+
|
112
|
+
json = '{"result":{"_struct_":"State","1:last_result":4,"2:vars":{"a":42}}}'
|
113
|
+
assert_equal json, out.join
|
114
|
+
end
|
115
|
+
|
116
|
+
def test_set_state_with_GET
|
117
|
+
rack = Stark::Rack::REST.new stark_rack
|
118
|
+
Thread.new do
|
119
|
+
env = {'rack.input' => StringIO.new, 'REQUEST_METHOD' => 'GET',
|
120
|
+
'PATH_INFO' => '/set_state',
|
121
|
+
'QUERY_STRING' => '_struct_=State&1-last_result=0&2-vars[a]=1&2-vars[b]=2'}
|
122
|
+
|
123
|
+
code, headers, out = rack.call env
|
124
|
+
end.join
|
125
|
+
|
126
|
+
assert_equal 0, @handler.last_result
|
127
|
+
assert_equal 1, @handler.get_var('a')
|
128
|
+
assert_equal 2, @handler.get_var('b')
|
129
|
+
end
|
130
|
+
|
131
|
+
def test_set_state_with_json_POST
|
132
|
+
rack = Stark::Rack::REST.new stark_rack
|
133
|
+
Thread.new do
|
134
|
+
env = {'rack.input' => StringIO.new('[{"_struct_":"State","1:last_result":0,"2:vars":{"a":1,"b":2}}]'),
|
135
|
+
'REQUEST_METHOD' => 'POST', 'PATH_INFO' => '/set_state',
|
136
|
+
'HTTP_CONTENT_TYPE' => 'application/json' }
|
137
|
+
|
138
|
+
code, headers, out = rack.call env
|
139
|
+
end.join
|
140
|
+
|
141
|
+
assert_equal 0, @handler.last_result
|
142
|
+
assert_equal 1, @handler.get_var('a')
|
143
|
+
assert_equal 2, @handler.get_var('b')
|
144
|
+
end
|
145
|
+
|
146
|
+
def test_set_state_json_bad_request
|
147
|
+
rack = Stark::Rack::REST.new stark_rack
|
148
|
+
code = headers = out = nil
|
149
|
+
Thread.new do
|
150
|
+
env = {'rack.input' => StringIO.new('42'),
|
151
|
+
'REQUEST_METHOD' => 'POST', 'PATH_INFO' => '/set_state',
|
152
|
+
'HTTP_CONTENT_TYPE' => 'application/json' }
|
153
|
+
|
154
|
+
code, headers, out = rack.call env
|
155
|
+
end.join
|
156
|
+
|
157
|
+
assert_equal 400, code
|
158
|
+
end
|
159
|
+
|
160
|
+
def test_get_metadata
|
161
|
+
metadata = { 'version' => '1.0 baby', 'name' => "This is a sweet service" }
|
162
|
+
rack = Stark::Rack::REST.new Stark::Rack::Metadata.new(stark_rack, metadata)
|
163
|
+
|
164
|
+
out = ['']
|
165
|
+
Thread.new do
|
166
|
+
env = {'rack.input' => StringIO.new, 'REQUEST_METHOD' => 'GET',
|
167
|
+
'PATH_INFO' => '/metadata', 'QUERY_STRING' => ''}
|
168
|
+
|
169
|
+
code, headers, out = rack.call env
|
170
|
+
end.join
|
171
|
+
|
172
|
+
json = '{"result":{"version":"1.0 baby","name":"This is a sweet service"}}'
|
173
|
+
assert_equal json, out.join
|
174
|
+
end
|
175
|
+
end
|