manveru-innate 2009.02.06

Sign up to get free protection for your applications and to get access to all the features.
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,29 @@
1
+ require 'spec/helper'
2
+ require 'example/link'
3
+
4
+ describe 'example/link' do
5
+ behaves_like :mock
6
+
7
+ should 'have index on Linking' do
8
+ get('/').body.should == 'simple link<br /><a href="/help">Help?</a>'
9
+ end
10
+
11
+ should 'have new on Linking' do
12
+ get('/new').body.should == 'Something new!'
13
+ end
14
+
15
+ should 'have help on Linking' do
16
+ get('/help').body.should ==
17
+ "You have help<br /><a href=\"/link_to/another\">A Different Node</a>"
18
+ end
19
+
20
+ should 'have another on Different' do
21
+ get('/link_to/another').body.
22
+ should == "<a href=\"/link_to/and/deeper\">Even deeper</a>"
23
+ end
24
+
25
+ should 'have and__deeper on Different' do
26
+ get('/link_to/and/deeper').body.
27
+ should == "<a href=\"/index\">Back to Linking Node</a>"
28
+ end
29
+ end
data/spec/helper.rb ADDED
@@ -0,0 +1,2 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__), '../lib/innate'))
2
+ require 'innate/spec'
@@ -0,0 +1,45 @@
1
+ require 'spec/helper'
2
+
3
+ Innate.options.cache.names = [:one, :two]
4
+ Innate.options.cache.one = $common_cache_class
5
+ Innate.options.cache.two = $common_cache_class
6
+ Innate.setup_dependencies
7
+
8
+ describe $common_cache_class do
9
+ cache = Innate::Cache.one
10
+
11
+ @hello = 'Hello, World!'
12
+
13
+ should 'store without ttl' do
14
+ cache.store(:hello, @hello).should == @hello
15
+ end
16
+
17
+ should 'fetch' do
18
+ cache.fetch(:hello).should == @hello
19
+ end
20
+
21
+ should 'delete' do
22
+ cache.delete(:hello).should == @hello
23
+ cache.fetch(:hello).should == nil
24
+ end
25
+
26
+ should 'delete two key/value pairs at once' do
27
+ cache.store(:hello, @hello).should == @hello
28
+ cache.store(:innate, 'innate').should == 'innate'
29
+ cache.delete(:hello, :innate).should == [@hello, 'innate']
30
+ end
31
+
32
+ should 'store with ttl' do
33
+ cache.store(:hello, @hello, :ttl => 0.2)
34
+ cache.fetch(:hello).should == @hello
35
+ sleep 0.3
36
+ cache.fetch(:hello).should == nil
37
+ end
38
+
39
+ should 'clear' do
40
+ cache.store(:hello, @hello)
41
+ cache.fetch(:hello).should == @hello
42
+ cache.clear
43
+ cache.fetch(:hello).should == nil
44
+ end
45
+ end
@@ -0,0 +1,5 @@
1
+ require 'spec/helper'
2
+
3
+ $common_cache_class = Innate::Cache::Marshal
4
+
5
+ require 'spec/innate/cache/common'
@@ -0,0 +1,5 @@
1
+ require 'spec/helper'
2
+
3
+ $common_cache_class = Innate::Cache::Memory
4
+
5
+ require 'spec/innate/cache/common'
@@ -0,0 +1,5 @@
1
+ require 'spec/helper'
2
+
3
+ $common_cache_class = Innate::Cache::YAML
4
+
5
+ require 'spec/innate/cache/common'
@@ -0,0 +1,22 @@
1
+ require 'spec/helper'
2
+
3
+ describe Innate::DynaMap do
4
+ @app = lambda{|env| [200, {}, ['pass']] }
5
+
6
+ should 'raise if nothing is mapped' do
7
+ lambda{ Innate::DynaMap.call({}) }.should.raise(RuntimeError)
8
+ end
9
+
10
+ should 'not raise if nothing is mapped' do
11
+ Innate.map('/', &@app)
12
+ Innate::DynaMap.call('SCRIPT_NAME' => '/').should == [200, {}, ['pass']]
13
+ end
14
+
15
+ should 'return mapped object' do
16
+ Innate.at('/').should == @app
17
+ end
18
+
19
+ should 'return path to object' do
20
+ Innate.to(@app).should == '/'
21
+ end
22
+ end
@@ -0,0 +1,66 @@
1
+ require 'spec/helper'
2
+ require 'innate/helper'
3
+
4
+ module Innate
5
+ module Helper
6
+ module SmileHelper
7
+ EXPOSE << self
8
+
9
+ def smile
10
+ ':)'
11
+ end
12
+ end
13
+
14
+ module FrownHelper
15
+ def frown
16
+ ':('
17
+ end
18
+ end
19
+ end
20
+ end
21
+
22
+ class HelperNodeExpose
23
+ include Innate::Node
24
+ map '/'
25
+
26
+ helper :smile_helper, :frown_helper
27
+
28
+ def frowny
29
+ "Oh, hi #{frown}"
30
+ end
31
+ end
32
+
33
+ describe HelperNodeExpose do
34
+ should 'expose an action' do
35
+ Innate::Mock.get('/smile').body.should == ':)'
36
+ Innate::Mock.get('/frown').status.should == 404
37
+ Innate::Mock.get('/frowny').body.should == "Oh, hi :("
38
+ end
39
+ end
40
+
41
+ class FooNodeLink
42
+ include Innate::Node
43
+ map '/foo'
44
+
45
+ helper :link, :cgi
46
+ end
47
+
48
+ describe Innate::Helper::Link do
49
+ FNL = FooNodeLink
50
+
51
+ should 'construct URI from ::r' do
52
+ FNL.r(:index).should == URI('/foo/index')
53
+ FNL.r(:/).should == URI('/foo/')
54
+ FNL.r(:index, :foo => :bar).should == URI('/foo/index?foo=bar')
55
+
56
+ uri = FNL.r(:index, :a => :b, :x => :y)
57
+ uri.query.split(';').sort.should == %w[a=b x=y]
58
+ end
59
+
60
+ should 'construct link from ::a' do
61
+ FNL.a(:index).should == '<a href="/foo/index">index</a>'
62
+ FNL.a('index', :index, :x => :y).should == '<a href="/foo/index?x=y">index</a>'
63
+ FNL.a('duh/bar', 'duh/bar', :x => :y).should == '<a href="/foo/duh/bar?x=y">duh/bar</a>'
64
+ FNL.a('foo', :/, :x => :y).should == '<a href="/foo/?x=y">foo</a>'
65
+ end
66
+ end
@@ -0,0 +1,80 @@
1
+ require 'spec/helper'
2
+ Innate.options.app.root = File.dirname(__FILE__)
3
+ Innate.options.app.view = ''
4
+
5
+ class AspectSpec
6
+ include Innate::Node
7
+ map '/'
8
+ provide :html => :none
9
+
10
+ before(:with_before){ $aspect_spec_before += 40 }
11
+ def with_before; $aspect_spec_before += 2; end
12
+
13
+ after(:with_after){ $aspect_spec_after += 40 }
14
+ def with_after; $aspect_spec_after += 2; end
15
+
16
+ wrap(:with_wrap){ $aspect_spec_wrap += 20 }
17
+ def with_wrap; $aspect_spec_wrap += 2; end
18
+
19
+ before(:with_instance_var){ @foo = 'Hello'; @bar = 'World' }
20
+ def with_instance_var; "#{@foo} #{@bar}"; end
21
+ end
22
+
23
+ class AspectAllSpec
24
+ include Innate::Node
25
+ map '/all'
26
+ provide :html => :none
27
+
28
+ before_all{ $aspect_spec_before_all += 40; @foo = 'Hello'; @bar = 'World' }
29
+ after_all{ $aspect_spec_after_all += 40 }
30
+ def before_first; $aspect_spec_before_all +=2 ; end
31
+ def before_second; $aspect_spec_before_all +=2; end
32
+ def with_instance_var_first; "#{@foo} #{@bar}"; end
33
+ def with_instance_var_second; "#{@foo} to the #{@bar}"; end
34
+ end
35
+
36
+ class AspecNoMethodSpec
37
+ include Innate::Node
38
+ map '/without_method'
39
+ view_root 'view'
40
+ before_all{ @foo = 'Hello'; @bar = 'World'}
41
+ end
42
+
43
+ describe Innate::Helper::Aspect do
44
+ behaves_like :mock
45
+
46
+ should 'execute before aspect' do
47
+ $aspect_spec_before = 0
48
+ get('/with_before').body.should == '42'
49
+ $aspect_spec_before.should == 42
50
+ end
51
+
52
+ should 'execute after asepct' do
53
+ $aspect_spec_after = 0
54
+ get('/with_after').body.should == '2'
55
+ $aspect_spec_after.should == 42
56
+ end
57
+
58
+ should 'execute wrap aspects' do
59
+ $aspect_spec_wrap = 0
60
+ get('/with_wrap').body.should == '22'
61
+ $aspect_spec_wrap == 42
62
+ end
63
+
64
+ should 'before_all and after_all' do
65
+ $aspect_spec_before_all = $aspect_spec_after_all = 0
66
+ get('/all/before_first').body.should == '42'
67
+ $aspect_spec_before_all.should == 42
68
+ $aspect_spec_after_all.should == 40
69
+ get('/all/before_second').body.should == '84'
70
+ $aspect_spec_before_all.should == 84
71
+ $aspect_spec_after_all.should == 80
72
+ end
73
+
74
+ should 'instance variables in blocks available to view/method' do
75
+ get('/with_instance_var').body.should == 'Hello World'
76
+ get('/all/with_instance_var_first').body.should == 'Hello World'
77
+ get('/all/with_instance_var_second').body.should == 'Hello to the World'
78
+ get('/without_method/aspect_hello').body.should == "Hello World!\n"
79
+ end
80
+ end
@@ -0,0 +1,37 @@
1
+ require 'spec/helper'
2
+ require 'innate/helper/cgi'
3
+
4
+ describe "url encode" do
5
+ extend Innate::Helper::CGI
6
+
7
+ it 'should url_encode strings' do
8
+ # ok, I believe that the web is dumb for this
9
+ # but this probably is a SHOULD thingy in the HTTP RFC
10
+ url_encode('title with spaces').should == 'title+with+spaces'
11
+ url_encode('[foo]').should == '%5Bfoo%5D'
12
+ u('//').should == '%2F%2F'
13
+ end
14
+ it 'should url_decode strings' do
15
+ url_decode('title%20with%20spaces').should == 'title with spaces'
16
+ url_decode('title+with+spaces').should == 'title with spaces'
17
+ end
18
+ it 'should be reversible' do
19
+ url_decode(u('../ etc/passwd')).should == '../ etc/passwd'
20
+ end
21
+ end
22
+
23
+ describe 'html escape' do
24
+ extend Innate::Helper::CGI
25
+
26
+ it 'should escape html' do
27
+ html_escape('& < >').should == '&amp; &lt; &gt;'
28
+ h('<&>').should == '&lt;&amp;&gt;'
29
+ end
30
+ it 'should unescape html' do
31
+ html_unescape('&lt; &amp; &gt;').should == '< & >'
32
+ end
33
+ it 'should be reversible' do
34
+ html_unescape(html_escape('2 > b && b <= 0')).should == '2 > b && b <= 0'
35
+ end
36
+ end
37
+
@@ -0,0 +1,148 @@
1
+ # Copyright (c) 2009 Michael Fellinger m.fellinger@gmail.com
2
+ # All files in this distribution are subject to the terms of the Ruby license.
3
+
4
+ require 'spec/helper'
5
+
6
+ class SpecFlash
7
+ include Innate::Node
8
+ map '/'
9
+
10
+ def welcome
11
+ flash[:name] = 'manveru'
12
+ "Welcome #{flash[:name]}"
13
+ end
14
+
15
+ def bye
16
+ "Bye #{flash[:name]}"
17
+ end
18
+
19
+ def box
20
+ flashbox
21
+ end
22
+
23
+ def check_empty
24
+ flash.empty?.to_s
25
+ end
26
+
27
+ def set_delete_key
28
+ flash[:name] = 'manveru'
29
+ flash.delete(:name)
30
+ flash[:name]
31
+ end
32
+
33
+ def delete_key
34
+ flash.delete(:name)
35
+ "Bye #{flash[:name]}"
36
+ end
37
+
38
+ def set(*hash)
39
+ Hash[*hash].each do |key, value|
40
+ flash[key] = value
41
+ end
42
+ hash.inspect
43
+ end
44
+
45
+ def merge!
46
+ flash.merge!(:name => 'feagliir').inspect
47
+ end
48
+
49
+ def merge
50
+ flash.merge(:name => 'feagliir').inspect
51
+ end
52
+
53
+ def inspect
54
+ flash[:yes] = :yeah
55
+ flash.inspect
56
+ end
57
+
58
+ def iterate
59
+ flash[:yes] = :yeah
60
+ elems = []
61
+ flash.each{|k,v| elems << [k,v] }
62
+ elems.inspect
63
+ end
64
+ end
65
+
66
+ class SpecFlashSub < SpecFlash
67
+ map '/sub'
68
+ end
69
+
70
+ describe Innate::Helper::Flash do
71
+ behaves_like :session
72
+
73
+ should 'set and forget flash twice' do
74
+ session do |mock|
75
+ mock.get('/welcome').body.should == 'Welcome manveru'
76
+ mock.get('/bye').body.should == 'Bye manveru'
77
+ mock.get('/bye').body.should == 'Bye '
78
+
79
+ mock.get('/welcome').body.should == 'Welcome manveru'
80
+ mock.get('/bye').body.should == 'Bye manveru'
81
+ mock.get('/bye').body.should == 'Bye '
82
+ end
83
+ end
84
+
85
+ should 'work over multiple nodes' do
86
+ session do |mock|
87
+ mock.get('/welcome').body.should == 'Welcome manveru'
88
+ mock.get('/sub/bye').body.should == 'Bye manveru'
89
+ mock.get('/sub/bye').body.should == 'Bye '
90
+
91
+ mock.get('/sub/welcome').body.should == 'Welcome manveru'
92
+ mock.get('/bye').body.should == 'Bye manveru'
93
+ mock.get('/bye').body.should == 'Bye '
94
+ end
95
+ end
96
+
97
+ should 'check if flash is empty' do
98
+ session do |mock|
99
+ mock.get('/welcome').body.should == 'Welcome manveru'
100
+ mock.get('/check_empty').body.should == 'false'
101
+ mock.get('/check_empty').body.should == 'true'
102
+ end
103
+ end
104
+
105
+ should 'set and delete key within one request' do
106
+ session do |mock|
107
+ mock.get('/set_delete_key').body.should == ''
108
+ end
109
+ end
110
+
111
+ should 'set and delete key over two request' do
112
+ session do |mock|
113
+ mock.get('/welcome').body.should == 'Welcome manveru'
114
+ mock.get('/delete_key').body.should == 'Bye '
115
+ end
116
+ end
117
+
118
+ should 'merge with hash' do
119
+ session do |mock|
120
+ mock.get('/merge').body.should == {:name => 'feagliir'}.inspect
121
+ mock.get('/bye').body.should == 'Bye '
122
+ end
123
+ end
124
+
125
+ should 'merge! with hash' do
126
+ session do |mock|
127
+ mock.get('/merge!').body.should == {:name => 'feagliir'}.inspect
128
+ mock.get('/bye').body.should == 'Bye feagliir'
129
+ end
130
+ end
131
+
132
+ should 'inspect combined' do
133
+ session do |mock|
134
+ mock.get('/welcome')
135
+ mock.get('/inspect').body.
136
+ should == {:name => 'manveru', :yes => :yeah}.inspect
137
+ end
138
+ end
139
+
140
+ should 'iterate over combined' do
141
+ session do |mock|
142
+ mock.get('/welcome')
143
+
144
+ hash = {:yes => :yeah, :name => 'manveru'}
145
+ Hash[*eval(mock.get('/iterate').body).flatten].should == hash
146
+ end
147
+ end
148
+ end