harper 0.0.4 → 0.1.0

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.
data/README.md ADDED
@@ -0,0 +1,59 @@
1
+ # Harper: Dead-simple, out-of-process, HTTP mocks
2
+
3
+ To mock a service using as Harper, POST a mock definition to Harper
4
+ before making your request. It's simple, and you've probably written
5
+ something similar a half-dozen times. Well, you don't need to anymore.
6
+
7
+ You might be interested in using Harper when you're building an app
8
+ that depends on an HTTP service, but you can't mock it out
9
+ in-process. For example, a single page JavaScript app running in a
10
+ mobile browser.
11
+
12
+ ## Ruby Client API
13
+
14
+ Unfortunately there aren't yet interfaces to Harper from other languages.
15
+
16
+ * Use `HarperClient::start` to start the Harper service in the
17
+ background.
18
+
19
+ * Use `HarperClient::stop` to stop the background service.
20
+
21
+ These two calls do start and stop another Ruby interpreter running in
22
+ the background, so you might want to run these at the beginning and
23
+ the end of your cucumber run, rather than before and after every
24
+ scenario.
25
+
26
+ This interface is incomplete. It is also possible to delete a
27
+ mock. This can be done by deleting the URL provided in the `Location`
28
+ header when creating a new mock.
29
+
30
+ If you require more control of Harper, or you want to support a new
31
+ language, check out `features/mock_http_rpc_service.feature`. And pull
32
+ requests are always welcomed.
33
+
34
+ ### Defining Mocks
35
+
36
+ Use `HarperClient::mock` to define a new mock. This method takes a
37
+ hash defining the mock. If a mock has already been defined for a URL,
38
+ Harper will silently replace it with the new mock.
39
+
40
+ * *url*: The URL path to mock out. This also identifies the mock. Required.
41
+ * *method*: The HTTP method to respond to. Required.
42
+
43
+ * *status*: The HTTP status code to provide. Optional. Defaults to 200.
44
+ * *content_type*: What content-type header to set when responding with
45
+ the mock. Required.
46
+ * *body*: A string to be used as the HTTP response body. Required.
47
+
48
+ * *delay*: A delay to include when responding to the mock,
49
+ in milliseconds. Optional. Defaults to no delay.
50
+
51
+ ## Typical Use
52
+
53
+ 1. Start Harper at the very start of your test run.
54
+ 2. In the Given steps or Background for your scenarios, define the
55
+ mocks that will be required for that scenario. If a similar mock has
56
+ already been defined, Harper will silently replace it.
57
+ 3. At the very end of your test run, stop Harper.
58
+
59
+ That's it.
data/bin/harper CHANGED
@@ -10,6 +10,8 @@ opts = Trollop::options do
10
10
  end
11
11
 
12
12
  def start(port)
13
+ # Harper needs access to the server hosting itself so that it can shut
14
+ # it down on demand
13
15
  server = Rack::Server.new :app => Harper::App, :Port => port, :server => 'webrick'
14
16
  Harper::App.server(server.server)
15
17
  server.start
@@ -35,8 +37,6 @@ def start_in_background(port)
35
37
  read.readline
36
38
  end
37
39
 
38
- # Harper needs access to the server hosting itself so that it can shut
39
- # it down on demand
40
40
  if opts[:bg]
41
41
  start_in_background(opts[:port])
42
42
  else
data/lib/harper/app.rb CHANGED
@@ -6,8 +6,6 @@ require 'json'
6
6
  module Harper
7
7
  class App < Sinatra::Base
8
8
 
9
- Version = "0.0.2"
10
-
11
9
  @@mocks = {}
12
10
  @@server = nil
13
11
 
data/lib/harper/client.rb CHANGED
@@ -15,13 +15,16 @@ class HarperClient
15
15
  end
16
16
 
17
17
  def start
18
- system("harper --port 4568 --bg")
18
+ Kernel.system("harper --port 4568 --bg")
19
19
  @started = true
20
20
  end
21
21
 
22
22
  def stop
23
23
  self.class.put "/h/control", :body => {:command => "quit"}.to_json
24
24
  @started = false
25
+ rescue Exception => e
26
+ # Ignore the error here as it's pretty common for the connection
27
+ # to be killed out from under the app
25
28
  end
26
29
 
27
30
  def mock(mock)
@@ -1,3 +1,3 @@
1
1
  module Harper
2
- Version = "0.0.4"
2
+ Version = "0.1.0"
3
3
  end
@@ -0,0 +1,66 @@
1
+ $: << File.dirname(__FILE__) + "/.."
2
+
3
+ require 'spec/spec_helper'
4
+ require 'harper/client'
5
+
6
+ describe HarperClient do
7
+
8
+ subject { HarperClient.new }
9
+
10
+ describe '#start' do
11
+ it "should start on port 4568" do
12
+ Kernel.should_receive(:system).with("harper --port 4568 --bg")
13
+ subject.start
14
+ end
15
+
16
+ it "should be started after calling start" do
17
+ Kernel.stub!(:system)
18
+ subject.start
19
+ subject.should be_started
20
+ end
21
+ end
22
+
23
+ describe '#stop' do
24
+ before(:each) do
25
+ Kernel.stub!(:system)
26
+ subject.start
27
+ end
28
+
29
+ it "should put a quit command to the control interface" do
30
+ HarperClient.should_receive(:put).with("/h/control", :body => "{\"command\":\"quit\"}")
31
+ subject.stop
32
+ end
33
+
34
+ it "should not be started" do
35
+ HarperClient.stub!(:put)
36
+ subject.stop
37
+ subject.should_not be_started
38
+ end
39
+
40
+ it "should swallow any errors that might result" do
41
+ HarperClient.stub!(:put).and_throw(:anything)
42
+ expect { subject.stop }.to_not raise_error
43
+ end
44
+ end
45
+
46
+ describe '#mock' do
47
+ describe 'using a hash' do
48
+ let(:mock_def) { {:sample => "hash" } }
49
+
50
+ it "should post to the mocks interface" do
51
+ HarperClient.should_receive(:post).with("/h/mocks", :body => mock_def.to_json)
52
+ subject.mock(mock_def)
53
+ end
54
+ end
55
+
56
+ describe 'using a string' do
57
+ let(:mock_def) { "sample" }
58
+
59
+ it "should post to the mocks interface" do
60
+ HarperClient.should_receive(:post).with("/h/mocks", :body => mock_def)
61
+ subject.mock(mock_def)
62
+ end
63
+ end
64
+ end
65
+
66
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: harper
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.4
4
+ version: 0.1.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,11 +9,11 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-03-05 00:00:00.000000000 Z
12
+ date: 2012-04-08 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: sinatra
16
- requirement: &70306501088500 !ruby/object:Gem::Requirement
16
+ requirement: &70294496714100 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ! '>='
@@ -21,10 +21,10 @@ dependencies:
21
21
  version: 1.0.0
22
22
  type: :runtime
23
23
  prerelease: false
24
- version_requirements: *70306501088500
24
+ version_requirements: *70294496714100
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: httparty
27
- requirement: &70306501087560 !ruby/object:Gem::Requirement
27
+ requirement: &70294496713200 !ruby/object:Gem::Requirement
28
28
  none: false
29
29
  requirements:
30
30
  - - ! '>='
@@ -32,10 +32,10 @@ dependencies:
32
32
  version: '0'
33
33
  type: :runtime
34
34
  prerelease: false
35
- version_requirements: *70306501087560
35
+ version_requirements: *70294496713200
36
36
  - !ruby/object:Gem::Dependency
37
37
  name: json
38
- requirement: &70306501086480 !ruby/object:Gem::Requirement
38
+ requirement: &70294496712180 !ruby/object:Gem::Requirement
39
39
  none: false
40
40
  requirements:
41
41
  - - ! '>='
@@ -43,10 +43,10 @@ dependencies:
43
43
  version: 1.4.6
44
44
  type: :runtime
45
45
  prerelease: false
46
- version_requirements: *70306501086480
46
+ version_requirements: *70294496712180
47
47
  - !ruby/object:Gem::Dependency
48
48
  name: trollop
49
- requirement: &70306501085640 !ruby/object:Gem::Requirement
49
+ requirement: &70294496711320 !ruby/object:Gem::Requirement
50
50
  none: false
51
51
  requirements:
52
52
  - - ! '>='
@@ -54,10 +54,10 @@ dependencies:
54
54
  version: '0'
55
55
  type: :runtime
56
56
  prerelease: false
57
- version_requirements: *70306501085640
57
+ version_requirements: *70294496711320
58
58
  - !ruby/object:Gem::Dependency
59
59
  name: rack-test
60
- requirement: &70306501084920 !ruby/object:Gem::Requirement
60
+ requirement: &70294496710600 !ruby/object:Gem::Requirement
61
61
  none: false
62
62
  requirements:
63
63
  - - ! '>='
@@ -65,10 +65,10 @@ dependencies:
65
65
  version: '0'
66
66
  type: :development
67
67
  prerelease: false
68
- version_requirements: *70306501084920
68
+ version_requirements: *70294496710600
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: sham_rack
71
- requirement: &70306501084320 !ruby/object:Gem::Requirement
71
+ requirement: &70294496710000 !ruby/object:Gem::Requirement
72
72
  none: false
73
73
  requirements:
74
74
  - - ! '>='
@@ -76,10 +76,10 @@ dependencies:
76
76
  version: '0'
77
77
  type: :development
78
78
  prerelease: false
79
- version_requirements: *70306501084320
79
+ version_requirements: *70294496710000
80
80
  - !ruby/object:Gem::Dependency
81
81
  name: rspec
82
- requirement: &70306501083780 !ruby/object:Gem::Requirement
82
+ requirement: &70294496709440 !ruby/object:Gem::Requirement
83
83
  none: false
84
84
  requirements:
85
85
  - - ! '>='
@@ -87,10 +87,10 @@ dependencies:
87
87
  version: '0'
88
88
  type: :development
89
89
  prerelease: false
90
- version_requirements: *70306501083780
90
+ version_requirements: *70294496709440
91
91
  - !ruby/object:Gem::Dependency
92
92
  name: cucumber
93
- requirement: &70306501083040 !ruby/object:Gem::Requirement
93
+ requirement: &70294496708720 !ruby/object:Gem::Requirement
94
94
  none: false
95
95
  requirements:
96
96
  - - ! '>='
@@ -98,10 +98,10 @@ dependencies:
98
98
  version: '0.10'
99
99
  type: :development
100
100
  prerelease: false
101
- version_requirements: *70306501083040
101
+ version_requirements: *70294496708720
102
102
  - !ruby/object:Gem::Dependency
103
103
  name: cucumber-sinatra
104
- requirement: &70306501075940 !ruby/object:Gem::Requirement
104
+ requirement: &70294496701580 !ruby/object:Gem::Requirement
105
105
  none: false
106
106
  requirements:
107
107
  - - ! '>='
@@ -109,7 +109,7 @@ dependencies:
109
109
  version: '0'
110
110
  type: :development
111
111
  prerelease: false
112
- version_requirements: *70306501075940
112
+ version_requirements: *70294496701580
113
113
  description: Dead simple mocking for HTTP services, a Sinatra app
114
114
  email:
115
115
  - giles.alexander@gmail.com
@@ -122,6 +122,7 @@ files:
122
122
  - .rvmrc
123
123
  - Gemfile
124
124
  - Gemfile.lock
125
+ - README.md
125
126
  - Rakefile
126
127
  - bin/harper
127
128
  - features/mock_http_rpc_service.feature
@@ -136,6 +137,7 @@ files:
136
137
  - lib/harper/app.rb
137
138
  - lib/harper/client.rb
138
139
  - lib/harper/version.rb
140
+ - spec/client_spec.rb
139
141
  - spec/harper_spec.rb
140
142
  - spec/spec_helper.rb
141
143
  homepage: http://github.com/gga/harper
@@ -170,5 +172,6 @@ test_files:
170
172
  - features/support/client_application.rb
171
173
  - features/support/env.rb
172
174
  - features/support/paths.rb
175
+ - spec/client_spec.rb
173
176
  - spec/harper_spec.rb
174
177
  - spec/spec_helper.rb