keight 0.0.1 → 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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 4c4b037e58fd8fe6bf09a20d6d682b749eb33aa1
4
- data.tar.gz: ad00095bed413d481bba4c1ad309e93a5363781e
3
+ metadata.gz: bc49bd013923bbf4714db247133b1dee371519d3
4
+ data.tar.gz: f5cda960b9bd0772aae79b835ceca64ae7470c5e
5
5
  SHA512:
6
- metadata.gz: 6ad2bde75007e0b5b65349d899f05cc27b85146845702e3057d888df325288a87bc182575e9752db1c24c5fb0ae79fa4e9965c0e3fd8e8e9127453bda55fa6fc
7
- data.tar.gz: f9fa23872351a09629b3365d312ff5d4b45fdff6c90aa2cebd7f905f2ac3f9157ec1f51d1fe93fa2ab5c52a7e3ddf8ea361e302f04810d5b4687363b3e10c38e
6
+ metadata.gz: 32ef664b317f9c4053f1bad16e61de02616bcec598d40eb566f278fcc9e87ac35511c6f031cd91a26fae2c06a9de088b2ee8db80530b7966473878f6e613c3d7
7
+ data.tar.gz: e45639182983542961cda6d1dfc9bdb7b4e6b282a235162a66dabe74da220bd0cdd46b177d5b4d2410a67ef48fc0d0bfa60dca17bf58fdf559a17b4f65eef4d6
data/README.md CHANGED
@@ -1,7 +1,7 @@
1
1
  Keight.rb README
2
2
  ================
3
3
 
4
- ($Release: 0.0.1 $)
4
+ ($Release: 0.1.0 $)
5
5
 
6
6
 
7
7
  Overview
@@ -41,10 +41,16 @@ Quick Tutorial
41
41
  --------------
42
42
 
43
43
  ```console
44
+ $ ruby -v # required Ruby >= 2.0
45
+ ruby 2.2.3p173 (2015-08-18 revision 51636) [x86_64-darwin14]
46
+ $ mkdir gems
47
+ $ export GEM_HOME=$PWD/gems
48
+ $ export PATH=$GEM_HOME/bin:$PATH
49
+
44
50
  $ gem install keight
45
51
  $ vi hello.rb
46
- $ vi config.ru
47
- $ rackup -c config.ru -p 8000
52
+ $ vi config.ru # != 'config.rb'
53
+ $ rackup -p 8000 config.ru
48
54
  ```
49
55
 
50
56
  hello.rb:
@@ -82,24 +88,38 @@ config.rb:
82
88
  require 'keight'
83
89
  require './hello'
84
90
 
85
- app = K8::RackApplication.new
91
+ app = K8::RackApplication.new()
86
92
  app.mount '/hello', HelloAction
87
93
 
94
+ ### or
95
+ #mapping = [
96
+ # ['/api', [
97
+ # ['/hello' , "./hello:HelloAction"],
98
+ # ]],
99
+ #]
100
+ #app = K8::RackApplication.new(mapping)
101
+
88
102
  run app
89
103
  ```
90
104
 
91
- Open http://localhost:8000/hello or http://localhost:8000/hello/123 by browser.
105
+ Open http://localhost:8000/hello or http://localhost:8000/hello/123
106
+ with your browser.
92
107
 
93
108
  Do you like it? If so, try `k8rb init myapp1` to generate project skeleton.
94
109
 
95
110
  ```console
96
111
  $ k8rb init myapp1
97
- $ cd myapp1
112
+ $ cd myapp1/
98
113
  $ export APP_ENV=dev # 'dev', 'prod', or 'stg'
99
114
  $ k8rb mapping
100
115
  $ k8rb configs
101
- $ rackup -c config.ru -p 8000
102
- $ ab -n 1000000 -c 100 http://127.0.0.1:8000/api/hello
116
+ $ rackup -p 8000 -E production config.ru
117
+ $ open http://127.0.0.1:8000/
118
+ $ ab -n 1000 -c 10 http://127.0.0.1:8000/api/hello
119
+ ## or:
120
+ $ gem install puma
121
+ $ rackup -p 8000 -E production -s puma config.ru
122
+ $ ab -n 10000 -c 100 http://localhost:8000/api/hello
103
123
  ```
104
124
 
105
125
 
@@ -1,5 +1,5 @@
1
1
  ###
2
- ### $Release: 0.0.1 $
2
+ ### $Release: 0.1.0 $
3
3
  ### $Copyright: copyright(c) 2014-2015 kuwata-lab.com all rights reserved $
4
4
  ### $License: MIT License $
5
5
  ###
@@ -7,7 +7,7 @@
7
7
 
8
8
  module Benchmarker
9
9
 
10
- VERSION = "$Release: 0.0.1 $".split(/ /)[1]
10
+ VERSION = "$Release: 0.1.0 $".split(/ /)[1]
11
11
 
12
12
  def self.new(opts={}, &block)
13
13
  #: creates runner object and returns it.
data/bin/k8rb CHANGED
@@ -2,7 +2,7 @@
2
2
  # -*- coding: utf-8 -*-
3
3
 
4
4
  ###
5
- ### $Release: 0.0.1 $
5
+ ### $Release: 0.1.0 $
6
6
  ### $Copyright: copyright(c) 2014-2015 kuwata-lab.com all rights reserved $
7
7
  ### $License: MIT License $
8
8
  ###
@@ -3,7 +3,7 @@
3
3
 
4
4
  Gem::Specification.new do |o|
5
5
  o.name = "keight"
6
- o.version = "$Release: 0.0.1 $".split[1]
6
+ o.version = "$Release: 0.1.0 $".split[1]
7
7
  o.author = "makoto kuwata"
8
8
  o.email = "kwa(at)kuwata-lab.com"
9
9
  o.platform = Gem::Platform::RUBY
@@ -31,6 +31,7 @@ END
31
31
  o.test_file = "test/keight_test.rb"
32
32
 
33
33
  o.required_ruby_version = '>= 2.0'
34
+ o.add_runtime_dependency 'rack', '~> 1.6'
34
35
  o.add_runtime_dependency 'baby_erubis', '~> 2.1', '>= 2.1.1'
35
36
  #o.add_development_dependency "oktest", "~> 0"
36
37
  end
@@ -1,7 +1,7 @@
1
1
  # -*- coding: utf-8 -*-
2
2
 
3
3
  ###
4
- ### $Release: 0.0.1 $
4
+ ### $Release: 0.1.0 $
5
5
  ### $Copyright: copyright(c) 2014-2015 kuwata-lab.com all rights reserved $
6
6
  ### $License: MIT License $
7
7
  ###
@@ -432,6 +432,10 @@ module K8
432
432
  end
433
433
 
434
434
 
435
+ class UnknownActionMethodError < BaseError
436
+ end
437
+
438
+
435
439
  class UnknownContentError < BaseError
436
440
  end
437
441
 
@@ -1091,12 +1095,13 @@ module K8
1091
1095
  end
1092
1096
 
1093
1097
  def _mount(mappings, urlpath_pattern, action_class)
1098
+ child_mappings = nil
1094
1099
  #; [!4l8xl] can accept array of pairs of urlpath and action class.
1095
1100
  if action_class.is_a?(Array)
1096
1101
  array = action_class
1097
1102
  child_mappings = []
1098
1103
  array.each {|upath, klass| _mount(child_mappings, upath, klass) }
1099
- action_class = child_mappings
1104
+ action_class = nil
1100
1105
  #; [!ne804] when target class name is string...
1101
1106
  elsif action_class.is_a?(String)
1102
1107
  str = action_class
@@ -1106,11 +1111,22 @@ module K8
1106
1111
  action_class.is_a?(Class) && action_class < BaseAction or
1107
1112
  raise ArgumentError.new("mount('#{urlpath_pattern}'): Action class expected but got: #{action_class.inspect}")
1108
1113
  end
1114
+ #; [!30cib] raises error when action method is not defined in action class.
1115
+ _validate_action_method_existence(action_class) if action_class
1109
1116
  #; [!flb11] mounts action class to urlpath.
1110
- mappings << [urlpath_pattern, action_class]
1117
+ mappings << [urlpath_pattern, action_class || child_mappings]
1111
1118
  end
1112
1119
  private :_mount
1113
1120
 
1121
+ def _validate_action_method_existence(action_class)
1122
+ action_class._action_method_mapping.each do |_, action_methods|
1123
+ action_methods.each do |req_meth, action_method_name|
1124
+ action_class.method_defined?(action_method_name) or
1125
+ raise UnknownActionMethodError.new("#{req_meth.inspect}=>#{action_method_name.inspect}: unknown action method in #{action_class}.")
1126
+ end
1127
+ end
1128
+ end
1129
+
1114
1130
  def _load_action_class(str, error)
1115
1131
  #; [!9brqr] raises error when string format is invalid.
1116
1132
  filepath, classname = str.split(/:/, 2)
@@ -1497,28 +1513,28 @@ module K8
1497
1513
  end
1498
1514
  begin
1499
1515
  #; [!rz13i] returns HTTP 404 when urlpath not found.
1500
- tuple = find(req.path) or
1516
+ tuple4 = find(req.path) or
1501
1517
  raise HttpException.new(404)
1502
- action_class, action_methods, urlpath_param_names, urlpath_param_values = tuple
1518
+ action_class, action_methods, urlpath_param_names, urlpath_param_values = tuple4
1503
1519
  #; [!rv3cf] returns HTTP 405 when urlpath found but request method not allowed.
1504
1520
  action_method = action_methods[req_meth_] or
1505
1521
  raise HttpException.new(405)
1506
1522
  #; [!0fgbd] finds action class and invokes action method with urlpath params.
1507
1523
  action_obj = action_class.new(req, resp)
1508
1524
  content = action_obj.handle_action(action_method, urlpath_param_values)
1509
- tuple = [resp.status, resp.headers, content]
1525
+ ret = [resp.status, resp.headers, content]
1510
1526
  rescue HttpException => ex
1511
- tuple = handle_http(ex, req, resp)
1527
+ ret = handle_http(ex, req, resp)
1512
1528
  rescue Exception => ex
1513
- tuple = handle_error(ex, req, resp)
1529
+ ret = handle_error(ex, req, resp)
1514
1530
  ensure
1515
1531
  #; [!vdllr] clears request and response if possible.
1516
1532
  req.clear() if req.respond_to?(:clear)
1517
1533
  resp.clear() if resp.respond_to?(:clear)
1518
1534
  end
1519
1535
  #; [!9wp9z] returns empty body when request method is HEAD.
1520
- tuple[2] = [""] if req_meth == :HEAD
1521
- return tuple
1536
+ ret[2] = [""] if req_meth == :HEAD
1537
+ return ret
1522
1538
  end
1523
1539
 
1524
1540
  def handle_http(ex, req, resp)
@@ -1724,7 +1740,7 @@ END
1724
1740
  def self.set(key, value, desc=nil)
1725
1741
  #; [!2yis0] raises error when not added yet.
1726
1742
  self.has?(key) or
1727
- raise K8::ConfigError.new("add(#{key.inspect}, #{value.inspect}): cannot set because not added yet; use add() or put() instead.")
1743
+ raise K8::ConfigError.new("set(#{key.inspect}, #{value.inspect}): cannot set because not added yet; use add() or put() instead.")
1728
1744
  #; [!3060g] sets key, value and desc.
1729
1745
  self.put(key, value, desc)
1730
1746
  end
@@ -4,7 +4,14 @@ require 'keight'
4
4
  require 'baby_erubis'
5
5
  require 'baby_erubis/renderer'
6
6
 
7
- require './config'
7
+
8
+ class StrippedHtmlTemplate < BabyErubis::Html
9
+ def parse(input, *args)
10
+ ## strip spaces of indentation
11
+ stripped = input.gsub(/^[ \t]+</, '<')
12
+ return super(stripped, *args)
13
+ end
14
+ end
8
15
 
9
16
 
10
17
  module My
@@ -18,17 +25,18 @@ class My::Action < K8::Action
18
25
  ## template
19
26
  ##
20
27
 
21
- include BabyErubis::HtmlEscaper
22
- include BabyErubis::Renderer
23
-
24
28
  ERUBY_PATH = ['app/template']
25
29
  ERUBY_LAYOUT = :_layout
26
- ERUBY_HTML = BabyErubis::Html
30
+ #ERUBY_HTML = BabyErubis::Html
31
+ ERUBY_HTML = StrippedHtmlTemplate
27
32
  ERUBY_HTML_EXT = '.html.eruby'
28
33
  ERUBY_TEXT = BabyErubis::Text
29
34
  ERUBY_TEXT_EXT = '.eruby'
30
35
  ERUBY_CACHE = {}
31
36
 
37
+ include BabyErubis::HtmlEscaper # define escape()
38
+ include BabyErubis::Renderer # define eruby_render_{html,text}()
39
+
32
40
  protected
33
41
 
34
42
  alias render_html eruby_render_html
@@ -21,24 +21,26 @@ if defined?(Config) # Ruby < 2.2 has obsoleted 'Config' object
21
21
  end
22
22
  end
23
23
 
24
-
24
+ ## define Config class
25
25
  require 'keight'
26
-
27
26
  class Config < K8::BaseConfig
28
27
  end
29
28
 
29
+ ## load 'app.rb', 'app_xxx.rb' and 'app_xxx.private'
30
30
  require_relative "config/app"
31
31
  require_relative "config/app_#{app_env}"
32
32
  fpath = File.join(File.dirname(__FILE__), "config", "app_#{app_env}.private")
33
33
  load fpath if File.file?(fpath)
34
34
 
35
+ ## if SECRET value is left, report error and exit.
35
36
  errmsg = Config.validate_values()
36
37
  if errmsg
37
38
  $stderr.write(errmsg)
38
39
  exit 1
39
40
  end
40
41
 
41
- ## directory to place uploaded files
42
- ENV['K8_UPLOAD_DIR'] = $config.k8_upload_dir if $config.k8_upload_dir
43
-
42
+ ## create $config object
44
43
  $config = Config.new()
44
+
45
+ ## temporary directory to put uploaded files
46
+ ENV['K8_UPLOAD_DIR'] = $config.k8_upload_dir if $config.k8_upload_dir
@@ -18,7 +18,7 @@ class BooksAction < K8::Action
18
18
  #
19
19
  def do_index(); "<index>"; end
20
20
  def do_create(); "<create>"; end
21
- #def do_new(); "<new>"; end
21
+ def do_new(); "<new>"; end
22
22
  def do_show(id); "<show:#{id.inspect}(#{id.class})>"; end
23
23
  def do_update(id); "<update:#{id.inspect}(#{id.class})>"; end
24
24
  def do_delete(id); "<delete:#{id.inspect}(#{id.class})>"; end
@@ -42,6 +42,7 @@ class AdminBooksAction < K8::Action
42
42
  #
43
43
  def do_index(); end
44
44
  def do_create(); end
45
+ def do_new(); end
45
46
  def do_show(id); end
46
47
  def do_update(id); end
47
48
  def do_delete(id); end
@@ -1653,6 +1654,17 @@ Oktest.scope do
1653
1654
  ok {pr}.raise?(ArgumentError, "mount('/api'): Action class expected but got: String")
1654
1655
  end
1655
1656
 
1657
+ spec "[!30cib] raises error when action method is not defined in action class." do
1658
+ |mapping|
1659
+ class ExampleAction3 < K8::Action
1660
+ mapping '', :GET=>:do_index, :POST=>:do_create
1661
+ def do_index; end
1662
+ end
1663
+ pr = proc { mapping.mount '/example3', ExampleAction3 }
1664
+ expected_msg = ":POST=>:do_create: unknown action method in ExampleAction3."
1665
+ ok {pr}.raise?(K8::UnknownActionMethodError, expected_msg)
1666
+ end
1667
+
1656
1668
  spec "[!w8mee] returns self." do
1657
1669
  |mapping|
1658
1670
  ret = mapping.mount '/books', BooksAction
@@ -2731,7 +2743,7 @@ Oktest.scope do
2731
2743
  ex = C41.instance_variable_get('@ex')
2732
2744
  ok {ex} != nil
2733
2745
  ok {ex}.is_a?(K8::ConfigError)
2734
- ok {ex.message} == "add(:hom, 123): cannot set because not added yet; use add() or put() instead."
2746
+ ok {ex.message} == "set(:hom, 123): cannot set because not added yet; use add() or put() instead."
2735
2747
  end
2736
2748
 
2737
2749
  spec "[!3060g] sets key, value and desc." do
@@ -1,5 +1,5 @@
1
1
  ###
2
- ### $Release: 0.0.1 $
2
+ ### $Release: 0.1.0 $
3
3
  ### $Copyright: copyright(c) 2014-2015 kuwata-lab.com all rights reserved $
4
4
  ### $License: MIT License $
5
5
  ###
@@ -16,7 +16,7 @@ end
16
16
  module Oktest
17
17
 
18
18
 
19
- VERSION = '$Release: 0.0.1 $'.split(/ /)[1]
19
+ VERSION = '$Release: 0.1.0 $'.split(/ /)[1]
20
20
 
21
21
 
22
22
  class SkipException < Exception
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: keight
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - makoto kuwata
@@ -9,8 +9,22 @@ autorequire:
9
9
  bindir:
10
10
  - bin
11
11
  cert_chain: []
12
- date: 2015-10-26 00:00:00.000000000 Z
12
+ date: 2015-10-27 00:00:00.000000000 Z
13
13
  dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: rack
16
+ requirement: !ruby/object:Gem::Requirement
17
+ requirements:
18
+ - - "~>"
19
+ - !ruby/object:Gem::Version
20
+ version: '1.6'
21
+ type: :runtime
22
+ prerelease: false
23
+ version_requirements: !ruby/object:Gem::Requirement
24
+ requirements:
25
+ - - "~>"
26
+ - !ruby/object:Gem::Version
27
+ version: '1.6'
14
28
  - !ruby/object:Gem::Dependency
15
29
  name: baby_erubis
16
30
  requirement: !ruby/object:Gem::Requirement