rjspotter-innate 2009.06.29

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/AUTHORS +10 -0
  2. data/CHANGELOG +3261 -0
  3. data/COPYING +18 -0
  4. data/MANIFEST +127 -0
  5. data/README.md +563 -0
  6. data/Rakefile +39 -0
  7. data/example/app/retro_games.rb +60 -0
  8. data/example/app/todo/layout/default.xhtml +11 -0
  9. data/example/app/todo/spec/todo.rb +63 -0
  10. data/example/app/todo/start.rb +51 -0
  11. data/example/app/todo/view/index.xhtml +39 -0
  12. data/example/app/whywiki_erb/layout/wiki.html.erb +15 -0
  13. data/example/app/whywiki_erb/spec/wiki.rb +19 -0
  14. data/example/app/whywiki_erb/start.rb +42 -0
  15. data/example/app/whywiki_erb/view/edit.erb +6 -0
  16. data/example/app/whywiki_erb/view/index.erb +12 -0
  17. data/example/custom_middleware.rb +35 -0
  18. data/example/hello.rb +11 -0
  19. data/example/howto_spec.rb +35 -0
  20. data/example/link.rb +27 -0
  21. data/example/provides.rb +31 -0
  22. data/example/session.rb +38 -0
  23. data/innate.gemspec +41 -0
  24. data/lib/innate.rb +269 -0
  25. data/lib/innate/action.rb +137 -0
  26. data/lib/innate/adapter.rb +76 -0
  27. data/lib/innate/cache.rb +134 -0
  28. data/lib/innate/cache/api.rb +128 -0
  29. data/lib/innate/cache/drb.rb +58 -0
  30. data/lib/innate/cache/file_based.rb +44 -0
  31. data/lib/innate/cache/marshal.rb +20 -0
  32. data/lib/innate/cache/memory.rb +21 -0
  33. data/lib/innate/cache/yaml.rb +20 -0
  34. data/lib/innate/current.rb +35 -0
  35. data/lib/innate/dynamap.rb +96 -0
  36. data/lib/innate/helper.rb +185 -0
  37. data/lib/innate/helper/aspect.rb +124 -0
  38. data/lib/innate/helper/cgi.rb +54 -0
  39. data/lib/innate/helper/flash.rb +36 -0
  40. data/lib/innate/helper/link.rb +94 -0
  41. data/lib/innate/helper/redirect.rb +85 -0
  42. data/lib/innate/helper/render.rb +152 -0
  43. data/lib/innate/helper/send_file.rb +26 -0
  44. data/lib/innate/log.rb +20 -0
  45. data/lib/innate/log/color_formatter.rb +49 -0
  46. data/lib/innate/log/hub.rb +77 -0
  47. data/lib/innate/middleware_compiler.rb +65 -0
  48. data/lib/innate/mock.rb +49 -0
  49. data/lib/innate/node.rb +1029 -0
  50. data/lib/innate/options.rb +37 -0
  51. data/lib/innate/options/dsl.rb +205 -0
  52. data/lib/innate/options/stub.rb +7 -0
  53. data/lib/innate/request.rb +141 -0
  54. data/lib/innate/response.rb +24 -0
  55. data/lib/innate/route.rb +114 -0
  56. data/lib/innate/session.rb +133 -0
  57. data/lib/innate/session/flash.rb +94 -0
  58. data/lib/innate/spec.rb +1 -0
  59. data/lib/innate/spec/bacon.rb +28 -0
  60. data/lib/innate/state.rb +26 -0
  61. data/lib/innate/state/accessor.rb +130 -0
  62. data/lib/innate/traited.rb +90 -0
  63. data/lib/innate/trinity.rb +18 -0
  64. data/lib/innate/version.rb +3 -0
  65. data/lib/innate/view.rb +97 -0
  66. data/lib/innate/view/erb.rb +14 -0
  67. data/lib/innate/view/etanni.rb +33 -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 +121 -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 +115 -0
  86. data/spec/innate/helper/link.rb +139 -0
  87. data/spec/innate/helper/redirect.rb +171 -0
  88. data/spec/innate/helper/render.rb +165 -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/modes.rb +61 -0
  98. data/spec/innate/node/mapping.rb +37 -0
  99. data/spec/innate/node/node.rb +135 -0
  100. data/spec/innate/node/resolve.rb +82 -0
  101. data/spec/innate/node/view/another_layout/another_layout.xhtml +3 -0
  102. data/spec/innate/node/view/bar.xhtml +1 -0
  103. data/spec/innate/node/view/foo.html.xhtml +1 -0
  104. data/spec/innate/node/view/only_view.xhtml +1 -0
  105. data/spec/innate/node/view/with_layout.xhtml +1 -0
  106. data/spec/innate/node/wrap_action_call.rb +83 -0
  107. data/spec/innate/options.rb +123 -0
  108. data/spec/innate/parameter.rb +154 -0
  109. data/spec/innate/provides.rb +99 -0
  110. data/spec/innate/provides/list.html.xhtml +1 -0
  111. data/spec/innate/provides/list.txt.xhtml +1 -0
  112. data/spec/innate/request.rb +79 -0
  113. data/spec/innate/route.rb +135 -0
  114. data/spec/innate/session.rb +58 -0
  115. data/spec/innate/traited.rb +55 -0
  116. data/tasks/authors.rake +30 -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_setup.rake +99 -0
  121. data/tasks/grancher.rake +12 -0
  122. data/tasks/manifest.rake +4 -0
  123. data/tasks/rcov.rake +19 -0
  124. data/tasks/release.rake +53 -0
  125. data/tasks/reversion.rake +8 -0
  126. data/tasks/setup.rake +6 -0
  127. data/tasks/ycov.rake +84 -0
  128. metadata +218 -0
@@ -0,0 +1,39 @@
1
+ require 'rake'
2
+ require 'rake/clean'
3
+ require 'rake/gempackagetask'
4
+ require 'time'
5
+ require 'date'
6
+
7
+ PROJECT_SPECS = FileList['spec/{innate,example}/**/*.rb'].exclude('common.rb')
8
+ PROJECT_MODULE = 'Innate'
9
+ PROJECT_README = 'README.md'
10
+ PROJECT_VERSION = ENV['VERSION'] || Date.today.strftime('%Y.%m.%d')
11
+
12
+ GEMSPEC = Gem::Specification.new{|s|
13
+ s.name = 'innate'
14
+ s.author = "Michael 'manveru' Fellinger"
15
+ s.summary = "Powerful web-framework wrapper for Rack."
16
+ s.description = "Simple, straight-forward base for web-frameworks."
17
+ s.email = 'm.fellinger@gmail.com'
18
+ s.homepage = 'http://github.com/manveru/innate'
19
+ s.platform = Gem::Platform::RUBY
20
+ s.version = PROJECT_VERSION
21
+ s.files = `git ls-files`.split("\n").sort
22
+ s.has_rdoc = true
23
+ s.require_path = 'lib'
24
+ s.rubyforge_project = "innate"
25
+ s.required_rubygems_version = '>= 1.3.1'
26
+
27
+ s.add_dependency('rack', '~> 1.0.0')
28
+
29
+ # rip those out if they cause you trouble
30
+ s.add_development_dependency('bacon', '>= 1.1.0')
31
+ s.add_development_dependency('json', '~> 1.1.6')
32
+ s.add_development_dependency('rack-test', '>= 0.3.0')
33
+ }
34
+
35
+ Dir['tasks/*.rake'].each{|f| import(f) }
36
+
37
+ task :default => [:bacon]
38
+
39
+ CLEAN.include('')
@@ -0,0 +1,60 @@
1
+ require 'innate'
2
+ require 'yaml/store'
3
+
4
+ STORE = YAML::Store.new('games.yaml')
5
+
6
+ def STORE.[](key) transaction{|s| super } end
7
+ def STORE.[]=(key, value) transaction{|s| super } end
8
+ def STORE.each(&block)
9
+ YAML.load_file('games.yaml').sort_by{|k,v| -v }.each(&block)
10
+ end
11
+
12
+ STORE['Pacman'] = 1
13
+
14
+ class Games
15
+ Innate.node('/')
16
+
17
+ def index
18
+ TEMPLATE
19
+ end
20
+
21
+ def create
22
+ STORE[request[:name]] ||= 0 if request.post?
23
+
24
+ redirect_referrer
25
+ end
26
+
27
+ def vote(name)
28
+ STORE[name] += 1
29
+
30
+ redirect_referrer
31
+ end
32
+
33
+ TEMPLATE = <<-'T'.strip
34
+ <?xml version='1.0' encoding='utf-8' ?>
35
+ <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
36
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
37
+ <html>
38
+ <head>
39
+ <title>Top Retro Games</title>
40
+ </head>
41
+ <body>
42
+ <h1>Vote on your favorite Retro Game</h1>
43
+ <form action="#{ r(:create) }" method="post">
44
+ <input type="text" name="name" />
45
+ <input type="submit" value="Add" />
46
+ </form>
47
+ <ol>
48
+ <?r STORE.each do |name, votes| ?>
49
+ <li>
50
+ #{ a("Vote", r(:vote, u(name))) }
51
+ #{ h "%5d => %s" % [votes, name] }
52
+ </li>
53
+ <?r end ?>
54
+ </ol>
55
+ </body>
56
+ </html>
57
+ T
58
+ end
59
+
60
+ Innate.start
@@ -0,0 +1,11 @@
1
+ <?xml version='1.0' encoding='utf-8' ?>
2
+ <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
3
+ <html>
4
+ <head>
5
+ <title>Innate TodoList</title>
6
+ </head>
7
+ <body>
8
+ <h1>Organize your life and learn Innate</h1>
9
+ #{ @content }
10
+ </body>
11
+ </html>
@@ -0,0 +1,63 @@
1
+ require 'innate/spec'
2
+
3
+ FileUtils.rm_f('todo.pstore')
4
+
5
+ require 'start'
6
+ require 'hpricot'
7
+
8
+ describe Todo do
9
+ behaves_like :mock, :multipart
10
+
11
+ it 'starts out without tasks' do
12
+ doc = Hpricot(get('/').body)
13
+ doc.at(:table).inner_text.strip.should.be.empty
14
+ end
15
+
16
+ it 'adds a task and redirects back' do
17
+ got = post('/create', multipart('title' => 'first task'))
18
+ got.status.should == 302
19
+ got['Location'].should == 'http://example.org/'
20
+ end
21
+
22
+ it 'shows the task as pending' do
23
+ doc = Hpricot(get('/').body)
24
+ doc.at('td/input[@name=title]')['value'].should == 'first task'
25
+ doc.at('td/input[@name=done]')['checked'].should.be.nil
26
+ end
27
+
28
+ it 'updates the task title and redirects back' do
29
+ got = post('/update', multipart('id' => 'first task', 'title' => 'wash dishes'))
30
+ got.status.should == 302
31
+ got['Location'].should == 'http://example.org/'
32
+ end
33
+
34
+ it 'shows the changed task title' do
35
+ doc = Hpricot(get('/').body)
36
+ doc.at('td/input[@name=title]')['value'].should == 'wash dishes'
37
+ doc.at('td/input[@name=done]')['checked'].should.be.nil
38
+ end
39
+
40
+ it 'marks the task as done and redirects back' do
41
+ mp = multipart('id' => 'wash dishes', 'title' => 'wash dishes', 'done' => 'on')
42
+ got = post('/update', mp)
43
+ got.status.should == 302
44
+ got['Location'].should == 'http://example.org/'
45
+ end
46
+
47
+ it 'shows the task as done' do
48
+ doc = Hpricot(get('/').body)
49
+ doc.at('td/input[@name=title]')['value'].should == 'wash dishes'
50
+ doc.at('td/input[@name=done]')['checked'].should == 'checked'
51
+ end
52
+
53
+ it 'deletes the task and redirects back' do
54
+ got = post('/delete', multipart('id' => 'wash dishes'))
55
+ got.status.should == 302
56
+ got['Location'].should == 'http://example.org/'
57
+ end
58
+
59
+ it 'shows no tasks' do
60
+ doc = Hpricot(get('/').body)
61
+ doc.at(:table).inner_text.strip.should.be.empty
62
+ end
63
+ end
@@ -0,0 +1,51 @@
1
+ require 'rubygems'
2
+ require 'innate'
3
+ require 'pstore'
4
+
5
+ LIST = PStore.new('todo.pstore')
6
+
7
+ class Todo
8
+ Innate.node '/'
9
+ layout 'default'
10
+
11
+ def index
12
+ @list = sync{|list| list.roots.map{|key| [key, list[key]] }}
13
+ end
14
+
15
+ def create
16
+ redirect_referer unless request.post? and title = request[:title]
17
+ title.strip!
18
+
19
+ sync{ LIST[title] = false } unless title.empty?
20
+ redirect_referer
21
+ end
22
+
23
+ def update
24
+ id, title, done = request[:id, :title, :done]
25
+ redirect_referer unless request.post? and id and title
26
+ done = !!done
27
+ title.strip!
28
+
29
+ if id == title
30
+ sync{ LIST[id] = done }
31
+ elsif title != ''
32
+ sync{ LIST.delete(id); LIST[title] = done }
33
+ end
34
+
35
+ redirect_referer
36
+ end
37
+
38
+ def delete
39
+ redirect_referer unless request.post? and id = request[:id]
40
+ sync{ LIST.delete(id) }
41
+ redirect_referer
42
+ end
43
+
44
+ private
45
+
46
+ def sync
47
+ Innate.sync{ LIST.transaction{ yield(LIST) }}
48
+ end
49
+ end
50
+
51
+ Innate.start
@@ -0,0 +1,39 @@
1
+ <form method="post" action="#{ r :create }">
2
+ <fieldset>
3
+ <legend>Create new task</legend>
4
+
5
+ <label for="form_title">Title:</label>
6
+ <input id="form_title" type="text" name="title" />
7
+
8
+ <input type="submit" value="Create" />
9
+ </fieldset>
10
+ </form>
11
+
12
+ <table>
13
+ <?r @list.each do |title, done| ?>
14
+ <tr>
15
+ <form method="post" action="#{ r :update }">
16
+ <input type="hidden" name="id" value="#{ h title }" />
17
+ <td>
18
+ <input type="text" name="title" value="#{ h title }" />
19
+ </td>
20
+ <td>
21
+ <?r if done ?>
22
+ <input type="checkbox" name="done" checked="checked" />
23
+ <?r else ?>
24
+ <input type="checkbox" name="done" />
25
+ <?r end ?>
26
+ </td>
27
+ <td>
28
+ <input type="submit" value="Update" />
29
+ </td>
30
+ </form>
31
+ <form method="post" action="#{ r :delete }">
32
+ <input type="hidden" name="id" value="#{ h title }" />
33
+ <td>
34
+ <input type="submit" value="Delete" />
35
+ </td>
36
+ </form>
37
+ </tr>
38
+ <?r end ?>
39
+ </table>
@@ -0,0 +1,15 @@
1
+ <?xml version='1.0' encoding='utf-8' ?>
2
+ <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
3
+ <html>
4
+ <head>
5
+ <title>MicroWiki <%= h @page %></title>
6
+ <style type="text/css">
7
+ a.exists{ color: #00f; }
8
+ a.missing{ color: #f00; }
9
+ textarea{ width: 90%; height: 20em; }
10
+ </style>
11
+ </head>
12
+ <body>
13
+ <%= @content %>
14
+ </body>
15
+ </html>
@@ -0,0 +1,19 @@
1
+ require 'innate'
2
+ require 'innate/spec'
3
+ require 'yaml/store'
4
+
5
+ base = File.join(File.dirname(__FILE__), '..')
6
+ DB = YAML::Store.new(db_file = "#{base}/spec/wiki.yaml")
7
+
8
+ require "start"
9
+
10
+ Innate.config.app.root = base
11
+
12
+ describe 'Wiki' do
13
+ it 'should have index page' do
14
+ page = Innate::Mock.get('/')
15
+ page.body.should == ''
16
+ end
17
+
18
+ FileUtils.rm_f(db_file)
19
+ end
@@ -0,0 +1,42 @@
1
+ # The minimal _why wiki in Innate with ERB
2
+
3
+ %w[rubygems innate erb maruku yaml/store].each{|l| require(l) }
4
+
5
+ DB = YAML::Store.new('wiki.yaml') unless defined?(DB)
6
+
7
+ class Wiki
8
+ Innate.node '/'
9
+ layout 'wiki'
10
+ provide :html, :engine => :ERB
11
+
12
+ def index(page = 'Home')
13
+ @page = page
14
+ @text = 'foo'
15
+ sync{
16
+ @text = DB[page].to_s.dup
17
+ @text.gsub!(/\[\[(.*?)\]\]/) do
18
+ %(<a href="#{r($1)}" class="#{DB[$1] ? 'exists' : 'missing'}">#{h($1)}</a>)
19
+ end
20
+ }
21
+ end
22
+
23
+ def edit(page)
24
+ @page = page
25
+ @text = sync{ DB[page].to_s }
26
+ end
27
+
28
+ def save
29
+ page, text = request[:page, :text]
30
+ sync{ DB[page] = text } if request.post? and page and text
31
+
32
+ redirect(r(page))
33
+ end
34
+
35
+ private
36
+
37
+ def sync
38
+ Innate.sync{ DB.transaction{ yield }}
39
+ end
40
+ end
41
+
42
+ Innate.start
@@ -0,0 +1,6 @@
1
+ <%= a("< #@page", @page) %>
2
+ <form method="post" action="<%= r :save %>">
3
+ <input type="hidden" name="page" value="<%= h @page %>" />
4
+ <textarea name="text"><%= @text %></textarea>
5
+ <input type="submit" value="Save" />
6
+ </form>
@@ -0,0 +1,12 @@
1
+ <% unless @page == 'Home' %>
2
+ <%= a('< Home', :Home) %>
3
+ <% end %>
4
+
5
+ <h1><%= h @page %></h1>
6
+
7
+ <% if @text.empty? %>
8
+ <%= a("Create #@page", :edit, @page) %>
9
+ <% else %>
10
+ <%= a("Edit #@page", :edit, @page) %>
11
+ <%= Maruku.new(@text).to_html %>
12
+ <% end %>
@@ -0,0 +1,35 @@
1
+ require 'rubygems'
2
+ require 'innate'
3
+
4
+ class Demo
5
+ Innate.node '/'
6
+
7
+ def index
8
+ 'Hello, World!'
9
+ end
10
+
11
+ def empty
12
+ response.status = 405
13
+ ''
14
+ end
15
+ end
16
+
17
+ Innate.start do |mw|
18
+ # Makes sure all requests and responses conform to Rack protocol
19
+ mw.use Rack::Lint
20
+
21
+ # Avoid showing empty failure pages, give information when it happens.
22
+ mw.use Rack::ShowStatus
23
+
24
+ # Catch exceptions inside Innate and give nice status info
25
+ mw.use Rack::ShowExceptions
26
+
27
+ # Log access
28
+ mw.use Rack::CommonLogger
29
+
30
+ # Reload modified files before request
31
+ mw.use Rack::Reloader
32
+
33
+ # Start up the application
34
+ mw.innate
35
+ end
@@ -0,0 +1,11 @@
1
+ require 'innate'
2
+
3
+ class Hello
4
+ Innate.node '/'
5
+
6
+ def index
7
+ 'Hello, World!'
8
+ end
9
+ end
10
+
11
+ Innate.start
@@ -0,0 +1,35 @@
1
+ require 'rubygems'
2
+ require 'innate'
3
+
4
+ class SpecMe
5
+ Innate.node '/'
6
+
7
+ def index
8
+ "I should be at /"
9
+ end
10
+
11
+ def foo
12
+ response['Content-Type'] = 'text/css'
13
+ "I should be at /foo"
14
+ end
15
+ end
16
+
17
+ require 'innate/spec'
18
+
19
+ describe 'An example spec' do
20
+ behaves_like :mock
21
+
22
+ should 'respond to /' do
23
+ got = get('/')
24
+ got.status.should == 200
25
+ got.body.should == "I should be at /"
26
+ got['Content-Type'].should == 'text/html'
27
+ end
28
+
29
+ should 'respond to /foo' do
30
+ got = get('/foo')
31
+ got.status.should == 200
32
+ got.body.should == "I should be at /foo"
33
+ got['Content-Type'].should == 'text/css'
34
+ end
35
+ end