manveru-innate 2009.02.06

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 (101) hide show
  1. data/CHANGELOG +1409 -0
  2. data/COPYING +18 -0
  3. data/MANIFEST +100 -0
  4. data/README.md +485 -0
  5. data/Rakefile +139 -0
  6. data/example/app/retro_games.rb +57 -0
  7. data/example/app/whywiki_erb/layout/wiki.html.erb +15 -0
  8. data/example/app/whywiki_erb/spec/wiki.rb +19 -0
  9. data/example/app/whywiki_erb/start.rb +45 -0
  10. data/example/app/whywiki_erb/view/edit.html.erb +6 -0
  11. data/example/app/whywiki_erb/view/index.html.erb +10 -0
  12. data/example/custom_middleware.rb +43 -0
  13. data/example/error_handling.rb +31 -0
  14. data/example/hello.rb +12 -0
  15. data/example/howto_spec.rb +60 -0
  16. data/example/link.rb +35 -0
  17. data/example/providing_hash.rb +46 -0
  18. data/example/session.rb +42 -0
  19. data/innate.gemspec +118 -0
  20. data/lib/innate.rb +191 -0
  21. data/lib/innate/action.rb +156 -0
  22. data/lib/innate/adapter.rb +89 -0
  23. data/lib/innate/cache.rb +117 -0
  24. data/lib/innate/cache/api.rb +106 -0
  25. data/lib/innate/cache/drb.rb +58 -0
  26. data/lib/innate/cache/file_based.rb +39 -0
  27. data/lib/innate/cache/marshal.rb +17 -0
  28. data/lib/innate/cache/memory.rb +22 -0
  29. data/lib/innate/cache/yaml.rb +17 -0
  30. data/lib/innate/core_compatibility/basic_object.rb +9 -0
  31. data/lib/innate/core_compatibility/string.rb +3 -0
  32. data/lib/innate/current.rb +37 -0
  33. data/lib/innate/dynamap.rb +81 -0
  34. data/lib/innate/helper.rb +195 -0
  35. data/lib/innate/helper/aspect.rb +62 -0
  36. data/lib/innate/helper/cgi.rb +39 -0
  37. data/lib/innate/helper/flash.rb +36 -0
  38. data/lib/innate/helper/link.rb +55 -0
  39. data/lib/innate/helper/partial.rb +90 -0
  40. data/lib/innate/helper/redirect.rb +85 -0
  41. data/lib/innate/helper/send_file.rb +18 -0
  42. data/lib/innate/log.rb +23 -0
  43. data/lib/innate/log/color_formatter.rb +43 -0
  44. data/lib/innate/log/hub.rb +72 -0
  45. data/lib/innate/mock.rb +49 -0
  46. data/lib/innate/node.rb +471 -0
  47. data/lib/innate/options.rb +91 -0
  48. data/lib/innate/options/dsl.rb +155 -0
  49. data/lib/innate/request.rb +165 -0
  50. data/lib/innate/response.rb +18 -0
  51. data/lib/innate/route.rb +109 -0
  52. data/lib/innate/session.rb +104 -0
  53. data/lib/innate/session/flash.rb +94 -0
  54. data/lib/innate/setup.rb +23 -0
  55. data/lib/innate/spec.rb +42 -0
  56. data/lib/innate/state.rb +22 -0
  57. data/lib/innate/state/accessor.rb +130 -0
  58. data/lib/innate/state/fiber.rb +68 -0
  59. data/lib/innate/state/thread.rb +39 -0
  60. data/lib/innate/traited.rb +20 -0
  61. data/lib/innate/trinity.rb +22 -0
  62. data/lib/innate/version.rb +3 -0
  63. data/lib/innate/view.rb +67 -0
  64. data/lib/innate/view/erb.rb +17 -0
  65. data/lib/innate/view/none.rb +9 -0
  66. data/lib/rack/middleware_compiler.rb +62 -0
  67. data/lib/rack/reloader.rb +192 -0
  68. data/spec/example/hello.rb +14 -0
  69. data/spec/example/link.rb +29 -0
  70. data/spec/helper.rb +2 -0
  71. data/spec/innate/cache/common.rb +45 -0
  72. data/spec/innate/cache/marshal.rb +5 -0
  73. data/spec/innate/cache/memory.rb +5 -0
  74. data/spec/innate/cache/yaml.rb +5 -0
  75. data/spec/innate/dynamap.rb +22 -0
  76. data/spec/innate/helper.rb +66 -0
  77. data/spec/innate/helper/aspect.rb +80 -0
  78. data/spec/innate/helper/cgi.rb +37 -0
  79. data/spec/innate/helper/flash.rb +148 -0
  80. data/spec/innate/helper/link.rb +82 -0
  81. data/spec/innate/helper/partial.rb +66 -0
  82. data/spec/innate/helper/redirect.rb +148 -0
  83. data/spec/innate/helper/send_file.rb +21 -0
  84. data/spec/innate/helper/view/aspect_hello.erb +1 -0
  85. data/spec/innate/helper/view/locals.erb +1 -0
  86. data/spec/innate/helper/view/loop.erb +4 -0
  87. data/spec/innate/helper/view/num.erb +1 -0
  88. data/spec/innate/helper/view/partial.erb +1 -0
  89. data/spec/innate/helper/view/recursive.erb +8 -0
  90. data/spec/innate/mock.rb +84 -0
  91. data/spec/innate/node.rb +180 -0
  92. data/spec/innate/node/bar.html +1 -0
  93. data/spec/innate/node/foo.html.erb +1 -0
  94. data/spec/innate/node/with_layout.erb +3 -0
  95. data/spec/innate/options.rb +90 -0
  96. data/spec/innate/parameter.rb +154 -0
  97. data/spec/innate/request.rb +73 -0
  98. data/spec/innate/route.rb +129 -0
  99. data/spec/innate/session.rb +59 -0
  100. data/spec/innate/traited.rb +55 -0
  101. metadata +160 -0
@@ -0,0 +1 @@
1
+ <h1>Hello, World!</h1>
@@ -0,0 +1 @@
1
+ <% 10.times do |n| %><%= n %><% end %>
@@ -0,0 +1,3 @@
1
+ <div class="content">
2
+ <%= @content %>
3
+ </div>
@@ -0,0 +1,90 @@
1
+ require 'lib/innate/core_compatibility/basic_object'
2
+ require 'lib/innate/options/dsl'
3
+
4
+ require 'bacon'
5
+
6
+ Bacon.extend(Bacon::TestUnitOutput)
7
+ Bacon.summary_on_exit
8
+
9
+ Options = Innate::Options
10
+
11
+ describe Options do
12
+ @options = Innate::Options.new(:spec)
13
+
14
+ should 'create option' do
15
+ @options.o('my name', :name, 'manveru')
16
+ @options.name.should == 'manveru'
17
+ end
18
+
19
+ should 'create options with meta hash' do
20
+ @options.o('the port', :port, 7000, :cli => '-p')
21
+ @options.port.should == 7000
22
+ end
23
+
24
+ should 'get complete hash via #get' do
25
+ @options.get(:port)[:cli].should == '-p'
26
+ @options.get(:port)[:doc].should == 'the port'
27
+ end
28
+
29
+ should 'get value via []' do
30
+ @options[:port].should == 7000
31
+ end
32
+
33
+ should 'create scope' do
34
+ @options.sub(:deep)
35
+ @options.deep.should.not.be.nil
36
+ end
37
+
38
+ should 'create option in scope' do
39
+ @options.deep.o('the browser', :browser, :firefox)
40
+ @options.deep.browser.should == :firefox
41
+ end
42
+
43
+ should 'append to scope via dsl' do
44
+ @options.sub(:deep).o('hi mom', :greeting, :mom)
45
+ @options.deep.greeting.should == :mom
46
+ end
47
+
48
+ should 'sub in subscope' do
49
+ @options.sub(:deep).sub(:down).o('deep down', :me, :too)
50
+ @options.deep.down.me.should == :too
51
+ end
52
+
53
+ should 'get sub-sub option' do
54
+ @options.get(:deep, :down, :me).should == {:value => :too, :doc => 'deep down'}
55
+ end
56
+
57
+ should 'respond with nil on getting missing option' do
58
+ @options.get(:deep, :down, :you).should.be.nil
59
+ end
60
+
61
+ should 'search in higher scope if key not found' do
62
+ @options.deep.port.should == 7000
63
+ end
64
+
65
+ should 'merge! existing options with other Enumerable' do
66
+ @options.merge!(:port => 4000, :name => 'feagliir')
67
+ @options.port.should == 4000
68
+ @options.name.should == 'feagliir'
69
+ end
70
+
71
+ should 'Be Enumerable' do
72
+ keys, values = [], []
73
+
74
+ @options.each{|k, v| keys << k; values << v }
75
+
76
+ keys.compact.sort_by{|k| k.to_s }.should == [:deep, :name, :port]
77
+ values.compact.size.should == 3
78
+ end
79
+
80
+ should "raise when trying to assign to key that doesn't exist" do
81
+ lambda{ @options[:foo] = :bar }.should.raise(ArgumentError)
82
+ end
83
+
84
+ should 'pretty_print' do
85
+ require 'pp'
86
+ p = PP.new
87
+ @options.pretty_print(p)
88
+ p.output.should =~ /:value=>4000/
89
+ end
90
+ end
@@ -0,0 +1,154 @@
1
+ require 'spec/helper'
2
+
3
+ class SpecParameter
4
+ include Innate::Node
5
+ map '/'
6
+
7
+ def index
8
+ "index"
9
+ end
10
+
11
+ def no_params
12
+ "no params"
13
+ end
14
+
15
+ def single_param param
16
+ "single param (#{param})"
17
+ end
18
+
19
+ def double_param param1, param2
20
+ "double param (#{param1}, #{param2})"
21
+ end
22
+
23
+ def all_params *params
24
+ "all params (#{params.join(', ')})"
25
+ end
26
+
27
+ def at_least_one param, *params
28
+ "at least one (#{param}, #{params.join(', ')})"
29
+ end
30
+
31
+ def one_default param = 'default'
32
+ "one_default (#{param})"
33
+ end
34
+
35
+ def cat1__cat11
36
+ 'cat1: cat11'
37
+ end
38
+
39
+ def cat1__cat11__cat111
40
+ 'cat1: cat11: cat111'
41
+ end
42
+ end
43
+
44
+ class SpecParameter2
45
+ include Innate::Node
46
+ map '/jo'
47
+
48
+ def add(one, two = nil, three = nil)
49
+ "#{one}:#{two}:#{three}"
50
+ end
51
+
52
+ def keys
53
+ request.params.keys.inspect
54
+ end
55
+ end
56
+
57
+ class SpecParameter3
58
+ include Innate::Node
59
+ map '/ma'
60
+
61
+ def index(*args)
62
+ request.params['foo'].to_s.dump
63
+ end
64
+ end
65
+
66
+ describe "Simple Parameters" do
67
+ def handle(*url)
68
+ response = Innate::Mock.get(*url)
69
+ response.status.should == 200
70
+ response.body
71
+ end
72
+
73
+ it "Should respond to no parameters given" do
74
+ handle('/no_params').should == "no params"
75
+ end
76
+
77
+ it "Should respond to only / with the index" do
78
+ handle('/').should == "index"
79
+ end
80
+
81
+ it "call /bar though index doesn't take params" do
82
+ lambda{ handle('/bar') }.should.raise
83
+ end
84
+
85
+ it "action that takes a single param" do
86
+ handle('/single_param/foo').should == "single param (foo)"
87
+ end
88
+
89
+ it "action that takes two params" do
90
+ handle('/double_param/foo/bar').should == "double param (foo, bar)"
91
+ end
92
+
93
+ it "action that takes two params but we give only one" do
94
+ lambda{ handle('/double_param/foo') }.should.raise
95
+ end
96
+
97
+ it "action that takes all params" do
98
+ handle('/all_params/foo/bar/foobar').should == "all params (foo, bar, foobar)"
99
+ end
100
+
101
+ it "action that takes all params but needs at least one" do
102
+ handle('/at_least_one/foo/bar/foobar').should == "at least one (foo, bar, foobar)"
103
+ end
104
+
105
+ it "action that takes all params but needs at least one (not given here)" do
106
+ lambda{ handle('/at_least_one') }.
107
+ should.raise(ArgumentError)
108
+ end
109
+
110
+ it "one default" do
111
+ handle('/one_default').should == "one_default (default)"
112
+ end
113
+
114
+ it "one default" do
115
+ handle('/one_default/my_default').should == "one_default (my_default)"
116
+ end
117
+
118
+ it "double underscore lookup" do
119
+ handle('/cat1/cat11').should == 'cat1: cat11'
120
+ end
121
+
122
+ it "double double underscore lookup" do
123
+ handle('/cat1/cat11/cat111').should == 'cat1: cat11: cat111'
124
+ end
125
+
126
+
127
+ it "jo/add should raise with 0 parameters" do
128
+ lambda{ handle('/jo/add') }.
129
+ should.raise(ArgumentError)
130
+ end
131
+
132
+ it "add should raise with 4 parameters" do
133
+ lambda{ handle('/jo/add/1/2/3/4') }.
134
+ should.raise(ArgumentError)
135
+ end
136
+
137
+ it "add should not raise with 1-3 parameters" do
138
+ handle('/jo/add/1').should == '1::'
139
+ handle('/jo/add/1/2').should == '1:2:'
140
+ handle('/jo/add/1/2/3').should == '1:2:3'
141
+ end
142
+
143
+ it 'params should have no content without params' do
144
+ handle('/ma').should == '""'
145
+ end
146
+
147
+ it 'should have a parameter via QUERY_PARAMS' do
148
+ handle('/ma?foo=bar').should == '"bar"'
149
+ end
150
+
151
+ it 'should handle valueless params' do
152
+ handle('/jo/keys?foo').should == '["foo"]'
153
+ end
154
+ end
@@ -0,0 +1,73 @@
1
+ require 'spec/helper'
2
+
3
+ describe Innate::Request do
4
+ def request(env = {})
5
+ Innate::Request.new(env)
6
+ end
7
+
8
+ @env = {
9
+ "GATEWAY_INTERFACE" => "CGI/1.1",
10
+ "HTTP_ACCEPT" => "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
11
+ "HTTP_ACCEPT_CHARSET" => "UTF-8,*",
12
+ "HTTP_ACCEPT_ENCODING" => "gzip,deflate",
13
+ "HTTP_ACCEPT_LANGUAGE" => "en-us,en;q=0.8,de-at;q=0.5,de;q=0.3",
14
+ "HTTP_CACHE_CONTROL" => "max-age=0",
15
+ "HTTP_CONNECTION" => "keep-alive",
16
+ "HTTP_HOST" => "localhost:7000",
17
+ "HTTP_KEEP_ALIVE" => "300",
18
+ "HTTP_USER_AGENT" => "Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.0.5) Gecko/2008123017 Firefox/3.0.4 Ubiquity/0.1.4",
19
+ "HTTP_VERSION" => "HTTP/1.1",
20
+ "PATH_INFO" => "/",
21
+ "QUERY_STRING" => "?a=b",
22
+ "REMOTE_ADDR" => "127.0.0.1",
23
+ "REMOTE_HOST" => "delta.local",
24
+ "REQUEST_METHOD" => "GET",
25
+ "REQUEST_PATH" => "/",
26
+ "REQUEST_URI" => "http://localhost:7000/",
27
+ "SCRIPT_NAME" => "",
28
+ "SERVER_NAME" => "localhost",
29
+ "SERVER_PORT" => "7000",
30
+ "SERVER_PROTOCOL" => "HTTP/1.1",
31
+ }
32
+
33
+ should 'provide #request_uri' do
34
+ request('REQUEST_URI' => '/?a=b').request_uri.should == '/?a=b'
35
+ request('PATH_INFO' => '/').request_uri.should == '/'
36
+ end
37
+
38
+ should 'provide #local_net?' do
39
+ request.local_net?('192.168.0.1').to_s.should == '192.168.0.0'
40
+ request.local_net?('252.168.0.1').should == nil
41
+ request.local_net?('unknown').should == nil
42
+ request('REMOTE_ADDR' => '211.3.129.47, 66.249.85.131').local_net?.should == nil
43
+ request('REMOTE_ADDR' => '211.3.129.47').local_net?.should == nil
44
+ end
45
+
46
+ should 'provide #subset' do
47
+ params = {'a' => 'b', 'c' => 'd', 'e' => 'f'}
48
+ env = { 'rack.request.form_hash' => params }
49
+ req = request(env)
50
+
51
+ req.params.should == params
52
+ req.subset(:a).should == {'a' => 'b'}
53
+ req.subset(:a, :c).should == {'a' => 'b', 'c' => 'd'}
54
+ end
55
+
56
+ should 'provide #domain' do
57
+ request(@env.merge('rack.url_scheme' => 'http')).domain.should ==
58
+ URI('http://localhost:7000/')
59
+ request(@env.merge('rack.url_scheme' => 'https')).domain.should ==
60
+ URI('https://localhost:7000/')
61
+ request(@env.merge('rack.url_scheme' => 'https')).domain('/foo').should ==
62
+ URI('https://localhost:7000/foo')
63
+ end
64
+
65
+ should 'provide #accept_language' do
66
+ request(@env).accept_language.should == %w[en-us en de-at de]
67
+ end
68
+
69
+ should 'provide #http_variables' do
70
+ r = request(@env).http_variables
71
+ r.should.not.be.empty
72
+ end
73
+ end
@@ -0,0 +1,129 @@
1
+ require 'spec/helper'
2
+
3
+ class SpecRouter
4
+ include Innate::Node
5
+ map '/'
6
+ provide :html => :None
7
+
8
+ def float(flt)
9
+ "Float: %3.3f" % flt
10
+ end
11
+
12
+ def string(str)
13
+ "String: #{str}"
14
+ end
15
+
16
+ def price(p)
17
+ "Price: \$#{p}"
18
+ end
19
+
20
+ def sum(a, b)
21
+ a.to_i + b.to_i
22
+ end
23
+
24
+ def bar
25
+ 'this is bar'
26
+ end
27
+ end
28
+
29
+ Route, Rewrite = Innate::Route, Innate::Rewrite
30
+
31
+ describe Innate::Route do
32
+ def check(uri, status, body = nil)
33
+ got = Innate::Mock.get(uri)
34
+ got.status.should == status
35
+ got.body.should == body if body
36
+ end
37
+
38
+ should 'take lambda routers' do
39
+ Route['string'] = lambda{|path, req|
40
+ path if path =~ %r!^/string!
41
+ }
42
+ Route['string'].class.should == Proc
43
+
44
+ Route['calc sum'] = lambda{|path, req|
45
+ if req[:do_calc]
46
+ lval, rval = req[:a, :b]
47
+ rval = rval.to_i * 10
48
+ "/sum/#{lval}/#{rval}"
49
+ end
50
+ }
51
+
52
+ Innate::Route('foo') do |path, req|
53
+ '/bar' if req[:bar]
54
+ end
55
+ end
56
+
57
+ should 'define string routes' do
58
+ Route['/foobar'] = '/bar'
59
+ Route['/foobar'].should == '/bar'
60
+ end
61
+
62
+ should 'define regex routes' do
63
+ Route[%r!^/(\d+\.\d{2})$!] = "/price/%.2f"
64
+ Route[%r!^/(\d+\.\d{2})$!].should == "/price/%.2f"
65
+
66
+ Route[%r!^/(\d+\.\d+)!] = "/float/%.3f"
67
+ Route[%r!^/(\d+\.\d+)!].should == "/float/%.3f"
68
+
69
+ Route[%r!^/(\w+)!] = "/string/%s"
70
+ Route[%r!^/(\w+)!].should == "/string/%s"
71
+ end
72
+
73
+ should 'be used at /float' do
74
+ check('/123.123', 200, 'Float: 123.123')
75
+ end
76
+
77
+ should 'be used at /string' do
78
+ check('/foo', 200, 'String: foo')
79
+ end
80
+
81
+ should 'use %.3f' do
82
+ check('/123.123456', 200, 'Float: 123.123')
83
+ end
84
+
85
+ should 'resolve in the order added' do
86
+ check('/12.84', 200, 'Price: $12.84')
87
+ end
88
+
89
+ should 'use lambda routers' do
90
+ check('/string/abc', 200, 'String: abc')
91
+
92
+ check('/?do_calc=1&a=2&b=6', 200, '62')
93
+ end
94
+
95
+ it 'should support Route() with blocks' do
96
+ check('/foo?bar=1', 200, 'this is bar')
97
+ end
98
+
99
+ it 'should support string route translations' do
100
+ check('/foobar', 200, 'this is bar')
101
+ end
102
+
103
+ it 'should clear routes' do
104
+ Route::ROUTES.size.should > 0
105
+ Route.clear
106
+ Route::ROUTES.size.should == 0
107
+ end
108
+
109
+ it 'should not recurse given a bad route' do
110
+ Innate::Route[ %r!^/good/(.+)$! ] = "/bad/%s"
111
+ check('/good/hi', 404)
112
+ end
113
+ end
114
+
115
+ describe Innate::Rewrite do
116
+ Innate::Rewrite[ %r!^/(.+)$! ] = "/string/%s"
117
+
118
+ it 'should rewrite on non-existent actions' do
119
+ got = Innate::Mock.get('/hello')
120
+ got.status.should == 200
121
+ got.body.should == 'String: hello'
122
+ end
123
+
124
+ it 'should exclude existing actions' do
125
+ got = Innate::Mock.get('/bar')
126
+ got.status.should == 200
127
+ got.body.should == 'this is bar'
128
+ end
129
+ end