hobby-test 0.0.4 → 0.0.5

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
  SHA1:
3
- metadata.gz: 61cd3a457c60be67607b061852aef03d00d6fcd7
4
- data.tar.gz: e9fae2b5ebbc5a727032b715a784323ec3e817c9
3
+ metadata.gz: 3562fd6babd886a773823d0dc6887b0f2b78a463
4
+ data.tar.gz: a0c92acd2d1defcbd44503364d7054956e9bad91
5
5
  SHA512:
6
- metadata.gz: 256a68e3c67766a20b0719e2a23a39d966938bf460f3619e3251755a208d867ba0f1f566f9bb94e04ca614a96b5e42d078757c939357fe929417e3c893cb2494
7
- data.tar.gz: 7e0eacc4fb1cbf4a702ab5b0615a44f97e5df84115290ec3f3cab7bf9cf718d165b73930893b370246ec4a6b84dda6cc85c9f38c420855b135a36ea5b9446b84
6
+ metadata.gz: 569d8473b72c10be990f4da0a0f91a741ea9c348e911980b0fefc2903b6ff9fc91ae60f8b0e7ddf4dd47428a8ab4811dd8435352009dc8a36148768b02b0bc03
7
+ data.tar.gz: ab16a3283435543d75910cd20107d33e04d40a1cb3546fab85e44b8b05b9a23c45ce24c4d024b50cf9a6b9010f1a81a6b1a3155cf0efa706112e6a5615af3393
data/.gitignore CHANGED
@@ -1 +1,2 @@
1
1
  Gemfile.lock
2
+ *.gem
@@ -1,10 +1,11 @@
1
1
  Gem::Specification.new do |g|
2
2
  g.name = 'hobby-test'
3
3
  g.files = `git ls-files`.split($/)
4
- g.version = '0.0.4'
4
+ g.version = '0.0.5'
5
5
  g.summary = 'A way to test HTTP exchanges via YAML specifications'
6
6
  g.authors = ['Anatoly Chernow']
7
7
 
8
8
  g.add_dependency 'excon'
9
- g.add_dependency 'to_proc'
9
+ g.add_dependency 'to_proc', '>= 0.0.7'
10
+ g.add_dependency 'include_constants'
10
11
  end
@@ -1,4 +1,5 @@
1
1
  require 'to_proc/all'
2
+ require 'include_constants'
2
3
  require 'excon'
3
4
 
4
5
  require 'yaml'
@@ -6,22 +7,20 @@ require 'json'
6
7
  require 'forwardable'
7
8
  require 'ostruct'
8
9
 
9
- require 'hobby/test/exchange'
10
- require 'hobby/test/report'
11
- require 'hobby/test/env'
12
-
13
10
  module Hobby
14
11
  class Test
15
- def self.from_file string
16
- new YAML.load_file string
12
+ def self.from_file string, **defaults
13
+ new (YAML.load_file string), defaults: defaults
17
14
  end
18
15
 
19
- def self.from_string string
20
- new YAML.load string
16
+ def self.from_string string, **defaults
17
+ new (YAML.load string), defaults: defaults
21
18
  end
22
19
 
23
- def initialize array_of_hashes
24
- @exchanges = array_of_hashes.map &Exchange
20
+ def initialize array_of_hashes, defaults: {}
21
+ @exchanges = array_of_hashes
22
+ .map(&[defaults, :merge])
23
+ .map(&Exchange)
25
24
  end
26
25
 
27
26
  def [] address
@@ -34,5 +33,11 @@ module Hobby
34
33
 
35
34
  Report.new @exchanges.map &[env]
36
35
  end
36
+
37
+ include_constants from: ToProc
37
38
  end
38
39
  end
40
+
41
+ require 'hobby/test/exchange'
42
+ require 'hobby/test/report'
43
+ require 'hobby/test/env'
@@ -2,9 +2,8 @@ module Hobby
2
2
  class Test
3
3
  class Exchange
4
4
  def initialize hash
5
- @request = Request.new hash.find { |key, _|
6
- Request::VERBS.include? key
7
- }
5
+ verb, params = hash.find &Key[Request::VERBS, :include?]
6
+ @request = Request.new [verb, params, *hash[:format]]
8
7
  @asserts = (hash['response']&.map &Assert) || []
9
8
  end
10
9
  attr_reader :request, :asserts
@@ -1,14 +1,12 @@
1
1
  class Hobby::Test::Exchange
2
- module Assert
3
- def self.[] pair
2
+ class Assert
3
+ def initialize pair
4
4
  key, delimiter, chain = pair[0].partition /\.|\[/
5
5
  chain.prepend (delimiter == '[' ? 'self[' : 'self.') unless chain.empty?
6
- const_get(key.capitalize).new key, chain, pair[1]
7
- end
8
6
 
9
- def initialize key, chain, value
10
- @key, @chain, @specified_value = key, chain, value
7
+ @key, @chain, @specified_value = key, chain, pair[1]
11
8
  end
9
+ attr_reader :key, :chain, :specified_value, :actual_value
12
10
 
13
11
  def ok?
14
12
  @ok
@@ -18,54 +16,23 @@ class Hobby::Test::Exchange
18
16
  dup.assert response
19
17
  end
20
18
 
21
- def compare_chain
22
- if chain.end_with? '>', '=', '<'
23
- actual_value.instance_eval "#{chain}(#{specified_value})"
24
- else
25
- (actual_value.instance_eval chain) == specified_value
26
- end
27
- end
28
-
29
- def assert response
30
- @actual_value = response.public_send key
31
- compare
32
- self
33
- end
34
-
35
- attr_reader :actual_value, :specified_value, :chain, :key
36
-
37
- class Status
38
- include Assert
39
-
40
- def compare
41
- @ok = actual_value == specified_value
19
+ protected
20
+ def assert response
21
+ @actual_value = response.public_send key
22
+ compare
23
+ self
42
24
  end
43
- end
44
-
45
- class Headers
46
- include Assert
47
25
 
48
26
  def compare
49
27
  @ok = chain.empty? ? actual_value == specified_value : compare_chain
50
28
  end
51
- end
52
29
 
53
- class Body
54
- include Assert
55
-
56
- def compare
57
- @actual_value = begin
58
- JSON.parse actual_value
59
- rescue JSON::ParserError
60
- actual_value
61
- end
62
-
63
- @ok = if chain.empty?
64
- actual_value == specified_value
65
- else
66
- compare_chain
67
- end
30
+ def compare_chain
31
+ if chain.end_with? '>', '=', '<'
32
+ actual_value.instance_eval "#{chain}(#{specified_value})"
33
+ else
34
+ (actual_value.instance_eval chain) == specified_value
35
+ end
68
36
  end
69
- end
70
37
  end
71
38
  end
@@ -1,35 +1,32 @@
1
1
  class Hobby::Test::Exchange
2
2
  class Request < OpenStruct
3
+ include ToProc
3
4
  VERBS = %w[delete get head options patch post put]
4
- def initialize pair
5
- @verb, hash = pair
5
+ def initialize triple
6
+ @verb, hash, @format = triple
6
7
 
7
- template_fields, regular_fields = hash.partition do |key, _|
8
- key.start_with? 'template.'
9
- end
8
+ template_fields, regular_fields = hash.partition &Key[:start_with?, 'template.']
10
9
  @templates = template_fields.map &Hobby::Test::Template
11
10
 
12
11
  super regular_fields.to_h
13
12
  end
14
13
  attr_reader :verb
15
14
 
16
- def regular_fields body_serializer:
15
+ def regular_fields
17
16
  hash = to_h
18
17
 
19
- if body && body_serializer
20
- hash[:body] = body_serializer.dump body
18
+ if body && @format
19
+ hash[:body] = @format.dump body
21
20
  end
22
21
 
23
22
  hash
24
23
  end
25
24
 
26
25
  def perform_in env
27
- body_serializer = JSON if body.is_a? Hash
28
- params = regular_fields(body_serializer: body_serializer)
29
- .merge @templates.map(&[env]).to_h
26
+ params = regular_fields.merge @templates.map(&[env]).to_h
30
27
 
31
28
  excon_response = env.connection.public_send verb, **params
32
- response = Response.new excon_response, body_serializer: body_serializer
29
+ response = Response.new excon_response, format: @format
33
30
  env.responses << response
34
31
  end
35
32
  end
@@ -1,16 +1,25 @@
1
1
  class Hobby::Test::Exchange
2
2
  class Response
3
- def initialize excon_response, body_serializer:
4
- @excon_response, @body_serializer = excon_response, body_serializer
3
+ def initialize excon_response, format:
4
+ @excon_response, @format = excon_response, format
5
5
  end
6
- attr_reader :body_serializer
6
+ attr_reader :format
7
7
 
8
- def [] key
9
- @serialized ||= JSON.load body
10
- @serialized[key]
8
+ def body
9
+ @body ||= if format
10
+ format.load @excon_response.body
11
+ else
12
+ PlainBody.new @excon_response.body
13
+ end
14
+ end
15
+
16
+ class PlainBody < String
17
+ def == expected_response
18
+ eql? expected_response.to_s
19
+ end
11
20
  end
12
21
 
13
22
  extend Forwardable
14
- delegate [:status, :headers, :body] => :@excon_response
23
+ delegate [:status, :headers] => :@excon_response
15
24
  end
16
25
  end
@@ -2,11 +2,11 @@ require 'hobby'
2
2
  require 'hobby/json'
3
3
 
4
4
  class MainApp
5
- include Hobby::App
5
+ include Hobby
6
6
  get { 'root' }
7
7
 
8
8
  class Counter
9
- include Hobby::App
9
+ include Hobby
10
10
  @@counter = 0
11
11
  get { @@counter }
12
12
  post { @@counter += 1 }
@@ -23,7 +23,7 @@ class MainApp
23
23
  get('/echo-with-query') { request.params.to_json }
24
24
 
25
25
  class Query
26
- include Hobby::App
26
+ include Hobby
27
27
  get { request.params['array'].class }
28
28
  end
29
29
  map('/query') { run Query.new }
@@ -68,7 +68,8 @@ class MainApp
68
68
  map('/array') { run ArrayApp.new }
69
69
 
70
70
  class ForLastResponse
71
- include Hobby::App
71
+ include Hobby
72
+ include JSON
72
73
  post { 42 }
73
74
  get '/:id' do my[:id].to_i * 2 end
74
75
  end
@@ -1,20 +1,23 @@
1
1
  require 'helper'
2
2
 
3
3
  describe 'passing and failing YAML specifications' do
4
- Dir["spec/yml/**/*.yml"].each do |path|
4
+ Dir["spec/yml/json/*.yml"].each do |path|
5
+ name = path.split('/').last
6
+ test = Hobby::Test.from_file path, format: JSON
7
+
8
+ it "passing #{name}" do
9
+ report = test[@socket]
10
+ assert { report.ok? }
11
+ end
12
+ end
13
+
14
+ Dir["spec/yml/plain/*.yml"].each do |path|
5
15
  name = path.split('/').last
6
16
  test = Hobby::Test.from_file path
7
17
 
8
- if path.include? 'passing'
9
- it "passing #{name}" do
10
- report = test[@socket]
11
- assert { report.ok? }
12
- end
13
- else
14
- it "failing #{name}" do
15
- report = test[@socket]
16
- assert { not report.ok? }
17
- end
18
+ it "passing #{name} plain text" do
19
+ report = test[@socket]
20
+ assert { report.ok? }
18
21
  end
19
22
  end
20
23
  end
@@ -21,7 +21,7 @@ describe Hobby::Test do
21
21
  end
22
22
 
23
23
  it 'in case of success' do
24
- test = described_class.from_file 'spec/yml/passing/0.yml'
24
+ test = described_class.from_file 'spec/yml/plain/basic.yml'
25
25
  report = test['http://localhost:8080']
26
26
  assert { report.ok? }
27
27
  end
@@ -2,10 +2,10 @@
2
2
  path: /for_last_response
3
3
 
4
4
  response:
5
- body: "42"
5
+ body: 42
6
6
 
7
7
  - get:
8
8
  template.path: uri 'for_last_response', last_response.body
9
9
 
10
10
  response:
11
- body: "84"
11
+ body: 84
File without changes
File without changes
@@ -0,0 +1,9 @@
1
+ - get:
2
+ path: /hash
3
+
4
+ - get:
5
+ template.path: uri 'for_last_response', last_response.body['a']
6
+
7
+ response:
8
+ status: 200
9
+ body: 2
@@ -8,4 +8,4 @@
8
8
  path: /counter
9
9
 
10
10
  response:
11
- body: "2"
11
+ body: 2
File without changes
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: hobby-test
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.4
4
+ version: 0.0.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Anatoly Chernow
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-12-31 00:00:00.000000000 Z
11
+ date: 2017-01-02 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: excon
@@ -26,6 +26,20 @@ dependencies:
26
26
  version: '0'
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: to_proc
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: 0.0.7
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: 0.0.7
41
+ - !ruby/object:Gem::Dependency
42
+ name: include_constants
29
43
  requirement: !ruby/object:Gem::Requirement
30
44
  requirements:
31
45
  - - ">="
@@ -64,15 +78,14 @@ files:
64
78
  - spec/setup/mutant.rb
65
79
  - spec/setup/power_assert.rb
66
80
  - spec/tcp_spec.rb
67
- - spec/yml/failing/0.yml
68
- - spec/yml/passing/0.yml
69
- - spec/yml/passing/access_last_response.yml
70
- - spec/yml/passing/chain_assertions.yml
71
- - spec/yml/passing/counter.yml
72
- - spec/yml/passing/echo.yml
73
- - spec/yml/passing/headers.yml
74
- - spec/yml/passing/query.yml
75
- - spec/yml/passing/referring_to_json_body.yml
81
+ - spec/yml/json/access_last_response.yml
82
+ - spec/yml/json/chain_assertions.yml
83
+ - spec/yml/json/echo.yml
84
+ - spec/yml/json/headers.yml
85
+ - spec/yml/json/referring_to_json_body.yml
86
+ - spec/yml/plain/basic.yml
87
+ - spec/yml/plain/counter.yml
88
+ - spec/yml/plain/query.yml
76
89
  homepage:
77
90
  licenses: []
78
91
  metadata: {}
@@ -1,12 +0,0 @@
1
- - get:
2
- path: /
3
-
4
- response:
5
- status: 200
6
- body: root-only app
7
-
8
- - get:
9
- path: /non-existent
10
-
11
- response:
12
- status: 200
@@ -1,9 +0,0 @@
1
- - get:
2
- path: /hash
3
-
4
- - get:
5
- template.path: uri 'for_last_response', last_response['a']
6
-
7
- response:
8
- status: 200
9
- body: '2'