hobby-test 0.0.4 → 0.0.5

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
  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'