endo 0.1.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.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: b99d1fdfdb8f0ad10fdbdc2a3e46b9974addee86
4
+ data.tar.gz: f39abeadde123c22cd9ffc792d2cdde034e34bc4
5
+ SHA512:
6
+ metadata.gz: 88b0052adb6db8f27c59b2bff2a7d677c5f1d07d73c3a6286564c61431c115236c29bd5684a591cd65ca42db17e975435e01ff4f0e9e0358f154a31e0e4cc555
7
+ data.tar.gz: 3bdd8f80f063cdd41d3efcdc562572c327077599330dceafec381a0e340b368460137ab2adae73f6293aad43bac991568e4d770d9ff2a8899edeed5d48a3110f
@@ -0,0 +1,10 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
10
+ /vendor
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in endo.gemspec
4
+ gemspec
@@ -0,0 +1,57 @@
1
+ # endo
2
+
3
+ This is a tool for testing api endpoints.
4
+ In development state.
5
+
6
+ # Usage
7
+
8
+ Write endo file.
9
+ ex. endo/sample.endo
10
+
11
+ ```ruby
12
+ set :base_url, 'http://endo-sample.maruware.com'
13
+
14
+ get '/articles'
15
+
16
+ get '/articles/:article_id' do
17
+ param 'article_id' do
18
+ from :get, '/articles' do |articles|
19
+ articles.first[:id]
20
+ end
21
+ end
22
+ end
23
+
24
+ post '/articles' do
25
+ param 'title', 'hello'
26
+ param 'text', 'Hello, world!'
27
+ end
28
+ ```
29
+
30
+ Exec endo command.
31
+
32
+ ```
33
+ $ endo exec endo/sample.endo
34
+ 🍺 /articles [142ms]
35
+ 🍺 /articles/1 [31ms]
36
+ 🍺 /articles [28ms]
37
+ ```
38
+
39
+ ## Installation
40
+
41
+ Add this line to your application's Gemfile:
42
+
43
+ ```ruby
44
+ gem 'endo'
45
+ ```
46
+
47
+ And then execute:
48
+
49
+ ```bash
50
+ $ bundle
51
+ ```
52
+
53
+ Or install it yourself as:
54
+
55
+ ```bash
56
+ $ gem install endo
57
+ ```
@@ -0,0 +1,2 @@
1
+ require "bundler/gem_tasks"
2
+
@@ -0,0 +1,4 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'endo/cli'
4
+ Endo::CLI.start
@@ -0,0 +1,27 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'endo/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "endo"
8
+ spec.version = Endo::VERSION
9
+ spec.authors = ["maruware"]
10
+ spec.email = ["maruware@maruware.com"]
11
+
12
+ spec.summary = %q{Testing api endpoints tool}
13
+ spec.description = %q{Testing api endpoints tool}
14
+ spec.homepage = "https://github.com/maruware/endo"
15
+
16
+ spec.files = `git ls-files`.split($/)
17
+ spec.bindir = "bin"
18
+ # spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
19
+ spec.executables = ['endo']
20
+ spec.require_paths = ["lib"]
21
+
22
+ spec.add_runtime_dependency "thor"
23
+
24
+ spec.add_development_dependency "bundler", "~> 1.8"
25
+ spec.add_development_dependency "rake", "~> 10.0"
26
+ spec.add_development_dependency "activesupport", "~> 4.2"
27
+ end
@@ -0,0 +1,16 @@
1
+ set :base_url, 'http://endo-sample.maruware.com'
2
+
3
+ get '/articles'
4
+
5
+ get '/articles/:article_id' do
6
+ param 'article_id' do
7
+ from :get, '/articles' do |articles|
8
+ articles.first[:id]
9
+ end
10
+ end
11
+ end
12
+
13
+ post '/articles' do
14
+ param 'title', 'hello'
15
+ param 'text', 'Hello, world!'
16
+ end
@@ -0,0 +1,8 @@
1
+ require "endo/version"
2
+ require "endo/cli"
3
+ require "endo/core"
4
+ require "endo/error"
5
+
6
+ module Endo
7
+ # Your code goes here...
8
+ end
@@ -0,0 +1,30 @@
1
+ require 'endo'
2
+ require 'thor'
3
+
4
+ module Endo
5
+ class CLI < Thor
6
+ default_command :exec
7
+
8
+ desc "exec usage", "exec desc"
9
+ def exec(endo_file=nil)
10
+ if endo_file.nil?
11
+ Dir.glob('endo/*.endo').each do |f|
12
+ exec_proc(f)
13
+ end
14
+ else
15
+ exec_proc(endo_file)
16
+ end
17
+ end
18
+
19
+ desc "version", "Print version"
20
+ def version
21
+ puts "endo version #{Endo::VERSION}"
22
+ end
23
+
24
+ private
25
+ def exec_proc(file_path)
26
+ executor = Endo::Core.new
27
+ executor.instance_eval File.read(file_path)
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,133 @@
1
+ require 'open-uri'
2
+ require 'json'
3
+ require 'net/http'
4
+
5
+ module Endo
6
+ class Core
7
+ def initialize
8
+ @props = {}
9
+ @responses = {}
10
+ end
11
+
12
+ def set(key, val)
13
+ #TODO: validate key
14
+ @props[key] = val
15
+ end
16
+
17
+ def get(endpoint, &block)
18
+ request(endpoint, :get, &block)
19
+ end
20
+
21
+ def post(endpoint, &block)
22
+ request(endpoint, :post, &block)
23
+ end
24
+
25
+ #TODO: 制限
26
+ def param(key, val=nil, &block)
27
+ unless (!val.nil?) ^ (!block.nil?) # Only either one
28
+ raise ArgumentError.new('DupValue')
29
+ end
30
+
31
+ @params[key] = if val
32
+ val
33
+ else
34
+ block.call
35
+ end
36
+
37
+ end
38
+
39
+ #TODO: Limit scope
40
+ def from(method, endpoint, &block)
41
+ key = build_response_key(method, endpoint)
42
+ unless @responses.has_key? key
43
+ raise RuntimeError.new("NotFoundKey [#{key}]")
44
+ end
45
+
46
+ unless block
47
+ raise ArgumentError.new('UndefinedBlock')
48
+ end
49
+
50
+ res = @responses[key]
51
+ val = block.call(res)
52
+ unless val.is_a?(String) || val.is_a?(Integer) || val.is_a?(Numeric)
53
+ raise RuntimeError.new('BadValueType')
54
+ end
55
+
56
+ val
57
+ end
58
+
59
+ private
60
+ def request(endpoint, method, &block)
61
+ org_endpoint = endpoint.clone
62
+
63
+ @params = {}
64
+ block.call if block
65
+
66
+ endpoint = apply_pattern_vars(endpoint, @params)
67
+
68
+ url = @props[:base_url] + endpoint
69
+
70
+ message = begin
71
+ t_start = Time.now.instance_eval { self.to_i * 1000 + (usec/1000) }
72
+ res = http_request_json(url, @params, method: method)
73
+ t_end = Time.now.instance_eval { self.to_i * 1000 + (usec/1000) }
74
+
75
+ @responses[build_response_key(method, endpoint)] = res
76
+ "🍺 #{endpoint} [#{t_end-t_start}ms]"
77
+ rescue Error::HttpError=>e
78
+ "💩 #{endpoint} [code: #{e.code}]"
79
+ end
80
+
81
+
82
+ puts message
83
+ end
84
+
85
+ def apply_pattern_vars(endpoint, params)
86
+ patterns = endpoint.scan(/:(\w+)/)
87
+ if patterns.any?
88
+ patterns.flatten!
89
+ patterns.each do |pattern|
90
+ unless params.has_key? pattern
91
+ raise RuntimeError.new("NotFoundPattern #{pattern}")
92
+ end
93
+
94
+ endpoint.sub!(/:#{pattern}/, params[pattern].to_s)
95
+ end
96
+
97
+ patterns.uniq.each do |pattern|
98
+ params.delete(pattern)
99
+ end
100
+ end
101
+ endpoint
102
+ end
103
+
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)
110
+ uri = URI.parse url
111
+
112
+ if method == :get
113
+ uri.query = URI.encode_www_form(params)
114
+ req = Net::HTTP::Get.new uri
115
+ end
116
+
117
+ if method == :post
118
+ req = Net::HTTP::Post.new uri.path
119
+ req.set_form_data(params)
120
+ end
121
+
122
+ res = Net::HTTP.start(uri.host, uri.port) {|http| http.request req }
123
+ raise Error::HttpError.new("HTTP Bad Status[#{res.code}] #{res.body}", res.code, res.body) unless /^20[0-8]$/ =~ res.code
124
+
125
+ return res.body
126
+ end
127
+
128
+ def build_response_key(method, endpoint)
129
+ "#{method}:#{endpoint}"
130
+ end
131
+
132
+ end
133
+ end
@@ -0,0 +1 @@
1
+ require 'endo/error/http_error'
@@ -0,0 +1,15 @@
1
+
2
+ module Endo
3
+ module Error
4
+ class HttpError < StandardError
5
+ attr_reader :code, :body
6
+
7
+ def initialize(message, code, body)
8
+ super(message)
9
+ @code = code
10
+ @body = body
11
+ end
12
+
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,3 @@
1
+ module Endo
2
+ VERSION = "0.1.0"
3
+ end
metadata ADDED
@@ -0,0 +1,113 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: endo
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - maruware
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-10-28 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: thor
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: bundler
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '1.8'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '1.8'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rake
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '10.0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '10.0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: activesupport
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '4.2'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '4.2'
69
+ description: Testing api endpoints tool
70
+ email:
71
+ - maruware@maruware.com
72
+ executables:
73
+ - endo
74
+ extensions: []
75
+ extra_rdoc_files: []
76
+ files:
77
+ - ".gitignore"
78
+ - Gemfile
79
+ - README.md
80
+ - Rakefile
81
+ - bin/endo
82
+ - endo.gemspec
83
+ - endo/sample.endo
84
+ - lib/endo.rb
85
+ - lib/endo/cli.rb
86
+ - lib/endo/core.rb
87
+ - lib/endo/error.rb
88
+ - lib/endo/error/http_error.rb
89
+ - lib/endo/version.rb
90
+ homepage: https://github.com/maruware/endo
91
+ licenses: []
92
+ metadata: {}
93
+ post_install_message:
94
+ rdoc_options: []
95
+ require_paths:
96
+ - lib
97
+ required_ruby_version: !ruby/object:Gem::Requirement
98
+ requirements:
99
+ - - ">="
100
+ - !ruby/object:Gem::Version
101
+ version: '0'
102
+ required_rubygems_version: !ruby/object:Gem::Requirement
103
+ requirements:
104
+ - - ">="
105
+ - !ruby/object:Gem::Version
106
+ version: '0'
107
+ requirements: []
108
+ rubyforge_project:
109
+ rubygems_version: 2.4.5
110
+ signing_key:
111
+ specification_version: 4
112
+ summary: Testing api endpoints tool
113
+ test_files: []