nitro 0.7.0 → 0.8.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (102) hide show
  1. data/AUTHORS +14 -4
  2. data/ChangeLog +192 -1
  3. data/README +50 -6
  4. data/RELEASES +60 -0
  5. data/Rakefile +1 -1
  6. data/bin/cluster.rb +2 -2
  7. data/bin/new_form.rb +1 -1
  8. data/examples/blog/config.rb +5 -4
  9. data/examples/blog/lib/blog.rb +56 -36
  10. data/examples/blog/root/comments.xhtml +5 -2
  11. data/examples/blog/root/entry_form.xhtml +7 -2
  12. data/examples/blog/root/login.xhtml +1 -1
  13. data/examples/blog/root/style.xsl +7 -0
  14. data/examples/og/mock_example.rb +6 -9
  15. data/examples/og/mysql_to_psql.rb +100 -0
  16. data/examples/og/run.rb +8 -17
  17. data/lib/glue.rb +7 -8
  18. data/lib/glue/array.rb +1 -1
  19. data/lib/glue/attribute.rb +86 -0
  20. data/lib/glue/cache.rb +1 -1
  21. data/lib/glue/hash.rb +1 -1
  22. data/lib/glue/inflector.rb +1 -1
  23. data/lib/glue/logger.rb +118 -18
  24. data/lib/glue/mixins.rb +1 -1
  25. data/lib/glue/number.rb +1 -1
  26. data/lib/glue/pool.rb +1 -1
  27. data/lib/glue/property.rb +48 -31
  28. data/lib/glue/string.rb +1 -1
  29. data/lib/glue/time.rb +2 -2
  30. data/lib/glue/validation.rb +400 -0
  31. data/lib/nitro/application.rb +6 -6
  32. data/lib/nitro/builders/form.rb +5 -5
  33. data/lib/nitro/builders/rss.rb +1 -1
  34. data/lib/nitro/builders/xhtml.rb +119 -0
  35. data/lib/nitro/builders/xml.rb +111 -0
  36. data/lib/nitro/config.rb +6 -6
  37. data/lib/nitro/events.rb +1 -1
  38. data/lib/nitro/html.rb +1 -1
  39. data/lib/nitro/markup.rb +15 -20
  40. data/lib/nitro/scaffold.rb +2 -2
  41. data/lib/nitro/server/appserver.rb +3 -3
  42. data/lib/nitro/server/cluster.rb +2 -2
  43. data/lib/nitro/server/dispatcher.rb +2 -2
  44. data/lib/nitro/server/filters/autologin.rb +1 -1
  45. data/lib/nitro/server/fragment.rb +2 -2
  46. data/lib/nitro/server/handlers.rb +2 -2
  47. data/lib/nitro/server/render.rb +17 -15
  48. data/lib/nitro/server/request.rb +6 -6
  49. data/lib/nitro/server/script.rb +2 -2
  50. data/lib/nitro/server/server.rb +2 -2
  51. data/lib/nitro/server/session.rb +6 -6
  52. data/lib/nitro/server/shaders.rb +2 -2
  53. data/lib/nitro/server/webrick.rb +1 -1
  54. data/lib/nitro/sitemap.rb +2 -2
  55. data/lib/nitro/uri.rb +1 -1
  56. data/lib/nitro/version.rb +7 -5
  57. data/lib/og.rb +95 -129
  58. data/lib/og/backend.rb +47 -46
  59. data/lib/og/backends/mysql.rb +64 -63
  60. data/lib/og/backends/psql.rb +73 -72
  61. data/lib/og/connection.rb +7 -8
  62. data/lib/og/enchant.rb +80 -0
  63. data/lib/og/meta.rb +21 -21
  64. data/lib/og/mock.rb +31 -88
  65. data/lib/og/version.rb +6 -5
  66. data/lib/parts/README +9 -0
  67. data/lib/parts/content.rb +23 -9
  68. data/test/glue/tc_attribute.rb +22 -0
  69. data/test/glue/tc_cache.rb +4 -6
  70. data/test/glue/tc_hash.rb +2 -2
  71. data/test/glue/tc_logger.rb +36 -0
  72. data/test/glue/tc_numbers.rb +2 -2
  73. data/test/glue/tc_property_mixins.rb +35 -4
  74. data/test/glue/tc_strings.rb +32 -32
  75. data/test/glue/tc_validation.rb +186 -0
  76. data/test/nitro/builders/tc_xhtml.rb +38 -0
  77. data/test/nitro/builders/tc_xml.rb +47 -0
  78. data/test/nitro/server/tc_request.rb +2 -2
  79. data/test/nitro/server/tc_session.rb +1 -1
  80. data/test/nitro/tc_sitemap.rb +1 -1
  81. data/test/nitro/ui/tc_pager.rb +1 -10
  82. data/test/tc_og.rb +3 -3
  83. data/vendor/blankslate.rb +53 -0
  84. data/vendor/extensions/_base.rb +153 -0
  85. data/vendor/extensions/_template.rb +36 -0
  86. data/vendor/extensions/all.rb +21 -0
  87. data/vendor/extensions/array.rb +68 -0
  88. data/vendor/extensions/binding.rb +224 -0
  89. data/vendor/extensions/class.rb +50 -0
  90. data/vendor/extensions/continuation.rb +71 -0
  91. data/vendor/extensions/enumerable.rb +250 -0
  92. data/vendor/extensions/hash.rb +23 -0
  93. data/vendor/extensions/io.rb +58 -0
  94. data/vendor/extensions/kernel.rb +42 -0
  95. data/vendor/extensions/module.rb +114 -0
  96. data/vendor/extensions/numeric.rb +230 -0
  97. data/vendor/extensions/object.rb +164 -0
  98. data/vendor/extensions/ostruct.rb +41 -0
  99. data/vendor/extensions/string.rb +316 -0
  100. data/vendor/extensions/symbol.rb +28 -0
  101. metadata +35 -13
  102. data/lib/glue/property.rb.old +0 -307
@@ -0,0 +1,38 @@
1
+ $:.unshift File.join(File.dirname(__FILE__), '..', '..', '..', 'lib')
2
+
3
+ require 'test/unit'
4
+ require 'nitro/builders/xhtml'
5
+
6
+ class TC_BuildersXhtml < Test::Unit::TestCase # :nodoc: all
7
+
8
+ def test_options
9
+ x = N::XhtmlString.new
10
+ options = ['Male', 'Female']
11
+ x.select(:name => 'sex') do
12
+ x.options(options, 1)
13
+ end
14
+ res = '<select name="sex"><option value="0">Male</option>' +
15
+ '<option value="1" selected="1">Female</option></select>'
16
+ assert_equal res, x
17
+
18
+ x = N::XhtmlString.new
19
+ options = ['Male', 'Female']
20
+ x.select('-- Select sex --', :name => 'sex') do
21
+ x.options(options, 1)
22
+ end
23
+ res = '<select name="sex"><option>-- Select sex --</option>' +
24
+ '<option value="0">Male</option>' +
25
+ '<option value="1" selected="1">Female</option></select>'
26
+ assert_equal res, x
27
+
28
+ x = N::XhtmlString.new
29
+ options = {'Male' => 'm', 'Female' => 'f'}
30
+ x.select(:name => 'sex') do
31
+ x.options(options, 'm')
32
+ end
33
+ res = '<select name="sex"><option value="m" selected="1">Male</option>' +
34
+ '<option value="f">Female</option></select>'
35
+ assert_equal res, x
36
+ end
37
+
38
+ end
@@ -0,0 +1,47 @@
1
+ $:.unshift File.join(File.dirname(__FILE__), '..', '..', '..', 'lib')
2
+
3
+ require 'test/unit'
4
+ require 'nitro/builders/xml'
5
+
6
+ class TC_BuildersXml < Test::Unit::TestCase # :nodoc: all
7
+
8
+ def test_string
9
+ x = N::XmlString.new
10
+
11
+ x.start_tag('html').
12
+ start_tag('title').text('hello').end_tag('title').
13
+ end_tag('html')
14
+
15
+ assert_equal '<html><title>hello</title></html>', x
16
+ end
17
+
18
+ def test_missing
19
+ x = N::XmlString.new
20
+ x.b('This is bold')
21
+ assert_equal '<b>This is bold</b>', x
22
+
23
+ x = N::XmlString.new
24
+ x.a('Navel', :href => 'http://www.navel.gr', :target => '_blank')
25
+ assert_equal '<a target="_blank" href="http://www.navel.gr">Navel</a>', x
26
+
27
+
28
+ x = N::XmlString.new
29
+ x.b {
30
+ x.i 'Hello', :class =>'new'
31
+ x.p 'Paragraph'
32
+ }
33
+ assert_equal '<b><i class="new">Hello</i><p>Paragraph</p></b>', x
34
+ end
35
+
36
+ def test_xml_builder
37
+ buffer = ''
38
+ x = N::XmlBuilder.new(buffer)
39
+
40
+ x.start_tag('html').
41
+ start_tag('title').text('hello').end_tag('title').
42
+ end_tag('html')
43
+
44
+ assert_equal '<html><title>hello</title></html>', buffer
45
+ end
46
+
47
+ end
@@ -2,7 +2,7 @@
2
2
 
3
3
  require "test/unit"
4
4
 
5
- require "glue/logger"; $log = Logger.new(STDERR) unless $log
5
+ require "glue/logger"
6
6
 
7
7
  require "nitro/server/cookie"
8
8
  require "nitro/server/request"
@@ -67,4 +67,4 @@ class TC_Request < Test::Unit::TestCase
67
67
  assert_equal(nil, request.get_tx_entity())
68
68
  end
69
69
 
70
- end
70
+ end
@@ -31,4 +31,4 @@ class TC_N2_Web_Server_Session < Test::Unit::TestCase
31
31
  assert_not_equal(id1, id6)
32
32
  end
33
33
 
34
- end
34
+ end
@@ -2,7 +2,7 @@
2
2
 
3
3
  require "test/unit"
4
4
 
5
- require "glue/logger"; $log = Logger.new(STDERR) unless $log
5
+ require "glue/logger"
6
6
 
7
7
  require "nitro/sitemap"
8
8
 
@@ -2,7 +2,7 @@
2
2
 
3
3
  require "test/unit"
4
4
 
5
- require "glue/logger"; $log = Logger.new(STDERR) unless $log
5
+ require "glue/logger"
6
6
 
7
7
  require "og"
8
8
  require "nitro/ui/pager"
@@ -22,15 +22,6 @@ end
22
22
  class TC_N_UI_Pager < Test::Unit::TestCase
23
23
 
24
24
  def setup
25
- =begin
26
- $og = Og::Database.new(
27
- :addres => "localhost",
28
- :database => "testdb",
29
- :user => "root",
30
- # :password => "navelrulez",
31
- :connection_count => 2
32
- )
33
- =end
34
25
  end
35
26
 
36
27
  def teardown
@@ -1,7 +1,7 @@
1
- require "test/unit"
1
+ $:.unshift File.join(File.dirname(__FILE__), '..', 'lib')
2
2
 
3
- require "glue/logger"; $log = Logger.new(STDERR) unless $log
4
- require "og"
3
+ require 'test/unit'
4
+ require 'og'
5
5
 
6
6
  module Test # :nodoc: all
7
7
 
@@ -0,0 +1,53 @@
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
+ module Builder #:nodoc:
12
+
13
+ # BlankSlate provides an abstract base class with no predefined
14
+ # methods (except for <tt>\_\_send__</tt> and <tt>\_\_id__</tt>).
15
+ # BlankSlate is useful as a base class when writing classes that
16
+ # depend upon <tt>method_missing</tt> (e.g. dynamic proxies).
17
+ class BlankSlate #:nodoc:
18
+ class << self
19
+ def hide(name)
20
+ undef_method name if
21
+ instance_methods.include?(name.to_s) and
22
+ name !~ /^(__|instance_eval)/
23
+ end
24
+ end
25
+
26
+ instance_methods.each { |m| hide(m) }
27
+ end
28
+ end
29
+
30
+ # Since Ruby is very dynamic, methods added to the ancestors of
31
+ # BlankSlate <em>after BlankSlate is defined</em> will show up in the
32
+ # list of available BlankSlate methods. We handle this by defining a hook in the Object and Kernel classes that will hide any defined
33
+ module Kernel #:nodoc:
34
+ class << self
35
+ alias_method :blank_slate_method_added, :method_added
36
+ def method_added(name)
37
+ blank_slate_method_added(name)
38
+ return if self != Kernel
39
+ Builder::BlankSlate.hide(name)
40
+ end
41
+ end
42
+ end
43
+
44
+ class Object #:nodoc:
45
+ class << self
46
+ alias_method :blank_slate_method_added, :method_added
47
+ def method_added(name)
48
+ blank_slate_method_added(name)
49
+ return if self != Object
50
+ Builder::BlankSlate.hide(name)
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,153 @@
1
+
2
+ #
3
+ # This file is 'required' by all files that implement standard class
4
+ # extensions as part of the "Ruby/Extensions" project.
5
+ #
6
+ # The "Extensions" project requires 1.8.0 or greater to run, as it is too
7
+ # much hassle at the moment to consider supporting older versions. That may
8
+ # one day be implemented if demand is there. One option would be to require
9
+ # "shim", so that we can assume all 1.8 library methods are implemented.
10
+ #
11
+ # This file is only of interest to developers of the package, so no detailed
12
+ # documentation is included here. However, by way of introduction, this is what
13
+ # it's all about. Each method that is implemented as part of this package is
14
+ # done so through a framework implemented in this file. Take the following
15
+ # simple example:
16
+ #
17
+ # ExtensionsProject.implement(Integer, :even?, :instance) do
18
+ # class Integer
19
+ # #
20
+ # # RDoc comments.
21
+ # #
22
+ # def even?
23
+ # self % 2 == 0
24
+ # end
25
+ # end
26
+ # end
27
+ #
28
+ # This purposes of this are as follows:
29
+ # - if the intended method (in this case IO.write) is already defined,
30
+ # we don't want to overwrite it (we issue a warning and move on)
31
+ # - if the intended method is _not_ implemented as a result of the block,
32
+ # we have not done as we said, and an error is raised
33
+ # - the ExtensionsProject class gathers information on which methods have
34
+ # been implemented, making for a very handy command-line reference (+rbxtm+)
35
+ #
36
+ # The <tt>ExtensionsProject.implement</tt> method is responsible for ensuring
37
+ # these are so. It gives us documentation, and some assurance that the
38
+ # extensions are doing what we say they are doing.
39
+ #
40
+
41
+ # :enddoc:
42
+
43
+ #
44
+ # For what reason does Ruby define Module#methods, Module#instance_methods,
45
+ # and Module#method_defined?, but not Module#instance_method_defined? ?
46
+ #
47
+ # No matter, extending standard classes is the name of the game here.
48
+ #
49
+ class Module
50
+ if Module.method_defined?(:instance_method_defined?)
51
+ STDERR.puts "Warning: Module#instance_method_defined? already defined; not overwriting"
52
+ else
53
+ def instance_method_defined?(_method)
54
+ instance_methods(true).find { |m| m == _method.to_s }
55
+ end
56
+ end
57
+
58
+ if Module.method_defined?(:module_method_defined?)
59
+ STDERR.puts "Warning: Module#module_method_defined? already defined; not overwriting"
60
+ else
61
+ def module_method_defined?(_method)
62
+ singleton_methods(true).find { |m| m == _method.to_s }
63
+ end
64
+ end
65
+ end
66
+
67
+
68
+ class ExtensionsProject
69
+
70
+ class << ExtensionsProject
71
+ @@extension_methods = []
72
+
73
+ #
74
+ # The list of methods implemented in this project.
75
+ #
76
+ def extension_methods
77
+ @@extension_methods
78
+ end
79
+
80
+ #
81
+ # Return the name of the project. To be used in error messages, etc., for
82
+ # consistency.
83
+ #
84
+ def project_name
85
+ "Ruby/Extensions"
86
+ end
87
+
88
+ #
89
+ # Wraps around the implementation of a method, emitting a warning if the
90
+ # method is already defined. Returns true to indicate - false to indicate
91
+ # failure (i.e. method is already defined). Raises an error if the
92
+ # specified method is not actually implemented by the block.
93
+ #
94
+ def implement(_module, _method, _type=:instance)
95
+ raise "Internal error: #{__FILE__}:#{__LINE__}" unless
96
+ _module.is_a? Module and
97
+ _method.is_a? Symbol and
98
+ _type == :instance or _type == :class or _type == :module
99
+
100
+ fullname = _module.to_s + string_rep(_type) + _method.to_s
101
+
102
+ if _defined?(_module, _method, _type)
103
+ STDERR.puts "#{project_name}: #{fullname} is already defined; not overwriting"
104
+ return false
105
+ else
106
+ yield # Perform the block; presumably a method implementation.
107
+ if _method == :initialize and _type == :instance
108
+ # Special case; we can't verify this.
109
+ @@extension_methods<< "#{_module}::new"
110
+ else
111
+ unless _defined?(_module, _method, _type)
112
+ raise "#{project_name}: internal error: was supposed to implement " +
113
+ "#{fullname}, but it didn't!"
114
+ end
115
+ @@extension_methods << fullname
116
+ end
117
+ return true
118
+ end
119
+ end
120
+
121
+
122
+ # See whether the given module implements the given method, taking account
123
+ # of the type (class/instance) required.
124
+ def _defined?(_module, _method, _type)
125
+ case _type
126
+ when :instance
127
+ _module.instance_method_defined?(_method) # See definition above.
128
+ when :class, :module
129
+ _module.module_method_defined?(_method) # See definition above.
130
+ end
131
+ end
132
+ private :_defined?
133
+
134
+
135
+ # Return the string representation of the given method type.
136
+ def string_rep(method_type)
137
+ case method_type
138
+ when :instance then "#"
139
+ when :class then "."
140
+ when :module then "."
141
+ else
142
+ nil
143
+ end
144
+ end
145
+ private :string_rep
146
+ end
147
+ end # class ExtensionsProject
148
+
149
+
150
+ if VERSION < "1.8.0"
151
+ raise "#{ExtensionsProject.project_name} requires Ruby 1.8.0 at least (for now)"
152
+ end
153
+
@@ -0,0 +1,36 @@
1
+ #!/usr/local/bin/ruby -w
2
+ # A template for new files in the project; of no interest to end users. An
3
+ # error will be raised if you +require+ it.
4
+ #--
5
+ # :enddoc:
6
+ #
7
+ # == extensions/XXX.rb
8
+ #
9
+ # Adds methods to the builtin XXX class.
10
+ #
11
+
12
+ raise "Do not load this file!"
13
+
14
+ require "extensions/_base"
15
+
16
+ #
17
+ # * Enumerable#build_hash
18
+ #
19
+ ExtensionsProject.implement(Enumerable, :build_hash) do
20
+ module Enumerable
21
+ #
22
+ # Like #map/#collect, but it generates a Hash.
23
+ #
24
+ # [1,5,11].build_hash { |x| [x, x**2] }
25
+ # => { 1 => 2, 5 => 25, 11 => 121 }
26
+ #
27
+ def build_hash
28
+ result = {}
29
+ self.each do |elt|
30
+ key, value = yield elt
31
+ result[key] = value
32
+ end
33
+ result
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,21 @@
1
+ #
2
+ # == extensions/all.rb
3
+ #
4
+ # Require this file in order to access all of the standard class extensions
5
+ # available, or require individual extension files to narrow the selection.
6
+ #
7
+
8
+ require 'extensions/array.rb'
9
+ require 'extensions/binding.rb'
10
+ require 'extensions/class.rb'
11
+ require 'extensions/continuation.rb'
12
+ require 'extensions/enumerable.rb'
13
+ require 'extensions/hash.rb'
14
+ require 'extensions/io.rb'
15
+ require 'extensions/kernel.rb'
16
+ require 'extensions/module.rb'
17
+ require 'extensions/numeric.rb'
18
+ require 'extensions/object.rb'
19
+ require 'extensions/ostruct.rb'
20
+ require 'extensions/string.rb'
21
+ require 'extensions/symbol.rb'
@@ -0,0 +1,68 @@
1
+ #!/usr/local/bin/ruby -w
2
+ #
3
+ # == extensions/array.rb
4
+ #
5
+ # Adds methods to the builtin Array class.
6
+ #
7
+
8
+ require "extensions/_base"
9
+
10
+ #
11
+ # * Array#select!
12
+ #
13
+ ExtensionsProject.implement(Array, :select!) do
14
+ class Array
15
+ #
16
+ # In-place version of Array#select. (Counterpart to, and opposite of, the
17
+ # built-in #reject!)
18
+ #
19
+ def select!
20
+ reject! { |e| not yield(e) }
21
+ end
22
+ end
23
+ end
24
+
25
+
26
+ #
27
+ # * Array#only
28
+ #
29
+ ExtensionsProject.implement(Array, :only) do
30
+ class Array
31
+ #
32
+ # Returns the _only_ element in the array. Raises an IndexError if the array's size is not
33
+ # 1.
34
+ #
35
+ # [5].only # -> 5
36
+ # [1,2,3].only # -> IndexError
37
+ # [].only # -> IndexError
38
+ #
39
+ def only
40
+ unless size == 1
41
+ raise IndexError, "Array#only called on non-single-element array"
42
+ end
43
+ first
44
+ end
45
+ end
46
+ end
47
+
48
+ #
49
+ # * Array#rand
50
+ #
51
+ ExtensionsProject.implement(Array, :rand) do
52
+ class Array
53
+ #
54
+ # Return a randomly-chosen (using Kernel.rand) element from the array.
55
+ #
56
+ # arr = [48, 71, 3, 39, 15]
57
+ # arr.rand # -> 71
58
+ # arr.rand # -> 39
59
+ # arr.rand # -> 48
60
+ # # etc.
61
+ #
62
+ def rand
63
+ idx = Kernel.rand(size)
64
+ at(idx)
65
+ end
66
+ end
67
+ end
68
+