nyara 0.0.1.pre.9 → 0.1.pre.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.
Files changed (76) hide show
  1. checksums.yaml +4 -4
  2. data/bin/nyara +3 -3
  3. data/changes +1 -0
  4. data/ext/event.c +16 -22
  5. data/ext/hashes.c +222 -4
  6. data/ext/inc/rdtsc.h +56 -0
  7. data/ext/inc/status_codes.inc +64 -0
  8. data/ext/inc/version.inc +1 -1
  9. data/ext/nyara.c +12 -10
  10. data/ext/nyara.h +5 -5
  11. data/ext/request.c +18 -24
  12. data/ext/request_parse.c +1 -1
  13. data/ext/route.cc +2 -4
  14. data/ext/url_encoded.c +51 -193
  15. data/lib/nyara/command.rb +39 -12
  16. data/lib/nyara/config.rb +10 -10
  17. data/lib/nyara/controller.rb +60 -14
  18. data/lib/nyara/cookie.rb +1 -1
  19. data/lib/nyara/hashes/config_hash.rb +2 -24
  20. data/lib/nyara/nyara.rb +33 -19
  21. data/lib/nyara/part.rb +7 -3
  22. data/lib/nyara/reload.rb +85 -0
  23. data/lib/nyara/request.rb +1 -1
  24. data/lib/nyara/route.rb +55 -19
  25. data/lib/nyara/templates/Gemfile +10 -1
  26. data/lib/nyara/templates/Rakefile +6 -1
  27. data/lib/nyara/templates/app/controllers/application_controller.rb +3 -0
  28. data/lib/nyara/templates/app/controllers/welcome_controller.rb +5 -0
  29. data/lib/nyara/templates/app/views/layouts/application.erb +12 -0
  30. data/lib/nyara/templates/app/views/welcome/index.erb +1 -0
  31. data/lib/nyara/templates/config/application.rb +34 -0
  32. data/lib/nyara/templates/config/boot.rb +4 -0
  33. data/lib/nyara/templates/config/development.rb +5 -0
  34. data/lib/nyara/templates/config/production.rb +8 -0
  35. data/lib/nyara/templates/config/test.rb +2 -0
  36. data/lib/nyara/templates/public/css/app.css +1 -0
  37. data/lib/nyara/templates/public/js/app.js +1 -0
  38. data/lib/nyara/templates/spec/spec_helper.rb +9 -0
  39. data/lib/nyara/test.rb +10 -2
  40. data/lib/nyara/view.rb +116 -67
  41. data/nyara.gemspec +3 -1
  42. data/rakefile +1 -1
  43. data/readme.md +1 -1
  44. data/spec/command_spec.rb +28 -24
  45. data/spec/config_spec.rb +24 -1
  46. data/spec/dummy/app/controllers/dummy_controller.rb +2 -0
  47. data/spec/dummy/app/models/dmmy_model.rb +2 -0
  48. data/spec/evented_io_spec.rb +2 -1
  49. data/spec/ext_route_spec.rb +2 -2
  50. data/spec/flash_spec.rb +8 -0
  51. data/spec/hashes_spec.rb +127 -0
  52. data/spec/integration_spec.rb +15 -0
  53. data/spec/path_helper_spec.rb +17 -5
  54. data/spec/performance/escape.rb +15 -4
  55. data/spec/performance/layout_render.rb +15 -10
  56. data/spec/performance/parse_accept_value.rb +24 -8
  57. data/spec/performance/parse_param.rb +14 -8
  58. data/spec/performance/performance_helper.rb +8 -21
  59. data/spec/performance_spec.rb +5 -4
  60. data/spec/route_spec.rb +7 -2
  61. data/spec/url_encoded_spec.rb +18 -74
  62. data/spec/view_spec.rb +1 -3
  63. data/spec/views/_partial.slim +1 -0
  64. data/spec/views/_partial_with_yield.erb +1 -0
  65. metadata +73 -43
  66. data/example/factorial.rb +0 -19
  67. data/example/hello.rb +0 -5
  68. data/example/project.rb +0 -11
  69. data/example/stream.rb +0 -14
  70. data/lib/nyara/controllers/public_controller.rb +0 -14
  71. data/lib/nyara/templates/config/session.key +0 -1
  72. data/tools/bench-cookie.rb +0 -22
  73. data/tools/foo.rb +0 -9
  74. data/tools/hello.rb +0 -46
  75. data/tools/memcheck.rb +0 -33
  76. data/tools/s.rb +0 -11
data/nyara.gemspec CHANGED
@@ -1,6 +1,6 @@
1
1
  Gem::Specification.new do |s|
2
2
  s.name = "nyara"
3
- s.version = "0.0.1.pre.9"
3
+ s.version = "0.1.pre.0"
4
4
  s.author = "Zete Lui"
5
5
  s.email = "nobody@example.com"
6
6
  s.homepage = "https://github.com/luikore/nyara"
@@ -20,6 +20,8 @@ Gem::Specification.new do |s|
20
20
  s.executables << 'nyara'
21
21
  s.extensions = ["ext/extconf.rb"]
22
22
  s.rubygems_version = '2.0.3'
23
+ s.add_runtime_dependency 'tilt', '>= 1.3'
24
+ s.add_runtime_dependency 'listen', '>= 1.1.3'
23
25
 
24
26
  s.rdoc_options += %w[
25
27
  -v
data/rakefile CHANGED
@@ -34,7 +34,7 @@ file version_file => ['nyara.gemspec', __FILE__] do
34
34
  version = nil
35
35
  lines.each do |line|
36
36
  if line =~ /s\.version =/
37
- version = line[/\d+(\.\d+)*(\.pre\d+)?/]
37
+ version = line[/\d+(\.\d+)*(\.pre\.\d+)?/]
38
38
  break
39
39
  end
40
40
  end
data/readme.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  [![Build Status](https://travis-ci.org/luikore/nyara.png)](https://travis-ci.org/luikore/nyara)
4
4
 
5
- - No dependencies, faster than any web framework on rack.
5
+ - Very few runtime dependencies, faster than any web framework on rack.
6
6
  - Nonblock but no callback hell, very low CPU and memory usage.
7
7
  - Simple usage, and you don't have to make everything non-block.
8
8
  - Prefork production server, with signal-based management which enables graceful restart.
data/spec/command_spec.rb CHANGED
@@ -1,46 +1,50 @@
1
1
  require_relative "spec_helper"
2
2
 
3
3
  module Nyara
4
- describe Command do
4
+ describe Command do
5
5
  it "#help" do
6
- assert_include(stdout { Nyara::Command.help },"Usage")
6
+ assert_include(stdout { Nyara::Command.help }, "Usage")
7
7
  end
8
-
8
+
9
9
  it "#version" do
10
- assert_equal(stdout { Nyara::Command.version }.strip,"Nyara #{Nyara::VERSION}")
10
+ assert_equal(stdout { Nyara::Command.version }.strip, "Nyara #{Nyara::VERSION}")
11
11
  end
12
-
12
+
13
13
  describe "#new_project" do
14
14
  before :all do
15
- @tmp_dir = '/tmp/nyara_test'
16
- @old_dir = Dir.pwd
15
+ @tmp_dir = Dir.mktmpdir 'nyara'
16
+ @old_dir = File.dirname __dir__
17
17
  FileUtils.mkdir_p(@tmp_dir)
18
- Dir.chdir(@tmp_dir)
19
-
20
18
  @app_name = "app_#{Time.now.to_i}"
19
+ @stdout = stdout do
20
+ Dir.chdir @tmp_dir do
21
+ Nyara::Command.new_project(@app_name)
22
+ end
23
+ end
21
24
  end
22
-
25
+
23
26
  after :all do
24
27
  FileUtils.rm_rf(@tmp_dir)
25
- Dir.chdir(@old_dir)
26
28
  end
27
-
29
+
28
30
  describe "should create app dir" do
29
-
30
-
31
31
  it "should run finish" do
32
- a = stdout { Nyara::Command.new_project(@app_name) }
33
- assert_include(a,"Enjoy!")
32
+ assert_include(@stdout, "Enjoy!")
33
+ end
34
+
35
+ it "should copy same files into new dir" do
36
+ des_files = filter_files Dir.glob(File.join @tmp_dir, @app_name, "**/*")
37
+ assert_not_equal(des_files.count, 0)
38
+ src_files = filter_files Dir.glob("#{@old_dir}/lib/nyara/templates/**/*")
39
+ assert_equal(des_files.count, src_files.count)
34
40
  end
35
-
36
-
37
- it "should copy same files in to new dir" do
38
- des_files = Dir.glob("./#{@app_name}/**/*")
39
- assert_not_equal(des_files.count,0)
40
- assert_equal(des_files.count,Dir.glob("#{@old_dir}/lib/nyara/templates/**/*").count)
41
+
42
+ def filter_files files
43
+ files.select do |f|
44
+ File.basename(f) !~ /\.DS_Store|\.gitignore|session\.key/
45
+ end
41
46
  end
42
47
  end
43
-
44
48
  end
45
49
  end
46
- end
50
+ end
data/spec/config_spec.rb CHANGED
@@ -37,7 +37,7 @@ module Nyara
37
37
  it "views and public default" do
38
38
  Config[:root] = '/root'
39
39
  Config.init
40
- assert_equal '/root/public', Config['public']
40
+ assert_equal nil, Config['public']
41
41
  assert_equal '/root/views', Config['views']
42
42
  end
43
43
 
@@ -97,6 +97,17 @@ module Nyara
97
97
  Config.reset
98
98
  end
99
99
 
100
+ it "root helpers" do
101
+ Config.init
102
+ assert_equal Dir.pwd, Config.root
103
+ Config.set :root, 'aaa'
104
+ assert_equal 'aaa', Config.root
105
+ Config.configure do
106
+ set :root,'bbb'
107
+ end
108
+ assert_equal 'bbb', Config.root
109
+ end
110
+
100
111
  it "creates logger" do
101
112
  assert Nyara.logger
102
113
  end
@@ -106,5 +117,17 @@ module Nyara
106
117
  Config.init
107
118
  assert_nil Nyara.logger
108
119
  end
120
+
121
+ it "auto load file" do
122
+ Config.configure do
123
+ set :env, 'test'
124
+ set :root, File.join(__dir__, 'dummy')
125
+ set :app_files, 'app/**/*.rb'
126
+ end
127
+ Config.init
128
+ Nyara.load_app
129
+ assert_equal true, Object.const_defined?('DummyModel')
130
+ assert_equal true, Object.const_defined?('DummyController')
131
+ end
109
132
  end
110
133
  end
@@ -0,0 +1,2 @@
1
+ class DummyController
2
+ end
@@ -0,0 +1,2 @@
1
+ class DummyModel
2
+ end
@@ -7,7 +7,8 @@ module Nyara
7
7
  @server = fork do
8
8
  exec 'ruby', __dir__ + '/apps/connect.rb'
9
9
  end
10
- sleep 1 # wait for server startup
10
+ GC.stress = false
11
+ sleep 1.8 # wait for server startup
11
12
  end
12
13
 
13
14
  after :all do
@@ -58,13 +58,13 @@ module Nyara
58
58
  scope, cont, args = Ext.lookup_route 'GET', '/hello/3world', nil
59
59
  assert_equal @e1.scope, scope
60
60
  assert_equal @e1.controller, cont
61
- assert_equal [3, :'#1'], args
61
+ assert_equal [:'#1', 3], args
62
62
 
63
63
  scope, _ = Ext.lookup_route 'GET', '/world', nil
64
64
  assert_equal nil, scope
65
65
 
66
66
  scope, _, args = Ext.lookup_route 'GET', '/a目录/2013-6-1', nil
67
- assert_equal [2013, 6, 1, :'#dir'], args
67
+ assert_equal [:'#dir', 2013, 6, 1], args
68
68
  end
69
69
  end
70
70
  end
data/spec/flash_spec.rb CHANGED
@@ -21,5 +21,13 @@ module Nyara
21
21
  assert_nil @flash.next['foo']
22
22
  assert_empty @session.values.first
23
23
  end
24
+
25
+ it "#clear" do
26
+ @flash.now['foo'] = 'foo'
27
+ @flash.next['bar'] = 'bar'
28
+ @flash.clear
29
+ assert_empty @flash.now
30
+ assert_empty @flash.next
31
+ end
24
32
  end
25
33
  end
data/spec/hashes_spec.rb CHANGED
@@ -10,6 +10,133 @@ module Nyara
10
10
  assert_equal true, h.key?('a')
11
11
  assert_equal 1, h.size
12
12
  end
13
+
14
+ context ".split_name" do
15
+ it "many entries" do
16
+ assert_equal ['a', 'b', '', '', 'c'], ParamHash.split_name("a[b][][][c]")
17
+ end
18
+
19
+ it "only 1 entry" do
20
+ assert_equal ['a'], ParamHash.split_name('a')
21
+ end
22
+
23
+ %w( a[ [ a] a[b]c a[[b] a[[b]] ).each do |k|
24
+ it "detects bad key: #{k}" do
25
+ assert_raise ArgumentError do
26
+ ParamHash.split_name k
27
+ end
28
+ end
29
+ end
30
+
31
+ it "detects empty key" do
32
+ assert_raise ArgumentError do
33
+ ParamHash.split_name ''
34
+ end
35
+ end
36
+ end
37
+
38
+ it "#nested_aset" do
39
+ h = ParamHash.new
40
+ h.nested_aset ['a', '', 'b'], 'c'
41
+ assert_equal({'a' => [{'b' => 'c'}]}, h)
42
+ end
43
+
44
+ context ".parse_cookie" do
45
+ it "parses complex cookie" do
46
+ history = CGI.escape '历史'
47
+ cookie = "pgv_pvi; pgv_si= ; pgv_pvi=som; sid=1d6c75f0 ; PLHistory=<#{history}>;"
48
+ h = ParamHash.parse_cookie ParamHash.new, cookie
49
+ assert_equal '1d6c75f0', h['sid']
50
+ assert_equal '', h['pgv_si']
51
+ assert_equal '', h['pgv_pvi'] # left orverrides right
52
+ assert_equal '<历史>', h['PLHistory']
53
+ end
54
+
55
+ it "parses empty cookie" do
56
+ cookie = ''
57
+ h = ParamHash.parse_cookie ParamHash.new, cookie
58
+ assert_empty h
59
+ end
60
+
61
+ it "parses cookie start with ','" do
62
+ h = ParamHash.parse_cookie ParamHash.new, ',a'
63
+ assert_equal 1, h.size
64
+ assert_equal '', h['a']
65
+
66
+ h = ParamHash.parse_cookie ParamHash.new, ' ,b = 1,a'
67
+ assert_equal 2, h.size
68
+ assert_equal '', h['a']
69
+ assert_equal '1', h['b']
70
+ end
71
+
72
+ it "parses cookie end with ';'" do
73
+ h = ParamHash.parse_cookie ParamHash.new, 'a ;'
74
+ assert_equal 1, h.size
75
+ assert_equal '', h['a']
76
+
77
+ h = ParamHash.parse_cookie ParamHash.new, 'b = 1; a ;'
78
+ assert_equal 2, h.size
79
+ assert_equal '', h['a']
80
+ assert_equal '1', h['b']
81
+ end
82
+
83
+ it "parses cookie with space around =" do
84
+
85
+ end
86
+
87
+ it "refuses to parse cookie into HeaderHash" do
88
+ assert_raise ArgumentError do
89
+ ParamHash.parse_cookie HeaderHash.new, 'session=3'
90
+ end
91
+ end
92
+ end
93
+
94
+ context ".parse_param" do
95
+ it "parses single char" do
96
+ h = ParamHash.parse_param ParamHash.new, 'a'
97
+ assert_equal '', h['a']
98
+ end
99
+
100
+ it "parses str end with '&'" do
101
+ h = ParamHash.parse_param ParamHash.new, 'a=b&'
102
+ assert_equal({'a' => 'b'}, h)
103
+ end
104
+
105
+ it "parses str begin with '&'" do
106
+ h = ParamHash.parse_param ParamHash.new, '&a=b'
107
+ assert_equal({'a' => 'b'}, h)
108
+ end
109
+
110
+ it "parses param with non-utf-8 chars" do
111
+ bad_s = CGI.escape "\xE2"
112
+ h = ParamHash.parse_param ParamHash.new, bad_s
113
+ assert_equal "", h["\xE2"]
114
+ end
115
+
116
+ it "parses nested kv and preserves hash class" do
117
+ h = ParamHash.parse_param ParamHash.new, "a[b][]=c"
118
+ assert_equal({'a' => {'b' => ['c']}}, h)
119
+ assert_equal ParamHash, h['a'].class
120
+ end
121
+
122
+ it "parses k without v and preserves hash class" do
123
+ h = ParamHash.parse_param ConfigHash.new, "a%5B%5d[b]"
124
+ assert_equal({'a' => [{'b' => ''}]}, h)
125
+ assert_equal Array, h[:a].class
126
+ assert_equal ConfigHash, h[:a].first.class
127
+ end
128
+
129
+ it "parses blank string" do
130
+ h = ParamHash.parse_param({}, '')
131
+ assert h.empty?
132
+ end
133
+
134
+ it "raises for HeaderHash" do
135
+ assert_raise ArgumentError do
136
+ ParamHash.parse_param(HeaderHash.new, '')
137
+ end
138
+ end
139
+ end
13
140
  end
14
141
 
15
142
  describe HeaderHash do
@@ -15,6 +15,7 @@ class TestController < Nyara::Controller
15
15
 
16
16
  meta '#create'
17
17
  post '/create' do
18
+ set_header 'partial', partial('_partial').strip
18
19
  redirect_to '#index'
19
20
  end
20
21
 
@@ -37,6 +38,12 @@ class TestController < Nyara::Controller
37
38
  view.end
38
39
  end
39
40
 
41
+ http :trace, '/stream-with-partial' do
42
+ view = stream erb: "before:<%= partial '_partial_with_yield' %>:after"
43
+ view.resume
44
+ view.end
45
+ end
46
+
40
47
  options '/error' do
41
48
  raise 'error'
42
49
  end
@@ -53,6 +60,7 @@ module Nyara
53
60
  reset
54
61
  map '/', TestController
55
62
  set :root, __dir__
63
+ set :public, 'public'
56
64
  set :logger, false
57
65
  end
58
66
  Nyara.setup
@@ -78,6 +86,7 @@ module Nyara
78
86
 
79
87
  it "redirect" do
80
88
  @test.post @test.path_to('test#create')
89
+ assert_equal 'This is a partial', @test.response.header['Partial']
81
90
  assert @test.response.success?
82
91
  assert_equal 'http://localhost:3000/', @test.redirect_location
83
92
  @test.follow_redirect
@@ -110,6 +119,12 @@ module Nyara
110
119
  assert_include @test.response.body, "slim:edit"
111
120
  end
112
121
 
122
+ it "stream-with-yield" do
123
+ @test.http :trace, '/stream-with-partial'
124
+ assert @test.response.success?
125
+ assert_equal "before:yield:after", @test.response.body.strip
126
+ end
127
+
113
128
  it "error" do
114
129
  @test.options '/error'
115
130
  assert_equal 500, @test.response.status
@@ -2,7 +2,11 @@ require_relative "spec_helper"
2
2
 
3
3
  class FooController < Nyara::Controller
4
4
  meta '#index'
5
- get '/%d' do |id|
5
+ get '/%.5d' do |id|
6
+ end
7
+
8
+ meta '#put'
9
+ put '/' do
6
10
  end
7
11
 
8
12
  class BarController < Nyara::Controller
@@ -36,7 +40,7 @@ module Nyara
36
40
  context '#path_to' do
37
41
  it "local query" do
38
42
  c = FooController.new :stub_request
39
- assert_equal '/12', c.path_to('#index', 12)
43
+ assert_equal '/00012', c.path_to('#index', 12)
40
44
  assert_raise ArgumentError do
41
45
  c.path_to '#index'
42
46
  end
@@ -59,13 +63,21 @@ module Nyara
59
63
  end
60
64
 
61
65
  it "perserves _method query" do
62
- pending
66
+ c = FooController.new :stub_request
67
+ path = c.path_to('#put')
68
+ assert_equal '/?_method=PUT', path
69
+
70
+ path = c.path_to('#put', :_method => 'POST')
71
+ assert_equal '/?_method=POST', path
72
+
73
+ path = c.path_to('#put', '_method' => nil)
74
+ assert_equal '/?_method=', path
63
75
  end
64
76
 
65
77
  it "appends format and query" do
66
78
  c = FooController.new :stub_request
67
79
  generated = c.path_to '#index', 1, format: 'js', 'utm_source' => 'a spam'
68
- assert_equal "/1.js?utm_source=a+spam", generated
80
+ assert_equal "/00001.js?utm_source=a+spam", generated
69
81
  end
70
82
  end
71
83
 
@@ -78,7 +90,7 @@ module Nyara
78
90
  request.host_with_port = 'yavaeye.com'
79
91
  c = FooController::BazController.new request
80
92
  assert_equal '//yavaeye.com/baz-prefix/1', c.url_to('#index', 1)
81
- assert_equal 'https://localhost:4567/1', c.url_to('foo#index', 1, scheme: 'https', host: 'localhost:4567')
93
+ assert_equal 'https://localhost:4567/00001', c.url_to('foo#index', 1, scheme: 'https', host: 'localhost:4567')
82
94
  end
83
95
  end
84
96
  end
@@ -1,10 +1,21 @@
1
1
  require_relative "performance_helper"
2
2
  require "cgi"
3
3
 
4
- s = 'abcde マfgイ'
4
+ S = 'abcde マfgイ'
5
5
 
6
- GC.disable
6
+ def nyara
7
+ Nyara::Ext.rdtsc_start
8
+ Nyara::Ext.escape S, false
9
+ Nyara::Ext.rdtsc
10
+ end
11
+
12
+ def cgi
13
+ Nyara::Ext.rdtsc_start
14
+ CGI.escape S
15
+ Nyara::Ext.rdtsc
16
+ end
17
+
18
+ nyara
19
+ cgi
7
20
 
8
- nyara = bench(10000){ Nyara::Ext.escape s, false }
9
- cgi = bench(10000){ CGI.escape s }
10
21
  dump nyara: nyara, cgi: cgi