webpoke 0.0.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +17 -0
- data/Gemfile +4 -0
- data/Rakefile +5 -0
- data/bin/poke +77 -0
- data/lib/Webpoke/Class.rb +10 -0
- data/lib/Webpoke/Config.rb +59 -0
- data/lib/Webpoke/Test.rb +83 -0
- data/lib/Webpoke/version.rb +3 -0
- data/lib/webpoke.rb +172 -0
- data/webpoke.gemspec +25 -0
- metadata +70 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 4b980ca6a8f667b53abd42762d98796f5ff420d2
|
4
|
+
data.tar.gz: d21244eb1d3d4456d433b2d0a37deb8faea1359b
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: b48244af31f75d68687a26a65e2bf0b37e5ff5a7fb80175fca71931b32b72252213dea9cf1d241e4000c22af6c06935d992e0de589df2879cd940e95a6182225
|
7
|
+
data.tar.gz: bb4357cf189c738263f457936ffced676d9870df6598a0786588fa846a5f2a5d19989453e694c53ca585a730d43c2868255c0c4ba88e607c3451d28270df9b3f
|
data/.gitignore
ADDED
data/Gemfile
ADDED
data/Rakefile
ADDED
data/bin/poke
ADDED
@@ -0,0 +1,77 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'webpoke'
|
4
|
+
require 'optparse'
|
5
|
+
|
6
|
+
options = {}
|
7
|
+
|
8
|
+
file = ARGV[0]
|
9
|
+
|
10
|
+
optparser = OptionParser.new do |opts|
|
11
|
+
opts.banner = "Usage: poke [options] file_with_tests"
|
12
|
+
opts.on( '-h', '--help', 'Display this screen' ) do
|
13
|
+
puts opts
|
14
|
+
exit
|
15
|
+
end
|
16
|
+
|
17
|
+
options[:bootstrap] = false
|
18
|
+
opts.on( '-b file', '--bootstrap file', "Bootstrap file" ) do |file|
|
19
|
+
options[:bootstrap] = File.expand_path file
|
20
|
+
end
|
21
|
+
|
22
|
+
options[:group] = []
|
23
|
+
opts.on( '-g group', '--group groups', Array, "Only run tests in group" ) do |group|
|
24
|
+
options[:group] = group
|
25
|
+
end
|
26
|
+
|
27
|
+
options[:quiet] = false
|
28
|
+
opts.on('-q', '--quiet', 'Run tests and exit with status code') do |quiet|
|
29
|
+
options[:quiet] = true
|
30
|
+
end
|
31
|
+
|
32
|
+
options[:doc] = false
|
33
|
+
opts.on('-d <file>', '--document <document>', "Generate documentation for test instead of running") do |file|
|
34
|
+
options[:doc] = File.expand_path file
|
35
|
+
end
|
36
|
+
|
37
|
+
options[:format] = false
|
38
|
+
formats = Webpoke.formats
|
39
|
+
opts.on("-f [#{formats.join('|')}]", "--format [#{formats.join('|')}]", "Set the format to a desired output\n") do |format|
|
40
|
+
|
41
|
+
if !formats.include?(format)
|
42
|
+
puts "<#{format}> is not a recognized format, try [#{formats.join(', ')}]"
|
43
|
+
exit
|
44
|
+
end
|
45
|
+
|
46
|
+
end
|
47
|
+
|
48
|
+
if !file
|
49
|
+
puts opts.help()
|
50
|
+
exit 255
|
51
|
+
end
|
52
|
+
|
53
|
+
end.parse!
|
54
|
+
|
55
|
+
if options[:bootstrap]
|
56
|
+
require options[:bootstrap]
|
57
|
+
end
|
58
|
+
|
59
|
+
|
60
|
+
if (File.directory?(file))
|
61
|
+
Dir.glob(File.expand_path(file)+'/*.rb').each do |f|
|
62
|
+
require File.expand_path(f)
|
63
|
+
end
|
64
|
+
elsif (File.file?(file))
|
65
|
+
require File.expand_path(file)
|
66
|
+
end
|
67
|
+
|
68
|
+
if options[:doc]
|
69
|
+
File.open(options[:doc], 'w+') do |f|
|
70
|
+
f << Webpoke.document(options[:group])
|
71
|
+
end
|
72
|
+
exit 0
|
73
|
+
end
|
74
|
+
|
75
|
+
Webpoke.run(options[:group])
|
76
|
+
|
77
|
+
puts "\nTests: #{Webpoke.tested}, success: #{Webpoke.success}, errors: #{Webpoke.failed}";
|
@@ -0,0 +1,59 @@
|
|
1
|
+
class Webpoke::Config
|
2
|
+
|
3
|
+
mark_accessible :base, :headers, :parse, :on_failure, :beforeSend, :format
|
4
|
+
|
5
|
+
@@valid_parse_types = ['json']
|
6
|
+
|
7
|
+
def initialize(&block)
|
8
|
+
@base = '';
|
9
|
+
@headers = {}
|
10
|
+
@parse = {input:nil, output:nil}
|
11
|
+
|
12
|
+
if (block_given?)
|
13
|
+
instance_eval(&block);
|
14
|
+
end
|
15
|
+
|
16
|
+
@format = @format || 'stdout'
|
17
|
+
|
18
|
+
end
|
19
|
+
|
20
|
+
def on_failure(&block)
|
21
|
+
if (block_given?)
|
22
|
+
@on_failure = block
|
23
|
+
else
|
24
|
+
@on_failure
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def beforeSend callable=nil
|
29
|
+
if callable
|
30
|
+
raise new Webpoke::ConfigError("Can't register your beforeSend callable because, well, it isn't callable") if !callable.respond_to? :call
|
31
|
+
@beforeSend = callable
|
32
|
+
else
|
33
|
+
@beforeSend
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def parse type=nil
|
38
|
+
if (type)
|
39
|
+
case type
|
40
|
+
when String
|
41
|
+
raise new Webpoke::ConfigError("I don't know how to parse [#{type}] responses yet :/") unless @@valid_parse_types.include? type
|
42
|
+
@parse = {
|
43
|
+
input: lambda {|d| JSON.parse(d, symbolyze_names: true)},
|
44
|
+
output: lambda {|d| d.to_json }
|
45
|
+
}
|
46
|
+
when Hash
|
47
|
+
@parse = type
|
48
|
+
end
|
49
|
+
else
|
50
|
+
@parse
|
51
|
+
end
|
52
|
+
|
53
|
+
end
|
54
|
+
|
55
|
+
|
56
|
+
end
|
57
|
+
|
58
|
+
class Webpoke::ConfigError < StandardError
|
59
|
+
end
|
data/lib/Webpoke/Test.rb
ADDED
@@ -0,0 +1,83 @@
|
|
1
|
+
=begin rdoc
|
2
|
+
A test
|
3
|
+
=end
|
4
|
+
class Webpoke::Test
|
5
|
+
|
6
|
+
mark_accessible :description, :group, :url, :method, :success, :query, :should_fail, :headers, :data
|
7
|
+
|
8
|
+
def initialize(&block)
|
9
|
+
instance_eval(&block);
|
10
|
+
@group = @group || ''
|
11
|
+
@method = @method || 'get'
|
12
|
+
@headers = @headers || {}
|
13
|
+
|
14
|
+
end
|
15
|
+
|
16
|
+
|
17
|
+
def default_success (code, body)
|
18
|
+
if @should_fail
|
19
|
+
return code > 399
|
20
|
+
else
|
21
|
+
return (200..202).include?(code)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
|
26
|
+
def success (&block)
|
27
|
+
@success = block
|
28
|
+
end
|
29
|
+
|
30
|
+
=begin rdoc
|
31
|
+
Returns the test description
|
32
|
+
|
33
|
+
|
34
|
+
=end
|
35
|
+
def to_s
|
36
|
+
@description
|
37
|
+
end
|
38
|
+
|
39
|
+
=begin rdoc
|
40
|
+
Returns the test description definition (so that we can auto-generate documentation)
|
41
|
+
=end
|
42
|
+
def describe
|
43
|
+
|
44
|
+
return {
|
45
|
+
description: @description,
|
46
|
+
url: @url,
|
47
|
+
method: @method
|
48
|
+
}
|
49
|
+
|
50
|
+
end
|
51
|
+
|
52
|
+
|
53
|
+
=begin rdoc
|
54
|
+
Run the test
|
55
|
+
=end
|
56
|
+
def passed? (response, body)
|
57
|
+
|
58
|
+
if !self.default_success(response, body)
|
59
|
+
return false
|
60
|
+
end
|
61
|
+
|
62
|
+
|
63
|
+
|
64
|
+
if @success
|
65
|
+
begin
|
66
|
+
result = @success.call(response, body)
|
67
|
+
rescue Exception => e
|
68
|
+
result = false
|
69
|
+
Webpoke.log "Error while executing success for test".red
|
70
|
+
Webpoke.log e
|
71
|
+
end
|
72
|
+
else
|
73
|
+
result = self.default_success(response, body)
|
74
|
+
end
|
75
|
+
|
76
|
+
return result
|
77
|
+
|
78
|
+
end
|
79
|
+
|
80
|
+
end
|
81
|
+
|
82
|
+
class Webpoke::TestError < StandardError
|
83
|
+
end
|
data/lib/webpoke.rb
ADDED
@@ -0,0 +1,172 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
#encoding: utf-8
|
3
|
+
#
|
4
|
+
#
|
5
|
+
# License
|
6
|
+
#
|
7
|
+
# DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE Version 2, December 2004
|
8
|
+
#
|
9
|
+
# (C) 2012 Roberto Hidalgo un@rob.mx
|
10
|
+
#
|
11
|
+
# Everyone is permitted to copy and distribute verbatim or modified copies of this license document, and changing it is allowed as long as the name is changed.
|
12
|
+
#
|
13
|
+
# DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
14
|
+
#
|
15
|
+
# You just DO WHAT THE FUCK YOU WANT TO.
|
16
|
+
|
17
|
+
|
18
|
+
class String
|
19
|
+
|
20
|
+
def red
|
21
|
+
"\033[41m\033[37m#{self}\033[0m"
|
22
|
+
end
|
23
|
+
|
24
|
+
def green
|
25
|
+
"\033[42m\033[37m#{self}\033[0m"
|
26
|
+
end
|
27
|
+
|
28
|
+
def bold
|
29
|
+
"\033[1m#{self}\033[0m";
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
33
|
+
|
34
|
+
module Webpoke
|
35
|
+
|
36
|
+
require 'httparty'
|
37
|
+
require 'Webpoke/Class'
|
38
|
+
require 'Webpoke/Config'
|
39
|
+
require 'Webpoke/Test'
|
40
|
+
|
41
|
+
$successes = 0;
|
42
|
+
$errors = 0;
|
43
|
+
$tested = 0;
|
44
|
+
$tests = [];
|
45
|
+
$log = ""
|
46
|
+
$config = nil
|
47
|
+
|
48
|
+
# Adds a test to the queue
|
49
|
+
# @param block [Proc] the configuration for this test
|
50
|
+
def test(&block)
|
51
|
+
$tests << Test.new(&block)
|
52
|
+
end
|
53
|
+
|
54
|
+
|
55
|
+
def args_for_test(test)
|
56
|
+
|
57
|
+
if (!$config)
|
58
|
+
$config = Webpoke::Config.new
|
59
|
+
end
|
60
|
+
|
61
|
+
args = {
|
62
|
+
headers: $config.headers.merge(test.headers),
|
63
|
+
}
|
64
|
+
|
65
|
+
if test.data
|
66
|
+
if $config.parse[:input]
|
67
|
+
args[:body] = config.parse[:input].call(test.data)
|
68
|
+
else
|
69
|
+
args[:data] = test.data
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
args[:query] = test.query if test.query
|
74
|
+
|
75
|
+
args
|
76
|
+
end
|
77
|
+
|
78
|
+
# Configures the poking
|
79
|
+
# @param &block [Block] the configuration options
|
80
|
+
# (see #Webpoke::Config)
|
81
|
+
def config (&block)
|
82
|
+
$config = Webpoke::Config.new(&block)
|
83
|
+
end
|
84
|
+
|
85
|
+
|
86
|
+
def run (group=nil)
|
87
|
+
|
88
|
+
$tests.each do |test|
|
89
|
+
return if group && !test.group == group
|
90
|
+
$tested +=1
|
91
|
+
|
92
|
+
fqu = if test.url.match(/^https?:\/\//i) then url; else $config.base+test.url; end
|
93
|
+
|
94
|
+
args = args_for_test(test)
|
95
|
+
|
96
|
+
$config.beforeSend(test.method, fqu, args) if $config.beforeSend
|
97
|
+
|
98
|
+
log "#{$tested}: #{test.description}".bold
|
99
|
+
log "#{test.method.upcase}: #{test.url}...", false
|
100
|
+
begin
|
101
|
+
r = HTTParty.send(test.method, fqu, args)
|
102
|
+
rescue Exception => e
|
103
|
+
log 'FAIL:'.red
|
104
|
+
log e
|
105
|
+
$errors += 1;
|
106
|
+
next;
|
107
|
+
end
|
108
|
+
|
109
|
+
begin
|
110
|
+
body = $config.parse[:ouput] ? $config.parse[:output].call(r.body) : r.body
|
111
|
+
rescue Exception => e
|
112
|
+
log "Parsing failure: ".red
|
113
|
+
log "\t#{e}"
|
114
|
+
log "Data:"
|
115
|
+
log "\t"+r.body
|
116
|
+
$errors += 1;
|
117
|
+
next;
|
118
|
+
end
|
119
|
+
|
120
|
+
if test.passed?(r.code, body)
|
121
|
+
$successes +=1
|
122
|
+
log "OK!".green
|
123
|
+
else
|
124
|
+
log "FAIL!".red
|
125
|
+
|
126
|
+
if $config.on_failure
|
127
|
+
log $config.on_failure.call(r.code, body)
|
128
|
+
end
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
132
|
+
end
|
133
|
+
|
134
|
+
|
135
|
+
def log (message, newLine=true)
|
136
|
+
return true if $config.format != 'stdout'
|
137
|
+
$stdout << message
|
138
|
+
$stdout << "\n" if newLine
|
139
|
+
end
|
140
|
+
|
141
|
+
def Webpoke.document(group)
|
142
|
+
|
143
|
+
data = []
|
144
|
+
|
145
|
+
$tests.each do |test|
|
146
|
+
return if group && !test.group == group
|
147
|
+
|
148
|
+
data << test.describe
|
149
|
+
|
150
|
+
end
|
151
|
+
|
152
|
+
return data.to_json
|
153
|
+
|
154
|
+
end
|
155
|
+
|
156
|
+
def Webpoke.success
|
157
|
+
return $successes
|
158
|
+
end
|
159
|
+
|
160
|
+
def Webpoke.failed
|
161
|
+
return $errors
|
162
|
+
end
|
163
|
+
|
164
|
+
def Webpoke.tested
|
165
|
+
return $tested
|
166
|
+
end
|
167
|
+
|
168
|
+
def Webpoke.formats
|
169
|
+
return ['json', 'html', 'stdout']
|
170
|
+
end
|
171
|
+
|
172
|
+
end
|
data/webpoke.gemspec
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'Webpoke/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |gem|
|
7
|
+
gem.name = "webpoke"
|
8
|
+
gem.version = Webpoke::VERSION
|
9
|
+
gem.authors = ["Roberto Hidalgo"]
|
10
|
+
gem.email = ["un@rob.mx"]
|
11
|
+
gem.description = "A very simple REST API tester"
|
12
|
+
gem.summary = "I still have no idea what is this"
|
13
|
+
gem.homepage = "https://github.com/unRob/webpoke"
|
14
|
+
gem.licenses = ['WTFPL', 'GPLv2']
|
15
|
+
gem.has_rdoc = true
|
16
|
+
|
17
|
+
gem.files = `git ls-files`.split($/)
|
18
|
+
gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
19
|
+
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
20
|
+
gem.require_paths = ["lib"]
|
21
|
+
|
22
|
+
|
23
|
+
gem.add_runtime_dependency 'httparty'
|
24
|
+
|
25
|
+
end
|
metadata
ADDED
@@ -0,0 +1,70 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: webpoke
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.3
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Roberto Hidalgo
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2013-06-13 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: httparty
|
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: A very simple REST API tester
|
28
|
+
email:
|
29
|
+
- un@rob.mx
|
30
|
+
executables:
|
31
|
+
- poke
|
32
|
+
extensions: []
|
33
|
+
extra_rdoc_files: []
|
34
|
+
files:
|
35
|
+
- .gitignore
|
36
|
+
- Gemfile
|
37
|
+
- Rakefile
|
38
|
+
- bin/poke
|
39
|
+
- lib/Webpoke/Class.rb
|
40
|
+
- lib/Webpoke/Config.rb
|
41
|
+
- lib/Webpoke/Test.rb
|
42
|
+
- lib/Webpoke/version.rb
|
43
|
+
- lib/webpoke.rb
|
44
|
+
- webpoke.gemspec
|
45
|
+
homepage: https://github.com/unRob/webpoke
|
46
|
+
licenses:
|
47
|
+
- WTFPL
|
48
|
+
- GPLv2
|
49
|
+
metadata: {}
|
50
|
+
post_install_message:
|
51
|
+
rdoc_options: []
|
52
|
+
require_paths:
|
53
|
+
- lib
|
54
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
55
|
+
requirements:
|
56
|
+
- - '>='
|
57
|
+
- !ruby/object:Gem::Version
|
58
|
+
version: '0'
|
59
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
60
|
+
requirements:
|
61
|
+
- - '>='
|
62
|
+
- !ruby/object:Gem::Version
|
63
|
+
version: '0'
|
64
|
+
requirements: []
|
65
|
+
rubyforge_project:
|
66
|
+
rubygems_version: 2.0.3
|
67
|
+
signing_key:
|
68
|
+
specification_version: 4
|
69
|
+
summary: I still have no idea what is this
|
70
|
+
test_files: []
|