httparrot 0.0.1

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.
@@ -0,0 +1,50 @@
1
+ require 'spec_helper'
2
+
3
+ describe HTTParrot::Config do
4
+
5
+ context "defaults" do
6
+ before(:each){ HTTParrot::Config.restore_defaults! }
7
+
8
+ specify{ HTTParrot::Config.Port.should eq(4000) }
9
+ specify{ HTTParrot::Config.SSLPort.should eq(4001) }
10
+ specify{ HTTParrot::Config.ssl.should be_true }
11
+ specify{ HTTParrot::Config.template_root.should be_nil }
12
+ specify{ HTTParrot::Config.verbose.should be_false }
13
+ end
14
+
15
+ context "updates" do
16
+ before(:each) { HTTParrot::Config.restore_defaults! }
17
+
18
+ it ":Port" do
19
+ HTTParrot::Config.Port = 5000
20
+ HTTParrot::Config.Port.should eq(5000)
21
+ HTTParrot::Config.config[:Port].should eq(5000)
22
+ end
23
+
24
+ it ":SSLPort" do
25
+ HTTParrot::Config.SSLPort = 5000
26
+ HTTParrot::Config.SSLPort.should eq(5000)
27
+ HTTParrot::Config.config[:SSLPort].should eq(5000)
28
+ end
29
+
30
+ it ":ssl" do
31
+ HTTParrot::Config.ssl = false
32
+ HTTParrot::Config.ssl.should be_false
33
+ HTTParrot::Config.config[:ssl].should be_false
34
+ end
35
+
36
+ it ":verbose" do
37
+ HTTParrot::Config.verbose = true
38
+ HTTParrot::Config.verbose.should be_true
39
+ HTTParrot::Config.config[:verbose].should be_true
40
+ end
41
+
42
+ it ":template_root" do
43
+ HTTParrot::Config.template_root = "updated value"
44
+ HTTParrot::Config.template_root.should eq("updated value")
45
+ HTTParrot::Config.config[:template_root].should eq("updated value")
46
+ end
47
+
48
+ end
49
+
50
+ end
@@ -0,0 +1,3 @@
1
+ require 'spec_helper'
2
+
3
+
@@ -0,0 +1,135 @@
1
+ require 'spec_helper'
2
+
3
+ describe HTTParrot::ResponseFactory do
4
+
5
+ context "API" do
6
+ specify{ described_class.should respond_to(:clear!) }
7
+ specify{ described_class.should respond_to(:define) }
8
+ specify{ described_class.should respond_to(:build) }
9
+ specify{ described_class.should respond_to(:one_of) }
10
+ specify{ described_class.should respond_to(:collection_of) }
11
+ end
12
+
13
+ context "#clear!" do
14
+
15
+ it "removes all factories when cleared" do
16
+ HTTParrot::ResponseFactory.define(:response) { |r| r.test = "Test" }
17
+ HTTParrot::ResponseFactory.clear!
18
+ HTTParrot::ResponseFactory.instance_variable_get("@factory_classes").size.should eq(0)
19
+ end
20
+
21
+ end
22
+
23
+ context "#collection_of" do
24
+ before(:each) { HTTParrot::ResponseFactory.clear! }
25
+
26
+ it "requires the factory_class to exist" do
27
+ expect{ HTTParrot::ResponseFactory.collection_of(:response, 10) }.to raise_error(/factory/)
28
+ end
29
+
30
+ it "returns the specified number of Widgets" do
31
+ HTTParrot::ResponseFactory.define(:response) { |t| t.value = "Test" }
32
+ c = HTTParrot::ResponseFactory.collection_of(:response, 10)
33
+ c.size.should eq(10)
34
+ end
35
+
36
+ it "returns Widgets with values from factory definitions" do
37
+ HTTParrot::ResponseFactory.define(:response) { |t| t.value = "Test" }
38
+ c = HTTParrot::ResponseFactory.collection_of(:response, 10)
39
+ c.each do |w|
40
+ w.should be_a(HTTParrot::Widget)
41
+ w.value.should eq("Test")
42
+ end
43
+ end
44
+
45
+ it "returns Widgets with values from factory definitions overridden" do
46
+ HTTParrot::ResponseFactory.define(:response) { |t| t.value = "Test" }
47
+ c = HTTParrot::ResponseFactory.collection_of(:response, 10, :value => "Over")
48
+ c.each do |w|
49
+ w.should be_a(HTTParrot::Widget)
50
+ w.value.should eq("Over")
51
+ end
52
+ end
53
+
54
+ end
55
+
56
+ context "#define" do
57
+ before(:each) { HTTParrot::ResponseFactory.clear! }
58
+
59
+ it "adds a factory to the factories available" do
60
+ HTTParrot::ResponseFactory.define(:response) { |r| r.test = "Test" }
61
+ HTTParrot::ResponseFactory.instance_variable_get("@factory_classes").size.should eq(1)
62
+ end
63
+
64
+ it "overwrites a factory with the same name" do
65
+ HTTParrot::ResponseFactory.should_receive(:warn).with(/redefinition/)
66
+ HTTParrot::ResponseFactory.define(:response) { |r| r.test = "Test1" }
67
+ HTTParrot::ResponseFactory.define(:response) { |r| r.test = "Test2" }
68
+ HTTParrot::ResponseFactory.instance_variable_get("@factory_classes").size.should eq(1)
69
+ end
70
+
71
+ it "warns when a factory is overwritten" do
72
+ HTTParrot::ResponseFactory.should_receive(:warn).with(/redefinition/)
73
+ HTTParrot::ResponseFactory.define(:response) { |r| r.test = "Test1" }
74
+ HTTParrot::ResponseFactory.define(:response) { |r| r.test = "Test2" }
75
+ end
76
+
77
+ it "requires a block to be sent during definition" do
78
+ lambda{ HTTParrot::ResponseFactory.define(:response) }.should raise_error(/block/)
79
+ end
80
+
81
+ it "requires a factory name to be included" do
82
+ lambda{ HTTParrot::ResponseFactory.define { nil } }.should raise_error(/arguments/)
83
+ end
84
+
85
+ end
86
+
87
+ context "#one_of" do
88
+
89
+ it "warns if choices are not provided" do
90
+ HTTParrot::ResponseFactory.should_receive(:warn).with(/choices/)
91
+ HTTParrot::ResponseFactory.one_of([])
92
+ end
93
+
94
+ it "returns a choice" do
95
+ choices = [1, 2, 3, 4, 5]
96
+ choices.should include(HTTParrot::ResponseFactory.one_of(choices))
97
+ choices = ["choice1", "choice2", "choice3"]
98
+ choices.should include(HTTParrot::ResponseFactory.one_of(choices))
99
+ end
100
+
101
+ end
102
+
103
+ context "#build" do
104
+ before(:each) { HTTParrot::ResponseFactory.clear! }
105
+
106
+ it "raises error if factory does not exist" do
107
+ expect{ HTTParrot::ResponseFactory.build(:response) }.to raise_error(/factory type/)
108
+ end
109
+
110
+ it "calls the definition block during build" do
111
+ HTTParrot::ResponseFactory.define(:response) { |r| raise "block call" }
112
+ expect{ HTTParrot::ResponseFactory.build(:response) }.to raise_error(/block call/)
113
+ end
114
+
115
+ it "returns a response with values set from definition" do
116
+ HTTParrot::ResponseFactory.define(:response) { |r| r.value = "Test1" }
117
+ res = HTTParrot::ResponseFactory.build(:response)
118
+ res.value.should eq("Test1")
119
+ end
120
+
121
+ it "returns a Widget" do
122
+ HTTParrot::ResponseFactory.define(:response) { |r| r.value = "Test1" }
123
+ res = HTTParrot::ResponseFactory.build(:response)
124
+ res.should be_a(HTTParrot::Widget)
125
+ end
126
+
127
+ it "overrides defaults when changes are provided in build" do
128
+ HTTParrot::ResponseFactory.define(:response) { |r| r.value = "Test1" }
129
+ res = HTTParrot::ResponseFactory.build(:response, :value => "New Val")
130
+ res.value.should eq("New Val")
131
+ end
132
+
133
+ end
134
+
135
+ end
@@ -0,0 +1,192 @@
1
+ require 'spec_helper'
2
+ require 'net/http'
3
+
4
+ describe HTTParrot::Server do
5
+
6
+ before(:all) do
7
+ @server = HTTParrot::Server.new
8
+ @server.start
9
+ end
10
+
11
+ after(:all) do
12
+ @server.stop
13
+ end
14
+
15
+ context "API" do
16
+ specify{ @server.should respond_to(:start) }
17
+ specify{ @server.should respond_to(:stop) }
18
+ specify{ @server.should respond_to(:running?) }
19
+ specify{ @server.should respond_to(:started?) }
20
+ specify{ @server.should respond_to(:clear!) }
21
+ specify{ @server.should respond_to(:reset_counts) }
22
+ specify{ @server.should respond_to(:call) }
23
+ specify{ @server.should respond_to(:register) }
24
+ end
25
+
26
+ specify{ @server.running?.should be_true }
27
+ specify{ @server.started?.should be_true }
28
+
29
+ context "#initialize" do
30
+
31
+ it "uses HTTParrot::Content defaults (by default)" do
32
+ current = described_class.new
33
+ current.options.should include(HTTParrot::Config.config)
34
+ end
35
+
36
+ it "allows overrides from passed options" do
37
+ current = described_class.new(:Port => 6000)
38
+ current.options[:Port].should eq(6000)
39
+ end
40
+
41
+ end
42
+
43
+ context "#clear!" do
44
+ before(:each) do
45
+ HTTParrot::ResponseFactory.clear!
46
+ HTTParrot::Config.config[:template_root] = File.dirname(__FILE__)
47
+ HTTParrot::ResponseFactory.define(:widget) { |r| r.widget_header = "SERVER" }
48
+ end
49
+
50
+ it "resets all handlers" do
51
+ handlers = @server.instance_variable_get("@call_handlers")
52
+ handlers.each_value {|v| v.should be_empty }
53
+ widget = HTTParrot::ResponseFactory.build(:widget)
54
+ @server.register(:get, lambda{ |v| v =~ /widget/ }, widget.to_rack)
55
+ @server.clear!
56
+ handlers = @server.instance_variable_get("@call_handlers")
57
+ handlers.each_value {|v| v.should be_empty }
58
+ end
59
+
60
+ end
61
+
62
+ describe "counts and call handlers" do
63
+ before(:each) do
64
+ HTTParrot::ResponseFactory.clear!
65
+ HTTParrot::Config.config[:template_root] = File.dirname(__FILE__)
66
+ HTTParrot::ResponseFactory.define(:widget) { |r| r.widget_header = "SERVER" }
67
+ @widget = HTTParrot::ResponseFactory.build(:widget)
68
+ @server.clear!
69
+ end
70
+
71
+ context "call_handlers" do
72
+ before(:each) do
73
+ @widget_handler = @server.register(:post, lambda{ |v| v =~ /widget/ }, @widget.to_rack)
74
+ http_request = Net::HTTP.new("127.0.0.1", HTTParrot::Config.Port)
75
+ http_request.post("/widget", "widget=widget")
76
+ end
77
+
78
+ it "counts calls" do
79
+ @widget_handler.response_count.should eq(1)
80
+ end
81
+
82
+ it "resets counts" do
83
+ @server.reset_counts
84
+ @widget_handler.response_count.should eq(0)
85
+ end
86
+
87
+ end
88
+
89
+ context "regex_handlers" do
90
+ before(:each) do
91
+ @widget_handler = @server.register(:post, /widget/, @widget.to_rack)
92
+ http_request = Net::HTTP.new("127.0.0.1", HTTParrot::Config.Port)
93
+ http_request.post("/widget", "widget=widget")
94
+ end
95
+
96
+ it "counts calls" do
97
+ @widget_handler.response_count.should eq(1)
98
+ end
99
+
100
+ it "resets counts" do
101
+ @server.reset_counts
102
+ @widget_handler.response_count.should eq(0)
103
+ end
104
+
105
+ end
106
+
107
+ context "endpoint_handlers" do
108
+ before(:each) do
109
+ @widget_handler = @server.register(:post, "widget", @widget.to_rack)
110
+ http_request = Net::HTTP.new("127.0.0.1", HTTParrot::Config.Port)
111
+ http_request.post("/widget", "widget=widget")
112
+ end
113
+
114
+ it "counts calls" do
115
+ @widget_handler.response_count.should eq(1)
116
+ end
117
+
118
+ it "resets counts" do
119
+ @server.reset_counts
120
+ @widget_handler.response_count.should eq(0)
121
+ end
122
+
123
+ end
124
+
125
+ context "complex_handlers" do
126
+ before(:each) do
127
+ @widget_handler = @server.register(:post, ["widget", /widget/], @widget.to_rack)
128
+ http_request = Net::HTTP.new("127.0.0.1", HTTParrot::Config.Port)
129
+ http_request.post("/widget", "widget=widget")
130
+ end
131
+
132
+ it "counts calls" do
133
+ @widget_handler.response_count.should eq(1)
134
+ end
135
+
136
+ it "resets counts" do
137
+ @server.reset_counts
138
+ @widget_handler.response_count.should eq(0)
139
+ end
140
+
141
+ end
142
+
143
+ end
144
+
145
+ context "#register" do
146
+ before(:each) do
147
+ HTTParrot::ResponseFactory.clear!
148
+ HTTParrot::Config.config[:template_root] = File.dirname(__FILE__)
149
+ HTTParrot::ResponseFactory.define(:widget) { |r| r.widget_header = "SERVER" }
150
+ @widget = HTTParrot::ResponseFactory.build(:widget)
151
+ @server.clear!
152
+ end
153
+
154
+ it "registers call_handlers" do
155
+ handlers = @server.instance_variable_get("@call_handlers")
156
+ handlers.each_value {|v| v.should be_empty }
157
+ @server.register(:get, lambda{ |v| v =~ /widget/ }, @widget.to_rack)
158
+ handlers[:get].should_not be_empty
159
+ handlers[:post].should be_empty
160
+ end
161
+
162
+ it "registers regex_handlers" do
163
+ handlers = @server.instance_variable_get("@regex_handlers")
164
+ handlers.each_value {|v| v.should be_empty }
165
+ @server.register(:get, /widget/, @widget.to_rack)
166
+ handlers[:get].should_not be_empty
167
+ handlers[:post].should be_empty
168
+ end
169
+
170
+ it "registers endpoint_handlers" do
171
+ handlers = @server.instance_variable_get("@endpoint_handlers")
172
+ handlers.each_value {|v| v.should be_empty }
173
+ @server.register(:get, "/widget", @widget.to_rack)
174
+ handlers[:get].should_not be_empty
175
+ handlers[:post].should be_empty
176
+ end
177
+
178
+ it "registers complex_handlers" do
179
+ handlers = @server.instance_variable_get("@complex_handlers")
180
+ handlers.each_value {|v| v.should be_empty }
181
+ @server.register(:get, ["/widget", /widget/], @widget.to_rack)
182
+ handlers[:get].should_not be_empty
183
+ handlers[:post].should be_empty
184
+ end
185
+
186
+ it "raises error when handler type cannot be inferred" do
187
+ expect{ @server.register(:get, 1, @widget.to_rack) }.to raise_error(/callable/)
188
+ end
189
+
190
+ end
191
+
192
+ end
@@ -0,0 +1,14 @@
1
+ require 'rubygems'
2
+ require 'bundler'
3
+ Bundler.setup :default, :development, :test
4
+
5
+ RSpec.configure do |c|
6
+ c.mock_with :rspec
7
+ c.formatter = "progress"
8
+ c.tty = true if defined?(JRUBY_VERSION)
9
+ c.color_enabled = true
10
+ end
11
+
12
+ $:.push File.expand_path('..', File.dirname(__FILE__))
13
+ $:.push File.expand_path('../lib', File.dirname(__FILE__))
14
+ require "httparrot"
@@ -0,0 +1,11 @@
1
+ <%
2
+ header["AWESOMEHEADER"] = awesome_header
3
+ header["ANOTHERONE"] = another_one
4
+ header["ANDONEMORE"] = and_one_more
5
+ %>
6
+
7
+ <SOMEML>
8
+ <VAL1><%= val1 %></VAL1>
9
+ <VAL2><%= val2 %></VAL2>
10
+ <VAL3><%= val3 %></VAL3>
11
+ </SOMEML>
@@ -0,0 +1,12 @@
1
+ <%
2
+ header["this"] = "that"
3
+ header["that"] = "this"
4
+ %>
5
+
6
+ WIDGETHEADER: <%= widget_header %>
7
+
8
+ <WIDGET>
9
+ <VAL1><%= val1 %></VAL1>
10
+ <VAL2><%= val2 %></VAL2>
11
+ <VAL3><%= val3 %></VAL3>
12
+ </WIDGET>
@@ -0,0 +1,183 @@
1
+ require 'spec_helper'
2
+
3
+ describe HTTParrot::Widget do
4
+
5
+ context "API" do
6
+ specify{ subject.should respond_to(:rack_response) }
7
+ specify{ subject.should respond_to(:to_hash) }
8
+ specify{ subject.should respond_to(:to_rack) }
9
+ specify{ subject.should respond_to(:to_rack_response) }
10
+ specify{ subject.should respond_to(:parent) }
11
+ specify{ subject.should respond_to(:parent!) }
12
+ end
13
+
14
+ specify{ subject.to_hash.should be_a(Hash) }
15
+
16
+ shared_examples "a parental relationship" do |meth|
17
+
18
+ it "adds new values" do
19
+ current = HTTParrot::Widget.new(:first => 1, :second => 2)
20
+ current.method(meth).call({:first => 2, :second => 1, :third => 3})
21
+ current.third.should eq(3)
22
+ end
23
+
24
+ it "raises error when not a symbol or respond_to? to_hash" do
25
+ expect{ subject.method(meth).call([]) }.to raise_error(/symbol/)
26
+ end
27
+
28
+ it "raises error when parent factory does not exist" do
29
+ expect{ subject.method(meth).call(:something) }.to raise_error(/unknown factory/i)
30
+ end
31
+
32
+ it "builds corresponding factory when symbol" do
33
+ HTTParrot::ResponseFactory.define(:response) { |r| r.value = "Test" }
34
+ current = HTTParrot::Widget.new
35
+ current.method(meth).call(:response)
36
+ current.value.should eq("Test")
37
+ end
38
+
39
+ it "adds values from multiple parents" do
40
+ current = HTTParrot::Widget.new
41
+ current.method(meth).call(:first => 1)
42
+ current.method(meth).call(:second => 2)
43
+ current.method(meth).call(:third => 3)
44
+ current.first.should eq(1)
45
+ current.second.should eq(2)
46
+ current.third.should eq(3)
47
+ end
48
+
49
+ end
50
+
51
+ context "#parent" do
52
+ before(:each) { HTTParrot::ResponseFactory.clear! }
53
+
54
+ it_behaves_like "a parental relationship", :parent
55
+
56
+ it "does not overwrite existing values" do
57
+ current = HTTParrot::Widget.new(:first => 1, :second => 2)
58
+ current.parent({:first => 2, :second => 1})
59
+ current.first.should eq(1)
60
+ current.second.should eq(2)
61
+ end
62
+
63
+ it "respects parent call order for adding values" do
64
+ current = HTTParrot::Widget.new
65
+ current.parent(:first => 1)
66
+ current.parent(:second => 2)
67
+ current.parent(:third => 3)
68
+ current.parent(:first => 2, :second => 3, :third => 1)
69
+ current.first.should eq(1)
70
+ current.second.should eq(2)
71
+ current.third.should eq(3)
72
+ end
73
+
74
+ end
75
+
76
+ context "#parent!" do
77
+ before(:each) { HTTParrot::ResponseFactory.clear! }
78
+
79
+ it_behaves_like "a parental relationship", :parent!
80
+
81
+ it "overwrites existing values" do
82
+ current = HTTParrot::Widget.new(:first => 1, :second => 2)
83
+ current.parent!({:first => 2, :second => 1})
84
+ current.first.should eq(2)
85
+ current.second.should eq(1)
86
+ end
87
+
88
+ it "overwrites with last parent call for adding values" do
89
+ current = HTTParrot::Widget.new
90
+ current.parent!(:first => 1)
91
+ current.parent!(:second => 2)
92
+ current.parent!(:third => 3)
93
+ current.parent!(:first => 2, :second => 3, :third => 1)
94
+ current.first.should eq(2)
95
+ current.second.should eq(3)
96
+ current.third.should eq(1)
97
+ end
98
+
99
+ end
100
+
101
+ context "#rack_response" do
102
+ before(:each) { HTTParrot::Config.restore_defaults! }
103
+
104
+ it "returns a valid rack response" do
105
+ current = described_class.new
106
+ HTTParrot::Config.config[:template_root] = File.dirname(__FILE__) + "/templates"
107
+ current.rack_response.should be_a(Array)
108
+ current.rack_response.size.should eq(3)
109
+ current.rack_response.first.should be_a(Integer)
110
+ current.rack_response.last.should respond_to(:each)
111
+ current.rack_response[1].should be_a(Hash)
112
+ end
113
+
114
+ end
115
+
116
+ context "#to_s" do
117
+ before(:each) { HTTParrot::Config.restore_defaults! }
118
+
119
+ it "renders the file when full path is present in template_file" do
120
+ current = described_class.new
121
+ current.template_file = File.expand_path("./templates/awesometown_protocol.erb",
122
+ File.dirname(__FILE__))
123
+
124
+ current.to_s
125
+ current.header.inspect.should match(/AWESOMEHEADER/i)
126
+ end
127
+
128
+ it "prioritizes template_file over HTTParrot::Config.template_root" do
129
+ current = described_class.new
130
+ current.template_file = File.expand_path("./templates/awesometown_protocol.erb",
131
+ File.dirname(__FILE__))
132
+
133
+ current.to_s
134
+ current.header.inspect.should match(/AWESOMEHEADER/i)
135
+ end
136
+
137
+ context "rendering erb with current widget" do
138
+ before(:each) { HTTParrot::ResponseFactory.clear! }
139
+
140
+ it "inserts the value of defined methods into the output" do
141
+ current = described_class.new
142
+ current.widget_header = "TEST HEADER"
143
+ HTTParrot::Config.config[:template_root] = File.dirname(__FILE__) + "/templates"
144
+ current.to_s.should match(/TEST HEADER/)
145
+ end
146
+
147
+ it "removes erb tags when value is not present" do
148
+ current = described_class.new
149
+ HTTParrot::Config.config[:template_root] = File.dirname(__FILE__) + "/templates"
150
+ current.to_s.should_not match(/widget_header/)
151
+ end
152
+
153
+ end
154
+
155
+ context "falls back to HTTParrot::Config[:template_root] when no template_file" do
156
+ before(:each) { HTTParrot::Config.restore_defaults! }
157
+
158
+ it "warn" do
159
+ current = described_class.new
160
+ bad_dir = File.expand_path("../lib/httparrot.rb", File.dirname(__FILE__))
161
+ HTTParrot::Config.config[:template_root] = File.dirname(bad_dir)
162
+ warning = Regexp.escape(current.__send__(:template_root_search))
163
+ current.should_receive(:warn).with(/#{warning}/)
164
+ current.to_s
165
+ end
166
+
167
+ it "success" do
168
+ current = described_class.new
169
+ HTTParrot::Config.config[:template_root] = File.dirname(__FILE__) + "/templates"
170
+ current.to_s.should match(/WIDGETHEADER/i)
171
+ end
172
+
173
+ it "success, handles trailing slash" do
174
+ current = described_class.new
175
+ HTTParrot::Config.config[:template_root] = File.dirname(__FILE__) + "/templates/"
176
+ current.to_s.should match(/WIDGETHEADER/i)
177
+ end
178
+
179
+ end
180
+
181
+ end
182
+
183
+ end