oncall 0.3.0 → 0.4.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 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