endo 0.1.0 → 0.2.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
  SHA1:
3
- metadata.gz: b99d1fdfdb8f0ad10fdbdc2a3e46b9974addee86
4
- data.tar.gz: f39abeadde123c22cd9ffc792d2cdde034e34bc4
3
+ metadata.gz: 90b76cfad1ab5f415e15a9b7f661c451844a8c18
4
+ data.tar.gz: 4d858870cf13514bec7e1fdc6460def568f6d93b
5
5
  SHA512:
6
- metadata.gz: 88b0052adb6db8f27c59b2bff2a7d677c5f1d07d73c3a6286564c61431c115236c29bd5684a591cd65ca42db17e975435e01ff4f0e9e0358f154a31e0e4cc555
7
- data.tar.gz: 3bdd8f80f063cdd41d3efcdc562572c327077599330dceafec381a0e340b368460137ab2adae73f6293aad43bac991568e4d770d9ff2a8899edeed5d48a3110f
6
+ metadata.gz: fe230bbd9feb1d12d59eae5ced3de6ffa5011a233336acce5234ada09a66038c2622559fa2e023b07748488325968bfd82a579b72d809879595159b74cfb4279
7
+ data.tar.gz: 82fb6f79d151d610f39a1a317fca3fd3c55b1b1fe908337ba2c77b8b9d4f9327c5b78b9c75c549c3fde6614373186976b52f859b2b927200ac7689ced7c14db4
data/README.md CHANGED
@@ -11,30 +11,27 @@ ex. endo/sample.endo
11
11
  ```ruby
12
12
  set :base_url, 'http://endo-sample.maruware.com'
13
13
 
14
- get '/articles'
14
+ get '/articles' do
15
+ expect(body: ->{ at(0)[:title] }).to eq 'good'
16
+ end
15
17
 
16
18
  get '/articles/:article_id' do
17
- param 'article_id' do
18
- from :get, '/articles' do |articles|
19
- articles.first[:id]
20
- end
19
+ param :article_id do
20
+ from :get, '/articles', ->{ first[:id] }
21
21
  end
22
+
23
+ expect(header: 'Content-Type').to eq 'application/json; charset=utf-8'
22
24
  end
23
25
 
24
- post '/articles' do
25
- param 'title', 'hello'
26
- param 'text', 'Hello, world!'
26
+ post '/articless' do
27
+ param :title, 'hello'
28
+ param :text, 'Hello, world!'
27
29
  end
28
30
  ```
29
31
 
30
32
  Exec endo command.
31
33
 
32
- ```
33
- $ endo exec endo/sample.endo
34
- 🍺 /articles [142ms]
35
- 🍺 /articles/1 [31ms]
36
- 🍺 /articles [28ms]
37
- ```
34
+ ![2016-03-07 21 24 08](https://cloud.githubusercontent.com/assets/1129887/13569450/7d9a796a-e4ab-11e5-9ab0-e52eef36ea0f.png)
38
35
 
39
36
  ## Installation
40
37
 
data/endo.gemspec CHANGED
@@ -20,6 +20,7 @@ Gem::Specification.new do |spec|
20
20
  spec.require_paths = ["lib"]
21
21
 
22
22
  spec.add_runtime_dependency "thor"
23
+ spec.add_runtime_dependency "colorize"
23
24
 
24
25
  spec.add_development_dependency "bundler", "~> 1.8"
25
26
  spec.add_development_dependency "rake", "~> 10.0"
data/endo/sample.endo CHANGED
@@ -1,16 +1,18 @@
1
1
  set :base_url, 'http://endo-sample.maruware.com'
2
2
 
3
- get '/articles'
3
+ get '/articles' do
4
+ expect(body: ->{ at(0)[:title] }).to eq 'good'
5
+ end
4
6
 
5
7
  get '/articles/:article_id' do
6
- param 'article_id' do
7
- from :get, '/articles' do |articles|
8
- articles.first[:id]
9
- end
8
+ param :article_id do
9
+ from :get, '/articles', ->{ first[:id] }
10
10
  end
11
+
12
+ expect(header: 'Content-Type').to eq 'application/json; charset=utf-8'
11
13
  end
12
14
 
13
- post '/articles' do
14
- param 'title', 'hello'
15
- param 'text', 'Hello, world!'
15
+ post '/articless' do
16
+ param :title, 'hello'
17
+ param :text, 'Hello, world!'
16
18
  end
data/lib/endo.rb CHANGED
@@ -1,5 +1,7 @@
1
1
  require "endo/version"
2
2
  require "endo/cli"
3
+ require "endo/matchers"
4
+ require "endo/expectation_target"
3
5
  require "endo/core"
4
6
  require "endo/error"
5
7
 
data/lib/endo/core.rb CHANGED
@@ -1,12 +1,16 @@
1
1
  require 'open-uri'
2
2
  require 'json'
3
3
  require 'net/http'
4
+ require 'colorize'
4
5
 
5
6
  module Endo
6
7
  class Core
8
+ include Endo::Matchers
9
+
7
10
  def initialize
8
11
  @props = {}
9
12
  @responses = {}
13
+ @expect_alls = {}
10
14
  end
11
15
 
12
16
  def set(key, val)
@@ -28,7 +32,7 @@ module Endo
28
32
  raise ArgumentError.new('DupValue')
29
33
  end
30
34
 
31
- @params[key] = if val
35
+ @params[key.to_s] = if val
32
36
  val
33
37
  else
34
38
  block.call
@@ -37,18 +41,21 @@ module Endo
37
41
  end
38
42
 
39
43
  #TODO: Limit scope
40
- def from(method, endpoint, &block)
44
+ def from(method, endpoint, lmd=nil, &block)
41
45
  key = build_response_key(method, endpoint)
42
46
  unless @responses.has_key? key
43
47
  raise RuntimeError.new("NotFoundKey [#{key}]")
44
48
  end
45
49
 
46
- unless block
50
+ res = @responses[key]
51
+ val = if lmd
52
+ res.instance_exec &lmd
53
+ elsif block
54
+ block.call(res)
55
+ else
47
56
  raise ArgumentError.new('UndefinedBlock')
48
57
  end
49
58
 
50
- res = @responses[key]
51
- val = block.call(res)
52
59
  unless val.is_a?(String) || val.is_a?(Integer) || val.is_a?(Numeric)
53
60
  raise RuntimeError.new('BadValueType')
54
61
  end
@@ -61,25 +68,31 @@ module Endo
61
68
  org_endpoint = endpoint.clone
62
69
 
63
70
  @params = {}
71
+ @expects = []
64
72
  block.call if block
65
73
 
66
74
  endpoint = apply_pattern_vars(endpoint, @params)
67
75
 
68
76
  url = @props[:base_url] + endpoint
69
77
 
70
- message = begin
78
+ begin
71
79
  t_start = Time.now.instance_eval { self.to_i * 1000 + (usec/1000) }
72
- res = http_request_json(url, @params, method: method)
80
+ res = http_request(url, @params, method: method)
73
81
  t_end = Time.now.instance_eval { self.to_i * 1000 + (usec/1000) }
74
82
 
75
- @responses[build_response_key(method, endpoint)] = res
76
- "🍺 #{endpoint} [#{t_end-t_start}ms]"
83
+ res_data = parse_body_json(res)
84
+ @responses[build_response_key(method, endpoint)] = res_data
85
+ validate_expects(res) unless @expect_alls.empty? && @expects.empty?
86
+ message = "🍺 #{endpoint} [#{t_end-t_start}ms]"
77
87
  rescue Error::HttpError=>e
78
- "💩 #{endpoint} [code: #{e.code}]"
88
+ message = "💩 #{endpoint} [code: #{e.code}]".red
89
+ exit 1
90
+ rescue Error::ValidationError => e
91
+ message = "👮 #{endpoint} [expected: \"#{e.expected}\" actual: \"#{e.actual}\"]".yellow
92
+ ensure
93
+ puts message
79
94
  end
80
95
 
81
-
82
- puts message
83
96
  end
84
97
 
85
98
  def apply_pattern_vars(endpoint, params)
@@ -101,33 +114,51 @@ module Endo
101
114
  endpoint
102
115
  end
103
116
 
104
- def http_request_json(url, params, method: :get, symbolize_names: true)
105
- res = http_request(url, params, method)
106
- JSON.parse(res, symbolize_names: symbolize_names)
107
- end
108
-
109
- def http_request(url, params, method)
117
+ def http_request(url, params, method: :get)
110
118
  uri = URI.parse url
111
119
 
112
- if method == :get
120
+ req = if method == :get
113
121
  uri.query = URI.encode_www_form(params)
114
122
  req = Net::HTTP::Get.new uri
115
- end
116
-
117
- if method == :post
123
+ elsif method == :post
118
124
  req = Net::HTTP::Post.new uri.path
119
125
  req.set_form_data(params)
126
+ req
120
127
  end
121
128
 
122
129
  res = Net::HTTP.start(uri.host, uri.port) {|http| http.request req }
123
130
  raise Error::HttpError.new("HTTP Bad Status[#{res.code}] #{res.body}", res.code, res.body) unless /^20[0-8]$/ =~ res.code
124
131
 
125
- return res.body
132
+ return res
133
+ end
134
+
135
+ def parse_body_json(res)
136
+ JSON.parse(res.body, symbolize_names: true)
126
137
  end
127
138
 
128
139
  def build_response_key(method, endpoint)
129
140
  "#{method}:#{endpoint}"
130
141
  end
131
142
 
143
+ def expect(header: nil, body: nil)
144
+ expectation = if header
145
+ ExpectationTarget.new(:header, header)
146
+ elsif(body)
147
+ ExpectationTarget.new(:body, body)
148
+ else
149
+ raise 'TODO'
150
+ end
151
+ @expects << expectation
152
+ return expectation
153
+ end
154
+
155
+ def validate_expects(res)
156
+ @expects.each do |expectation|
157
+ unless expectation.matches?(res)
158
+ raise Error::ValidationError.new(expectation.expected, expectation.actual)
159
+ end
160
+ end
161
+ end
162
+
132
163
  end
133
164
  end
data/lib/endo/error.rb CHANGED
@@ -1 +1,2 @@
1
- require 'endo/error/http_error'
1
+ require 'endo/error/http_error'
2
+ require 'endo/error/validation_error'
@@ -0,0 +1,15 @@
1
+
2
+ module Endo
3
+ module Error
4
+ class ValidationError < StandardError
5
+ attr_reader :expected, :actual
6
+
7
+ def initialize(expected, actual)
8
+ super("expected: #{expected}\n actual: #{actual}")
9
+ @expected = expected
10
+ @actual = actual
11
+ end
12
+
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,32 @@
1
+ module Endo
2
+ class ExpectationTarget
3
+ attr_reader :actual
4
+
5
+ def initialize(target, query)
6
+ @target = target
7
+ @query = query
8
+ end
9
+
10
+ def to(matcher)
11
+ @matcher = matcher
12
+ end
13
+
14
+ def matches?(res)
15
+ @actual = case @target
16
+ when :header
17
+ res.header[@query]
18
+ when :body
19
+ obj = JSON.parse res.body, symbolize_names: true
20
+ obj.instance_exec(&@query)
21
+ end
22
+ @matcher.matches?(@actual)
23
+ end
24
+
25
+
26
+ def expected
27
+ @matcher.expected
28
+ end
29
+
30
+
31
+ end
32
+ end
@@ -0,0 +1,11 @@
1
+ require 'endo/matchers/base_matcher'
2
+ require 'endo/matchers/eq'
3
+
4
+
5
+ module Endo
6
+ module Matchers
7
+ def eq(expected)
8
+ Matchers::Eq.new(expected)
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,15 @@
1
+ module Endo
2
+ module Matchers
3
+ class BaseMatcher
4
+ attr_reader :expected
5
+
6
+ def initialize(expected)
7
+ @expected = expected
8
+ end
9
+
10
+ def matches?(actual)
11
+ match(expected, actual)
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,12 @@
1
+ module Endo
2
+ module Matchers
3
+ class Eq < BaseMatcher
4
+ attr_reader :expected
5
+
6
+ private
7
+ def match(expected, actual)
8
+ actual == expected
9
+ end
10
+ end
11
+ end
12
+ end
data/lib/endo/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Endo
2
- VERSION = "0.1.0"
2
+ VERSION = "0.2.0"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: endo
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - maruware
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-10-28 00:00:00.000000000 Z
11
+ date: 2016-03-07 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: thor
@@ -24,6 +24,20 @@ dependencies:
24
24
  - - ">="
25
25
  - !ruby/object:Gem::Version
26
26
  version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: colorize
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
27
41
  - !ruby/object:Gem::Dependency
28
42
  name: bundler
29
43
  requirement: !ruby/object:Gem::Requirement
@@ -86,6 +100,11 @@ files:
86
100
  - lib/endo/core.rb
87
101
  - lib/endo/error.rb
88
102
  - lib/endo/error/http_error.rb
103
+ - lib/endo/error/validation_error.rb
104
+ - lib/endo/expectation_target.rb
105
+ - lib/endo/matchers.rb
106
+ - lib/endo/matchers/base_matcher.rb
107
+ - lib/endo/matchers/eq.rb
89
108
  - lib/endo/version.rb
90
109
  homepage: https://github.com/maruware/endo
91
110
  licenses: []
@@ -106,7 +125,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
106
125
  version: '0'
107
126
  requirements: []
108
127
  rubyforge_project:
109
- rubygems_version: 2.4.5
128
+ rubygems_version: 2.4.5.1
110
129
  signing_key:
111
130
  specification_version: 4
112
131
  summary: Testing api endpoints tool