http_baseline 2.0.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.
- checksums.yaml +7 -0
- data/.gitignore +23 -0
- data/Gemfile +3 -0
- data/LICENSE.txt +22 -0
- data/README.md +60 -0
- data/Rakefile +14 -0
- data/cucumber.yml +7 -0
- data/features/step_definitions/generic/debugging_steps.rb +34 -0
- data/features/step_definitions/generic/header_steps.rb +56 -0
- data/features/step_definitions/generic/request_steps.rb +69 -0
- data/features/step_definitions/generic/response_steps.rb +133 -0
- data/features/step_definitions/generic/user_story_steps.rb +11 -0
- data/features/step_definitions/internal_test_steps.rb +42 -0
- data/features/support/env.rb +3 -0
- data/http_baseline.gemspec +36 -0
- data/lib/ext_core/array.rb +10 -0
- data/lib/ext_core/hash.rb +3 -0
- data/lib/ext_core/object.rb +9 -0
- data/lib/ext_core/query.rb +58 -0
- data/lib/ext_core/string.rb +142 -0
- data/lib/http_baseline/adapter/abstract.rb +25 -0
- data/lib/http_baseline/adapter/rest/response/logger.rb +37 -0
- data/lib/http_baseline/adapter/rest.rb +63 -0
- data/lib/http_baseline/evf.rb +21 -0
- data/lib/http_baseline/methods.rb +17 -0
- data/lib/http_baseline/null_broadcaster.rb +21 -0
- data/lib/http_baseline/version.rb +8 -0
- data/lib/http_baseline.rb +67 -0
- data/spec/lib/root_spec.rb +14 -0
- data/spec/spec_helper.rb +18 -0
- data/spec/support/fixtures.rb +23 -0
- data/spec/support/simplecov_setup.rb +12 -0
- metadata +270 -0
@@ -0,0 +1,142 @@
|
|
1
|
+
class ::String
|
2
|
+
|
3
|
+
unless method_defined? :camelize
|
4
|
+
# By default, +camelize+ converts strings to UpperCamelCase. If the argument to +camelize+
|
5
|
+
# is set to <tt>:lower</tt> then +camelize+ produces lowerCamelCase.
|
6
|
+
#
|
7
|
+
# +camelize+ will also convert '/' to '::' which is useful for converting paths to namespaces.
|
8
|
+
#
|
9
|
+
# As a rule of thumb you can think of +camelize+ as the inverse of +underscore+,
|
10
|
+
# though there are cases where that does not hold:
|
11
|
+
#
|
12
|
+
# "SSLError".underscore.camelize # => "SslError"
|
13
|
+
#
|
14
|
+
def camelize(first_letter_in_uppercase = true)
|
15
|
+
lower_case_and_underscored_word = self
|
16
|
+
if first_letter_in_uppercase
|
17
|
+
lower_case_and_underscored_word.to_s.gsub(/\/(.?)/) { "::#{$1.upcase}" }.gsub(/(?:^|_)(.)/) { $1.upcase }
|
18
|
+
else
|
19
|
+
lower_case_and_underscored_word.to_s[0].chr.downcase + camelize(lower_case_and_underscored_word)[1..-1]
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
unless method_defined? :underscore
|
25
|
+
# Makes an underscored, lowercase form from the expression in the string.
|
26
|
+
#
|
27
|
+
# Changes '::' to '/' to convert namespaces to paths.
|
28
|
+
#
|
29
|
+
# Examples:
|
30
|
+
# "FooBar".underscore # => "foo_bar"
|
31
|
+
# "FooBar::Errors".underscore # => foo_bar/errors
|
32
|
+
#
|
33
|
+
# As a rule of thumb you can think of +underscore+ as the inverse of +camelize+,
|
34
|
+
# though there are cases where that does not hold:
|
35
|
+
#
|
36
|
+
# "SSLError".underscore.camelize # => "SslError"
|
37
|
+
#
|
38
|
+
def underscore()
|
39
|
+
camel_cased_word = self
|
40
|
+
word = camel_cased_word.to_s.dup
|
41
|
+
word.gsub!(/::/, '/')
|
42
|
+
word.gsub!(/([A-Z]+)([A-Z][a-z])/,'\1_\2')
|
43
|
+
word.gsub!(/([a-z\d])([A-Z])/,'\1_\2')
|
44
|
+
word.tr!("-", "_")
|
45
|
+
word.downcase!
|
46
|
+
word
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
unless method_defined? :constantize
|
51
|
+
# Ruby 1.9 introduces an inherit argument for Module#const_get and
|
52
|
+
# #const_defined? and changes their default behavior.
|
53
|
+
if Module.method(:const_get).arity == 1
|
54
|
+
# Tries to find a constant with the name specified in the argument string:
|
55
|
+
#
|
56
|
+
# "Module".constantize # => Module
|
57
|
+
# "Test::Unit".constantize # => Test::Unit
|
58
|
+
#
|
59
|
+
# The name is assumed to be the one of a top-level constant, no matter whether
|
60
|
+
# it starts with "::" or not. No lexical context is taken into account:
|
61
|
+
#
|
62
|
+
# C = 'outside'
|
63
|
+
# module M
|
64
|
+
# C = 'inside'
|
65
|
+
# C # => 'inside'
|
66
|
+
# "C".constantize # => 'outside', same as ::C
|
67
|
+
# end
|
68
|
+
#
|
69
|
+
# NameError is raised when the name is not in CamelCase or the constant is
|
70
|
+
# unknown.
|
71
|
+
def constantize()
|
72
|
+
camel_cased_word = self
|
73
|
+
names = camel_cased_word.split('::')
|
74
|
+
names.shift if names.empty? || names.first.empty?
|
75
|
+
|
76
|
+
constant = Object
|
77
|
+
names.each do |name|
|
78
|
+
constant = constant.const_defined?(name) ? constant.const_get(name) : constant.const_missing(name)
|
79
|
+
end
|
80
|
+
constant
|
81
|
+
end
|
82
|
+
else
|
83
|
+
def constantize() #:nodoc:
|
84
|
+
camel_cased_word = self
|
85
|
+
names = camel_cased_word.split('::')
|
86
|
+
names.shift if names.empty? || names.first.empty?
|
87
|
+
|
88
|
+
constant = Object
|
89
|
+
names.each do |name|
|
90
|
+
constant = constant.const_defined?(name, false) ? constant.const_get(name) : constant.const_missing(name)
|
91
|
+
end
|
92
|
+
constant
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
def squish
|
98
|
+
dup.squish!
|
99
|
+
end
|
100
|
+
|
101
|
+
# Performs a destructive squish. See String#squish.
|
102
|
+
def squish!
|
103
|
+
gsub!(/\A[[:space:]]+/, '')
|
104
|
+
gsub!(/[[:space:]]+\z/, '')
|
105
|
+
gsub!(/[[:space:]]+/, ' ')
|
106
|
+
self
|
107
|
+
end
|
108
|
+
|
109
|
+
# Truncates a given +text+ after a given <tt>length</tt> if +text+ is longer than <tt>length</tt>:
|
110
|
+
#
|
111
|
+
# 'Once upon a time in a world far far away'.truncate(27)
|
112
|
+
# # => "Once upon a time in a wo..."
|
113
|
+
#
|
114
|
+
# Pass a string or regexp <tt>:separator</tt> to truncate +text+ at a natural break:
|
115
|
+
#
|
116
|
+
# 'Once upon a time in a world far far away'.truncate(27, separator: ' ')
|
117
|
+
# # => "Once upon a time in a..."
|
118
|
+
#
|
119
|
+
# 'Once upon a time in a world far far away'.truncate(27, separator: /\s/)
|
120
|
+
# # => "Once upon a time in a..."
|
121
|
+
#
|
122
|
+
# The last characters will be replaced with the <tt>:omission</tt> string (defaults to "...")
|
123
|
+
# for a total length not exceeding <tt>length</tt>:
|
124
|
+
#
|
125
|
+
# 'And they found that many people were sleeping better.'.truncate(25, omission: '... (continued)')
|
126
|
+
# # => "And they f... (continued)"
|
127
|
+
def truncate(truncate_at, options = {})
|
128
|
+
return dup unless length > truncate_at
|
129
|
+
|
130
|
+
options[:omission] ||= '...'
|
131
|
+
length_with_room_for_omission = truncate_at - options[:omission].length
|
132
|
+
stop = \
|
133
|
+
if options[:separator]
|
134
|
+
rindex(options[:separator], length_with_room_for_omission) || length_with_room_for_omission
|
135
|
+
else
|
136
|
+
length_with_room_for_omission
|
137
|
+
end
|
138
|
+
|
139
|
+
"#{self[0...stop]}#{options[:omission]}"
|
140
|
+
end
|
141
|
+
|
142
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
require 'json'
|
2
|
+
require 'uri'
|
3
|
+
|
4
|
+
module HttpBaseline
|
5
|
+
module Adapter
|
6
|
+
class Abstract
|
7
|
+
|
8
|
+
def initialize(config)
|
9
|
+
@config = config
|
10
|
+
@options = { :ssl => @config.ssl.enabled.true?, :ssl_options => { :verify => @config.ssl.verify } }
|
11
|
+
@protocol = @config.ssl.enabled.true? ? 'https' : 'http'
|
12
|
+
@uri = URI.parse("#{@protocol}://#{@config.domain}:#{@config.tcp_port}")
|
13
|
+
end
|
14
|
+
|
15
|
+
def ssl?
|
16
|
+
@uri.scheme == 'https'
|
17
|
+
end
|
18
|
+
|
19
|
+
def headers
|
20
|
+
@client.headers
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
module HttpBaseline
|
2
|
+
module Adapter
|
3
|
+
class Rest
|
4
|
+
module Response
|
5
|
+
class Logger < Faraday::Response::Middleware
|
6
|
+
extend Forwardable
|
7
|
+
|
8
|
+
def initialize(app, logger = nil)
|
9
|
+
super(app)
|
10
|
+
@logger = logger || HttpBaseline.logger
|
11
|
+
end
|
12
|
+
|
13
|
+
def_delegators :@logger, :debug, :info, :warn, :error, :fatal
|
14
|
+
|
15
|
+
def call(env)
|
16
|
+
debug "#{env.method} #{env.url.to_s}"
|
17
|
+
debug('request') { dump_headers env.request_headers }
|
18
|
+
debug('request') { env.body }
|
19
|
+
super
|
20
|
+
end
|
21
|
+
|
22
|
+
def on_complete(env)
|
23
|
+
debug('Status') { env.status.to_s }
|
24
|
+
debug('response') { dump_headers env.response_headers }
|
25
|
+
debug('response') { env.body }
|
26
|
+
end
|
27
|
+
|
28
|
+
private
|
29
|
+
|
30
|
+
def dump_headers(headers)
|
31
|
+
headers.map { |k, v| "#{k}: #{v.inspect}" }.join("\n")
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,63 @@
|
|
1
|
+
module HttpBaseline
|
2
|
+
module Adapter
|
3
|
+
class Rest < Abstract
|
4
|
+
require 'faraday'
|
5
|
+
require 'faraday/request/multipart'
|
6
|
+
require 'faraday_middleware'
|
7
|
+
require 'http_baseline/adapter/rest/response/logger'
|
8
|
+
|
9
|
+
attr_reader :uri
|
10
|
+
|
11
|
+
def initialize(config)
|
12
|
+
super
|
13
|
+
@client = Faraday.new do |pipe|
|
14
|
+
pipe.use Faraday::Request::UrlEncoded
|
15
|
+
pipe.use FaradayMiddleware::EncodeJson
|
16
|
+
pipe.use FaradayMiddleware::FollowRedirects
|
17
|
+
pipe.use FaradayMiddleware::Mashify
|
18
|
+
pipe.use Response::Logger
|
19
|
+
pipe.url_prefix = @uri
|
20
|
+
end
|
21
|
+
headers[:user_agent] = 'WS v%s' % HttpBaseline::VERSION
|
22
|
+
end
|
23
|
+
|
24
|
+
|
25
|
+
def attach_extension(other_module)
|
26
|
+
@client.use other_module
|
27
|
+
end
|
28
|
+
|
29
|
+
|
30
|
+
def get(url, *args)
|
31
|
+
@client.get(configured_path(url), *args)
|
32
|
+
end
|
33
|
+
|
34
|
+
|
35
|
+
def post(url, body = nil, *args)
|
36
|
+
@client.post(configured_path(url), body, *args)
|
37
|
+
end
|
38
|
+
|
39
|
+
|
40
|
+
def delete(url, *args)
|
41
|
+
@client.delete(configured_path(url), *args)
|
42
|
+
end
|
43
|
+
|
44
|
+
def put(url, body = nil, *args)
|
45
|
+
@client.put(configured_path(url), body, *args)
|
46
|
+
end
|
47
|
+
|
48
|
+
private
|
49
|
+
|
50
|
+
def configured_path(url)
|
51
|
+
@config.path_prefix.to_s + url
|
52
|
+
end
|
53
|
+
|
54
|
+
def reset_config
|
55
|
+
@client.url_prefix = @uri.to_s
|
56
|
+
if @options[:ssl_options]
|
57
|
+
@client.ssl.merge!(@options[:ssl_options])
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module HttpBaseline
|
2
|
+
class Abstract < ::Evf::Abstract
|
3
|
+
|
4
|
+
config.comm = Evf::Support::Options.new unless config.respond_to?(:comm)
|
5
|
+
config.comm.http = Evf::Support::Options.new
|
6
|
+
config.comm.http.ssl = Evf::Support::Options.new
|
7
|
+
config.comm.http.ssl.enabled = 'no'
|
8
|
+
|
9
|
+
invocation 'init.http.config', :before => :load_context_config, group => :all do |env|
|
10
|
+
HttpBaseline.config = env.config
|
11
|
+
HttpBaseline.logger = env.config.logger
|
12
|
+
HttpBaseline.broadcaster = env.broadcaster
|
13
|
+
|
14
|
+
%w(debugging header request response user_story).each do |definition|
|
15
|
+
require HttpBaseline::SHARED_DEFINITIONS.join('%s_steps' % definition)
|
16
|
+
end
|
17
|
+
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module HttpBaseline
|
2
|
+
module Methods
|
3
|
+
|
4
|
+
def set_headers_by(c_type)
|
5
|
+
type = case c_type
|
6
|
+
when /json/i
|
7
|
+
'application/json'
|
8
|
+
when /form/i
|
9
|
+
'application/x-www-form-urlencoded'
|
10
|
+
else
|
11
|
+
c_type
|
12
|
+
end
|
13
|
+
connection.add_header 'Content-Type', type unless c_type.nil? || c_type.empty?
|
14
|
+
end
|
15
|
+
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module HttpBaseline
|
2
|
+
class NullBroadcaster
|
3
|
+
|
4
|
+
def initialize(logger)
|
5
|
+
@logger = logger
|
6
|
+
end
|
7
|
+
|
8
|
+
def notify_all_with(object, notification_type, *args)
|
9
|
+
@logger.debug '[%s]: %s -> accepted :%s with %s' % [uname, object.class.name, notification_type, args.join(', ')]
|
10
|
+
end
|
11
|
+
|
12
|
+
def uname
|
13
|
+
@uname ||= self.class.name.split('::').last
|
14
|
+
end
|
15
|
+
|
16
|
+
def subscribe(other)
|
17
|
+
(@null_storage ||= []) << other
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,67 @@
|
|
1
|
+
$:.unshift File.expand_path '../', __FILE__
|
2
|
+
require 'http_baseline/version'
|
3
|
+
require 'base64'
|
4
|
+
require 'bigdecimal'
|
5
|
+
require 'cgi'
|
6
|
+
require 'date'
|
7
|
+
require 'digest/sha1'
|
8
|
+
require 'enumerator'
|
9
|
+
require 'forwardable'
|
10
|
+
require 'net/http'
|
11
|
+
require 'net/https'
|
12
|
+
require 'openssl'
|
13
|
+
require 'stringio'
|
14
|
+
require 'time'
|
15
|
+
require 'zlib'
|
16
|
+
require 'builder'
|
17
|
+
require 'json'
|
18
|
+
require 'jsonpath'
|
19
|
+
require 'logger'
|
20
|
+
require 'addressable/uri'
|
21
|
+
require 'ext_core/query'
|
22
|
+
require 'ext_core/object'
|
23
|
+
require 'ext_core/array'
|
24
|
+
require 'ext_core/hash'
|
25
|
+
require 'ext_core/string'
|
26
|
+
require 'hashie'
|
27
|
+
|
28
|
+
module HttpBaseline
|
29
|
+
SHARED_DEFINITIONS = Pathname(__FILE__).join('..', '..', 'features', 'step_definitions', 'generic')
|
30
|
+
|
31
|
+
autoload :Methods, 'http_baseline/methods'
|
32
|
+
autoload :NullBroadcaster, 'http_baseline/null_broadcaster'
|
33
|
+
|
34
|
+
module Adapter
|
35
|
+
autoload :Abstract, 'http_baseline/adapter/abstract'
|
36
|
+
autoload :Rest, 'http_baseline/adapter/rest'
|
37
|
+
end
|
38
|
+
|
39
|
+
class << self
|
40
|
+
attr_writer :config
|
41
|
+
end
|
42
|
+
|
43
|
+
def self.config
|
44
|
+
@config ||= Hashie::Mash.new
|
45
|
+
end
|
46
|
+
|
47
|
+
def self.logger
|
48
|
+
@logger ||= begin
|
49
|
+
logger = ::Logger.new $stdout
|
50
|
+
logger.level = ::Logger::DEBUG
|
51
|
+
logger
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
def self.logger=(val)
|
56
|
+
@logger = val
|
57
|
+
end
|
58
|
+
|
59
|
+
def self.broadcaster
|
60
|
+
@broadcaster ||= NullBroadcaster.new(self.logger)
|
61
|
+
end
|
62
|
+
|
63
|
+
def self.broadcaster=(other_bundle)
|
64
|
+
@broadcaster = other_bundle
|
65
|
+
end
|
66
|
+
|
67
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
require 'bundler/setup'
|
2
|
+
require 'yaml'
|
3
|
+
|
4
|
+
$:.unshift File.expand_path('../', File.dirname(__FILE__))
|
5
|
+
|
6
|
+
require 'http_baseline'
|
7
|
+
|
8
|
+
Dir[File.expand_path('support/**/*.rb', File.dirname(__FILE__))].each do |file|
|
9
|
+
require file if File.file?(file)
|
10
|
+
end
|
11
|
+
|
12
|
+
RSpec.configure do |config|
|
13
|
+
config.color = true
|
14
|
+
config.formatter = :documentation
|
15
|
+
config.include Fixtures
|
16
|
+
end
|
17
|
+
|
18
|
+
include Fixtures
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'pathname'
|
2
|
+
|
3
|
+
module Fixtures
|
4
|
+
def fixture_path(name)
|
5
|
+
File.join '../fixtures', name
|
6
|
+
end
|
7
|
+
|
8
|
+
def absolute_fixture_path(name)
|
9
|
+
File.expand_path fixture_path(name), File.dirname(__FILE__)
|
10
|
+
end
|
11
|
+
|
12
|
+
def fixture(name)
|
13
|
+
File.read absolute_fixture_path(name)
|
14
|
+
end
|
15
|
+
|
16
|
+
def binary_fixture(name)
|
17
|
+
File.open(absolute_fixture_path(name), "rb") { |f| f.read }
|
18
|
+
end
|
19
|
+
|
20
|
+
def fixtures_path
|
21
|
+
Pathname(absolute_fixture_path '')
|
22
|
+
end
|
23
|
+
end
|