anmo 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,4 @@
1
+ *.gem
2
+ .bundle
3
+ Gemfile.lock
4
+ pkg/*
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in anmo.gemspec
4
+ gemspec
@@ -0,0 +1,3 @@
1
+ guard 'shell' do
2
+ watch(/lib|test\/.*rb/) {|m| system "rake test" }
3
+ end
@@ -0,0 +1,7 @@
1
+ require "bundler/gem_tasks"
2
+
3
+ task :test do
4
+ Dir.glob("test/**/*_test.rb").each do |f|
5
+ require File.expand_path(File.join(File.dirname(__FILE__), f))
6
+ end
7
+ end
@@ -0,0 +1,31 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "anmo/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "anmo"
7
+ s.version = Anmo::VERSION
8
+ s.authors = ["Andrew Vos"]
9
+ s.email = ["andrew.vos@gmail.com"]
10
+ s.homepage = ""
11
+ s.summary = %q{}
12
+ s.description = %q{}
13
+
14
+ s.rubyforge_project = "anmo"
15
+
16
+ s.files = `git ls-files`.split("\n")
17
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
18
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
19
+ s.require_paths = ["lib"]
20
+
21
+ s.add_runtime_dependency "rack"
22
+ s.add_runtime_dependency "thin"
23
+ s.add_development_dependency "rake"
24
+ s.add_development_dependency "minitest"
25
+ s.add_development_dependency "rack-test"
26
+ s.add_development_dependency "cucumber"
27
+ s.add_development_dependency "rspec"
28
+ s.add_development_dependency "guard"
29
+ s.add_development_dependency "httparty"
30
+ s.add_development_dependency "guard-shell"
31
+ end
@@ -0,0 +1,115 @@
1
+ Feature: API
2
+ In order to test applications against stable APIs
3
+ As a developer
4
+ I want to be able to mock http endpoints
5
+
6
+ Scenario: Launch a server
7
+ When I execute the following code in a new thread
8
+ """
9
+ Anmo.launch_server
10
+ """
11
+ Then I see an anmo server on port 8787
12
+
13
+ Scenario: Launch a server with a port
14
+ When I execute the following code in a new thread
15
+ """
16
+ Anmo.launch_server 9393
17
+ """
18
+ Then I see an anmo server on port 9393
19
+
20
+ Scenario: Create a request
21
+ Given an anmo server
22
+ When I execute the code
23
+ """
24
+ Anmo.server = "http://localhost:8787"
25
+ Anmo.create_request({
26
+ :path => "/lollll",
27
+ :body => "can't think of anything",
28
+ :required_headers => {"meh" => "bleh", "blah" => "blah"}
29
+ })
30
+ """
31
+ And I request the uri "http://localhost:8787/lollll" with the headers
32
+ """
33
+ {
34
+ "meh": "bleh",
35
+ "blah": "blah"
36
+ }
37
+ """
38
+ Then I see the response body "can't think of anything"
39
+
40
+ Scenario: Save object
41
+ Given an anmo server
42
+ When I execute the code
43
+ """
44
+ Anmo.server = "http://localhost:8787"
45
+ Anmo.create_request({
46
+ :path => "/some/object",
47
+ :body => "some data"
48
+ })
49
+ """
50
+ And I request the uri "http://localhost:8787/some/object"
51
+ Then I see the response body "some data"
52
+
53
+ Scenario: Save object with http status code
54
+ Given an anmo server
55
+ When I execute the code
56
+ """
57
+ Anmo.server = "http://localhost:8787"
58
+ Anmo.create_request({
59
+ :path => "/some/object",
60
+ :status => 123
61
+ })
62
+ """
63
+ And I request the uri "http://localhost:8787/some/object"
64
+ Then I see the response code 123
65
+
66
+ Scenario: Request without required headers 404s
67
+ Given an anmo server
68
+ When I execute the code
69
+ """
70
+ Anmo.server = "http://localhost:8787"
71
+ Anmo.create_request({
72
+ :path => "/some/object",
73
+ :required_headers => {:meh => "bleh", :durp => "derp"}
74
+ })
75
+ """
76
+ And I request the uri "http://localhost:8787/some/object"
77
+ Then I see the response code 404
78
+
79
+ Scenario: Request with required headers
80
+ Given an anmo server
81
+ When I execute the code
82
+ """
83
+ Anmo.server = "http://localhost:8787"
84
+ Anmo.create_request({
85
+ :path => "/some/object",
86
+ :body => "helloow",
87
+ :required_headers => {:meh => "bleh", :durp => "derp"}
88
+ })
89
+ """
90
+ And I request the uri "http://localhost:8787/some/object" with the headers
91
+ """
92
+ {
93
+ "meh": "bleh",
94
+ "durp": "derp"
95
+ }
96
+ """
97
+ Then I see the response body "helloow"
98
+ And I see the response code 200
99
+
100
+ Scenario: Delete all saved objects
101
+ Given an anmo server
102
+ When I execute the code
103
+ """
104
+ Anmo.server = "http://localhost:8787"
105
+ Anmo.create_request({
106
+ :path => "/some/object",
107
+ :body => "some data"
108
+ })
109
+ """
110
+ And I execute the code
111
+ """
112
+ Anmo.delete_all
113
+ """
114
+ And I request the uri "http://localhost:8787/some/object"
115
+ Then I see the response code 404
@@ -0,0 +1,51 @@
1
+ When /^I execute the following code in a new thread$/ do |code|
2
+ Thread.new do
3
+ eval code
4
+ end
5
+ end
6
+
7
+ When /^I execute the code$/ do |code|
8
+ eval code
9
+ end
10
+
11
+ Then /^I see an anmo server on port (\d+)$/ do |port|
12
+ response = nil
13
+
14
+ timeout 5 do
15
+ while response.nil?
16
+ response = HTTParty.get("http://localhost:#{port}") rescue nil
17
+ end
18
+ end
19
+
20
+ response.body.should include "Not Found"
21
+ end
22
+
23
+ Given /^an anmo server$/ do
24
+ Thread.new do
25
+ Anmo.launch_server
26
+ end
27
+ timeout 5 do
28
+ response = nil
29
+ while response.nil?
30
+ response = HTTParty.get("http://localhost:8787") rescue nil
31
+ end
32
+ sleep 0.1
33
+ end
34
+ end
35
+
36
+ When /^I request the uri "([^"]*)"$/ do |uri|
37
+ @response = HTTParty.get(uri)
38
+ end
39
+
40
+ When /^I request the uri "([^"]*)" with the headers$/ do |uri, headers|
41
+ headers = JSON.parse(headers)
42
+ @response = HTTParty.get(uri, :headers => headers)
43
+ end
44
+
45
+ Then /^I see the response body "([^"]*)"$/ do |body|
46
+ @response.body.should == body
47
+ end
48
+
49
+ Then /^I see the response code (\d+)$/ do |code|
50
+ @response.code.should == code.to_i
51
+ end
@@ -0,0 +1,13 @@
1
+ require "rack"
2
+ require "rack/test"
3
+ require "httparty"
4
+
5
+ $:.unshift(File.expand_path(File.join(File.dirname(__FILE__), "../../lib")))
6
+ require "anmo"
7
+ require "anmo/application"
8
+
9
+ World(Rack::Test::Methods)
10
+
11
+ def app
12
+ Anmo::Application.new
13
+ end
@@ -0,0 +1,21 @@
1
+ require "anmo/version"
2
+ require "anmo/application"
3
+ require "thin"
4
+
5
+ module Anmo
6
+ class << self
7
+ attr_accessor :server
8
+ end
9
+
10
+ def self.launch_server port = 8787
11
+ Thin::Server.start("0.0.0.0", port, Anmo::Application.new)
12
+ end
13
+
14
+ def self.create_request options
15
+ HTTParty.put("#{server}/__CREATE__", :body => options.to_json)
16
+ end
17
+
18
+ def self.delete_all
19
+ HTTParty.put("#{server}/__DELETE_ALL__")
20
+ end
21
+ end
@@ -0,0 +1,65 @@
1
+ require "ostruct"
2
+
3
+ module Anmo
4
+ class Application
5
+ def call env
6
+ @stored_requests ||= []
7
+ request = Rack::Request.new(env)
8
+
9
+ if request.path_info == "/__CREATE__"
10
+ process_create_request request
11
+ elsif request.path_info == "/__DELETE_ALL__"
12
+ process_delete_all_request request
13
+ else
14
+ process_normal_request request
15
+ end
16
+ end
17
+
18
+ private
19
+
20
+ def process_create_request request
21
+ request_info = JSON.parse(read_request_body(request))
22
+ @stored_requests.unshift(request_info)
23
+ [201, {}, ""]
24
+ end
25
+
26
+ def process_delete_all_request request
27
+ @stored_requests = []
28
+ [200, {}, ""]
29
+ end
30
+
31
+ def process_normal_request request
32
+ if found_request = find_stored_request(request)
33
+ [Integer(found_request["status"]||200), {"Content-Type" => "text/html"}, [found_request["body"]]]
34
+ else
35
+ [404, {"Content-Type" => "text/html"}, "Not Found"]
36
+ end
37
+ end
38
+
39
+ def find_stored_request actual_request
40
+ found_request = @stored_requests.find {|r| r["path"] == actual_request.path_info}
41
+ if found_request
42
+ required_headers = found_request["required_headers"] || []
43
+ required_headers.each do |name, value|
44
+ if actual_request.env[convert_header_name_to_rack_style_name(name)] != value
45
+ found_request = nil
46
+ break
47
+ end
48
+ end
49
+ end
50
+ found_request
51
+ end
52
+
53
+ def convert_header_name_to_rack_style_name name
54
+ name = "HTTP_#{name}"
55
+ name.gsub!("-", "_")
56
+ name.upcase!
57
+ name
58
+ end
59
+
60
+ def read_request_body request
61
+ request.body.rewind
62
+ request.body.read
63
+ end
64
+ end
65
+ end
@@ -0,0 +1,3 @@
1
+ module Anmo
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,86 @@
1
+ require "minitest/pride"
2
+ require "minitest/autorun"
3
+ require "minitest/unit"
4
+ require "rack/test"
5
+ require "json"
6
+ require File.expand_path(File.join(File.dirname(__FILE__), "../../lib/anmo/application"))
7
+
8
+ module Anmo
9
+ class ApplicationTest < MiniTest::Unit::TestCase
10
+ include Rack::Test::Methods
11
+
12
+ def app
13
+ Application.new
14
+ end
15
+
16
+ def save_object path, body, status, required_headers
17
+ options = {
18
+ :path => path,
19
+ :body => body,
20
+ :status => status,
21
+ :required_headers => required_headers
22
+ }
23
+ put "__CREATE__", options.to_json
24
+ end
25
+
26
+ def test_404s_if_object_does_not_exist
27
+ get "/bla/bla/bla.json"
28
+ assert_equal "Not Found", last_response.body
29
+ assert last_response.not_found?
30
+ end
31
+
32
+ def test_stores_mock_data
33
+ save_object "/this/is/the/path.object", "please save this", nil, nil
34
+ assert_equal 201, last_response.status
35
+
36
+ get "/this/is/the/path.object"
37
+ assert_equal "please save this", last_response.body
38
+ assert last_response.ok?
39
+ end
40
+
41
+ def test_stores_status_code
42
+ save_object "/monkeys", nil, 123, nil
43
+ get "/monkeys"
44
+ assert_equal 123, last_response.status
45
+ end
46
+
47
+ def test_allows_deleting_all_objects
48
+ save_object "/this/is/the/path.object", "please save this", nil, nil
49
+
50
+ get "/this/is/the/path.object"
51
+ first_response = last_response
52
+
53
+ put "__DELETE_ALL__"
54
+ assert_equal 200, last_response.status
55
+
56
+ get "/this/is/the/path.object"
57
+ second_response = last_response
58
+
59
+ assert_equal "please save this", first_response.body
60
+ assert_equal "Not Found", second_response.body
61
+ assert_equal 404, second_response.status
62
+ end
63
+
64
+ def test_404s_if_request_does_not_have_required_headers
65
+ save_object "/oh/hai", nil, nil, {"ruby" => "hipsters", "meh" => "bleh"}
66
+ get "/oh/hai"
67
+ assert_equal 404, last_response.status
68
+ end
69
+
70
+ def test_returns_value_if_request_has_required_headers
71
+ save_object "/oh/hai", "the content", nil, {"lol-ruby" => "hipsters", "meh" => "bleh"}
72
+ header "lol-ruby", "hipsters"
73
+ header "meh", "bleh"
74
+ get "/oh/hai"
75
+ assert_equal 200, last_response.status
76
+ assert_equal "the content", last_response.body
77
+ end
78
+
79
+ def test_returns_the_last_added_object_first
80
+ save_object "/oh/hai", "the first content", nil, nil
81
+ save_object "/oh/hai", "the second content", nil, nil
82
+ get "/oh/hai"
83
+ assert_equal "the second content", last_response.body
84
+ end
85
+ end
86
+ end
metadata ADDED
@@ -0,0 +1,171 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: anmo
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Andrew Vos
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-02-26 00:00:00.000000000Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: rack
16
+ requirement: &70320251647360 !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: *70320251647360
25
+ - !ruby/object:Gem::Dependency
26
+ name: thin
27
+ requirement: &70320251646940 !ruby/object:Gem::Requirement
28
+ none: false
29
+ requirements:
30
+ - - ! '>='
31
+ - !ruby/object:Gem::Version
32
+ version: '0'
33
+ type: :runtime
34
+ prerelease: false
35
+ version_requirements: *70320251646940
36
+ - !ruby/object:Gem::Dependency
37
+ name: rake
38
+ requirement: &70320251646520 !ruby/object:Gem::Requirement
39
+ none: false
40
+ requirements:
41
+ - - ! '>='
42
+ - !ruby/object:Gem::Version
43
+ version: '0'
44
+ type: :development
45
+ prerelease: false
46
+ version_requirements: *70320251646520
47
+ - !ruby/object:Gem::Dependency
48
+ name: minitest
49
+ requirement: &70320251646100 !ruby/object:Gem::Requirement
50
+ none: false
51
+ requirements:
52
+ - - ! '>='
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ type: :development
56
+ prerelease: false
57
+ version_requirements: *70320251646100
58
+ - !ruby/object:Gem::Dependency
59
+ name: rack-test
60
+ requirement: &70320251645680 !ruby/object:Gem::Requirement
61
+ none: false
62
+ requirements:
63
+ - - ! '>='
64
+ - !ruby/object:Gem::Version
65
+ version: '0'
66
+ type: :development
67
+ prerelease: false
68
+ version_requirements: *70320251645680
69
+ - !ruby/object:Gem::Dependency
70
+ name: cucumber
71
+ requirement: &70320251645260 !ruby/object:Gem::Requirement
72
+ none: false
73
+ requirements:
74
+ - - ! '>='
75
+ - !ruby/object:Gem::Version
76
+ version: '0'
77
+ type: :development
78
+ prerelease: false
79
+ version_requirements: *70320251645260
80
+ - !ruby/object:Gem::Dependency
81
+ name: rspec
82
+ requirement: &70320251644840 !ruby/object:Gem::Requirement
83
+ none: false
84
+ requirements:
85
+ - - ! '>='
86
+ - !ruby/object:Gem::Version
87
+ version: '0'
88
+ type: :development
89
+ prerelease: false
90
+ version_requirements: *70320251644840
91
+ - !ruby/object:Gem::Dependency
92
+ name: guard
93
+ requirement: &70320251644420 !ruby/object:Gem::Requirement
94
+ none: false
95
+ requirements:
96
+ - - ! '>='
97
+ - !ruby/object:Gem::Version
98
+ version: '0'
99
+ type: :development
100
+ prerelease: false
101
+ version_requirements: *70320251644420
102
+ - !ruby/object:Gem::Dependency
103
+ name: httparty
104
+ requirement: &70320251644000 !ruby/object:Gem::Requirement
105
+ none: false
106
+ requirements:
107
+ - - ! '>='
108
+ - !ruby/object:Gem::Version
109
+ version: '0'
110
+ type: :development
111
+ prerelease: false
112
+ version_requirements: *70320251644000
113
+ - !ruby/object:Gem::Dependency
114
+ name: guard-shell
115
+ requirement: &70320251643580 !ruby/object:Gem::Requirement
116
+ none: false
117
+ requirements:
118
+ - - ! '>='
119
+ - !ruby/object:Gem::Version
120
+ version: '0'
121
+ type: :development
122
+ prerelease: false
123
+ version_requirements: *70320251643580
124
+ description: ''
125
+ email:
126
+ - andrew.vos@gmail.com
127
+ executables: []
128
+ extensions: []
129
+ extra_rdoc_files: []
130
+ files:
131
+ - .gitignore
132
+ - Gemfile
133
+ - Guardfile
134
+ - Rakefile
135
+ - anmo.gemspec
136
+ - features/api.feature
137
+ - features/step_definitions/api_steps.rb
138
+ - features/support/env.rb
139
+ - lib/anmo.rb
140
+ - lib/anmo/application.rb
141
+ - lib/anmo/version.rb
142
+ - test/anmo/application_test.rb
143
+ homepage: ''
144
+ licenses: []
145
+ post_install_message:
146
+ rdoc_options: []
147
+ require_paths:
148
+ - lib
149
+ required_ruby_version: !ruby/object:Gem::Requirement
150
+ none: false
151
+ requirements:
152
+ - - ! '>='
153
+ - !ruby/object:Gem::Version
154
+ version: '0'
155
+ required_rubygems_version: !ruby/object:Gem::Requirement
156
+ none: false
157
+ requirements:
158
+ - - ! '>='
159
+ - !ruby/object:Gem::Version
160
+ version: '0'
161
+ requirements: []
162
+ rubyforge_project: anmo
163
+ rubygems_version: 1.8.10
164
+ signing_key:
165
+ specification_version: 3
166
+ summary: ''
167
+ test_files:
168
+ - features/api.feature
169
+ - features/step_definitions/api_steps.rb
170
+ - features/support/env.rb
171
+ - test/anmo/application_test.rb