innate 2009.04

Sign up to get free protection for your applications and to get access to all the features.
Files changed (128) hide show
  1. data/CHANGELOG +2981 -0
  2. data/COPYING +18 -0
  3. data/MANIFEST +127 -0
  4. data/README.md +563 -0
  5. data/Rakefile +35 -0
  6. data/example/app/retro_games.rb +60 -0
  7. data/example/app/todo/layout/default.xhtml +11 -0
  8. data/example/app/todo/spec/todo.rb +63 -0
  9. data/example/app/todo/start.rb +51 -0
  10. data/example/app/todo/view/index.xhtml +39 -0
  11. data/example/app/whywiki_erb/layout/wiki.html.erb +15 -0
  12. data/example/app/whywiki_erb/spec/wiki.rb +19 -0
  13. data/example/app/whywiki_erb/start.rb +42 -0
  14. data/example/app/whywiki_erb/view/edit.erb +6 -0
  15. data/example/app/whywiki_erb/view/index.erb +12 -0
  16. data/example/custom_middleware.rb +35 -0
  17. data/example/hello.rb +11 -0
  18. data/example/howto_spec.rb +35 -0
  19. data/example/link.rb +27 -0
  20. data/example/provides.rb +31 -0
  21. data/example/session.rb +38 -0
  22. data/innate.gemspec +29 -0
  23. data/lib/innate.rb +269 -0
  24. data/lib/innate/action.rb +150 -0
  25. data/lib/innate/adapter.rb +76 -0
  26. data/lib/innate/cache.rb +134 -0
  27. data/lib/innate/cache/api.rb +128 -0
  28. data/lib/innate/cache/drb.rb +58 -0
  29. data/lib/innate/cache/file_based.rb +41 -0
  30. data/lib/innate/cache/marshal.rb +17 -0
  31. data/lib/innate/cache/memory.rb +22 -0
  32. data/lib/innate/cache/yaml.rb +17 -0
  33. data/lib/innate/current.rb +37 -0
  34. data/lib/innate/dynamap.rb +96 -0
  35. data/lib/innate/helper.rb +183 -0
  36. data/lib/innate/helper/aspect.rb +124 -0
  37. data/lib/innate/helper/cgi.rb +54 -0
  38. data/lib/innate/helper/flash.rb +36 -0
  39. data/lib/innate/helper/link.rb +94 -0
  40. data/lib/innate/helper/redirect.rb +85 -0
  41. data/lib/innate/helper/render.rb +87 -0
  42. data/lib/innate/helper/send_file.rb +26 -0
  43. data/lib/innate/log.rb +20 -0
  44. data/lib/innate/log/color_formatter.rb +43 -0
  45. data/lib/innate/log/hub.rb +73 -0
  46. data/lib/innate/middleware_compiler.rb +65 -0
  47. data/lib/innate/mock.rb +49 -0
  48. data/lib/innate/node.rb +1025 -0
  49. data/lib/innate/options.rb +37 -0
  50. data/lib/innate/options/dsl.rb +202 -0
  51. data/lib/innate/options/stub.rb +7 -0
  52. data/lib/innate/request.rb +141 -0
  53. data/lib/innate/response.rb +23 -0
  54. data/lib/innate/route.rb +110 -0
  55. data/lib/innate/session.rb +121 -0
  56. data/lib/innate/session/flash.rb +94 -0
  57. data/lib/innate/spec.rb +23 -0
  58. data/lib/innate/state.rb +27 -0
  59. data/lib/innate/state/accessor.rb +130 -0
  60. data/lib/innate/state/fiber.rb +74 -0
  61. data/lib/innate/state/thread.rb +47 -0
  62. data/lib/innate/traited.rb +85 -0
  63. data/lib/innate/trinity.rb +18 -0
  64. data/lib/innate/version.rb +3 -0
  65. data/lib/innate/view.rb +60 -0
  66. data/lib/innate/view/erb.rb +15 -0
  67. data/lib/innate/view/etanni.rb +36 -0
  68. data/lib/innate/view/none.rb +9 -0
  69. data/spec/example/app/retro_games.rb +30 -0
  70. data/spec/example/hello.rb +13 -0
  71. data/spec/example/link.rb +25 -0
  72. data/spec/example/provides.rb +16 -0
  73. data/spec/example/session.rb +22 -0
  74. data/spec/helper.rb +10 -0
  75. data/spec/innate/action/layout.rb +107 -0
  76. data/spec/innate/action/layout/file_layout.xhtml +1 -0
  77. data/spec/innate/cache/common.rb +47 -0
  78. data/spec/innate/cache/marshal.rb +5 -0
  79. data/spec/innate/cache/memory.rb +5 -0
  80. data/spec/innate/cache/yaml.rb +5 -0
  81. data/spec/innate/dynamap.rb +22 -0
  82. data/spec/innate/helper.rb +86 -0
  83. data/spec/innate/helper/aspect.rb +75 -0
  84. data/spec/innate/helper/cgi.rb +37 -0
  85. data/spec/innate/helper/flash.rb +118 -0
  86. data/spec/innate/helper/link.rb +139 -0
  87. data/spec/innate/helper/redirect.rb +160 -0
  88. data/spec/innate/helper/render.rb +133 -0
  89. data/spec/innate/helper/send_file.rb +21 -0
  90. data/spec/innate/helper/view/aspect_hello.xhtml +1 -0
  91. data/spec/innate/helper/view/locals.xhtml +1 -0
  92. data/spec/innate/helper/view/loop.xhtml +4 -0
  93. data/spec/innate/helper/view/num.xhtml +1 -0
  94. data/spec/innate/helper/view/partial.xhtml +1 -0
  95. data/spec/innate/helper/view/recursive.xhtml +7 -0
  96. data/spec/innate/mock.rb +84 -0
  97. data/spec/innate/node/mapping.rb +37 -0
  98. data/spec/innate/node/node.rb +134 -0
  99. data/spec/innate/node/resolve.rb +82 -0
  100. data/spec/innate/node/view/another_layout/another_layout.xhtml +3 -0
  101. data/spec/innate/node/view/bar.xhtml +1 -0
  102. data/spec/innate/node/view/foo.html.xhtml +1 -0
  103. data/spec/innate/node/view/only_view.xhtml +1 -0
  104. data/spec/innate/node/view/with_layout.xhtml +1 -0
  105. data/spec/innate/node/wrap_action_call.rb +83 -0
  106. data/spec/innate/options.rb +115 -0
  107. data/spec/innate/parameter.rb +154 -0
  108. data/spec/innate/provides.rb +99 -0
  109. data/spec/innate/provides/list.html.xhtml +1 -0
  110. data/spec/innate/provides/list.txt.xhtml +1 -0
  111. data/spec/innate/request.rb +77 -0
  112. data/spec/innate/route.rb +135 -0
  113. data/spec/innate/session.rb +54 -0
  114. data/spec/innate/state/fiber.rb +58 -0
  115. data/spec/innate/state/thread.rb +40 -0
  116. data/spec/innate/traited.rb +55 -0
  117. data/tasks/bacon.rake +66 -0
  118. data/tasks/changelog.rake +18 -0
  119. data/tasks/gem.rake +22 -0
  120. data/tasks/gem_installer.rake +76 -0
  121. data/tasks/grancher.rake +12 -0
  122. data/tasks/install_dependencies.rake +4 -0
  123. data/tasks/manifest.rake +4 -0
  124. data/tasks/rcov.rake +19 -0
  125. data/tasks/release.rake +51 -0
  126. data/tasks/reversion.rake +8 -0
  127. data/tasks/setup.rake +28 -0
  128. metadata +181 -0
@@ -0,0 +1 @@
1
+ <p>#{ @content }</p>
@@ -0,0 +1,47 @@
1
+ require 'spec/helper'
2
+
3
+ Innate::Cache.options.names = [:one, :two]
4
+ Innate::Cache.options.one = $common_cache_class
5
+ Innate::Cache.options.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)
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)
30
+ cache.fetch(:hello).should == nil
31
+ cache.fetch(:innate).should == nil
32
+ end
33
+
34
+ should 'store with ttl' do
35
+ cache.store(:hello, @hello, :ttl => 0.2)
36
+ cache.fetch(:hello).should == @hello
37
+ sleep 0.3
38
+ cache.fetch(:hello).should == nil
39
+ end
40
+
41
+ should 'clear' do
42
+ cache.store(:hello, @hello)
43
+ cache.fetch(:hello).should == @hello
44
+ cache.clear
45
+ cache.fetch(:hello).should == nil
46
+ end
47
+ 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,86 @@
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
+
67
+ should 'return module when Module is given to #each' do
68
+ Innate::HelpersHelper.each_extend(self, Innate::Helper::Link) do |p|
69
+ p.should == Innate::Helper::Link
70
+ end
71
+ end
72
+
73
+ should 'raise if helpers are not found' do
74
+ lambda{
75
+ Innate::HelpersHelper.each(:foo, :bar)
76
+ }.should.raise(LoadError).
77
+ message.should == "Helper foo not found"
78
+ end
79
+
80
+ should 'raise if helper is not found' do
81
+ lambda{
82
+ Innate::HelpersHelper.try_require(:foo)
83
+ }.should.raise(LoadError).
84
+ message.should == "Helper foo not found"
85
+ end
86
+ end
@@ -0,0 +1,75 @@
1
+ require 'spec/helper'
2
+
3
+ class AspectSpec
4
+ Innate.node('/', self).provide(:html, :None)
5
+
6
+ before(:with_before){ $aspect_spec_before += 40 }
7
+ def with_before; $aspect_spec_before += 2; end
8
+
9
+ after(:with_after){ $aspect_spec_after += 40 }
10
+ def with_after; $aspect_spec_after += 2; end
11
+
12
+ wrap(:with_wrap){ $aspect_spec_wrap += 20 }
13
+ def with_wrap; $aspect_spec_wrap += 2; end
14
+
15
+ before(:with_instance_var){ @foo = 'Hello'; @bar = 'World' }
16
+ def with_instance_var; "#{@foo} #{@bar}"; end
17
+ end
18
+
19
+ class AspectAllSpec
20
+ Innate.node('/all', self).provide(:html, :None)
21
+
22
+ before_all{ $aspect_spec_before_all += 40; @foo = 'Hello'; @bar = 'World' }
23
+ after_all{ $aspect_spec_after_all += 40 }
24
+ def before_first; $aspect_spec_before_all +=2 ; end
25
+ def before_second; $aspect_spec_before_all +=2; end
26
+ def with_instance_var_first; "#{@foo} #{@bar}"; end
27
+ def with_instance_var_second; "#{@foo} to the #{@bar}"; end
28
+ end
29
+
30
+ class AspecNoMethodSpec
31
+ Innate.node('/without_method', self)
32
+ include Innate::Node
33
+ map '/without_method'
34
+ map_views '/'
35
+ before_all{ @foo = 'Hello'; @bar = 'World'}
36
+ end
37
+
38
+ describe Innate::Helper::Aspect do
39
+ behaves_like :mock
40
+
41
+ it 'executes before aspect' do
42
+ $aspect_spec_before = 0
43
+ get('/with_before').body.should == '42'
44
+ $aspect_spec_before.should == 42
45
+ end
46
+
47
+ it 'executes after asepct' do
48
+ $aspect_spec_after = 0
49
+ get('/with_after').body.should == '2'
50
+ $aspect_spec_after.should == 42
51
+ end
52
+
53
+ it 'executes wrap aspects' do
54
+ $aspect_spec_wrap = 0
55
+ get('/with_wrap').body.should == '22'
56
+ $aspect_spec_wrap == 42
57
+ end
58
+
59
+ it 'calls before_all and after_all' do
60
+ $aspect_spec_before_all = $aspect_spec_after_all = 0
61
+ get('/all/before_first').body.should == '42'
62
+ $aspect_spec_before_all.should == 42
63
+ $aspect_spec_after_all.should == 40
64
+ get('/all/before_second').body.should == '84'
65
+ $aspect_spec_before_all.should == 84
66
+ $aspect_spec_after_all.should == 80
67
+ end
68
+
69
+ it 'makes instance variables in blocks available to view/method' do
70
+ get('/with_instance_var').body.should == 'Hello World'
71
+ get('/all/with_instance_var_first').body.should == 'Hello World'
72
+ get('/all/with_instance_var_second').body.should == 'Hello to the World'
73
+ get('/without_method/aspect_hello').body.should == "Hello World!"
74
+ end
75
+ 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,118 @@
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 check_empty
20
+ flash.empty?.to_s
21
+ end
22
+
23
+ def set_delete_key
24
+ flash[:name] = 'manveru'
25
+ flash.delete(:name)
26
+ flash[:name].to_s
27
+ end
28
+
29
+ def delete_key
30
+ flash.delete(:name)
31
+ "Bye #{flash[:name]}"
32
+ end
33
+
34
+ def merge!
35
+ flash.merge!(:name => 'feagliir').inspect
36
+ end
37
+
38
+ def merge
39
+ flash.merge(:name => 'feagliir').inspect
40
+ end
41
+
42
+ def inspect
43
+ flash[:yes] = :yeah
44
+ flash.inspect
45
+ end
46
+
47
+ def iterate
48
+ flash[:yes] = :yeah
49
+ elems = []
50
+ flash.each{|k,v| elems << [k,v] }
51
+ elems.inspect
52
+ end
53
+ end
54
+
55
+ class SpecFlashSub < SpecFlash
56
+ map '/sub'
57
+ end
58
+
59
+ describe Innate::Helper::Flash do
60
+ behaves_like :mock
61
+
62
+ should 'set and forget flash twice' do
63
+ get('/welcome').body.should == 'Welcome manveru'
64
+ get('/bye').body.should == 'Bye manveru'
65
+ get('/bye').body.should == 'Bye'
66
+
67
+ get('/welcome').body.should == 'Welcome manveru'
68
+ get('/bye').body.should == 'Bye manveru'
69
+ get('/bye').body.should == 'Bye'
70
+ end
71
+
72
+ should 'work over multiple nodes' do
73
+ get('/welcome').body.should == 'Welcome manveru'
74
+ get('/sub/bye').body.should == 'Bye manveru'
75
+ get('/sub/bye').body.should == 'Bye'
76
+
77
+ get('/sub/welcome').body.should == 'Welcome manveru'
78
+ get('/bye').body.should == 'Bye manveru'
79
+ get('/bye').body.should == 'Bye'
80
+ end
81
+
82
+ should 'check if flash is empty' do
83
+ get('/welcome').body.should == 'Welcome manveru'
84
+ get('/check_empty').body.should == 'false'
85
+ get('/check_empty').body.should == 'true'
86
+ end
87
+
88
+ should 'set and delete key within one request' do
89
+ get('/set_delete_key').body.should == ''
90
+ end
91
+
92
+ should 'set and delete key over two request' do
93
+ get('/welcome').body.should == 'Welcome manveru'
94
+ get('/delete_key').body.should == 'Bye'
95
+ end
96
+
97
+ should 'merge with hash' do
98
+ get('/merge').body.should == {:name => 'feagliir'}.inspect
99
+ get('/bye').body.should == 'Bye'
100
+ end
101
+
102
+ should 'merge! with hash' do
103
+ get('/merge!').body.should == {:name => 'feagliir'}.inspect
104
+ get('/bye').body.should == 'Bye feagliir'
105
+ end
106
+
107
+ should 'inspect combined' do
108
+ get('/welcome')
109
+ get('/inspect').body.should == {:name => 'manveru', :yes => :yeah}.inspect
110
+ end
111
+
112
+ should 'iterate over combined' do
113
+ get('/welcome')
114
+
115
+ hash = {:yes => :yeah, :name => 'manveru'}
116
+ Hash[*eval(get('/iterate').body).flatten].should == hash
117
+ end
118
+ end
@@ -0,0 +1,139 @@
1
+ require 'spec/helper'
2
+
3
+ class One
4
+ include Innate::Node
5
+ map '/'
6
+
7
+ def auto_route
8
+ UsingRouteSelf.new.route.to_s
9
+ end
10
+ end
11
+
12
+ class Two
13
+ include Innate::Node
14
+ map '/two'
15
+
16
+ def auto_route
17
+ UsingRouteSelf.new.route.to_s
18
+ end
19
+ end
20
+
21
+ class UsingRouteSelf
22
+ include Innate::Helper::Link
23
+
24
+ attr_reader :route
25
+
26
+ def initialize
27
+ @route = route_self(:elsewhere)
28
+ end
29
+ end
30
+
31
+ describe Innate::Helper::Link do
32
+ describe '#route' do
33
+ should 'respond with URI for node' do
34
+ One.route.should == URI('/')
35
+ Two.route.should == URI('/two/')
36
+ end
37
+
38
+ should 'respond with URI for node with path /' do
39
+ One.route('/').should == URI('/')
40
+ Two.route('/').should == URI('/two/')
41
+ end
42
+
43
+ should 'respond with URI for node with path /foo' do
44
+ One.route('/foo').should == URI('/foo')
45
+ One.route(:foo).should == URI('/foo')
46
+
47
+ Two.route('/foo').should == URI('/two/foo')
48
+ Two.route(:foo).should == URI('/two/foo')
49
+ end
50
+
51
+ should 'respond with URI for node with path /foo/bar' do
52
+ One.route('/foo/bar').should == URI('/foo/bar')
53
+ One.route(:foo, :bar).should == URI('/foo/bar')
54
+
55
+ Two.route('/foo/bar').should == URI('/two/foo/bar')
56
+ Two.route(:foo, :bar).should == URI('/two/foo/bar')
57
+ end
58
+
59
+ should 'respond with URI for node with path /foo/bar+baz' do
60
+ One.route('/foo/bar+baz').should == URI('/foo/bar+baz')
61
+ One.route(:foo, 'bar baz').should == URI('/foo/bar+baz')
62
+
63
+ Two.route('/foo/bar+baz').should == URI('/two/foo/bar+baz')
64
+ Two.route(:foo, 'bar baz').should == URI('/two/foo/bar+baz')
65
+ end
66
+
67
+ should 'respond with URI for node with GET params' do
68
+ One.route('/', :a => :b).should == URI('/?a=b')
69
+
70
+ One.route('/foo', :a => :b).should == URI('/foo?a=b')
71
+ One.route(:foo, :a => :b ).should == URI('/foo?a=b')
72
+
73
+ One.route('/foo/bar', :a => :b).should == URI('/foo/bar?a=b')
74
+ One.route(:foo, :bar, :a => :b).should == URI('/foo/bar?a=b')
75
+
76
+ Two.route('/', :a => :b).should == URI('/two/?a=b')
77
+
78
+ Two.route('foo', :a => :b).should == URI('/two/foo?a=b')
79
+ Two.route(:foo, :a => :b ).should == URI('/two/foo?a=b')
80
+ Two.route('/foo/bar', :a => :b).should == URI('/two/foo/bar?a=b')
81
+ Two.route(:foo, :bar, :a => :b).should == URI('/two/foo/bar?a=b')
82
+ end
83
+
84
+ should 'prefix the links as defined in the options' do
85
+ Innate.options.prefix = '/bar'
86
+ One.route('/foo').should == URI('/bar/foo')
87
+ Innate.options.prefix = '/'
88
+ end
89
+ end
90
+
91
+ describe '#anchor' do
92
+ should 'respond with a tag with default text' do
93
+ One.anchor('hello').should == '<a href="/hello">hello</a>'
94
+ Two.anchor('hello').should == '<a href="/two/hello">hello</a>'
95
+ end
96
+
97
+ should 'respond with a tag with explicit text' do
98
+ One.anchor('hello', :foo).should == '<a href="/foo">hello</a>'
99
+ Two.anchor('hello', :foo).should == '<a href="/two/foo">hello</a>'
100
+ end
101
+
102
+ should 'pass parameters to #route' do
103
+ One.anchor('hello', :foo, :a => :b).
104
+ should == '<a href="/foo?a=b">hello</a>'
105
+ Two.anchor('hello', :foo, :a => :b).
106
+ should == '<a href="/two/foo?a=b">hello</a>'
107
+ end
108
+
109
+ should 'escape text' do
110
+ One.anchor('<blink> & <a>', :foo).
111
+ should == '<a href="/foo">&lt;blink&gt; &amp; &lt;a&gt;</a>'
112
+ end
113
+ end
114
+
115
+ describe 'combining #anchor and #route' do
116
+ should 'not escape twice' do
117
+ One.anchor('foo', One.route(:index, :bar => 'a/b/c')).
118
+ should == '<a href="/index?bar=a%2Fb%2Fc">foo</a>'
119
+ end
120
+
121
+ should 'handle complete uris gracefully' do
122
+ One.anchor('foo', 'http://example.com/?foo=bar&baz=qux').
123
+ should == '<a href="http://example.com/?foo=bar&amp;baz=qux">foo</a>'
124
+ end
125
+
126
+ should 'be able to route from one node to another' do
127
+ Two.anchor('foo', One.route(:index)).should == '<a href="/index">foo</a>'
128
+ One.anchor('foo', Two.route(:index)).should == '<a href="/two/index">foo</a>'
129
+ end
130
+ end
131
+
132
+ describe '#route_self' do
133
+ behaves_like :mock
134
+ should 'provide a route to the node of the currently active action' do
135
+ get('/auto_route').body.should == '/elsewhere'
136
+ get('/two/auto_route').body.should == '/two/elsewhere'
137
+ end
138
+ end
139
+ end