nitro 0.6.0 → 0.7.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (59) hide show
  1. data/ChangeLog +175 -0
  2. data/README +41 -7
  3. data/RELEASES +24 -0
  4. data/Rakefile +5 -7
  5. data/bin/new_app.rb +26 -4
  6. data/bin/new_form.rb +54 -0
  7. data/bin/proto/config.rb +3 -3
  8. data/bin/proto/root/index.xhtml +2 -34
  9. data/bin/proto/root/style.css +4 -70
  10. data/bin/proto/root/style.xsl +8 -39
  11. data/doc/tutorial.txt +5 -0
  12. data/examples/blog/app.rb +2 -1
  13. data/examples/blog/config.rb +7 -2
  14. data/examples/blog/root/style.xsl +1 -2
  15. data/examples/flash/README +34 -0
  16. data/examples/flash/app.rb +20 -0
  17. data/examples/flash/config.rb +38 -0
  18. data/examples/flash/lib/flash.rb +40 -0
  19. data/examples/flash/root/index.xhtml +25 -0
  20. data/examples/flash/root/show_inline_text.xhtml +12 -0
  21. data/examples/flash/tmp.swf +0 -0
  22. data/examples/og/README +7 -0
  23. data/examples/og/mock_example.rb +58 -0
  24. data/examples/og/run.rb +9 -5
  25. data/examples/tiny/root/include.xhtml +3 -0
  26. data/examples/tiny/root/index.xhtml +2 -1
  27. data/lib/glue/property.rb +166 -107
  28. data/lib/glue/property.rb.old +307 -0
  29. data/lib/nitro/builders/form.rb +26 -17
  30. data/lib/nitro/events.rb +1 -1
  31. data/lib/nitro/markup.rb +120 -0
  32. data/lib/nitro/server/cookie.rb +1 -1
  33. data/lib/nitro/server/dispatcher.rb +5 -6
  34. data/lib/nitro/server/filters.rb +1 -1
  35. data/lib/nitro/server/render.rb +33 -29
  36. data/lib/nitro/server/shaders.rb +32 -3
  37. data/lib/nitro/server/user.rb +1 -1
  38. data/lib/nitro/server/webrick.rb +9 -4
  39. data/lib/nitro/ui/popup.rb +1 -1
  40. data/lib/nitro/ui/select.rb +1 -1
  41. data/lib/nitro/ui/tabs.rb +1 -1
  42. data/lib/nitro/version.rb +2 -2
  43. data/lib/og.rb +17 -6
  44. data/lib/og/backend.rb +34 -4
  45. data/lib/og/backends/mysql.rb +3 -17
  46. data/lib/og/backends/psql.rb +5 -17
  47. data/lib/og/meta.rb +41 -26
  48. data/lib/og/mock.rb +223 -0
  49. data/lib/og/version.rb +2 -2
  50. data/lib/parts/content.rb +61 -0
  51. data/test/glue/{tc_properties.rb → tc_property.rb} +0 -1
  52. data/test/glue/tc_property_mixins.rb +62 -0
  53. data/test/og/tc_lifecycle.rb +107 -0
  54. data/test/tc_og.rb +31 -4
  55. data/vendor/README +6 -0
  56. data/vendor/binding_of_caller.rb +81 -0
  57. data/vendor/breakpoint.rb +526 -0
  58. data/vendor/breakpoint_client.rb +157 -0
  59. metadata +135 -95
@@ -0,0 +1,40 @@
1
+ # code:
2
+ # * George Moschovitis <gm@navel.gr>
3
+ #
4
+ # (c) 2004 Navel, all rights reserved.
5
+ # $Id: flash.rb 189 2004-12-13 21:38:05Z gmosx $
6
+
7
+ require 'nitro/service'
8
+ require 'ming/ming'
9
+
10
+ module N
11
+
12
+
13
+ # = FlashService
14
+ #
15
+ class FlashService < N::Service
16
+ include Ming
17
+
18
+ SOURCE_FILE = __FILE__
19
+
20
+ def show_text
21
+ create_flash
22
+ end
23
+
24
+ private
25
+
26
+ def create_flash
27
+ m = SWFMovie.new
28
+ f = SWFBrowserFont.new('_serif')
29
+ t = SWFTextField.new
30
+ t.set_font(f)
31
+ t.add_string(@params['text'])
32
+ m.add(t)
33
+ @response.header['Content-Type'] = 'application/x-shockwave-flash'
34
+ m.save('tmp.swf')
35
+ @out = File.read('tmp.swf')
36
+ end
37
+
38
+ end
39
+
40
+ end # module
@@ -0,0 +1,25 @@
1
+ <?xml version="1.0"?>
2
+
3
+ <html>
4
+
5
+ <h1>Dynamic flash generation.</h1>
6
+
7
+ <p>
8
+ <h3>Implemented as an action</h3>
9
+ <form name="t1" action="show_text">
10
+ Enter some text here:<br />
11
+ <input type="text" name="text" /><br />
12
+ <input type="submit" />
13
+ </form>
14
+ </p>
15
+
16
+ <p>
17
+ <h3>Implemented inline in the template action</h3>
18
+ <form name="t1" action="show_inline_text">
19
+ Enter some text here:<br />
20
+ <input type="text" name="text" /><br />
21
+ <input type="submit" />
22
+ </form>
23
+ </p>
24
+
25
+ </html>
@@ -0,0 +1,12 @@
1
+ <?xml version="1.0"?>
2
+
3
+ <!--
4
+ This template is transormed to a template inside the FlashService.
5
+ -->
6
+ <root>
7
+ <?r
8
+ # just call the method in the service.
9
+ create_flash
10
+ ?>
11
+ </root>
12
+
Binary file
data/examples/og/README CHANGED
@@ -1,4 +1,11 @@
1
1
  = Og Example
2
2
 
3
+ == run.rb
4
+
3
5
  A simple example that demonstrates some Og features. The example
4
6
  automatically creates a 'test' database.
7
+
8
+ == mock_example.rb
9
+
10
+ Demonstrates how easily the Og infrastructure can be mocked,
11
+ for easy test unit writing.
@@ -0,0 +1,58 @@
1
+ # = Og Mocking Example
2
+ #
3
+ # A simple example to demonstrate how to mock Og.
4
+ # Very useful in test units.
5
+ #
6
+ # code:
7
+ # * George Moschovitis <gm@navel.gr>
8
+ #
9
+ # (c) 2004 Navel, all rights reserved.
10
+ # $Id: run.rb 185 2004-12-10 13:29:09Z gmosx $
11
+
12
+ $LOAD_PATH.unshift '../../lib'
13
+
14
+ require 'rubygems'
15
+ require 'flexmock'
16
+ require 'og'
17
+ require 'og/mock'
18
+ require 'logger'
19
+
20
+ $log = Logger.new($stderr)
21
+
22
+ class Article
23
+ prop_accessor :body, String
24
+
25
+ def initialize(body = nil)
26
+ @body = body
27
+ end
28
+ end
29
+
30
+ class SimpleTest < Test::Unit::TestCase
31
+
32
+ def setup
33
+ $og = Og::MockDatabase.new
34
+ end
35
+
36
+ def teardown
37
+ $og = nil
38
+ end
39
+
40
+ def test_me
41
+ mocks = [
42
+ Article.new('body1'),
43
+ Article.new('body2'),
44
+ Article.new('body3')
45
+ ]
46
+ $og.mock_handle(:load_all) { |klass, extrasql| mocks }
47
+
48
+ # differnt ways to call the mocked method...
49
+ puts 'Here are the articles:', Article.all
50
+ puts 'Here are the articles:', Article.load_all
51
+ puts 'Here are the articles:', $og.load_all(Article)
52
+
53
+ # 3 times called
54
+ assert_equal(3, $og.mock_count(:load_all))
55
+ end
56
+
57
+ end
58
+
data/examples/og/run.rb CHANGED
@@ -6,7 +6,7 @@
6
6
  # * George Moschovitis <gm@navel.gr>
7
7
  #
8
8
  # (c) 2004 Navel, all rights reserved.
9
- # $Id: run.rb 185 2004-12-10 13:29:09Z gmosx $
9
+ # $Id: run.rb 198 2004-12-22 11:26:59Z gmosx $
10
10
 
11
11
  $:.unshift "../../lib"
12
12
 
@@ -103,7 +103,7 @@ class Category
103
103
  prop_accessor :body, String
104
104
 
105
105
  # define a 'many to many' relation.
106
- many_to_many Article
106
+ many_to_many :articles, Article
107
107
 
108
108
  def initialize(title = nil)
109
109
  @title = title
@@ -141,7 +141,6 @@ end
141
141
  # Initialize a logger.
142
142
 
143
143
  $log = Logger.new(STDERR);
144
-
145
144
  # Og configuration.
146
145
  config = {
147
146
  :address => "localhost",
@@ -199,9 +198,11 @@ c2.article_oid = a1.oid
199
198
  # managed objects).
200
199
  $og << c2
201
200
 
201
+ # an alternative (easier and cooler) way to add children in a
202
+ # has_many relation:
202
203
  c3 = ArticleComment.new("Comment 3")
203
- c3.article = a1
204
- c3.save!
204
+ # add_comment is automatically added by Og.
205
+ a1.add_comment(c3)
205
206
 
206
207
  puts "\n\n"
207
208
  puts "* Print all all comments for article 1:"
@@ -287,4 +288,7 @@ puts '---'
287
288
 
288
289
  article.categories.each { |c| puts c.title }
289
290
 
291
+ # create and save the article in one step.
292
+ article = Article.create("title", "body")
290
293
 
294
+ puts '--', article.oid
@@ -0,0 +1,3 @@
1
+ <p>
2
+ this is a <b>statically</b> included file.
3
+ </p>
@@ -33,6 +33,7 @@
33
33
  <p>
34
34
  Counter: #{session[:counter]}
35
35
  </p>
36
-
36
+ <br />
37
+ <?include href="include.xhtml"?>
37
38
 
38
39
  </html>
data/lib/glue/property.rb CHANGED
@@ -2,10 +2,9 @@
2
2
  # * George Moschovitis <gm@navel.gr>
3
3
  # design:
4
4
  # * Anastastios Koutoumanos <ak@navel.gr>
5
- # * Elias Karakoulakis <ekarak@ktismata.com>
6
5
  #
7
6
  # (c) 2004 Navel, all rights reserved.
8
- # $Id: property.rb 185 2004-12-10 13:29:09Z gmosx $
7
+ # $Id: property.rb 200 2004-12-27 11:24:41Z gmosx $
9
8
 
10
9
  require "glue/array"
11
10
  require "glue/hash"
@@ -25,10 +24,8 @@ module G
25
24
  #
26
25
  #--
27
26
  # TODO:
28
- # Inject only the really needd methods into Module.
29
27
  # Perhaps a sync is needed in evals (!!!!)
30
28
  #++
31
- #
32
29
  class Property
33
30
  # the symbol of the property
34
31
  attr_accessor :symbol
@@ -36,7 +33,7 @@ class Property
36
33
  attr_accessor :name
37
34
  # the class of the property
38
35
  attr_accessor :klass
39
- # additional metadata (like sql declaratio, sql index, etc)
36
+ # additional metadata (like sql declaration, sql index, etc)
40
37
  attr_accessor :meta
41
38
 
42
39
  def initialize(symbol, klass, meta = {})
@@ -52,6 +49,119 @@ class Property
52
49
  def to_s
53
50
  return name
54
51
  end
52
+
53
+ end
54
+
55
+ # = PropertyUtils
56
+ #
57
+ # A collection of Property related utility methods.
58
+ #
59
+ module PropertyUtils
60
+
61
+ # Add accessors to the properties to the given target
62
+ # (Module or Class). For simplicity also create the
63
+ # meta accessors.
64
+ #--
65
+ # gmosx: Perhaps we 'll optimize this in the future.
66
+ #++
67
+ def self.enchant(target)
68
+ unless target.singleton_methods.include?('__props')
69
+ target.module_eval <<-"end_eval", __FILE__, __LINE__
70
+ @@__meta = G::SafeHash.new
71
+ @@__props = G::SafeArray.new
72
+
73
+ def self.__props
74
+ @@__props
75
+ end
76
+
77
+ def self.__props=(props)
78
+ @@__props = props
79
+ end
80
+
81
+ def self.__meta
82
+ @@__meta
83
+ end
84
+
85
+ def self.__meta=(meta)
86
+ @@__meta = meta
87
+ end
88
+ end_eval
89
+ end
90
+ end
91
+
92
+ # Copy properties from src (Module or Class) to dest.
93
+ #
94
+ def self.copy_props(src, dest)
95
+ src.__props.each do |p|
96
+ add_prop(dest, p)
97
+ end
98
+
99
+ # copy the metadata.
100
+ src.__meta.each do |k, val|
101
+ val.each { |v| dest.meta(k, v) } if val
102
+ end
103
+ end
104
+
105
+ # Add the property to the target (Class or Module)
106
+ #
107
+ def self.add_prop(target, prop)
108
+ if idx = target.__props.index(prop)
109
+ # override in case of duplicates. Keep the order of the props.
110
+ target.__props[idx] = prop
111
+ else
112
+ target.__props << prop
113
+ end
114
+
115
+ # Precompile the property read/write methods
116
+
117
+ s, klass = prop.symbol, prop.klass
118
+
119
+ if prop.meta[:reader]
120
+ target.module_eval %{
121
+ def #{s}
122
+ return @#{s}
123
+ end
124
+ }
125
+ end
126
+
127
+ # gmosx: __force_xxx reuses xxx= to allow for easier
128
+ # overrides.
129
+ if prop.meta[:writer]
130
+ target.module_eval %{
131
+ #{prop_setter(prop)}
132
+
133
+ def __force_#{s}(val)
134
+ self.#{s}=(} + case klass.name
135
+ when Fixnum.name
136
+ "val.to_i()"
137
+ when String.name
138
+ "val.to_s()"
139
+ when Float.name
140
+ "val.to_f()"
141
+ when Time.name
142
+ "Time.parse(val.to_s())"
143
+ when TrueClass.name, FalseClass.name
144
+ "val.to_i() > 0"
145
+ else
146
+ "val"
147
+ end + %{)
148
+ end
149
+ }
150
+ end
151
+ end
152
+
153
+ # Generates the property setter code. Can be overriden
154
+ # to support extra functionality (example: markup)
155
+ #
156
+ def self.prop_setter(prop)
157
+ s = prop.symbol
158
+ %{
159
+ def #{s}=(val)
160
+ @#{s} = val
161
+ end
162
+ }
163
+ end
164
+
55
165
  end
56
166
 
57
167
  end # module
@@ -90,36 +200,55 @@ class Module
90
200
  end
91
201
  end
92
202
 
93
- unless self.methods.include?("__props")
94
- eval %{
95
- # Properties
96
- # An array is used to enforce order.
97
- def __props
98
- @__props
99
- end
203
+ G::PropertyUtils.enchant(self)
100
204
 
101
- def __props=(props)
102
- @__props = props
205
+ if self.is_a?(Class)
206
+
207
+ # Add some extra code to append features to
208
+ # subclasses.
209
+ self.module_eval <<-"end_eval", __FILE__, __LINE__
210
+
211
+ def self.inherited(sub)
212
+ G::PropertyUtils.enchant(sub)
213
+ G::PropertyUtils.copy_props(self, sub)
214
+ # gmosx: We have to define @@__props first to avoid reusing
215
+ # the hash from the module. super must stay at the end.
216
+ super
103
217
  end
104
-
105
- def __meta
106
- @__meta
218
+
219
+ end_eval
220
+
221
+ else
222
+
223
+ # Add some extra code for modules to append
224
+ # their features to classes that include it.
225
+ self.module_eval <<-"end_eval", __FILE__, __LINE__
226
+
227
+ def self.append_features(base)
228
+ G::PropertyUtils.enchant(base)
229
+ G::PropertyUtils.copy_props(self, base)
230
+ # gmosx: We have to define @@__props first to avoid reusing
231
+ # the hash from the module. super must stay at the end.
232
+ super
107
233
  end
108
234
 
109
- def __meta=(meta)
110
- @__meta = meta
111
- end
112
- }
235
+ end_eval
236
+
113
237
  end
114
-
115
- @__props = G::SafeArray.new() unless @__props
116
-
238
+
117
239
  property = G::Property.new(symbol, klass, meta)
118
240
 
119
241
  reader = meta[:reader] || true
120
242
  writer = writer || meta[:writer] || false
121
-
122
- __add_prop(property, reader, writer)
243
+
244
+ meta[:reader] = true if meta[:reader].nil?
245
+ if defined?(writer)
246
+ meta[:writer] = writer
247
+ else
248
+ meta[:writer] = true if meta[:writer].nil?
249
+ end
250
+
251
+ G::PropertyUtils.add_prop(self, property)
123
252
  end
124
253
 
125
254
  # Helper method. Accepts a collection of symbols and generates
@@ -218,90 +347,20 @@ class Module
218
347
  end
219
348
  end
220
349
 
221
- # Add the property
222
- #
223
- def __add_prop(prop, reader = true, writer = true)
224
- if idx = @__props.index(prop)
225
- # override in case of duplicates. Keep the order of the props.
226
- @__props[idx] = prop
227
- else
228
- @__props << prop
229
- end
230
-
231
- # Precompile the property read/write methods
232
-
233
- s, klass = prop.symbol, prop.klass
234
-
235
- if reader
236
- module_eval %{
237
- def #{s}
238
- return @#{s}
239
- end
240
- }
241
- end
242
-
243
- # gmosx: __force_xxx reuses xxx= to allow for easier
244
- # overrides.
245
- if writer
246
- module_eval %{
247
- def #{s}=(val)
248
- @#{s} = val
249
- end
250
-
251
- def __force_#{s}(val)
252
- self.#{s}=(} + case klass.name
253
- when Fixnum.name
254
- "val.to_i()"
255
- when String.name
256
- "val.to_s()"
257
- when Float.name
258
- "val.to_f()"
259
- when Time.name
260
- "Time.parse(val.to_s())"
261
- when TrueClass.name, FalseClass.name
262
- "val.to_i() > 0"
263
- else
264
- "val"
265
- end + %{)
266
- end
267
- }
268
- end
269
- end
270
350
 
271
- # Attach metadata
272
- #
351
+ # Attach metadata.
352
+ # Guard against duplicates, no need to keep order.
353
+ # This method uses closures :)
354
+ #--
355
+ # gmosx: crappy implementation, recode.
356
+ #++
273
357
  def meta(key, val)
274
- @__meta = G::SafeHash.new unless @__meta
275
-
276
- @__meta[key] = [] unless @__meta[key]
277
-
278
- # guard against duplicates, no need to keep order.
279
- @__meta[key].delete_if { |v| val == v }
280
- @__meta[key] << val
358
+ self.module_eval <<-"end_eval", __FILE__, __LINE__
359
+ @@__meta[key] ||= []
360
+ @@__meta[key].delete_if { |v| val == v }
361
+ @@__meta[key] << val
362
+ end_eval
281
363
  end
282
-
283
- # This method is typically called before including other
284
- # modules to preserve properties order.
285
- #
286
- def inherit_meta(mod = superclass)
287
- # concat props.
288
- if mod.__props
289
- @__props = G::SafeArray.new unless @__props
290
-
291
- mod.__props.each { |p|
292
- __add_prop(p)
293
- }
294
- end
295
364
 
296
- # concat metadata
297
- if mod.__meta
298
- mod.__meta.each { |k, val|
299
- val.each { |v|
300
- meta(k, v)
301
- } if val
302
- }
303
- end
304
- end
305
-
306
365
  end
307
366