oncall 0.3.0 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: b32fb0bf81e7eb52f7ed4a716584e5634d2109d00f68e9d99ac687576b7dafe7
4
- data.tar.gz: 8896c3f2830722e034f7de93c907e5d40ac257114f49179aa875937c0a59687a
3
+ metadata.gz: 78f13efef7b8e1d440f5c895eaab176727a63e60575d86acf4ac27e2aac4ad51
4
+ data.tar.gz: 20107a1ee7f2c76212b8f82cc62f368ee4a5eac67872fb3214e61cf2603ef37d
5
5
  SHA512:
6
- metadata.gz: 121096a38968f48da32314255339cef94e526a6d30a9ff31331e2e1c0f93f2d443169f3e52ec7ab44180f01904bd469d3517f7f7cf0ae532d95c4793dbbbd6bf
7
- data.tar.gz: 56acd28d76bfd3a65c8a94f89f6b10052efaab80e135d41e35b8e017c0a479aae09ac960ae2c2c4bc450e6370368a6bb769a7f411be6ee623313e9c1fba8827c
6
+ metadata.gz: 13c56a09b37eb72ce432b59bbfb6505d314e5530ca0e4ad174df439c0e70fe3a7f9d29afba6b2bac8246c921f61cfaf5bde1175b683f7c1c969a1ae25c0b8445
7
+ data.tar.gz: c1077f3388f215dd5c41e6643729f59ad99060cd8e48f3003871c3e14577cb31018fb5ea2feeedb24c05a9adf2b71406bef4ec315ae77429126f99d925a4be33
data/README.md CHANGED
@@ -1,11 +1,12 @@
1
1
  # 🤙 Oncall
2
2
 
3
+ [![Build Status](https://travis-ci.org/koenwoortman/oncall.svg?branch=master)](https://travis-ci.org/koenwoortman/oncall)
3
4
  [![Gem Version](https://badge.fury.io/rb/oncall.svg)](https://badge.fury.io/rb/oncall)
4
5
 
5
6
  > Oncall is a DSL for testing JSON API's.
6
7
 
7
8
  #### Install
8
- ```
9
+ ```sh
9
10
  $ gem install oncall
10
11
  ```
11
12
 
@@ -22,12 +23,12 @@ $ gem install oncall
22
23
  ## Get started
23
24
 
24
25
  Initialize
25
- ```
26
+ ```sh
26
27
  $ oncall --init
27
28
  ```
28
29
 
29
30
  Add tests
30
- ```
31
+ ```ruby
31
32
  group :user do
32
33
  header 'Content-Type' => 'application/json'
33
34
 
@@ -49,12 +50,27 @@ end
49
50
  ```
50
51
 
51
52
  Run them
52
- ```
53
+ ```sh
53
54
  $ oncall
54
55
  ```
55
56
 
56
57
  ## Usage
57
58
 
59
+ ```
60
+ Usage: oncall [options]
61
+ --env ENV Specify the environment to test against
62
+ --path PATH Set the path for finding tests
63
+ --pattern PATTERN Load files matching pattern
64
+ --exclude PATTERN Exclude files matching pattern
65
+ --group GROUP Filter tests by group
66
+ --persist PATH Write output to a file instead of $stdout
67
+ --config PATH Path to the config file
68
+ --init Initialize your project with Oncall
69
+ --verbose Increases the verbosity level for a more detailed output
70
+ --version Display the version
71
+ --help This help message
72
+ ```
73
+
58
74
 
59
75
  ## Configuration
60
76
 
@@ -66,5 +82,5 @@ This project is licensed under the MIT License - see the [LICENSE](LICENSE) file
66
82
 
67
83
  ## Acknowledgments
68
84
 
69
- * Inspired by [rspec](https://github.com/rspec/rspec).
70
- * And using [Ruby JSON Schema Validator](https://github.com/ruby-json-schema/json-schema).
85
+ * Inspired by [RSpec](https://github.com/rspec/rspec).
86
+ * Uses [Ruby JSON Schema Validator](https://github.com/ruby-json-schema/json-schema).
@@ -9,8 +9,14 @@ require 'json-schema'
9
9
  module Oncall
10
10
  require_relative 'oncall/cli'
11
11
  require_relative 'oncall/dsl'
12
+ require_relative 'oncall/http'
12
13
  require_relative 'oncall/options'
13
- require_relative 'oncall/invocations'
14
+ require_relative 'oncall/invocations/base_runner'
15
+ require_relative 'oncall/invocations/console_runner'
16
+ require_relative 'oncall/invocations/help_runner'
17
+ require_relative 'oncall/invocations/init_runner'
18
+ require_relative 'oncall/invocations/test_runner'
19
+ require_relative 'oncall/invocations/version_runner'
14
20
  require_relative 'oncall/test_file'
15
21
  require_relative 'oncall/reporter'
16
22
  require_relative 'oncall/version'
@@ -19,21 +25,9 @@ module Oncall
19
25
  attr_writer :options
20
26
  end
21
27
 
28
+ SCRIPT = 'oncall'
29
+
22
30
  def self.options
23
31
  @options ||= Oncall::Options.new
24
32
  end
25
-
26
- def self.uri(path, params)
27
- parts = path.split('/')
28
- return '/' if parts.empty?
29
-
30
- parts.each_with_index do |part, index|
31
- if part.start_with?(':')
32
- part[0] = ''
33
- parts[index] = params[part.to_sym]
34
- end
35
- end
36
-
37
- parts.join('/')
38
- end
39
33
  end
@@ -1,11 +1,9 @@
1
1
  module Oncall
2
2
  # Manage the processing of command line options
3
3
  class CLI
4
- SCRIPT = 'oncall'
5
-
6
4
  attr_reader :args, :options
7
5
 
8
- def initialize(args, options=Oncall.options)
6
+ def initialize(args, options = Oncall.options)
9
7
  @args = args
10
8
  @options = options
11
9
  end
@@ -15,51 +13,65 @@ module Oncall
15
13
  end
16
14
 
17
15
  def run
16
+ parse_cli_options
17
+ load_config_file
18
+
18
19
  begin
19
- parser.parse!(args)
20
- rescue OptionParser::InvalidOption => e
21
- abort "#{SCRIPT}: #{e.message}\nPlease use --help for a listing of valid options"
22
- rescue OptionParser::MissingArgument => e
23
- abort "#{SCRIPT}: #{e.message}"
20
+ status = options.runner.run($stderr, $stdout)
21
+ rescue Exception => e
22
+ abort "#{Oncall::SCRIPT}: #{e.message}"
24
23
  end
25
24
 
26
- status = options.runner.run($stderr, $stdout)
27
25
  exit(status) if status.is_a? Integer
28
26
  end
29
27
 
30
28
  private
31
29
 
32
- def parser
30
+ def load_config_file
31
+ options.parse_config
32
+ rescue Exception => e
33
+ abort "#{Oncall::SCRIPT}: #{e.message}"
34
+ end
35
+
36
+ def parse_cli_options
37
+ option_parser.parse!(args)
38
+ rescue OptionParser::InvalidOption => e
39
+ abort "#{Oncall::SCRIPT}: #{e.message}\nPlease use --help for a listing of valid options"
40
+ rescue OptionParser::MissingArgument => e
41
+ abort "#{Oncall::SCRIPT}: #{e.message}"
42
+ end
43
+
44
+ def option_parser
33
45
  OptionParser.new do |opt|
34
- opt.on('--env ENV', String) do |env|
46
+ opt.on('--env ENV', String, 'Specify the environment to test against') do |env|
35
47
  options.env= env
36
48
  end
37
49
 
38
- opt.on('--path PATH', String) do |path|
50
+ opt.on('--path PATH', String, 'Set the path for finding tests') do |path|
39
51
  options.path= path
40
52
  end
41
53
 
42
- opt.on('--pattern PATTERN', String) do |pattern|
54
+ opt.on('--pattern PATTERN', String, 'Load files matching pattern') do |pattern|
43
55
  options.pattern= pattern
44
56
  end
45
57
 
46
- opt.on('--exclude PATTERN', String) do |pattern|
58
+ opt.on('--exclude PATTERN', String, 'Exclude files matching pattern') do |pattern|
47
59
  options.exclude= pattern
48
60
  end
49
61
 
50
- opt.on('--group GROUP', String) do |group|
62
+ opt.on('--group GROUP', String, 'Filter tests by group') do |group|
51
63
  options.group= group
52
64
  end
53
65
 
54
- opt.on('--persist PATH', String) do |path|
66
+ opt.on('--persist PATH', String, 'Write output to a file instead of $stdout') do |path|
55
67
  options.persist= path
56
68
  end
57
69
 
58
- opt.on('--config PATH', String) do |path|
70
+ opt.on('--config PATH', String, 'Path to the config file') do |path|
59
71
  options.config= path
60
72
  end
61
73
 
62
- opt.on('--init', '') do
74
+ opt.on('--init', 'Initialize your project with Oncall') do
63
75
  options.runner= Oncall::Invocations::InitRunner.new
64
76
  end
65
77
 
@@ -68,12 +80,16 @@ module Oncall
68
80
  # options.runner= Oncall::Invocations::ConsoleRunner.new
69
81
  # end
70
82
 
71
- opt.on('--version', '') do
83
+ opt.on('--verbose', 'Increases the verbosity level for a more detailed output') do
84
+ options.verbose= true
85
+ end
86
+
87
+ opt.on('--version', 'Display the version') do
72
88
  options.runner= Oncall::Invocations::VersionRunner.new
73
89
  end
74
90
 
75
91
  opt.on_tail('--help', 'This help message') do
76
- options.runner= Oncall::Invocations::HelpRunner.new(parser)
92
+ options.runner= Oncall::Invocations::HelpRunner.new(option_parser)
77
93
  end
78
94
  end
79
95
  end
@@ -1,46 +1,30 @@
1
1
  module Oncall
2
2
  class DSL
3
- private
4
-
5
- attr_accessor :response, :request
6
- attr_reader :reporter, :file, :http
7
-
8
- public
9
-
10
3
  def initialize(file, reporter)
11
4
  @reporter = reporter
12
5
  @file = file
13
- @http = Net::HTTP.new('localhost', 4567)
14
- @headers = { 'User-Agent' => "oncall/#{Oncall::VERSION}" }
6
+ @http = nil
7
+ @headers = {}
15
8
  @params = {}
16
- @query = {}
17
- @response = nil
18
- @request = nil
19
9
  end
20
10
 
21
11
  def to_s
22
- file
12
+ @file
23
13
  end
24
14
 
25
15
  private
26
16
 
27
- def group(name=nil, &block)
28
- return reporter.empty_group(self) unless block_given?
17
+ def group(_name=nil, &block)
18
+ return @reporter.empty_group(self) unless block_given?
29
19
 
30
20
  instance_exec &block
31
21
  end
32
22
 
33
23
  def get(path, &block)
34
- return reporter.empty_call(self) unless block_given?
24
+ return @reporter.empty_call(self) unless block_given?
35
25
 
36
- uri = Oncall.uri(path, @params)
37
- @request = Net::HTTP::Get.new(uri)
38
-
39
- @headers.each do |key, value|
40
- @request[key] = value
41
- end
42
-
43
- @response = http.request(request)
26
+ @http = Oncall::HTTP.new(path, headers: @headers, params: @params)
27
+ @http.get
44
28
 
45
29
  instance_exec &block
46
30
  end
@@ -48,14 +32,8 @@ module Oncall
48
32
  def post(path, &block)
49
33
  return reporter.empty_call(self) unless block_given?
50
34
 
51
- uri = Oncall.uri(path, @params)
52
- @request = Net::HTTP::Post.new(uri)
53
-
54
- @headers.each do |key, value|
55
- @request[key] = value
56
- end
57
-
58
- @response = http.request(request)
35
+ @http = Oncall::HTTP.new(path, headers: @headers, params: @params)
36
+ @http.post
59
37
 
60
38
  instance_exec &block
61
39
  end
@@ -73,13 +51,13 @@ module Oncall
73
51
  end
74
52
 
75
53
  def validate(expected)
76
- result = JSON::Validator.validate(expected, @response.body)
77
- reporter.json_schema(self, result, expected)
54
+ result = JSON::Validator.validate(expected, @http.response_body)
55
+ @reporter.json_schema(self, result, expected)
78
56
  end
79
57
 
80
58
  def status(expected)
81
- result = response.code == expected.to_s
82
- reporter.status(self, result, expected)
59
+ result = @http.response_code == expected.to_s
60
+ @reporter.status(self, result, expected)
83
61
  end
84
62
  end
85
63
  end
@@ -0,0 +1,47 @@
1
+ module Oncall
2
+ class HTTP
3
+ attr_accessor :path, :headers, :params
4
+
5
+ def initialize(path, **opts)
6
+ @path = path
7
+ @client = Net::HTTP.new(Oncall.options.host, Oncall.options.port)
8
+ @headers = opts[:headers] || { 'User-Agent' => "#{Oncall::SCRIPT}/#{Oncall::VERSION}" }
9
+ @params = opts[:params] || {}
10
+ @query = opts[:query] || {}
11
+ end
12
+
13
+ def get
14
+ request = Net::HTTP::Get.new(uri)
15
+ @response = @client.request(request)
16
+ end
17
+
18
+ def post
19
+ request = Net::HTTP::Post.new(uri)
20
+ @response = @client.request(request)
21
+ end
22
+
23
+ def response_body
24
+ @response.body
25
+ end
26
+
27
+ def response_code
28
+ @response.code
29
+ end
30
+
31
+ private
32
+
33
+ def uri
34
+ parts = path.split('/')
35
+ return '/' if parts.empty?
36
+
37
+ parts.each_with_index do |part, index|
38
+ if part.start_with?(':')
39
+ part[0] = ''
40
+ parts[index] = params[part.to_sym]
41
+ end
42
+ end
43
+
44
+ parts.join('/')
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,9 @@
1
+ module Oncall
2
+ module Invocations
3
+ class BaseRunner
4
+ def run(_err, _out)
5
+ raise NotImplementedError
6
+ end
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,6 @@
1
+ module Oncall
2
+ module Invocations
3
+ class ConsoleRunner < BaseRunner
4
+ end
5
+ end
6
+ end
@@ -0,0 +1,15 @@
1
+ module Oncall
2
+ module Invocations
3
+ class HelpRunner < BaseRunner
4
+ attr_reader :parser
5
+
6
+ def initialize(parser)
7
+ @parser = parser
8
+ end
9
+
10
+ def run(_err, out)
11
+ out.puts parser
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,14 @@
1
+ module Oncall
2
+ module Invocations
3
+ class InitRunner < BaseRunner
4
+ def run(_err, _out)
5
+ config_template_path = File.join(File.dirname(__FILE__), '..', 'templates', 'oncall.yml.template')
6
+ template = File.read(config_template_path)
7
+
8
+ File.open(File.join(Dir.getwd, 'oncall.yml'), 'w') do |file|
9
+ file.write(template)
10
+ end
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,40 @@
1
+ module Oncall
2
+ module Invocations
3
+ class TestRunner < BaseRunner
4
+ def run(err, out)
5
+ reporter.report do |r|
6
+ suite.map { |g| g.run(r) }
7
+ end
8
+
9
+ reporter.success? ? 0 : 1
10
+ end
11
+
12
+ private
13
+
14
+ def reporter
15
+ @reporter ||= Oncall::Reporter.new
16
+ end
17
+
18
+ def suite
19
+ files = []
20
+
21
+ test_files.each do |file|
22
+ test_file = Oncall::TestFile.new(file)
23
+ files << test_file
24
+ end
25
+
26
+ files
27
+ end
28
+
29
+ def test_files
30
+ matched_files = Dir.glob(options.pattern)
31
+ excluded_files = Dir.glob(options.exclude)
32
+ matched_files - excluded_files
33
+ end
34
+
35
+ def options
36
+ Oncall.options
37
+ end
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,9 @@
1
+ module Oncall
2
+ module Invocations
3
+ class VersionRunner < BaseRunner
4
+ def run(_err, out)
5
+ out.puts "#{Oncall::SCRIPT}: v#{Oncall::VERSION}"
6
+ end
7
+ end
8
+ end
9
+ end
@@ -1,26 +1,91 @@
1
1
  module Oncall
2
2
  class Options
3
- attr_writer :runner
4
- attr_accessor :env,
5
- :pattern,
3
+ attr_writer :runner, :config, :env
4
+ attr_accessor :pattern,
6
5
  :exclude,
7
6
  :group,
8
7
  :persist,
9
- :config,
10
- :path
8
+ :path,
9
+ :verbose,
10
+ :host,
11
+ :port
11
12
 
12
13
  def initialize
13
- @env = 'develop'
14
- @pattern = '**{,/*/**}/*_oncall.rb'
14
+ @env = nil
15
+ @pattern = default_pattern
15
16
  @exclude = ''
16
17
  @group = nil
17
18
  @persist = nil
18
- @config = nil
19
19
  @path = nil
20
+ @verbose = default_verbosity
21
+ @host = default_host
22
+ @port = default_port
20
23
  end
21
24
 
22
25
  def runner
23
26
  @runner ||= Oncall::Invocations::TestRunner.new
24
27
  end
28
+
29
+ def config
30
+ @config ||= config_default
31
+ end
32
+
33
+ def env
34
+ @env ||= default_env
35
+ end
36
+
37
+ def parse_config
38
+ conf_file = load_config_file
39
+
40
+ set_default_env conf_file
41
+ update_options conf_file
42
+ end
43
+
44
+ private
45
+
46
+ def update_options(conf_file)
47
+ raise "Expected env '#{env}' does not exist in config" unless conf_file.key? env
48
+
49
+ @domain = conf_file[env]['domain'] if conf_file[env].key? 'domain'
50
+ @port = conf_file[env]['port'] if conf_file[env].key? 'port'
51
+ end
52
+
53
+ def set_default_env(conf_file)
54
+ return if @env
55
+
56
+ @env = conf_file['default'] if conf_file.key? 'default'
57
+ end
58
+
59
+ def load_config_file
60
+ YAML.load_file(config)
61
+ end
62
+
63
+ def default_pattern
64
+ '**{,/*/**}/*_oncall.rb'
65
+ end
66
+
67
+ def default_env
68
+ 'develop'
69
+ end
70
+
71
+ def default_host
72
+ 'localhost'
73
+ end
74
+
75
+ def default_port
76
+ 3000
77
+ end
78
+
79
+ def default_verbosity
80
+ false
81
+ end
82
+
83
+ def config_default
84
+ File.join(Dir.pwd, config_file_name)
85
+ end
86
+
87
+ def config_file_name
88
+ 'oncall.yml'
89
+ end
25
90
  end
26
91
  end
@@ -7,7 +7,7 @@ module Oncall
7
7
  end
8
8
 
9
9
  def run(reporter)
10
- Oncall::DSL.new(file, reporter).instance_eval File.read(file)
10
+ Oncall::DSL.new(self, reporter).instance_eval File.read(file)
11
11
  end
12
12
  end
13
13
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Oncall
4
- VERSION = '0.3.0'
4
+ VERSION = '0.4.0'
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: oncall
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0
4
+ version: 0.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Koen Woortman
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-11-08 00:00:00.000000000 Z
11
+ date: 2019-11-18 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: colorize
@@ -56,16 +56,16 @@ dependencies:
56
56
  name: rspec
57
57
  requirement: !ruby/object:Gem::Requirement
58
58
  requirements:
59
- - - ">="
59
+ - - '='
60
60
  - !ruby/object:Gem::Version
61
- version: '0'
61
+ version: 3.9.0
62
62
  type: :development
63
63
  prerelease: false
64
64
  version_requirements: !ruby/object:Gem::Requirement
65
65
  requirements:
66
- - - ">="
66
+ - - '='
67
67
  - !ruby/object:Gem::Version
68
- version: '0'
68
+ version: 3.9.0
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: sinatra
71
71
  requirement: !ruby/object:Gem::Requirement
@@ -92,9 +92,14 @@ files:
92
92
  - bin/oncall
93
93
  - lib/oncall.rb
94
94
  - lib/oncall/cli.rb
95
- - lib/oncall/config.rb
96
95
  - lib/oncall/dsl.rb
97
- - lib/oncall/invocations.rb
96
+ - lib/oncall/http.rb
97
+ - lib/oncall/invocations/base_runner.rb
98
+ - lib/oncall/invocations/console_runner.rb
99
+ - lib/oncall/invocations/help_runner.rb
100
+ - lib/oncall/invocations/init_runner.rb
101
+ - lib/oncall/invocations/test_runner.rb
102
+ - lib/oncall/invocations/version_runner.rb
98
103
  - lib/oncall/options.rb
99
104
  - lib/oncall/reporter.rb
100
105
  - lib/oncall/templates/oncall.yml.template
@@ -1,4 +0,0 @@
1
- module Oncall
2
- class Config
3
- end
4
- end
@@ -1,73 +0,0 @@
1
- module Oncall
2
- module Invocations
3
- class ConsoleRunner
4
- def run(err, out); end
5
- end
6
-
7
- class HelpRunner
8
- attr_reader :parser
9
-
10
- def initialize(parser)
11
- @parser = parser
12
- end
13
-
14
- def run(err, out)
15
- out.puts parser
16
- end
17
- end
18
-
19
- class InitRunner
20
- def run(err, out)
21
- config_template_path = File.join(File.dirname(__FILE__), 'templates', 'oncall.yml.template')
22
- template = File.read(config_template_path)
23
-
24
- File.open(File.join(Dir.getwd, 'oncall.yml'), 'w') do |file|
25
- file.write(template)
26
- end
27
- end
28
- end
29
-
30
- class VersionRunner
31
- def run(err, out)
32
- out.puts "Oncall: v#{Oncall::VERSION}"
33
- end
34
- end
35
-
36
- class TestRunner
37
- def run(err, out)
38
- reporter.report do |r|
39
- suite.map { |g| g.run(r) }
40
- end
41
-
42
- reporter.success? ? 0 : 1
43
- end
44
-
45
- private
46
-
47
- def reporter
48
- @reporter ||= Oncall::Reporter.new
49
- end
50
-
51
- def suite
52
- files = []
53
-
54
- test_files.each do |file|
55
- test_file = Oncall::TestFile.new(file)
56
- files << test_file
57
- end
58
-
59
- files
60
- end
61
-
62
- def test_files
63
- matched_files = Dir.glob(options.pattern)
64
- excluded_files = Dir.glob(options.exclude)
65
- matched_files - excluded_files
66
- end
67
-
68
- def options
69
- Oncall.options
70
- end
71
- end
72
- end
73
- end