webservice 0.1.0 → 0.1.1

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: 07c8ee13d83466e51e8f64a5e99b2a6888cfcfbf
4
- data.tar.gz: 97ac77aaa41f5d2e6cc2da96eedf56113a651b56
3
+ metadata.gz: c0ff082b8bd1417341423a5a5abdee33a74725e8
4
+ data.tar.gz: da6f80a3b3196dff209bab205bb5576c0c891876
5
5
  SHA512:
6
- metadata.gz: b37abaf32931d4c68dd8156570339c7be5a5d60bab3715ed6469eea5f5d111a43a3add567baa67821ca68852d3de1c6288a759f0064a0c2e8f31ecd123842c32
7
- data.tar.gz: ea119606858cfd41bb05e81880939a478c0d5d587b5f5b42db049c0cd126f3b3f8cb5a946baeb3ee9021b71a84304236ca41fadeb08197f1962d67847ddec3df
6
+ metadata.gz: 0755f9c681941673028c0951c89ba2b34e832ff9bdc3a9f1c79eaad9ba7c3fa2c56db3beddc87a85bac337d03488bbd61389fcdb30e6cd23b61f8267bc6b048a
7
+ data.tar.gz: 8580d408cb8fb79baf05c4a9480c7c5b6f59ca2880e608388d62be9d4ced01cc843e5124399a380c91b4c325d5a4ca13a3a022366b1ea0333950535a79d66e64
data/Manifest.txt CHANGED
@@ -1,9 +1,13 @@
1
- HISTORY.md
2
- Manifest.txt
3
- README.md
4
- Rakefile
5
- lib/webservice.rb
6
- lib/webservice/builder.rb
7
- lib/webservice/version.rb
8
- test/helper.rb
9
- test/test_builder.rb
1
+ HISTORY.md
2
+ Manifest.txt
3
+ README.md
4
+ Rakefile
5
+ lib/webservice.rb
6
+ lib/webservice/base.rb
7
+ lib/webservice/builder.rb
8
+ lib/webservice/version.rb
9
+ test/helper.rb
10
+ test/service/app.rb
11
+ test/test_app.rb
12
+ test/test_builder.rb
13
+ test/test_builder_debug.rb
data/Rakefile CHANGED
@@ -11,21 +11,21 @@ Hoe.spec 'webservice' do
11
11
  self.urls = ['https://github.com/rubylibs/webservice']
12
12
 
13
13
  self.author = 'Gerald Bauer'
14
- self.email = 'webslideshow@googlegroups.com'
14
+ self.email = 'ruby-talk@ruby-lang.org'
15
15
 
16
16
  # switch extension to .markdown for gihub formatting
17
17
  self.readme_file = 'README.md'
18
18
  self.history_file = 'HISTORY.md'
19
19
 
20
20
  self.extra_deps = [
21
- ['logutils' ],
22
- ['textutils' ] # note: use for File.read_utf8
21
+ ['logutils'],
22
+ ['rack', '>=2.0.3']
23
23
  ]
24
24
 
25
25
  self.licenses = ['Public Domain']
26
26
 
27
27
  self.spec_extras = {
28
- required_ruby_version: '>= 1.9.2'
28
+ required_ruby_version: '>= 2.3'
29
29
  }
30
30
 
31
31
 
data/lib/webservice.rb CHANGED
@@ -3,15 +3,15 @@
3
3
  # 3rd party gems/libs
4
4
 
5
5
  require 'logutils'
6
- require 'textutils' # note: used for File.read_utf8 for now
7
6
 
7
+ require 'rack'
8
8
 
9
9
  # our own code
10
10
  require 'webservice/version' # note: let version always go first
11
11
  require 'webservice/builder'
12
-
12
+ require 'webservice/base'
13
13
 
14
14
 
15
15
 
16
16
  # say hello
17
- puts Webservice.banner
17
+ puts Webservice.banner if defined?($RUBYLIBS_DEBUG) && $RUBYLIBS_DEBUG
@@ -0,0 +1,116 @@
1
+ # encoding: utf-8
2
+
3
+
4
+ module Webservice
5
+
6
+ class Base
7
+ class << self
8
+
9
+ ## todo/check: all verbs needed! (supported) - why, why not??
10
+ %w(GET POST PATCH PUT DELETE HEAD OPTIONS).each do |method|
11
+ define_method( method.downcase ) do |pattern, &block|
12
+ puts "[debug] Webservice::Base.#{method.downcase} - add route #{method} '#{pattern}' to >#{self.name}< (#{self.object_id})"
13
+ routes[method] << [compile_pattern(pattern), block]
14
+ end
15
+ end
16
+
17
+ ## def builder
18
+ ## @builder ||= Rack::Builder.new
19
+ ## end
20
+
21
+ def routes
22
+ @routes ||= Hash.new { |hash, key| hash[key]=[] }
23
+ end
24
+
25
+
26
+ def run!
27
+ app_class = self ## note: self will be derived class (e.g. App and not Base)
28
+ puts "[debug] Webservice::Base.run! - self: >#{app_class.name}< (#{app_class.object_id}) : #{app_class.class.name}" # assume self is class
29
+ app_obj = app_class.new
30
+ app = Rack::Builder.new
31
+ app.map( '/' ) { run app_obj } ## e.g. run App
32
+ port = 4567
33
+ Rack::Handler.get('webrick').run( app, Port:port ) do |server|
34
+ ## todo: add traps here - why, why not??
35
+ end
36
+ end
37
+
38
+
39
+ private
40
+
41
+ def compile_pattern( pattern )
42
+ keys = []
43
+ pattern.gsub!( /(:\w+)/ ) do |match|
44
+ keys << $1[1..-1]
45
+ '([^/?#]+)'
46
+ end
47
+ [%r{^#{pattern}$}, keys]
48
+ end
49
+ end
50
+
51
+
52
+ attr_reader :request
53
+ attr_reader :response
54
+ attr_reader :params
55
+ attr_reader :env
56
+
57
+ def call(env)
58
+ dup.call!(env)
59
+ end
60
+
61
+ def call!(env)
62
+ env['PATH_INFO'] = '/' if env['PATH_INFO'].empty?
63
+ @request = Rack::Request.new(env)
64
+ @response = Rack::Response.new
65
+ @params = request.params
66
+ @env = env
67
+ route_eval
68
+ @response.finish
69
+ end
70
+
71
+ def session
72
+ request.env["rack.session"] || raise("Rack::Session handler is missing")
73
+ end
74
+
75
+ def halt( *args )
76
+ response.status = args.detect{|arg| arg.is_a?(Fixnum) } || 200
77
+ response.header.merge!(args.detect{|arg| arg.is_a?(Hash) } || {})
78
+ response.body = [args.detect{|arg| arg.is_a?(String) } || '']
79
+ throw :halt, response
80
+ end
81
+
82
+
83
+ private
84
+
85
+ def route_eval
86
+ catch(:halt) do
87
+ self.class.routes[request.request_method].each do |matcher, block|
88
+ if match = request.path_info.match( matcher[0] )
89
+ if (captures = match.captures) && !captures.empty?
90
+ url_params = Hash[*matcher[1].zip(captures).flatten]
91
+ @params = url_params.merge(params)
92
+ end
93
+ handle_response( instance_eval( &block ))
94
+ return
95
+ end
96
+ end
97
+ halt 404
98
+ end
99
+ end
100
+
101
+ def handle_response( obj )
102
+ ### todo/fix: set content type to json
103
+ ### call serializer or to_json
104
+
105
+ ## note: dummy for now
106
+ if obj.is_a?(String)
107
+ response.write obj
108
+ else
109
+ response.write "hello - obj: #{obj.class.name} - to be done"
110
+ end
111
+ end
112
+
113
+ end # class Base
114
+
115
+ end # module Webservice
116
+
@@ -5,28 +5,28 @@ module Webservice
5
5
  class Builder
6
6
 
7
7
  def self.load_file( path)
8
- code = File.read_utf8( path )
8
+ code = File.open( path, 'r:bom|utf-8' ).read
9
9
  self.load( code )
10
10
  end
11
11
 
12
12
  def self.load( code )
13
- builder = Builder.new
14
- builder.instance_eval( code )
15
- builder
13
+ app_class = Class.new( Base )
14
+ app_class.instance_eval( code ) ## use class_eval ??
15
+
16
+ builder = Builder.new
17
+ builder.app_class = app_class
18
+ builder
16
19
  end
17
20
 
18
21
 
19
22
  include LogUtils::Logging
20
23
 
24
+ attr_accessor :app_class
25
+
21
26
  def initialize
22
- # to be done
23
27
  end
24
28
 
25
- def get( pattern, &block )
26
- puts "add route get '#{pattern}'"
27
- end
28
29
 
29
30
  end # class Builder
30
31
 
31
32
  end # module Webservice
32
-
@@ -3,7 +3,7 @@
3
3
  module Webservice
4
4
  MAJOR = 0 ## todo: namespace inside version or something - why? why not??
5
5
  MINOR = 1
6
- PATCH = 0
6
+ PATCH = 1
7
7
  VERSION = [MAJOR,MINOR,PATCH].join('.')
8
8
 
9
9
  def self.version
data/test/helper.rb CHANGED
@@ -9,5 +9,9 @@ require 'minitest/autorun'
9
9
 
10
10
 
11
11
  ## our own code
12
- require 'webservice'
12
+ require 'webservice' ## includes rack
13
+
14
+
15
+ ## more libs
16
+ require 'rack/test'
13
17
 
@@ -0,0 +1,25 @@
1
+
2
+ get '/' do
3
+ "Hello World"
4
+ end
5
+
6
+ get '/hello/:name' do
7
+ "Hello #{params['name']}"
8
+ end
9
+
10
+ get '/:message/:name' do
11
+ @message = params['message']
12
+ @name = params['name']
13
+ "#{@message} #{@name}"
14
+ end
15
+
16
+ get '/halt/404' do
17
+ halt 404 # 404 - not found
18
+ ## todo: check why log reports 200-OK (for status code)!!
19
+ end
20
+
21
+ get '/halt_error' do
22
+ halt 500, "Error fatal" # 500 - internal server error
23
+ ## todo: check why log reports 200-OK (for status code)!!
24
+ end
25
+
data/test/test_app.rb ADDED
@@ -0,0 +1,65 @@
1
+ # encoding: utf-8
2
+
3
+ ###
4
+ # to run use
5
+ # ruby -I ./lib -I ./test test/test_app.rb
6
+
7
+
8
+ require 'helper'
9
+
10
+
11
+ class TestApp < MiniTest::Test
12
+
13
+ include Rack::Test::Methods
14
+
15
+ def app
16
+ ## return (rack-ready) app object
17
+ @@app ||= begin
18
+ builder = Webservice::Builder.load_file( "#{Webservice.root}/test/service/app.rb" )
19
+ pp builder.app_class.routes
20
+ builder.app_class.new
21
+ end
22
+ end
23
+
24
+ def test_get
25
+ get '/'
26
+ assert last_response.ok?
27
+ assert_equal 'Hello World', last_response.body
28
+
29
+ get '/hello/world'
30
+ assert last_response.ok?
31
+ assert_equal 'Hello world', last_response.body
32
+
33
+ ##############################
34
+ ## get '/hello/:name'
35
+ get '/hello/ruby'
36
+ assert last_response.ok?
37
+ assert_equal 'Hello ruby', last_response.body
38
+
39
+ get '/hello/ruby?test=t' ## try w/ extra query string/params
40
+ assert last_response.ok?
41
+ assert_equal 'Hello ruby', last_response.body
42
+
43
+ ##################################
44
+ ## get '/:message/:name'
45
+ get '/servus/wien'
46
+ assert last_response.ok?
47
+ assert_equal 'servus wien', last_response.body
48
+
49
+ get '/Hallo/Welt'
50
+ assert last_response.ok?
51
+ assert_equal 'Hallo Welt', last_response.body
52
+ end
53
+
54
+ def test_halt
55
+ ## get '/halt/404'
56
+ get '/halt/404'
57
+
58
+ ## get '/halt_error' - 500, "Error fatal" # 500 - internal server error
59
+ get '/halt_error'
60
+
61
+ ## todo: check error codes
62
+ assert true
63
+ end
64
+
65
+ end # class TestApp
data/test/test_builder.rb CHANGED
@@ -12,18 +12,21 @@ class TestBuilder < MiniTest::Test
12
12
 
13
13
  def test_beer_builder
14
14
  builder = Webservice::Builder.load_file( "#{Webservice.root}/examples/beer.rb" )
15
+ pp builder.app_class.routes
15
16
 
16
17
  assert true # if we get here - test success
17
18
  end
18
19
 
19
20
  def test_football_builder
20
21
  builder = Webservice::Builder.load_file( "#{Webservice.root}/examples/football.rb" )
22
+ pp builder.app_class.routes
21
23
 
22
24
  assert true # if we get here - test success
23
25
  end
24
26
 
25
27
  def test_world_builder
26
28
  builder = Webservice::Builder.load_file( "#{Webservice.root}/examples/world.rb" )
29
+ pp builder.app_class.routes
27
30
 
28
31
  assert true # if we get here - test success
29
32
  end
@@ -0,0 +1,20 @@
1
+ # encoding: utf-8
2
+
3
+ ###
4
+ # to run use
5
+ # ruby -I ./lib -I ./test test/test_builder_debug.rb
6
+
7
+
8
+ require 'helper'
9
+
10
+
11
+ class TestBuilderDebug < MiniTest::Test
12
+
13
+ def test_builder
14
+ builder = Webservice::Builder.load_file( "#{Webservice.root}/examples/debug.rb" )
15
+ pp builder.app_class.routes
16
+
17
+ assert true # if we get here - test success
18
+ end
19
+
20
+ end # class TestBuilderDebug
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: webservice
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Gerald Bauer
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-04-19 00:00:00.000000000 Z
11
+ date: 2017-08-18 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: logutils
@@ -25,19 +25,19 @@ dependencies:
25
25
  - !ruby/object:Gem::Version
26
26
  version: '0'
27
27
  - !ruby/object:Gem::Dependency
28
- name: textutils
28
+ name: rack
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
31
  - - ">="
32
32
  - !ruby/object:Gem::Version
33
- version: '0'
33
+ version: 2.0.3
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - ">="
39
39
  - !ruby/object:Gem::Version
40
- version: '0'
40
+ version: 2.0.3
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: rdoc
43
43
  requirement: !ruby/object:Gem::Requirement
@@ -58,16 +58,16 @@ dependencies:
58
58
  requirements:
59
59
  - - "~>"
60
60
  - !ruby/object:Gem::Version
61
- version: '3.13'
61
+ version: '3.16'
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: '3.13'
68
+ version: '3.16'
69
69
  description: webservice - yet another HTTP JSON API (web service) builder
70
- email: webslideshow@googlegroups.com
70
+ email: ruby-talk@ruby-lang.org
71
71
  executables: []
72
72
  extensions: []
73
73
  extra_rdoc_files:
@@ -75,16 +75,19 @@ extra_rdoc_files:
75
75
  - Manifest.txt
76
76
  - README.md
77
77
  files:
78
- - ".gemtest"
79
78
  - HISTORY.md
80
79
  - Manifest.txt
81
80
  - README.md
82
81
  - Rakefile
83
82
  - lib/webservice.rb
83
+ - lib/webservice/base.rb
84
84
  - lib/webservice/builder.rb
85
85
  - lib/webservice/version.rb
86
86
  - test/helper.rb
87
+ - test/service/app.rb
88
+ - test/test_app.rb
87
89
  - test/test_builder.rb
90
+ - test/test_builder_debug.rb
88
91
  homepage: https://github.com/rubylibs/webservice
89
92
  licenses:
90
93
  - Public Domain
@@ -99,7 +102,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
99
102
  requirements:
100
103
  - - ">="
101
104
  - !ruby/object:Gem::Version
102
- version: 1.9.2
105
+ version: '2.3'
103
106
  required_rubygems_version: !ruby/object:Gem::Requirement
104
107
  requirements:
105
108
  - - ">="
@@ -107,9 +110,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
107
110
  version: '0'
108
111
  requirements: []
109
112
  rubyforge_project:
110
- rubygems_version: 2.4.2
113
+ rubygems_version: 2.5.2
111
114
  signing_key:
112
115
  specification_version: 4
113
116
  summary: webservice - yet another HTTP JSON API (web service) builder
114
- test_files:
115
- - test/test_builder.rb
117
+ test_files: []
data/.gemtest DELETED
File without changes