yafs 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 385cc47ec88fed9fc010425357a7bbec1477e325
4
+ data.tar.gz: af9f726b7c815815f3c6221172bbf990e1dc739c
5
+ SHA512:
6
+ metadata.gz: 6253652950e09c1a6e285969491c76203fccfff2be4eb551ac1afaf7bc199e6c1dc86ec84c32b636f11b2467ccf5e8c9283ca0cbf3393a26c5ea02386cbc0775
7
+ data.tar.gz: 40365dc4ff62495e60f5474579a36b6395ce4ac6d8784151b5cef2943f0a89889e6d354f5def8ef2a8506e396b0fce528e5791c26030bf6b0eb516101e5b207b
File without changes
@@ -0,0 +1,166 @@
1
+ require 'rack'
2
+ require 'singleton'
3
+ require 'WEBrick'
4
+
5
+ Thread.abort_on_exception = true
6
+
7
+ module Fake
8
+ class Response
9
+ attr_reader :body, :status
10
+
11
+ def initialize(body, status)
12
+ @body = body
13
+ @status = status
14
+ end
15
+
16
+ end
17
+
18
+ #
19
+ # Queue which returns last value forever
20
+ #
21
+ class InfiniteQueue
22
+ def initialize
23
+ @current_item_index = 0
24
+ @items = []
25
+ end
26
+
27
+ def <<(item)
28
+ @items << item
29
+ end
30
+
31
+ def next
32
+ item = @items[@current_item_index]
33
+ @current_item_index += 1 if @current_item_index < (@items.count - 1)
34
+ item
35
+ end
36
+ end
37
+
38
+ class RequestHandler
39
+ attr_reader :responses
40
+
41
+ def initialize(path)
42
+ @path = path
43
+ @responses = InfiniteQueue.new
44
+ end
45
+
46
+ def call(request)
47
+ return unless request.path.eql? @path
48
+ current_response = @responses.next
49
+ Rack::Response.new([current_response.body], status=current_response.status)
50
+ end
51
+
52
+ end
53
+
54
+ class RequestHandlerBuilder
55
+ def initialize(request_handler)
56
+ @request_handler = request_handler
57
+ end
58
+
59
+ #
60
+ # DSL
61
+ #
62
+ def respond(body:nil, status:200)
63
+ @request_handler.responses << Response.new(body, status)
64
+ self
65
+ end
66
+ end
67
+
68
+ class RackApp
69
+ def initialize
70
+ @handlers = []
71
+ end
72
+
73
+ def add_request_handler(request_handler)
74
+ @handlers << request_handler
75
+ end
76
+
77
+ def call(env)
78
+ request = Rack::Request.new(env)
79
+ # TODO: Make this part of rack stack
80
+ Requests.add_request(request)
81
+
82
+ @handlers.each do |handler|
83
+ response = handler.call(request)
84
+ return response if response
85
+ end
86
+ raise "NO HANDLER for #{request.path}"
87
+ end
88
+ end
89
+
90
+ class Server
91
+
92
+ def start(rack_app, webrick_config)
93
+ return unless @server_thread.nil?
94
+ mutex = Mutex.new
95
+ server_started = ConditionVariable.new
96
+ @server_thread = Thread.new(rack_app, webrick_config) do |app, config|
97
+ @server = WEBrick::HTTPServer.new(config)
98
+ @server.mount "/", Rack::Handler::WEBrick, app
99
+ server_started.signal
100
+ @server.start
101
+ end
102
+ mutex.synchronize do
103
+ server_started.wait(mutex)
104
+ end
105
+ end
106
+
107
+ def stop
108
+ unless @server_thread.nil?
109
+ @server.shutdown
110
+ @server_thread.join if @server_thread.alive?
111
+ @server_thread = nil
112
+ end
113
+ end
114
+ end
115
+
116
+ class Service
117
+ def initialize(port:8080, bind:"localhost")
118
+ @app = RackApp.new
119
+ @webrick_config = {Port:port, BindAddress:bind}
120
+ @server = Server.new
121
+ end
122
+
123
+ def get(path)
124
+ request_handler = RequestHandler.new(path)
125
+ @app.add_request_handler(request_handler)
126
+ RequestHandlerBuilder.new(request_handler)
127
+ end
128
+
129
+ def start
130
+ @server.start(@app, @webrick_config)
131
+ end
132
+
133
+ def stop
134
+ @server.stop
135
+ end
136
+ end
137
+
138
+ class Requests
139
+
140
+ attr_accessor :requests
141
+ include Singleton
142
+ class << self
143
+ def request(method, path)
144
+ matching_request = nil
145
+ instance.requests.each do |request|
146
+ if request.request_method == method.to_s.upcase &&
147
+ request.path == path
148
+ matching_request = request
149
+ end
150
+ end
151
+ matching_request
152
+ end
153
+
154
+ def add_request(request)
155
+ instance.requests << request
156
+ end
157
+ end
158
+ private
159
+ def initialize
160
+ @requests = []
161
+ end
162
+
163
+
164
+ end
165
+ end
166
+
@@ -0,0 +1,109 @@
1
+ require 'spec_helper'
2
+ require 'httparty'
3
+
4
+ describe 'Fake Service' do
5
+ let(:fs) { Fake::Service.new(port:4567) }
6
+ after(:each) { fs.stop }
7
+
8
+ describe "configuration" do
9
+ let(:fs) { Fake::Service.new(bind:'127.0.0.1') }
10
+ it "can be bind to different addresses" do
11
+ fs.get('/').respond(body:"ok")
12
+ fs.start
13
+ expect(HTTParty.get('http://127.0.0.1:8080').body).to eq "ok"
14
+ end
15
+ end
16
+
17
+ describe "many fake services on different ports" do
18
+ xit "handles requests ok" do
19
+ end
20
+ end
21
+
22
+ describe "Simple service without parameters" do
23
+ it "simple to setup" do
24
+ fs.get('/').respond(body:"_response_")
25
+ fs.start
26
+
27
+ response = HTTParty.get('http://localhost:4567')
28
+ expect(response.body).to eq "_response_"
29
+ end
30
+ end
31
+
32
+ describe "Response code" do
33
+ it "returns assigned response code" do
34
+ fs.get('/').respond(status:404)
35
+ fs.start
36
+
37
+ response = HTTParty.get('http://localhost:4567')
38
+ expect(response.code).to eq 404
39
+ end
40
+ end
41
+
42
+ describe "Paths" do
43
+ describe "static paths" do
44
+ it "routes requests to correct handler" do
45
+ fs.get('/cart').respond(body:"1")
46
+ fs.get('/order/new').respond(body:"2")
47
+ fs.start
48
+
49
+ expect(HTTParty.get('http://localhost:4567/cart' ).response.body).to eq "1"
50
+ expect(HTTParty.get('http://localhost:4567/order/new').response.body).to eq "2"
51
+ end
52
+ end
53
+
54
+ describe "dynamic paths" do
55
+ xit "routes request to match path variables" do
56
+ fs.get('/cart/:id/status').response(body:"ok")
57
+ fs.start
58
+ expect(HTTParty.get('http://localhost:4567/cart/path/status').response.body).to eq "ok"
59
+ end
60
+ end
61
+
62
+ describe "Responding specific request" do
63
+ xit "can respond based on query parameter" do
64
+ # what about specific parameters vs some parameter
65
+ fs.get('/cart/option').param('id=5').respond("ok") # Matches /cart/option?id=5,
66
+ end
67
+ end
68
+
69
+ describe "Checking request parameters" do
70
+ it "can verify single parameter" do
71
+ fs.get('/cart')
72
+ fs.start
73
+ HTTParty.get('http://localhost:4567/cart?id=5&status=pending')
74
+ params = Fake::Requests.request(:get, '/cart').params
75
+ expect(params.has_key? 'id')
76
+ expect(params.has_key? 'status')
77
+ expect(params["id"]).to eq "5"
78
+ expect(params["status"]).to eq "pending"
79
+ end
80
+
81
+ xit "can name a request to ease matching of request" do
82
+ fs.get('/cart', name: :my_cart_request)
83
+ fs.start
84
+ HTTParty.get('http://localhost:4567/cart?id=5&status=pending')
85
+ expect(Fake::Requests.request(:my_cart_request)).not_to be nil
86
+ end
87
+ end
88
+
89
+ describe "ordering" do
90
+ xit "routes request to latest handler, which match the request" do
91
+ end
92
+ end
93
+ end
94
+
95
+ describe "Setting responses" do
96
+ describe "chaining responses" do
97
+ it "returns responses in order" do
98
+ fs.get('/cart').respond(body:"1").respond(body:"2").respond(body:"3")
99
+ fs.start
100
+ expect(HTTParty.get('http://localhost:4567/cart').response.body).to eq "1"
101
+ expect(HTTParty.get('http://localhost:4567/cart').response.body).to eq "2"
102
+ expect(HTTParty.get('http://localhost:4567/cart').response.body).to eq "3"
103
+ expect(HTTParty.get('http://localhost:4567/cart').response.body).to eq "3"
104
+ expect(HTTParty.get('http://localhost:4567/cart').response.body).to eq "3"
105
+ end
106
+ end
107
+ end
108
+
109
+ end
@@ -0,0 +1,93 @@
1
+ # This file was generated by the `rspec --init` command. Conventionally, all
2
+ # specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`.
3
+ # The generated `.rspec` file contains `--require spec_helper` which will cause
4
+ # this file to always be loaded, without a need to explicitly require it in any
5
+ # files.
6
+ #
7
+ # Given that it is always loaded, you are encouraged to keep this file as
8
+ # light-weight as possible. Requiring heavyweight dependencies from this file
9
+ # will add to the boot time of your test suite on EVERY test run, even for an
10
+ # individual file that may not need all of that loaded. Instead, consider making
11
+ # a separate helper file that requires the additional dependencies and performs
12
+ # the additional setup, and require it from the spec files that actually need
13
+ # it.
14
+ #
15
+ # The `.rspec` file also contains a few flags that are not defaults but that
16
+ # users commonly want.
17
+ #
18
+ # See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
19
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), *%w[.. lib]))
20
+ require 'fake_service'
21
+ RSpec.configure do |config|
22
+ # rspec-expectations config goes here. You can use an alternate
23
+ # assertion/expectation library such as wrong or the stdlib/minitest
24
+ # assertions if you prefer.
25
+ config.expect_with :rspec do |expectations|
26
+ # This option will default to `true` in RSpec 4. It makes the `description`
27
+ # and `failure_message` of custom matchers include text for helper methods
28
+ # defined using `chain`, e.g.:
29
+ # be_bigger_than(2).and_smaller_than(4).description
30
+ # # => "be bigger than 2 and smaller than 4"
31
+ # ...rather than:
32
+ # # => "be bigger than 2"
33
+ expectations.include_chain_clauses_in_custom_matcher_descriptions = true
34
+ end
35
+
36
+ # rspec-mocks config goes here. You can use an alternate test double
37
+ # library (such as bogus or mocha) by changing the `mock_with` option here.
38
+ config.mock_with :rspec do |mocks|
39
+ # Prevents you from mocking or stubbing a method that does not exist on
40
+ # a real object. This is generally recommended, and will default to
41
+ # `true` in RSpec 4.
42
+ mocks.verify_partial_doubles = true
43
+ end
44
+
45
+ # The settings below are suggested to provide a good initial experience
46
+ # with RSpec, but feel free to customize to your heart's content.
47
+ =begin
48
+ # These two settings work together to allow you to limit a spec run
49
+ # to individual examples or groups you care about by tagging them with
50
+ # `:focus` metadata. When nothing is tagged with `:focus`, all examples
51
+ # get run.
52
+ config.filter_run :focus
53
+ config.run_all_when_everything_filtered = true
54
+
55
+ # Limits the available syntax to the non-monkey patched syntax that is
56
+ # recommended. For more details, see:
57
+ # - http://myronmars.to/n/dev-blog/2012/06/rspecs-new-expectation-syntax
58
+ # - http://teaisaweso.me/blog/2013/05/27/rspecs-new-message-expectation-syntax/
59
+ # - http://myronmars.to/n/dev-blog/2014/05/notable-changes-in-rspec-3#new__config_option_to_disable_rspeccore_monkey_patching
60
+ config.disable_monkey_patching!
61
+
62
+ # This setting enables warnings. It's recommended, but in some cases may
63
+ # be too noisy due to issues in dependencies.
64
+ config.warnings = true
65
+
66
+ # Many RSpec users commonly either run the entire suite or an individual
67
+ # file, and it's useful to allow more verbose output when running an
68
+ # individual spec file.
69
+ if config.files_to_run.one?
70
+ # Use the documentation formatter for detailed output,
71
+ # unless a formatter has already been configured
72
+ # (e.g. via a command-line flag).
73
+ config.default_formatter = 'doc'
74
+ end
75
+
76
+ # Print the 10 slowest examples and example groups at the
77
+ # end of the spec run, to help surface which specs are running
78
+ # particularly slow.
79
+ config.profile_examples = 10
80
+
81
+ # Run specs in random order to surface order dependencies. If you find an
82
+ # order dependency and want to debug it, you can fix the order by providing
83
+ # the seed, which is printed after each run.
84
+ # --seed 1234
85
+ config.order = :random
86
+
87
+ # Seed global randomization in this process using the `--seed` CLI option.
88
+ # Setting this allows you to use `--seed` to deterministically reproduce
89
+ # test failures related to randomization by passing the same `--seed` value
90
+ # as the one that triggered the failure.
91
+ Kernel.srand config.seed
92
+ =end
93
+ end
metadata ADDED
@@ -0,0 +1,63 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: yafs
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Mika Lackman
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-04-14 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rack
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ description: Fake http service, which is easy to use in tests
28
+ email: mika.lackman@gmail.com
29
+ executables: []
30
+ extensions: []
31
+ extra_rdoc_files: []
32
+ files:
33
+ - README.md
34
+ - lib/fake_service.rb
35
+ - spec/features/fake_service_spec.rb
36
+ - spec/spec_helper.rb
37
+ homepage:
38
+ licenses:
39
+ - MIT
40
+ metadata: {}
41
+ post_install_message:
42
+ rdoc_options: []
43
+ require_paths:
44
+ - lib
45
+ required_ruby_version: !ruby/object:Gem::Requirement
46
+ requirements:
47
+ - - ">="
48
+ - !ruby/object:Gem::Version
49
+ version: '0'
50
+ required_rubygems_version: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ requirements: []
56
+ rubyforge_project:
57
+ rubygems_version: 2.2.2
58
+ signing_key:
59
+ specification_version: 4
60
+ summary: Yet another fake http service for e2e tests
61
+ test_files:
62
+ - spec/features/fake_service_spec.rb
63
+ - spec/spec_helper.rb