vanilli-ruby 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.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: f6e60458d2a143b7ab40102bb484447123451bc4
4
+ data.tar.gz: a3cee75a0c3765f16505c2456c50b42f5d87c1d3
5
+ SHA512:
6
+ metadata.gz: a6e8b5484f7db8964cf147da31b57c0240fafbc63eba528351c91c8b33335be45651a1392ed1272aed7f550a420a129c4c32a911ce34d1e47bf7178e97c910c5
7
+ data.tar.gz: db24cf62f4c37f3a924dbd4db64ca558b0a9c7c30eeb72da1281d20e2e0bd5dd1aafb1a07051cff8147a8b2023eecb89d4b82b6b65b2eaf6ba4ad713d1e320b8
data/.gitignore ADDED
@@ -0,0 +1,13 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
10
+
11
+ *.iml
12
+ .idea
13
+ *.gem
data/.rubocop.yml ADDED
@@ -0,0 +1,8 @@
1
+ LineLength:
2
+ Enabled: false
3
+
4
+ Metrics/MethodLength:
5
+ Enabled: false
6
+
7
+ Metrics/ParameterLists:
8
+ Enabled: false
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,25 @@
1
+ Copyright (c) 2013-2015, MixRadio
2
+ All rights reserved.
3
+
4
+ Redistribution and use in source and binary forms, with or without
5
+ modification, are permitted provided that the following conditions are met:
6
+
7
+ 1. Redistributions of source code must retain the above copyright
8
+ notice, this list of conditions and the following disclaimer.
9
+ 2. Redistributions in binary form must reproduce the above copyright
10
+ notice, this list of conditions and the following disclaimer in the
11
+ documentation and/or other materials provided with the distribution.
12
+ 3. Neither the name of Alistair Dutton nor the names of its contributors
13
+ may be used to endorse or promote products derived from this software
14
+ without specific prior written permission.
15
+
16
+ THIS SOFTWARE IS PROVIDED BY ALISTAIR DUTTON ''AS IS'' AND ANY
17
+ EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19
+ DISCLAIMED. IN NO EVENT SHALL ALISTAIR DUTTON BE LIABLE FOR ANY
20
+ DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21
+ (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22
+ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23
+ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
data/README.md ADDED
@@ -0,0 +1,63 @@
1
+ # vanilli-ruby
2
+ Ruby bindings for use with [vanilli](https://github.com/mixradio/vanilli).
3
+
4
+ ## Installation
5
+
6
+ Add this line to your application's Gemfile:
7
+
8
+ ```ruby
9
+ gem 'vanilli-ruby'
10
+ ```
11
+
12
+ And then execute:
13
+
14
+ $ bundle
15
+
16
+ Or install it yourself as:
17
+
18
+ $ gem install vanilli-ruby
19
+
20
+ ## Usage
21
+ Two classes are provided `VanilliServer` and `VanilliClient`.
22
+
23
+ ### VanilliClient
24
+ This class provides a client API for interacting with a running vanilli server. The API has
25
+ deliberately been kept as close as possible to the canonical javascript API with a few "rubifications"
26
+ (snake case on method names for example). However, the API is close enough that providing extra
27
+ documentation here is counter-productive - please see the [javascript documentation](https://github.com/mixradio/vanilli/wiki/API).
28
+
29
+ Instantiating the client is straightforward:
30
+
31
+ ```ruby
32
+ require 'vanilli/client'
33
+
34
+ vanilli = VanilliClient.new
35
+
36
+ vanilli.stub(...)
37
+ #etc.
38
+ ```
39
+
40
+ ### VanilliServer
41
+ Of course, to be able to make use of the client one needs a vanilli server running to connect to. This
42
+ can be achieved in a number of ways:
43
+
44
+ * Start vanilli via its CLI
45
+ ```sh
46
+ npm install -g vanilli
47
+ vanilli --port 9000
48
+ ```
49
+
50
+ * Start vanilli from javascript
51
+ i.e. use the javascript API perhaps from some grunt/gulp/npm based task.
52
+
53
+ * Use VanilliServer provided with this ruby gem
54
+ This just acts as a wrapper around the vanilli CLI. Therefore you *MUST* have vanilli installed to your
55
+ path for this to work. Once installed, start something like this:
56
+
57
+ ```ruby
58
+ vanilli_server = VanilliServer.new(port: 9000,
59
+ log_level: "debug",
60
+ static_root: "/your/web/app/assets",
61
+ static_include: ['**/*.html', '**/*.js', '**/*.css*', '/robots.txt'])
62
+ .start
63
+ ```
data/Rakefile ADDED
@@ -0,0 +1,9 @@
1
+ require "bundler/gem_tasks"
2
+ require 'rubocop/rake_task'
3
+
4
+ desc 'Run RuboCop on the lib directory'
5
+ RuboCop::RakeTask.new(:rubocop) do |task|
6
+ task.patterns = ['lib/**/*.rb']
7
+ end
8
+
9
+ task default: :rubocop
data/bin/console ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'bundler/setup'
4
+ require 'vanilli/server'
5
+ require 'vanilli/client'
6
+
7
+ require 'irb'
8
+ IRB.start
data/bin/setup ADDED
@@ -0,0 +1,7 @@
1
+ #!/bin/bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+
5
+ bundle install
6
+
7
+ # Do any other automated setup that you need to do here
@@ -0,0 +1,180 @@
1
+ require 'rest-client'
2
+ require 'json'
3
+
4
+ private def unwrap_regex(thing)
5
+ if thing.is_a?(Regexp)
6
+ return { regex: thing.source }
7
+ else
8
+ return thing
9
+ end
10
+ end
11
+
12
+ private def fail_body_with_no_contenttype(body, content_type)
13
+ fail 'Body was specified for but content-type was missing.' if body && !content_type
14
+ end
15
+
16
+ private def map_over_hash(h, f)
17
+ if h.nil?
18
+ return nil
19
+ else
20
+ return h.map { |key, value| { key => send(f, value) } }.reduce(:merge)
21
+ end
22
+ end
23
+
24
+ private def strip_nils(h)
25
+ h.delete_if { |_k, v| v.nil? }
26
+ end
27
+
28
+ private def stringify_non_json_content(content_blob)
29
+ body = content_blob[:body]
30
+
31
+ if (body.is_a? Hash) && (content_blob[:contentType] != 'application/json')
32
+ return content_blob.merge(body: body.to_json)
33
+ else
34
+ return content_blob
35
+ end
36
+ end
37
+
38
+ # Provides ruby bindings for the vanilli client. API is a
39
+ # "rubified" (i.e. snake-case for camel-case) version of the
40
+ # default javascript API provided with vanilli.
41
+ class VanilliClient
42
+ # Represents a single stub as will be registered with
43
+ # the vanilli server.
44
+ class Stub
45
+ attr_writer :expect
46
+
47
+ def initialize(criteria:, priority:)
48
+ @criteria = criteria
49
+ @priority = priority
50
+ end
51
+
52
+ # Construct the response for the stub
53
+ def respond_with(status, body: nil, content_type: nil, headers: nil, times: 1)
54
+ fail 'Status code is missing.' if status.nil?
55
+ fail_body_with_no_contenttype(body, content_type)
56
+
57
+ @response = stringify_non_json_content(strip_nils(status: status,
58
+ contentType: content_type,
59
+ body: body,
60
+ headers: headers))
61
+ @times = times
62
+
63
+ self
64
+ end
65
+
66
+ # Vanilli will wait the specified number of milliseconds
67
+ # before responding with the stub response.
68
+ def wait(milliseconds:)
69
+ @response[:wait] = milliseconds
70
+ self
71
+ end
72
+
73
+ # The body of the matching request(s) will be logged by vanilli
74
+ # under the specified capture id.
75
+ def capture(capture_id)
76
+ @capture_id = capture_id
77
+ self
78
+ end
79
+
80
+ # Converts the stub to JSON for sending to vanilli.
81
+ def to_json
82
+ strip_nils(criteria: strip_nils(@criteria),
83
+ priority: @priority,
84
+ response: strip_nils(@response),
85
+ times: @times,
86
+ captureId: @capture_id,
87
+ expect: @expect).to_json
88
+ end
89
+ end
90
+
91
+ # Create a new Stub that will be matched
92
+ # against the specified criteria.
93
+ def on_request(method, url, content_type: nil, body: nil, query: nil, headers: nil, priority: nil)
94
+ fail 'Url is missing.' unless url
95
+ fail_body_with_no_contenttype(body, content_type)
96
+
97
+ Stub.new(criteria: stringify_non_json_content(method: method,
98
+ url: unwrap_regex(url),
99
+ contentType: content_type,
100
+ body: body,
101
+ query: map_over_hash(query, :unwrap_regex),
102
+ headers: map_over_hash(headers, :unwrap_regex)),
103
+ priority: priority)
104
+ end
105
+
106
+ # Creates a Stub for a GET request that will be
107
+ # matched against the specified criteria.
108
+ def on_get(url, query: nil, headers: nil, priority: nil)
109
+ on_request('GET', url, query: query, headers: headers, priority: priority)
110
+ end
111
+
112
+ # Creates a Stub for a POST request that will be
113
+ # matched against the specified criteria.
114
+ def on_post(url, query: nil, headers: nil, priority: nil, content_type: nil, body: nil)
115
+ on_request('POST', url, query: query, headers: headers, priority: priority, content_type: content_type, body: body)
116
+ end
117
+
118
+ # Creates a Stub for a PUT request that will be
119
+ # matched against the specified criteria.
120
+ def on_put(url, query: nil, headers: nil, priority: nil, content_type: nil, body: nil)
121
+ on_request('PUT', url, query: query, headers: headers, priority: priority, content_type: content_type, body: body)
122
+ end
123
+
124
+ # Creates a Stub for a DELETE request that will be
125
+ # matched against the specified criteria.
126
+ def on_delete(url, query: nil, headers: nil, priority: nil)
127
+ on_request('DELETE', url, query: query, headers: headers, priority: priority)
128
+ end
129
+
130
+ # Registers the specified Stub(s) with the vanilli server.
131
+ def stub(*stubs)
132
+ stubs.each do |stub|
133
+ begin
134
+ RestClient.post 'http://localhost:9000/_vanilli/stubs', stub.to_json, content_type: :json, accept: :json
135
+ rescue => e
136
+ raise e.response
137
+ end
138
+ end
139
+ end
140
+
141
+ # Registers the specified Stub as an expectation on the
142
+ # vanilli server.
143
+ def expect(expectation)
144
+ expectation.expect = true
145
+ stub(expectation)
146
+ end
147
+
148
+ # Clears the vanilli server of all stubs.
149
+ def clear
150
+ RestClient.delete 'http://localhost:9000/_vanilli/stubs'
151
+ rescue => e
152
+ raise e.response
153
+ end
154
+
155
+ # Verifies that all vanilli expectations have been met. If
156
+ # not, an error is thrown.
157
+ def verify
158
+ begin
159
+ res = JSON.parse(RestClient.get 'http://localhost:9000/_vanilli/verify')
160
+ rescue => e
161
+ raise e.response
162
+ end
163
+
164
+ fail 'VERIFICATION FAILED: ' + res['errors'].join('\n') if res['errors'].length > 0
165
+ end
166
+
167
+ # Pulls back details of all requests that were logged against the
168
+ # specified capture id.
169
+ def get_captures(capture_id)
170
+ JSON.parse(RestClient.get 'http://localhost:9000/_vanilli/captures/' + capture_id)
171
+ rescue => e
172
+ raise e.response
173
+ end
174
+
175
+ # Pulls back details of the last request that was logged against the
176
+ # specified capture id.
177
+ def get_capture(capture_id)
178
+ get_captures(capture_id).last
179
+ end
180
+ end
@@ -0,0 +1,45 @@
1
+ require 'rest-client'
2
+
3
+ # Provides hooks for starting and stopping a vanilli server. Relies on the vanilli CLI
4
+ # API and therefore requires vanilli to be installed.
5
+ class VanilliServer
6
+ def initialize(port:, static_root: nil, static_include: [], static_exclude: [], static_default: 'index.html', log_level: 'warn')
7
+ @static_root = static_root
8
+ @static_default = static_default
9
+ @static_include = static_include.join(',')
10
+ @static_exclude = static_exclude.join(',')
11
+ @port = port
12
+ @log_level = log_level
13
+ end
14
+
15
+ # Shells out to start vanilli
16
+ def start(cwd: '.')
17
+ @pid = spawn("vanilli --port #{@port} \
18
+ --logLevel=#{@log_level} \
19
+ --staticRoot=#{@static_root} \
20
+ --staticDefault=#{@static_default} \
21
+ --staticInclude=#{@static_include} \
22
+ --staticExclude=#{@static_exclude}", chdir: cwd)
23
+
24
+ Timeout.timeout(3) do
25
+ begin
26
+ RestClient.get "http://localhost:#{@port}/_vanilli/ping"
27
+ rescue
28
+ sleep 0.1
29
+ retry
30
+ end
31
+ end
32
+
33
+ self
34
+ end
35
+
36
+ # Stops the vanilli server by killing the
37
+ # process started when shelling out to start vanilli
38
+ def stop
39
+ if @pid
40
+ Process.kill('KILL', @pid)
41
+ Process.wait @pid
42
+ end
43
+ @pid = nil
44
+ end
45
+ end
@@ -0,0 +1,31 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+
5
+ Gem::Specification.new do |spec|
6
+ spec.name = "vanilli-ruby"
7
+ spec.version = "0.0.1"
8
+ spec.authors = ["Alistair Dutton"]
9
+ spec.email = ["kelveden@gmail.com"]
10
+
11
+ spec.summary = "Ruby bindings for vanilli"
12
+ spec.description = "Provides a ruby API for starting a vanilli server and interacting with it."
13
+ spec.homepage = "https://github.com/mixradio/vanilli-ruby"
14
+ spec.license = "BSD-3-Clause"
15
+
16
+ if spec.respond_to?(:metadata)
17
+ spec.metadata['allowed_push_host'] = "https://rubygems.org"
18
+ else
19
+ raise "RubyGems 2.0 or newer is required to protect against public gem pushes."
20
+ end
21
+
22
+ spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
23
+ spec.bindir = "exe"
24
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
25
+ spec.require_paths = ["lib"]
26
+
27
+ spec.add_development_dependency "bundler", "~> 1.9"
28
+ spec.add_development_dependency "rake", "~> 10.4"
29
+ spec.add_development_dependency "rubocop", "~> 0.31"
30
+ spec.add_runtime_dependency "rest-client", "~> 1.8"
31
+ end
metadata ADDED
@@ -0,0 +1,113 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: vanilli-ruby
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Alistair Dutton
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2015-05-22 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.9'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.9'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '10.4'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '10.4'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rubocop
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '0.31'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '0.31'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rest-client
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '1.8'
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '1.8'
69
+ description: Provides a ruby API for starting a vanilli server and interacting with
70
+ it.
71
+ email:
72
+ - kelveden@gmail.com
73
+ executables: []
74
+ extensions: []
75
+ extra_rdoc_files: []
76
+ files:
77
+ - ".gitignore"
78
+ - ".rubocop.yml"
79
+ - Gemfile
80
+ - LICENSE.txt
81
+ - README.md
82
+ - Rakefile
83
+ - bin/console
84
+ - bin/setup
85
+ - lib/vanilli/client.rb
86
+ - lib/vanilli/server.rb
87
+ - vanilli-ruby.gemspec
88
+ homepage: https://github.com/mixradio/vanilli-ruby
89
+ licenses:
90
+ - BSD-3-Clause
91
+ metadata:
92
+ allowed_push_host: https://rubygems.org
93
+ post_install_message:
94
+ rdoc_options: []
95
+ require_paths:
96
+ - lib
97
+ required_ruby_version: !ruby/object:Gem::Requirement
98
+ requirements:
99
+ - - ">="
100
+ - !ruby/object:Gem::Version
101
+ version: '0'
102
+ required_rubygems_version: !ruby/object:Gem::Requirement
103
+ requirements:
104
+ - - ">="
105
+ - !ruby/object:Gem::Version
106
+ version: '0'
107
+ requirements: []
108
+ rubyforge_project:
109
+ rubygems_version: 2.4.6
110
+ signing_key:
111
+ specification_version: 4
112
+ summary: Ruby bindings for vanilli
113
+ test_files: []