activeobject 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (80) hide show
  1. data/CHANGE +10 -0
  2. data/Interface_desc +21 -0
  3. data/MIT-LICENSE +20 -0
  4. data/README +72 -0
  5. data/Rakefile.rb +9 -0
  6. data/active-object.gemspec +50 -0
  7. data/examples/account.rb +69 -0
  8. data/examples/data.tch +0 -0
  9. data/examples/light_cloud.yml +18 -0
  10. data/examples/test.rb +3 -0
  11. data/examples/user.rb +112 -0
  12. data/init.rb +4 -0
  13. data/lib/active-object.rb +23 -0
  14. data/lib/active_object/adapters/light_cloud.rb +40 -0
  15. data/lib/active_object/adapters/tokyo_cabinet.rb +48 -0
  16. data/lib/active_object/adapters/tokyo_tyrant.rb +14 -0
  17. data/lib/active_object/associations.rb +200 -0
  18. data/lib/active_object/base.rb +415 -0
  19. data/lib/active_object/callbacks.rb +180 -0
  20. data/lib/active_object/observer.rb +180 -0
  21. data/lib/active_object/serialization.rb +99 -0
  22. data/lib/active_object/serializers/json_serializer.rb +75 -0
  23. data/lib/active_object/serializers/xml_serializer.rb +325 -0
  24. data/lib/active_object/validations.rb +687 -0
  25. data/lib/active_support/callbacks.rb +303 -0
  26. data/lib/active_support/core_ext/array/access.rb +53 -0
  27. data/lib/active_support/core_ext/array/conversions.rb +183 -0
  28. data/lib/active_support/core_ext/array/extract_options.rb +20 -0
  29. data/lib/active_support/core_ext/array/grouping.rb +106 -0
  30. data/lib/active_support/core_ext/array/random_access.rb +12 -0
  31. data/lib/active_support/core_ext/array.rb +13 -0
  32. data/lib/active_support/core_ext/blank.rb +58 -0
  33. data/lib/active_support/core_ext/class/attribute_accessors.rb +54 -0
  34. data/lib/active_support/core_ext/class/inheritable_attributes.rb +140 -0
  35. data/lib/active_support/core_ext/class/removal.rb +50 -0
  36. data/lib/active_support/core_ext/class.rb +3 -0
  37. data/lib/active_support/core_ext/duplicable.rb +43 -0
  38. data/lib/active_support/core_ext/enumerable.rb +72 -0
  39. data/lib/active_support/core_ext/hash/conversions.rb +259 -0
  40. data/lib/active_support/core_ext/hash/keys.rb +52 -0
  41. data/lib/active_support/core_ext/hash.rb +8 -0
  42. data/lib/active_support/core_ext/module/aliasing.rb +74 -0
  43. data/lib/active_support/core_ext/module/attr_accessor_with_default.rb +31 -0
  44. data/lib/active_support/core_ext/module/attribute_accessors.rb +58 -0
  45. data/lib/active_support/core_ext/module.rb +16 -0
  46. data/lib/active_support/core_ext/object/conversions.rb +14 -0
  47. data/lib/active_support/core_ext/object/extending.rb +80 -0
  48. data/lib/active_support/core_ext/object/instance_variables.rb +74 -0
  49. data/lib/active_support/core_ext/object/metaclass.rb +13 -0
  50. data/lib/active_support/core_ext/object/misc.rb +43 -0
  51. data/lib/active_support/core_ext/object.rb +5 -0
  52. data/lib/active_support/core_ext/string/inflections.rb +167 -0
  53. data/lib/active_support/core_ext/string.rb +7 -0
  54. data/lib/active_support/core_ext.rb +4 -0
  55. data/lib/active_support/inflections.rb +55 -0
  56. data/lib/active_support/inflector.rb +348 -0
  57. data/lib/active_support/vendor/builder-2.1.2/blankslate.rb +113 -0
  58. data/lib/active_support/vendor/builder-2.1.2/builder/blankslate.rb +20 -0
  59. data/lib/active_support/vendor/builder-2.1.2/builder/css.rb +250 -0
  60. data/lib/active_support/vendor/builder-2.1.2/builder/xchar.rb +115 -0
  61. data/lib/active_support/vendor/builder-2.1.2/builder/xmlbase.rb +139 -0
  62. data/lib/active_support/vendor/builder-2.1.2/builder/xmlevents.rb +63 -0
  63. data/lib/active_support/vendor/builder-2.1.2/builder/xmlmarkup.rb +328 -0
  64. data/lib/active_support/vendor/builder-2.1.2/builder.rb +13 -0
  65. data/lib/active_support/vendor/xml-simple-1.0.11/xmlsimple.rb +1021 -0
  66. data/lib/active_support/vendor.rb +14 -0
  67. data/lib/active_support.rb +6 -0
  68. data/spec/case/association_test.rb +97 -0
  69. data/spec/case/base_test.rb +74 -0
  70. data/spec/case/callbacks_observers_test.rb +38 -0
  71. data/spec/case/callbacks_test.rb +424 -0
  72. data/spec/case/serialization_test.rb +87 -0
  73. data/spec/case/validations_test.rb +1482 -0
  74. data/spec/data.tch +0 -0
  75. data/spec/helper.rb +15 -0
  76. data/spec/light_cloud.yml +18 -0
  77. data/spec/model/account.rb +4 -0
  78. data/spec/model/topic.rb +26 -0
  79. data/spec/model/user.rb +8 -0
  80. metadata +173 -0
@@ -0,0 +1,250 @@
1
+ #!/usr/bin/env ruby
2
+ #--
3
+ # Copyright 2004, 2005 by Jim Weirich (jim@weirichhouse.org).
4
+ # Copyright 2005 by Scott Barron (scott@elitists.net).
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
+ # Much of this is taken from Jim's work in xmlbase.rb and xmlmarkup.rb.
12
+ # Documentation has also been copied and pasted and modified to reflect
13
+ # that we're building CSS here instead of XML. Jim is conducting the
14
+ # orchestra here and I'm just off in the corner playing a flute.
15
+ #++
16
+
17
+ # Provide a flexible and easy to use Builder for creating Cascading
18
+ # Style Sheets (CSS).
19
+
20
+
21
+ require 'builder/blankslate'
22
+
23
+ module Builder
24
+
25
+ # Create a Cascading Style Sheet (CSS) using Ruby.
26
+ #
27
+ # Example usage:
28
+ #
29
+ # css = Builder::CSS.new
30
+ #
31
+ # text_color = '#7F7F7F'
32
+ # preferred_fonts = 'Helvetica, Arial, sans_serif'
33
+ #
34
+ # css.comment! 'This is our stylesheet'
35
+ # css.body {
36
+ # background_color '#FAFAFA'
37
+ # font_size 'small'
38
+ # font_family preferred_fonts
39
+ # color text_color
40
+ # }
41
+ #
42
+ # css.id!('navbar') {
43
+ # width '500px'
44
+ # }
45
+ #
46
+ # css.class!('navitem') {
47
+ # color 'red'
48
+ # }
49
+ #
50
+ # css.a :hover {
51
+ # text_decoration 'underline'
52
+ # }
53
+ #
54
+ # css.div(:id => 'menu') {
55
+ # background 'green'
56
+ # }
57
+ #
58
+ # css.div(:class => 'foo') {
59
+ # background 'red'
60
+ # }
61
+ #
62
+ # This will yield the following stylesheet:
63
+ #
64
+ # /* This is our stylesheet */
65
+ # body {
66
+ # background_color: #FAFAFA;
67
+ # font_size: small;
68
+ # font_family: Helvetica, Arial, sans_serif;
69
+ # color: #7F7F7F;
70
+ # }
71
+ #
72
+ # #navbar {
73
+ # width: 500px;
74
+ # }
75
+ #
76
+ # .navitem {
77
+ # color: red;
78
+ # }
79
+ #
80
+ # a:hover {
81
+ # text_decoration: underline;
82
+ # }
83
+ #
84
+ # div#menu {
85
+ # background: green;
86
+ # }
87
+ #
88
+ # div.foo {
89
+ # background: red;
90
+ # }
91
+ #
92
+ class CSS < BlankSlate
93
+
94
+ # Create a CSS builder.
95
+ #
96
+ # out:: Object receiving the markup.1 +out+ must respond to
97
+ # <tt><<</tt>.
98
+ # indent:: Number of spaces used for indentation (0 implies no
99
+ # indentation and no line breaks).
100
+ #
101
+ def initialize(indent=2)
102
+ @indent = indent
103
+ @target = []
104
+ @parts = []
105
+ @library = {}
106
+ end
107
+
108
+ def +(part)
109
+ _join_with_op! '+'
110
+ self
111
+ end
112
+
113
+ def >>(part)
114
+ _join_with_op! ''
115
+ self
116
+ end
117
+
118
+ def >(part)
119
+ _join_with_op! '>'
120
+ self
121
+ end
122
+
123
+ def |(part)
124
+ _join_with_op! ','
125
+ self
126
+ end
127
+
128
+ # Return the target of the builder
129
+ def target!
130
+ @target * ''
131
+ end
132
+
133
+ # Create a comment string in the output.
134
+ def comment!(comment_text)
135
+ @target << "/* #{comment_text} */\n"
136
+ end
137
+
138
+ def id!(arg, &block)
139
+ _start_container('#'+arg.to_s, nil, block_given?)
140
+ _css_block(block) if block
141
+ _unify_block
142
+ self
143
+ end
144
+
145
+ def class!(arg, &block)
146
+ _start_container('.'+arg.to_s, nil, block_given?)
147
+ _css_block(block) if block
148
+ _unify_block
149
+ self
150
+ end
151
+
152
+ def store!(sym, &block)
153
+ @library[sym] = block.to_proc
154
+ end
155
+
156
+ def group!(*args, &block)
157
+ args.each do |arg|
158
+ if arg.is_a?(Symbol)
159
+ instance_eval(&@library[arg])
160
+ else
161
+ instance_eval(&arg)
162
+ end
163
+ _text ', ' unless arg == args.last
164
+ end
165
+ if block
166
+ _css_block(block)
167
+ _unify_block
168
+ end
169
+ end
170
+
171
+ def method_missing(sym, *args, &block)
172
+ sym = "#{sym}:#{args.shift}" if args.first.kind_of?(Symbol)
173
+ if block
174
+ _start_container(sym, args.first)
175
+ _css_block(block)
176
+ _unify_block
177
+ elsif @in_block
178
+ _indent
179
+ _css_line(sym, *args)
180
+ _newline
181
+ return self
182
+ else
183
+ _start_container(sym, args.first, false)
184
+ _unify_block
185
+ end
186
+ self
187
+ end
188
+
189
+ # "Cargo culted" from Jim who also "cargo culted" it. See xmlbase.rb.
190
+ def nil?
191
+ false
192
+ end
193
+
194
+ private
195
+ def _unify_block
196
+ @target << @parts * ''
197
+ @parts = []
198
+ end
199
+
200
+ def _join_with_op!(op)
201
+ rhs, lhs = @target.pop, @target.pop
202
+ @target << "#{lhs} #{op} #{rhs}"
203
+ end
204
+
205
+ def _text(text)
206
+ @parts << text
207
+ end
208
+
209
+ def _css_block(block)
210
+ _newline
211
+ _nested_structures(block)
212
+ _end_container
213
+ _end_block
214
+ end
215
+
216
+ def _end_block
217
+ _newline
218
+ _newline
219
+ end
220
+
221
+ def _newline
222
+ _text "\n"
223
+ end
224
+
225
+ def _indent
226
+ _text ' ' * @indent
227
+ end
228
+
229
+ def _nested_structures(block)
230
+ @in_block = true
231
+ self.instance_eval(&block)
232
+ @in_block = false
233
+ end
234
+
235
+ def _start_container(sym, atts = {}, with_bracket = true)
236
+ selector = sym.to_s
237
+ selector << ".#{atts[:class]}" if atts && atts[:class]
238
+ selector << '#' + "#{atts[:id]}" if atts && atts[:id]
239
+ @parts << "#{selector}#{with_bracket ? ' {' : ''}"
240
+ end
241
+
242
+ def _end_container
243
+ @parts << "}"
244
+ end
245
+
246
+ def _css_line(sym, *args)
247
+ _text("#{sym.to_s.gsub('_','-')}: #{args * ' '};")
248
+ end
249
+ end
250
+ end
@@ -0,0 +1,115 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ # The XChar library is provided courtesy of Sam Ruby (See
4
+ # http://intertwingly.net/stories/2005/09/28/xchar.rb)
5
+
6
+ # --------------------------------------------------------------------
7
+
8
+ # If the Builder::XChar module is not currently defined, fail on any
9
+ # name clashes in standard library classes.
10
+
11
+ module Builder
12
+ def self.check_for_name_collision(klass, method_name, defined_constant=nil)
13
+ if klass.instance_methods.include?(method_name.to_s)
14
+ fail RuntimeError,
15
+ "Name Collision: Method '#{method_name}' is already defined in #{klass}"
16
+ end
17
+ end
18
+ end
19
+
20
+ if ! defined?(Builder::XChar)
21
+ Builder.check_for_name_collision(String, "to_xs")
22
+ Builder.check_for_name_collision(Fixnum, "xchr")
23
+ end
24
+
25
+ ######################################################################
26
+ module Builder
27
+
28
+ ####################################################################
29
+ # XML Character converter, from Sam Ruby:
30
+ # (see http://intertwingly.net/stories/2005/09/28/xchar.rb).
31
+ #
32
+ module XChar # :nodoc:
33
+
34
+ # See
35
+ # http://intertwingly.net/stories/2004/04/14/i18n.html#CleaningWindows
36
+ # for details.
37
+ CP1252 = { # :nodoc:
38
+ 128 => 8364, # euro sign
39
+ 130 => 8218, # single low-9 quotation mark
40
+ 131 => 402, # latin small letter f with hook
41
+ 132 => 8222, # double low-9 quotation mark
42
+ 133 => 8230, # horizontal ellipsis
43
+ 134 => 8224, # dagger
44
+ 135 => 8225, # double dagger
45
+ 136 => 710, # modifier letter circumflex accent
46
+ 137 => 8240, # per mille sign
47
+ 138 => 352, # latin capital letter s with caron
48
+ 139 => 8249, # single left-pointing angle quotation mark
49
+ 140 => 338, # latin capital ligature oe
50
+ 142 => 381, # latin capital letter z with caron
51
+ 145 => 8216, # left single quotation mark
52
+ 146 => 8217, # right single quotation mark
53
+ 147 => 8220, # left double quotation mark
54
+ 148 => 8221, # right double quotation mark
55
+ 149 => 8226, # bullet
56
+ 150 => 8211, # en dash
57
+ 151 => 8212, # em dash
58
+ 152 => 732, # small tilde
59
+ 153 => 8482, # trade mark sign
60
+ 154 => 353, # latin small letter s with caron
61
+ 155 => 8250, # single right-pointing angle quotation mark
62
+ 156 => 339, # latin small ligature oe
63
+ 158 => 382, # latin small letter z with caron
64
+ 159 => 376, # latin capital letter y with diaeresis
65
+ }
66
+
67
+ # See http://www.w3.org/TR/REC-xml/#dt-chardata for details.
68
+ PREDEFINED = {
69
+ 38 => '&amp;', # ampersand
70
+ 60 => '&lt;', # left angle bracket
71
+ 62 => '&gt;', # right angle bracket
72
+ }
73
+
74
+ # See http://www.w3.org/TR/REC-xml/#charsets for details.
75
+ VALID = [
76
+ 0x9, 0xA, 0xD,
77
+ (0x20..0xD7FF),
78
+ (0xE000..0xFFFD),
79
+ (0x10000..0x10FFFF)
80
+ ]
81
+ end
82
+
83
+ end
84
+
85
+
86
+ ######################################################################
87
+ # Enhance the Fixnum class with a XML escaped character conversion.
88
+ #
89
+ class Fixnum
90
+ XChar = Builder::XChar if ! defined?(XChar)
91
+
92
+ # XML escaped version of chr
93
+ def xchr
94
+ n = XChar::CP1252[self] || self
95
+ case n when *XChar::VALID
96
+ XChar::PREDEFINED[n] or (n<128 ? n.chr : "&##{n};")
97
+ else
98
+ '*'
99
+ end
100
+ end
101
+ end
102
+
103
+
104
+ ######################################################################
105
+ # Enhance the String class with a XML escaped character version of
106
+ # to_s.
107
+ #
108
+ class String
109
+ # XML escaped version of to_s
110
+ def to_xs
111
+ unpack('U*').map {|n| n.xchr}.join # ASCII, UTF-8
112
+ rescue
113
+ unpack('C*').map {|n| n.xchr}.join # ISO-8859-1, WIN-1252
114
+ end
115
+ end
@@ -0,0 +1,139 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'builder/blankslate'
4
+
5
+ module Builder
6
+
7
+ # Generic error for builder
8
+ class IllegalBlockError < RuntimeError; end
9
+
10
+ # XmlBase is a base class for building XML builders. See
11
+ # Builder::XmlMarkup and Builder::XmlEvents for examples.
12
+ class XmlBase < BlankSlate
13
+
14
+ # Create an XML markup builder.
15
+ #
16
+ # out:: Object receiving the markup. +out+ must respond to
17
+ # <tt><<</tt>.
18
+ # indent:: Number of spaces used for indentation (0 implies no
19
+ # indentation and no line breaks).
20
+ # initial:: Level of initial indentation.
21
+ #
22
+ def initialize(indent=0, initial=0)
23
+ @indent = indent
24
+ @level = initial
25
+ end
26
+
27
+ # Create a tag named +sym+. Other than the first argument which
28
+ # is the tag name, the arguments are the same as the tags
29
+ # implemented via <tt>method_missing</tt>.
30
+ def tag!(sym, *args, &block)
31
+ method_missing(sym.to_sym, *args, &block)
32
+ end
33
+
34
+ # Create XML markup based on the name of the method. This method
35
+ # is never invoked directly, but is called for each markup method
36
+ # in the markup block.
37
+ def method_missing(sym, *args, &block)
38
+ text = nil
39
+ attrs = nil
40
+ sym = "#{sym}:#{args.shift}" if args.first.kind_of?(Symbol)
41
+ args.each do |arg|
42
+ case arg
43
+ when Hash
44
+ attrs ||= {}
45
+ attrs.merge!(arg)
46
+ else
47
+ text ||= ''
48
+ text << arg.to_s
49
+ end
50
+ end
51
+ if block
52
+ unless text.nil?
53
+ raise ArgumentError, "XmlMarkup cannot mix a text argument with a block"
54
+ end
55
+ _indent
56
+ _start_tag(sym, attrs)
57
+ _newline
58
+ _nested_structures(block)
59
+ _indent
60
+ _end_tag(sym)
61
+ _newline
62
+ elsif text.nil?
63
+ _indent
64
+ _start_tag(sym, attrs, true)
65
+ _newline
66
+ else
67
+ _indent
68
+ _start_tag(sym, attrs)
69
+ text! text
70
+ _end_tag(sym)
71
+ _newline
72
+ end
73
+ @target
74
+ end
75
+
76
+ # Append text to the output target. Escape any markup. May be
77
+ # used within the markup brackets as:
78
+ #
79
+ # builder.p { |b| b.br; b.text! "HI" } #=> <p><br/>HI</p>
80
+ def text!(text)
81
+ _text(_escape(text))
82
+ end
83
+
84
+ # Append text to the output target without escaping any markup.
85
+ # May be used within the markup brackets as:
86
+ #
87
+ # builder.p { |x| x << "<br/>HI" } #=> <p><br/>HI</p>
88
+ #
89
+ # This is useful when using non-builder enabled software that
90
+ # generates strings. Just insert the string directly into the
91
+ # builder without changing the inserted markup.
92
+ #
93
+ # It is also useful for stacking builder objects. Builders only
94
+ # use <tt><<</tt> to append to the target, so by supporting this
95
+ # method/operation builders can use other builders as their
96
+ # targets.
97
+ def <<(text)
98
+ _text(text)
99
+ end
100
+
101
+ # For some reason, nil? is sent to the XmlMarkup object. If nil?
102
+ # is not defined and method_missing is invoked, some strange kind
103
+ # of recursion happens. Since nil? won't ever be an XML tag, it
104
+ # is pretty safe to define it here. (Note: this is an example of
105
+ # cargo cult programming,
106
+ # cf. http://fishbowl.pastiche.org/2004/10/13/cargo_cult_programming).
107
+ def nil?
108
+ false
109
+ end
110
+
111
+ private
112
+
113
+ require 'builder/xchar'
114
+ def _escape(text)
115
+ text.to_xs
116
+ end
117
+
118
+ def _escape_quote(text)
119
+ _escape(text).gsub(%r{"}, '&quot;') # " WART
120
+ end
121
+
122
+ def _newline
123
+ return if @indent == 0
124
+ text! "\n"
125
+ end
126
+
127
+ def _indent
128
+ return if @indent == 0 || @level == 0
129
+ text!(" " * (@level * @indent))
130
+ end
131
+
132
+ def _nested_structures(block)
133
+ @level += 1
134
+ block.call(self)
135
+ ensure
136
+ @level -= 1
137
+ end
138
+ end
139
+ end
@@ -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
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(handler)
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
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