innate 2009.04

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 (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