actionpack 0.9.0

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of actionpack might be problematic. Click here for more details.

Files changed (100) hide show
  1. data/CHANGELOG +604 -0
  2. data/MIT-LICENSE +21 -0
  3. data/README +418 -0
  4. data/RUNNING_UNIT_TESTS +14 -0
  5. data/examples/.htaccess +24 -0
  6. data/examples/address_book/index.rhtml +33 -0
  7. data/examples/address_book/layout.rhtml +8 -0
  8. data/examples/address_book_controller.cgi +9 -0
  9. data/examples/address_book_controller.fcgi +6 -0
  10. data/examples/address_book_controller.rb +52 -0
  11. data/examples/address_book_controller.rbx +4 -0
  12. data/examples/benchmark.rb +52 -0
  13. data/examples/benchmark_with_ar.fcgi +89 -0
  14. data/examples/blog_controller.cgi +53 -0
  15. data/examples/debate/index.rhtml +14 -0
  16. data/examples/debate/new_topic.rhtml +22 -0
  17. data/examples/debate/topic.rhtml +32 -0
  18. data/examples/debate_controller.cgi +57 -0
  19. data/install.rb +93 -0
  20. data/lib/action_controller.rb +47 -0
  21. data/lib/action_controller/assertions/action_pack_assertions.rb +166 -0
  22. data/lib/action_controller/assertions/active_record_assertions.rb +65 -0
  23. data/lib/action_controller/base.rb +626 -0
  24. data/lib/action_controller/benchmarking.rb +49 -0
  25. data/lib/action_controller/cgi_ext/cgi_ext.rb +43 -0
  26. data/lib/action_controller/cgi_ext/cgi_methods.rb +91 -0
  27. data/lib/action_controller/cgi_process.rb +123 -0
  28. data/lib/action_controller/filters.rb +279 -0
  29. data/lib/action_controller/flash.rb +65 -0
  30. data/lib/action_controller/layout.rb +143 -0
  31. data/lib/action_controller/request.rb +92 -0
  32. data/lib/action_controller/rescue.rb +94 -0
  33. data/lib/action_controller/response.rb +15 -0
  34. data/lib/action_controller/scaffolding.rb +183 -0
  35. data/lib/action_controller/session/active_record_store.rb +72 -0
  36. data/lib/action_controller/session/drb_server.rb +9 -0
  37. data/lib/action_controller/session/drb_store.rb +31 -0
  38. data/lib/action_controller/support/class_attribute_accessors.rb +57 -0
  39. data/lib/action_controller/support/class_inheritable_attributes.rb +37 -0
  40. data/lib/action_controller/support/clean_logger.rb +10 -0
  41. data/lib/action_controller/support/cookie_performance_fix.rb +121 -0
  42. data/lib/action_controller/support/inflector.rb +70 -0
  43. data/lib/action_controller/templates/rescues/_request_and_response.rhtml +28 -0
  44. data/lib/action_controller/templates/rescues/diagnostics.rhtml +22 -0
  45. data/lib/action_controller/templates/rescues/layout.rhtml +29 -0
  46. data/lib/action_controller/templates/rescues/missing_template.rhtml +2 -0
  47. data/lib/action_controller/templates/rescues/template_error.rhtml +26 -0
  48. data/lib/action_controller/templates/rescues/unknown_action.rhtml +2 -0
  49. data/lib/action_controller/templates/scaffolds/edit.rhtml +6 -0
  50. data/lib/action_controller/templates/scaffolds/layout.rhtml +29 -0
  51. data/lib/action_controller/templates/scaffolds/list.rhtml +24 -0
  52. data/lib/action_controller/templates/scaffolds/new.rhtml +5 -0
  53. data/lib/action_controller/templates/scaffolds/show.rhtml +9 -0
  54. data/lib/action_controller/test_process.rb +194 -0
  55. data/lib/action_controller/url_rewriter.rb +153 -0
  56. data/lib/action_view.rb +40 -0
  57. data/lib/action_view/base.rb +253 -0
  58. data/lib/action_view/helpers/active_record_helper.rb +171 -0
  59. data/lib/action_view/helpers/date_helper.rb +223 -0
  60. data/lib/action_view/helpers/debug_helper.rb +17 -0
  61. data/lib/action_view/helpers/form_helper.rb +176 -0
  62. data/lib/action_view/helpers/form_options_helper.rb +169 -0
  63. data/lib/action_view/helpers/tag_helper.rb +59 -0
  64. data/lib/action_view/helpers/text_helper.rb +129 -0
  65. data/lib/action_view/helpers/url_helper.rb +72 -0
  66. data/lib/action_view/partials.rb +61 -0
  67. data/lib/action_view/template_error.rb +84 -0
  68. data/lib/action_view/vendor/builder.rb +13 -0
  69. data/lib/action_view/vendor/builder/blankslate.rb +21 -0
  70. data/lib/action_view/vendor/builder/xmlbase.rb +143 -0
  71. data/lib/action_view/vendor/builder/xmlevents.rb +63 -0
  72. data/lib/action_view/vendor/builder/xmlmarkup.rb +288 -0
  73. data/rakefile +105 -0
  74. data/test/abstract_unit.rb +9 -0
  75. data/test/controller/action_pack_assertions_test.rb +295 -0
  76. data/test/controller/active_record_assertions_test.rb +118 -0
  77. data/test/controller/cgi_test.rb +142 -0
  78. data/test/controller/cookie_test.rb +38 -0
  79. data/test/controller/filters_test.rb +159 -0
  80. data/test/controller/flash_test.rb +69 -0
  81. data/test/controller/layout_test.rb +49 -0
  82. data/test/controller/redirect_test.rb +44 -0
  83. data/test/controller/render_test.rb +169 -0
  84. data/test/controller/url_test.rb +318 -0
  85. data/test/fixtures/layouts/builder.rxml +3 -0
  86. data/test/fixtures/layouts/standard.rhtml +1 -0
  87. data/test/fixtures/test/_customer.rhtml +1 -0
  88. data/test/fixtures/test/greeting.rhtml +1 -0
  89. data/test/fixtures/test/hello.rxml +4 -0
  90. data/test/fixtures/test/hello_world.rhtml +1 -0
  91. data/test/fixtures/test/hello_xml_world.rxml +11 -0
  92. data/test/fixtures/test/list.rhtml +1 -0
  93. data/test/template/active_record_helper_test.rb +76 -0
  94. data/test/template/date_helper_test.rb +103 -0
  95. data/test/template/form_helper_test.rb +115 -0
  96. data/test/template/form_options_helper_test.rb +174 -0
  97. data/test/template/tag_helper_test.rb +18 -0
  98. data/test/template/text_helper_test.rb +62 -0
  99. data/test/template/url_helper_test.rb +35 -0
  100. metadata +154 -0
@@ -0,0 +1,63 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ #--
4
+ # Copyright 2004 by Jim Weirich (jim@weirichhouse.org).
5
+ # All rights reserved.
6
+
7
+ # Permission is granted for use, copying, modification, distribution,
8
+ # and distribution of modified versions of this work as long as the
9
+ # above copyright notice is included.
10
+ #++
11
+
12
+ require 'builder/xmlmarkup'
13
+
14
+ module Builder #:nodoc:
15
+
16
+ # Create a series of SAX-like XML events (e.g. start_tag, end_tag)
17
+ # from the markup code. XmlEvent objects are used in a way similar
18
+ # to XmlMarkup objects, except that a series of events are generated
19
+ # and passed to a handler rather than generating character-based
20
+ # markup.
21
+ #
22
+ # Usage:
23
+ # xe = Builder::XmlEvents.new(hander)
24
+ # xe.title("HI") # Sends start_tag/end_tag/text messages to the handler.
25
+ #
26
+ # Indentation may also be selected by providing value for the
27
+ # indentation size and initial indentation level.
28
+ #
29
+ # xe = Builder::XmlEvents.new(handler, indent_size, initial_indent_level)
30
+ #
31
+ # == XML Event Handler
32
+ #
33
+ # The handler object must expect the following events.
34
+ #
35
+ # [<tt>start_tag(tag, attrs)</tt>]
36
+ # Announces that a new tag has been found. +tag+ is the name of
37
+ # the tag and +attrs+ is a hash of attributes for the tag.
38
+ #
39
+ # [<tt>end_tag(tag)</tt>]
40
+ # Announces that an end tag for +tag+ has been found.
41
+ #
42
+ # [<tt>text(text)</tt>]
43
+ # Announces that a string of characters (+text+) has been found.
44
+ # A series of characters may be broken up into more than one
45
+ # +text+ call, so the client cannot assume that a single
46
+ # callback contains all the text data.
47
+ #
48
+ class XmlEvents < XmlMarkup #:nodoc:
49
+ def text!(text)
50
+ @target.text(text)
51
+ end
52
+
53
+ def _start_tag(sym, attrs, end_too=false)
54
+ @target.start_tag(sym, attrs)
55
+ _end_tag(sym) if end_too
56
+ end
57
+
58
+ def _end_tag(sym)
59
+ @target.end_tag(sym)
60
+ end
61
+ end
62
+
63
+ end
@@ -0,0 +1,288 @@
1
+ #!/usr/bin/env ruby
2
+ #--
3
+ # Copyright 2004 by Jim Weirich (jim@weirichhouse.org).
4
+ # All rights reserved.
5
+
6
+ # Permission is granted for use, copying, modification, distribution,
7
+ # and distribution of modified versions of this work as long as the
8
+ # above copyright notice is included.
9
+ #++
10
+
11
+ # Provide a flexible and easy to use Builder for creating XML markup.
12
+ # See XmlBuilder for usage details.
13
+
14
+ require 'builder/xmlbase'
15
+
16
+ module Builder #:nodoc:
17
+
18
+ # Create XML markup easily. All (well, almost all) methods sent to
19
+ # an XmlMarkup object will be translated to the equivalent XML
20
+ # markup. Any method with a block will be treated as an XML markup
21
+ # tag with nested markup in the block.
22
+ #
23
+ # Examples will demonstrate this easier than words. In the
24
+ # following, +xm+ is an +XmlMarkup+ object.
25
+ #
26
+ # xm.em("emphasized") # => <em>emphasized</em>
27
+ # xm.em { xmm.b("emp & bold") } # => <em><b>emph &amp; bold</b></em>
28
+ # xm.a("A Link", "href"=>"http://onestepback.org")
29
+ # # => <a href="http://onestepback.org">A Link</a>
30
+ # xm.div { br } # => <div><br/></div>
31
+ # xm.target("name"=>"compile", "option"=>"fast")
32
+ # # => <target option="fast" name="compile"\>
33
+ # # NOTE: order of attributes is not specified.
34
+ #
35
+ # xm.instruct! # <?xml version="1.0" encoding="UTF-8"?>
36
+ # xm.html { # <html>
37
+ # xm.head { # <head>
38
+ # xm.title("History") # <title>History</title>
39
+ # } # </head>
40
+ # xm.body { # <body>
41
+ # xm.comment! "HI" # <!-- HI -->
42
+ # xm.h1("Header") # <h1>Header</h1>
43
+ # xm.p("paragraph") # <p>paragraph</p>
44
+ # } # </body>
45
+ # } # </html>
46
+ #
47
+ # == Notes:
48
+ #
49
+ # * The order that attributes are inserted in markup tags is
50
+ # undefined.
51
+ #
52
+ # * Sometimes you wish to insert text without enclosing tags. Use
53
+ # the <tt>text!</tt> method to accomplish this.
54
+ #
55
+ # Example:
56
+ #
57
+ # xm.div { # <div>
58
+ # xm.text! "line"; xm.br # line<br/>
59
+ # xm.text! "another line"; xmbr # another line<br/>
60
+ # } # </div>
61
+ #
62
+ # * The special XML characters <, >, and & are converted to &lt;,
63
+ # &gt; and &amp; automatically. Use the <tt><<</tt> operation to
64
+ # insert text without modification.
65
+ #
66
+ # * Sometimes tags use special characters not allowed in ruby
67
+ # identifiers. Use the <tt>tag!</tt> method to handle these
68
+ # cases.
69
+ #
70
+ # Example:
71
+ #
72
+ # xml.tag!("SOAP:Envelope") { ... }
73
+ #
74
+ # will produce ...
75
+ #
76
+ # <SOAP:Envelope> ... </SOAP:Envelope>"
77
+ #
78
+ # <tt>tag!</tt> will also take text and attribute arguments (after
79
+ # the tag name) like normal markup methods. (But see the next
80
+ # bullet item for a better way to handle XML namespaces).
81
+ #
82
+ # * Direct support for XML namespaces is now available. If the
83
+ # first argument to a tag call is a symbol, it will be joined to
84
+ # the tag to produce a namespace:tag combination. It is easier to
85
+ # show this than describe it.
86
+ #
87
+ # xml.SOAP :Envelope do ... end
88
+ #
89
+ # Just put a space before the colon in a namespace to produce the
90
+ # right form for builder (e.g. "<tt>SOAP:Envelope</tt>" =>
91
+ # "<tt>xml.SOAP :Envelope</tt>")
92
+ #
93
+ # * XmlMarkup builds the markup in any object (called a _target_)
94
+ # that accepts the <tt><<</tt> method. If no target is given,
95
+ # then XmlMarkup defaults to a string target.
96
+ #
97
+ # Examples:
98
+ #
99
+ # xm = Builder::XmlMarkup.new
100
+ # result = xm.title("yada")
101
+ # # result is a string containing the markup.
102
+ #
103
+ # buffer = ""
104
+ # xm = Builder::XmlMarkup.new(buffer)
105
+ # # The markup is appended to buffer (using <<)
106
+ #
107
+ # xm = Builder::XmlMarkup.new(STDOUT)
108
+ # # The markup is written to STDOUT (using <<)
109
+ #
110
+ # xm = Builder::XmlMarkup.new
111
+ # x2 = Builder::XmlMarkup.new(:target=>xm)
112
+ # # Markup written to +x2+ will be send to +xm+.
113
+ #
114
+ # * Indentation is enabled by providing the number of spaces to
115
+ # indent for each level as a second argument to XmlBuilder.new.
116
+ # Initial indentation may be specified using a third parameter.
117
+ #
118
+ # Example:
119
+ #
120
+ # xm = Builder.new(:ident=>2)
121
+ # # xm will produce nicely formatted and indented XML.
122
+ #
123
+ # xm = Builder.new(:indent=>2, :margin=>4)
124
+ # # xm will produce nicely formatted and indented XML with 2
125
+ # # spaces per indent and an over all indentation level of 4.
126
+ #
127
+ # builder = Builder::XmlMarkup.new(:target=>$stdout, :indent=>2)
128
+ # builder.name { |b| b.first("Jim"); b.last("Weirich) }
129
+ # # prints:
130
+ # # <name>
131
+ # # <first>Jim</first>
132
+ # # <last>Weirich</last>
133
+ # # </name>
134
+ #
135
+ # * The instance_eval implementation which forces self to refer to
136
+ # the message receiver as self is now obsolete. We now use normal
137
+ # block calls to execute the markup block. This means that all
138
+ # markup methods must now be explicitly send to the xml builder.
139
+ # For instance, instead of
140
+ #
141
+ # xml.div { strong("text") }
142
+ #
143
+ # you need to write:
144
+ #
145
+ # xml.div { xml.strong("text") }
146
+ #
147
+ # Although more verbose, the subtle change in semantics within the
148
+ # block was found to be prone to error. To make this change a
149
+ # little less cumbersome, the markup block now gets the markup
150
+ # object sent as an argument, allowing you to use a shorter alias
151
+ # within the block.
152
+ #
153
+ # For example:
154
+ #
155
+ # xml_builder = Builder::XmlMarkup.new
156
+ # xml_builder.div { |xml|
157
+ # xml.stong("text")
158
+ # }
159
+ #
160
+ class XmlMarkup < XmlBase
161
+
162
+ # Create an XML markup builder. Parameters are specified by an
163
+ # option hash.
164
+ #
165
+ # :target=><em>target_object</em>::
166
+ # Object receiving the markup. +out+ must respond to the
167
+ # <tt><<</tt> operator. The default is a plain string target.
168
+ # :indent=><em>indentation</em>::
169
+ # Number of spaces used for indentation. The default is no
170
+ # indentation and no line breaks.
171
+ # :margin=><em>initial_indentation_level</em>::
172
+ # Amount of initial indentation (specified in levels, not
173
+ # spaces).
174
+ #
175
+ def initialize(options={})
176
+ indent = options[:indent] || 0
177
+ margin = options[:margin] || 0
178
+ super(indent, margin)
179
+ @target = options[:target] || ""
180
+ end
181
+
182
+ # Return the target of the builder.
183
+ def target!
184
+ @target
185
+ end
186
+
187
+ def comment!(comment_text)
188
+ _ensure_no_block block_given?
189
+ _special("<!-- ", " -->", comment_text, nil)
190
+ end
191
+
192
+ # Insert an XML declaration into the XML markup.
193
+ #
194
+ # For example:
195
+ #
196
+ # xml.declare! :ELEMENT, :blah, "yada"
197
+ # # => <!ELEMENT blah "yada">
198
+ def declare!(inst, *args, &block)
199
+ _indent
200
+ @target << "<!#{inst}"
201
+ args.each do |arg|
202
+ case arg
203
+ when String
204
+ @target << %{ "#{arg}"}
205
+ when Symbol
206
+ @target << " #{arg}"
207
+ end
208
+ end
209
+ if block_given?
210
+ @target << " ["
211
+ _newline
212
+ _nested_structures(block)
213
+ @target << "]"
214
+ end
215
+ @target << ">"
216
+ _newline
217
+ end
218
+
219
+ # Insert a processing instruction into the XML markup. E.g.
220
+ #
221
+ # For example:
222
+ #
223
+ # xml.instruct!
224
+ # #=> <?xml encoding="UTF-8" version="1.0"?>
225
+ # xml.instruct! :aaa, :bbb=>"ccc"
226
+ # #=> <?aaa bbb="ccc"?>
227
+ #
228
+ def instruct!(directive_tag=:xml, attrs={})
229
+ _ensure_no_block block_given?
230
+ if directive_tag == :xml
231
+ a = { :version=>"1.0", :encoding=>"UTF-8" }
232
+ attrs = a.merge attrs
233
+ end
234
+ _special("<?#{directive_tag}", "?>", nil, attrs)
235
+ end
236
+
237
+ private
238
+
239
+ # NOTE: All private methods of a builder object are prefixed when
240
+ # a "_" character to avoid possible conflict with XML tag names.
241
+
242
+ # Insert text directly in to the builder's target.
243
+ def _text(text)
244
+ @target << text
245
+ end
246
+
247
+ # Insert special instruction.
248
+ def _special(open, close, data=nil, attrs=nil)
249
+ _indent
250
+ @target << open
251
+ @target << data if data
252
+ _insert_attributes(attrs) if attrs
253
+ @target << close
254
+ _newline
255
+ end
256
+
257
+ # Start an XML tag. If <tt>end_too</tt> is true, then the start
258
+ # tag is also the end tag (e.g. <br/>
259
+ def _start_tag(sym, attrs, end_too=false)
260
+ @target << "<#{sym}"
261
+ _insert_attributes(attrs)
262
+ @target << "/" if end_too
263
+ @target << ">"
264
+ end
265
+
266
+ # Insert an ending tag.
267
+ def _end_tag(sym)
268
+ @target << "</#{sym}>"
269
+ end
270
+
271
+ # Insert the attributes (given in the hash).
272
+ def _insert_attributes(attrs)
273
+ return if attrs.nil?
274
+ attrs.each do |k, v|
275
+ @target << %{ #{k}="#{v}"}
276
+ end
277
+ end
278
+
279
+ def _ensure_no_block(got_block)
280
+ if got_block
281
+ fail IllegalBlockError,
282
+ "Blocks are not allowed on XML instructions"
283
+ end
284
+ end
285
+
286
+ end
287
+
288
+ end
@@ -0,0 +1,105 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+ require 'rake/testtask'
4
+ require 'rake/rdoctask'
5
+ require 'rake/packagetask'
6
+ require 'rake/gempackagetask'
7
+ require 'rake/contrib/rubyforgepublisher'
8
+
9
+ PKG_VERSION = "0.9.0"
10
+
11
+ desc "Default Task"
12
+ task :default => [ :test ]
13
+
14
+ # Run the unit tests
15
+
16
+ Rake::TestTask.new { |t|
17
+ t.libs << "test"
18
+ t.pattern = 'test/*/*_test.rb'
19
+ t.verbose = true
20
+ }
21
+
22
+
23
+ # Genereate the RDoc documentation
24
+
25
+ Rake::RDocTask.new { |rdoc|
26
+ rdoc.rdoc_dir = 'doc'
27
+ rdoc.title = "Action Pack -- On rails from request to response"
28
+ rdoc.options << '--line-numbers --inline-source --main README'
29
+ rdoc.rdoc_files.include('README', 'RUNNING_UNIT_TESTS', 'CHANGELOG')
30
+ rdoc.rdoc_files.include('lib/**/*.rb')
31
+ }
32
+
33
+
34
+ # Create compressed packages
35
+
36
+
37
+ dist_dirs = [ "lib", "test", "examples" ]
38
+
39
+ spec = Gem::Specification.new do |s|
40
+ s.platform = Gem::Platform::RUBY
41
+ s.name = 'actionpack'
42
+ s.summary = "Web-flow and rendering framework putting the VC in MVC."
43
+ s.description = %q{Eases web-request routing, handling, and response as a half-way front, half-way page controller. Implemented with specific emphasis on enabling easy unit/integration testing that doesn't require a browser.}
44
+ s.version = PKG_VERSION
45
+
46
+ s.author = "David Heinemeier Hansson"
47
+ s.email = "david@loudthinking.com"
48
+ s.rubyforge_project = "actionpack"
49
+ s.homepage = "http://actionpack.rubyonrails.org"
50
+
51
+ s.has_rdoc = true
52
+ s.requirements << 'none'
53
+ s.require_path = 'lib'
54
+ s.autorequire = 'action_controller'
55
+
56
+ s.files = [ "rakefile", "install.rb", "README", "RUNNING_UNIT_TESTS", "CHANGELOG", "MIT-LICENSE", "examples/.htaccess" ]
57
+ dist_dirs.each do |dir|
58
+ s.files = s.files + Dir.glob( "#{dir}/**/*" ).delete_if { |item| item.include?( "CVS" ) }
59
+ end
60
+ s.files.delete "examples/benchmark.rb"
61
+ s.files.delete "examples/benchmark_with_ar.fcgi"
62
+ end
63
+
64
+ Rake::GemPackageTask.new(spec) do |p|
65
+ p.gem_spec = spec
66
+ p.need_tar = true
67
+ p.need_zip = true
68
+ end
69
+
70
+
71
+ # Publish documentation
72
+ desc "Publish the API documentation"
73
+ task :pdoc => [:rdoc] do
74
+ Rake::SshDirPublisher.new("davidhh@one.textdrive.com", "domains/rubyonrails.org/ap", "doc").upload
75
+ end
76
+
77
+ desc "Publish to RubyForge"
78
+ task :rubyforge do
79
+ Rake::RubyForgePublisher.new('actionpack', 'webster132').upload
80
+ end
81
+
82
+
83
+ desc "Count lines in the main rake file"
84
+ task :lines do
85
+ lines = 0
86
+ codelines = 0
87
+ Dir.foreach("lib/action_controller") { |file_name|
88
+ next unless file_name =~ /.*rb/
89
+
90
+ f = File.open("lib/action_controller/" + file_name)
91
+
92
+ while line = f.gets
93
+ lines += 1
94
+ next if line =~ /^\s*$/
95
+ next if line =~ /^\s*#/
96
+ codelines += 1
97
+ end
98
+ }
99
+ puts "Lines #{lines}, LOC #{codelines}"
100
+ end
101
+
102
+ desc "Publish to RubyForge"
103
+ task :rubyforge do
104
+ Rake::RubyForgePublisher.new('activecontrol', 'webster132').upload
105
+ end