merb 0.4.2 → 0.5.0
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.
- data/README +21 -14
- data/Rakefile +157 -108
- data/SVN_REVISION +1 -0
- data/app_generators/merb/templates/Rakefile +20 -4
- data/app_generators/merb/templates/app/views/exceptions/internal_server_error.html.erb +1 -1
- data/app_generators/merb/templates/config/boot.rb +1 -1
- data/app_generators/merb/templates/config/dependencies.rb +3 -3
- data/app_generators/merb/templates/config/merb.yml +5 -0
- data/app_generators/merb/templates/config/merb_init.rb +3 -3
- data/app_generators/merb/templates/script/destroy +3 -0
- data/app_generators/merb/templates/script/generate +1 -1
- data/app_generators/merb/templates/spec/spec_helper.rb +2 -2
- data/app_generators/merb/templates/test/test_helper.rb +1 -1
- data/app_generators/merb_plugin/merb_plugin_generator.rb +4 -0
- data/bin/merb +1 -3
- data/lib/merb.rb +144 -76
- data/lib/merb/abstract_controller.rb +6 -5
- data/lib/merb/assets.rb +119 -0
- data/lib/merb/boot_loader.rb +217 -0
- data/lib/merb/caching.rb +1 -1
- data/lib/merb/caching/action_cache.rb +1 -1
- data/lib/merb/caching/fragment_cache.rb +1 -1
- data/lib/merb/caching/store/file_cache.rb +1 -1
- data/lib/merb/config.rb +290 -0
- data/lib/merb/controller.rb +5 -5
- data/lib/merb/core_ext/get_args.rb +1 -0
- data/lib/merb/core_ext/hash.rb +182 -169
- data/lib/merb/core_ext/kernel.rb +57 -26
- data/lib/merb/dispatcher.rb +6 -6
- data/lib/merb/drb_server.rb +1 -1
- data/lib/merb/generators/merb_generator_helpers.rb +7 -6
- data/lib/merb/logger.rb +1 -1
- data/lib/merb/mail_controller.rb +3 -4
- data/lib/merb/mailer.rb +2 -2
- data/lib/merb/mixins/basic_authentication.rb +2 -2
- data/lib/merb/mixins/controller.rb +1 -1
- data/lib/merb/mixins/general_controller.rb +13 -20
- data/lib/merb/mixins/inline_partial.rb +32 -0
- data/lib/merb/mixins/render.rb +3 -3
- data/lib/merb/mixins/responder.rb +1 -1
- data/lib/merb/mixins/view_context.rb +159 -33
- data/lib/merb/mongrel_handler.rb +9 -9
- data/lib/merb/plugins.rb +1 -1
- data/lib/merb/request.rb +25 -1
- data/lib/merb/router.rb +264 -226
- data/lib/merb/server.rb +66 -560
- data/lib/merb/session/cookie_store.rb +14 -13
- data/lib/merb/session/mem_cache_session.rb +20 -10
- data/lib/merb/session/memory_session.rb +21 -11
- data/lib/merb/template.rb +2 -2
- data/lib/merb/template/erubis.rb +3 -33
- data/lib/merb/template/haml.rb +8 -3
- data/lib/merb/test/fake_request.rb +8 -3
- data/lib/merb/test/helper.rb +66 -22
- data/lib/merb/test/rspec.rb +9 -155
- data/lib/merb/test/rspec_matchers/controller_matchers.rb +117 -0
- data/lib/merb/test/rspec_matchers/markup_matchers.rb +98 -0
- data/lib/merb/upload_handler.rb +2 -1
- data/lib/merb/version.rb +38 -3
- data/lib/merb/view_context.rb +1 -2
- data/lib/tasks/merb.rake +11 -11
- data/merb_generators/part_controller/USAGE +5 -0
- data/merb_generators/part_controller/part_controller_generator.rb +27 -0
- data/merb_generators/part_controller/templates/controller.rb +8 -0
- data/merb_generators/part_controller/templates/helper.rb +5 -0
- data/merb_generators/part_controller/templates/index.html.erb +3 -0
- data/rspec_generators/merb_controller_test/merb_controller_test_generator.rb +1 -1
- data/script/destroy +14 -0
- data/script/generate +14 -0
- data/spec/fixtures/controllers/dispatch_spec_controllers.rb +9 -1
- data/spec/fixtures/controllers/render_spec_controllers.rb +5 -5
- data/spec/fixtures/models/router_spec_models.rb +10 -0
- data/spec/merb/abstract_controller_spec.rb +2 -2
- data/spec/merb/assets_spec.rb +207 -0
- data/spec/merb/caching_spec.rb +2 -2
- data/spec/merb/controller_spec.rb +7 -2
- data/spec/merb/cookie_store_spec.rb +1 -1
- data/spec/merb/core_ext/class_spec.rb +97 -0
- data/spec/merb/core_ext/enumerable_spec.rb +27 -0
- data/spec/merb/core_ext/hash_spec.rb +251 -0
- data/spec/merb/core_ext/inflector_spec.rb +34 -0
- data/spec/merb/core_ext/kernel_spec.rb +25 -0
- data/spec/merb/core_ext/numeric_spec.rb +26 -0
- data/spec/merb/core_ext/object_spec.rb +47 -0
- data/spec/merb/core_ext/string_spec.rb +22 -0
- data/spec/merb/core_ext/symbol_spec.rb +7 -0
- data/spec/merb/dependency_spec.rb +22 -0
- data/spec/merb/dispatch_spec.rb +23 -12
- data/spec/merb/fake_request_spec.rb +8 -0
- data/spec/merb/generator_spec.rb +140 -21
- data/spec/merb/handler_spec.rb +5 -5
- data/spec/merb/mail_controller_spec.rb +3 -3
- data/spec/merb/render_spec.rb +1 -1
- data/spec/merb/responder_spec.rb +3 -3
- data/spec/merb/router_spec.rb +260 -191
- data/spec/merb/server_spec.rb +5 -5
- data/spec/merb/upload_handler_spec.rb +7 -0
- data/spec/merb/version_spec.rb +33 -0
- data/spec/merb/view_context_spec.rb +217 -59
- data/spec/spec_generator_helper.rb +15 -0
- data/spec/spec_helper.rb +5 -3
- data/spec/spec_helpers/url_shared_behaviour.rb +5 -7
- metadata +32 -7
- data/lib/merb/caching/store/memcache.rb +0 -20
- data/lib/merb/mixins/form_control.rb +0 -332
- data/lib/patch +0 -69
- data/spec/merb/core_ext_spec.rb +0 -464
- data/spec/merb/form_control_mixin_spec.rb +0 -431
data/lib/patch
DELETED
|
@@ -1,69 +0,0 @@
|
|
|
1
|
-
Index: Rakefile
|
|
2
|
-
===================================================================
|
|
3
|
-
--- Rakefile (revision 888)
|
|
4
|
-
+++ Rakefile (working copy)
|
|
5
|
-
@@ -1,4 +1,4 @@
|
|
6
|
-
-
|
|
7
|
-
+PLATFORM = RUBY_PLATFORM if !defined?(PLATFORM)
|
|
8
|
-
require 'rubygems'
|
|
9
|
-
gem 'echoe', '>=2.7'
|
|
10
|
-
require 'echoe'
|
|
11
|
-
Index: ext/http11/http11.c
|
|
12
|
-
===================================================================
|
|
13
|
-
--- ext/http11/http11.c (revision 888)
|
|
14
|
-
+++ ext/http11/http11.c (working copy)
|
|
15
|
-
@@ -74,7 +74,7 @@
|
|
16
|
-
f = rb_str_dup(global_http_prefix);
|
|
17
|
-
f = rb_str_buf_cat(f, field, flen);
|
|
18
|
-
|
|
19
|
-
- for(ch = RSTRING(f)->ptr, end = ch + RSTRING(f)->len; ch < end; ch++) {
|
|
20
|
-
+ for(ch = RSTRING_PTR(f), end = ch + RSTRING_LEN(f); ch < end; ch++) {
|
|
21
|
-
if(*ch == '-') {
|
|
22
|
-
*ch = '_';
|
|
23
|
-
} else {
|
|
24
|
-
@@ -169,12 +169,12 @@
|
|
25
|
-
rb_hash_aset(req, global_gateway_interface, global_gateway_interface_value);
|
|
26
|
-
if((temp = rb_hash_aref(req, global_http_host)) != Qnil) {
|
|
27
|
-
/* ruby better close strings off with a '\0' dammit */
|
|
28
|
-
- colon = strchr(RSTRING(temp)->ptr, ':');
|
|
29
|
-
+ colon = strchr(RSTRING_PTR(temp), ':');
|
|
30
|
-
if(colon != NULL) {
|
|
31
|
-
- rb_hash_aset(req, global_server_name, rb_str_substr(temp, 0, colon - RSTRING(temp)->ptr));
|
|
32
|
-
+ rb_hash_aset(req, global_server_name, rb_str_substr(temp, 0, colon - RSTRING_PTR(temp)));
|
|
33
|
-
rb_hash_aset(req, global_server_port,
|
|
34
|
-
- rb_str_substr(temp, colon - RSTRING(temp)->ptr+1,
|
|
35
|
-
- RSTRING(temp)->len));
|
|
36
|
-
+ rb_str_substr(temp, colon - RSTRING_PTR(temp)+1,
|
|
37
|
-
+ RSTRING_LEN(temp)));
|
|
38
|
-
} else {
|
|
39
|
-
rb_hash_aset(req, global_server_name, temp);
|
|
40
|
-
rb_hash_aset(req, global_server_port, global_port_80);
|
|
41
|
-
@@ -295,8 +295,8 @@
|
|
42
|
-
DATA_GET(self, http_parser, http);
|
|
43
|
-
|
|
44
|
-
from = FIX2INT(start);
|
|
45
|
-
- dptr = RSTRING(data)->ptr;
|
|
46
|
-
- dlen = RSTRING(data)->len;
|
|
47
|
-
+ dptr = RSTRING_PTR(data);
|
|
48
|
-
+ dlen = RSTRING_LEN(data);
|
|
49
|
-
|
|
50
|
-
if(from >= dlen) {
|
|
51
|
-
rb_raise(eHttpParserError, "Requested start is after data buffer end.");
|
|
52
|
-
Index: ext/http11/ext_help.h
|
|
53
|
-
===================================================================
|
|
54
|
-
--- ext/http11/ext_help.h (revision 888)
|
|
55
|
-
+++ ext/http11/ext_help.h (working copy)
|
|
56
|
-
@@ -11,4 +11,13 @@
|
|
57
|
-
#define TRACE()
|
|
58
|
-
#endif
|
|
59
|
-
|
|
60
|
-
+/* ruby 1.9 compat */
|
|
61
|
-
+#ifndef RSTRING_PTR
|
|
62
|
-
+#define RSTRING_PTR(str) RSTRING(str)->ptr
|
|
63
|
-
+#endif
|
|
64
|
-
+
|
|
65
|
-
+#ifndef RSTRING_LEN
|
|
66
|
-
+#define RSTRING_LEN(str) RSTRING(str)->len
|
|
67
|
-
+#endif
|
|
68
|
-
+
|
|
69
|
-
#endif
|
data/spec/merb/core_ext_spec.rb
DELETED
|
@@ -1,464 +0,0 @@
|
|
|
1
|
-
require File.dirname(__FILE__) + '/../spec_helper'
|
|
2
|
-
|
|
3
|
-
describe "A Numeric object" do
|
|
4
|
-
|
|
5
|
-
it "should be able to convert to US currency" do
|
|
6
|
-
1.5.to_currency.should == "$1.50"
|
|
7
|
-
end
|
|
8
|
-
|
|
9
|
-
it "should be able to convert to Danish currency" do
|
|
10
|
-
15_000_000.5.to_currency(nil, ".", ",", "DM").should == "15.000.000,50DM"
|
|
11
|
-
end
|
|
12
|
-
|
|
13
|
-
{
|
|
14
|
-
:microsecond => Float(10 ** -6), :millisecond => Float(10 ** -3), :second => 1,
|
|
15
|
-
:minute => 60, :hour => 3600, :day => 86400, :week => 604800,
|
|
16
|
-
:month => 2592000, :year => 31536000, :decade => 315360000
|
|
17
|
-
}.each do |method,seconds|
|
|
18
|
-
|
|
19
|
-
it "should be able to convert to #{method}s (singular version)" do
|
|
20
|
-
1.send(method).should == seconds
|
|
21
|
-
end
|
|
22
|
-
|
|
23
|
-
it "should be able to convert to #{method}s (plural version)" do
|
|
24
|
-
2.send("#{method}s").should == seconds * 2
|
|
25
|
-
end
|
|
26
|
-
|
|
27
|
-
end
|
|
28
|
-
|
|
29
|
-
end
|
|
30
|
-
|
|
31
|
-
class MyString < String; end
|
|
32
|
-
class String
|
|
33
|
-
def self.define_meta meth, val
|
|
34
|
-
meta_def meth do; val; end
|
|
35
|
-
end
|
|
36
|
-
end
|
|
37
|
-
|
|
38
|
-
describe "An object" do
|
|
39
|
-
|
|
40
|
-
it "should be able to return a passed in object that is modified by a block" do
|
|
41
|
-
(returning({}) {|x| x.merge!(:foo => :bar)}).should == {:foo => :bar}
|
|
42
|
-
end
|
|
43
|
-
|
|
44
|
-
it "should be able to get a meta class" do
|
|
45
|
-
MyString.meta_class.to_s.should == "#<Class:MyString>"
|
|
46
|
-
end
|
|
47
|
-
|
|
48
|
-
it "should be able to execute code in the meta-class' context" do
|
|
49
|
-
(MyString.meta_eval { self }).should == MyString.meta_class
|
|
50
|
-
end
|
|
51
|
-
|
|
52
|
-
it "should be able to define a method on the meta-class" do
|
|
53
|
-
MyString.define_meta :foo, :bar
|
|
54
|
-
MyString.foo.should == :bar
|
|
55
|
-
end
|
|
56
|
-
|
|
57
|
-
it "should be able to define methods on its instances" do
|
|
58
|
-
MyString.class_def :foo do; :bar; end
|
|
59
|
-
MyString.new.foo.should == :bar
|
|
60
|
-
end
|
|
61
|
-
|
|
62
|
-
{[] => true,
|
|
63
|
-
[1] => false,
|
|
64
|
-
[nil] => false,
|
|
65
|
-
nil => true,
|
|
66
|
-
true => false,
|
|
67
|
-
false => true,
|
|
68
|
-
"" => true,
|
|
69
|
-
" " => true,
|
|
70
|
-
" hey " => false
|
|
71
|
-
}.each do |obj, expected|
|
|
72
|
-
it "should be able to determine whether the #{obj.class} #{obj.inspect} is blank" do
|
|
73
|
-
obj.blank?.should == expected
|
|
74
|
-
end
|
|
75
|
-
end
|
|
76
|
-
end
|
|
77
|
-
|
|
78
|
-
describe Enumerable do
|
|
79
|
-
|
|
80
|
-
before do
|
|
81
|
-
@mascots = ['louie', 'bert', 'ernie']
|
|
82
|
-
end
|
|
83
|
-
|
|
84
|
-
it "should perform injecting" do
|
|
85
|
-
@mascots.injecting({}){|m,i| m[i] = i.size }.should ==
|
|
86
|
-
{'louie'=>5, 'bert'=>4, 'ernie'=>5}
|
|
87
|
-
end
|
|
88
|
-
|
|
89
|
-
it "should find arrays of things inside other arrays" do
|
|
90
|
-
@mascots.include_any?('louie', 'sasquatch').should be_true
|
|
91
|
-
end
|
|
92
|
-
|
|
93
|
-
it "should recognize absence of arrays of things inside other arrays" do
|
|
94
|
-
@mascots.include_any?('chicken', 'sasquatch').should be_false
|
|
95
|
-
end
|
|
96
|
-
|
|
97
|
-
it "should group by" do
|
|
98
|
-
groups = (1..6).group_by{|i| i%3}
|
|
99
|
-
groups[0].should == [3,6]
|
|
100
|
-
groups[1].should == [1,4]
|
|
101
|
-
groups[2].should == [2,5]
|
|
102
|
-
end
|
|
103
|
-
|
|
104
|
-
end
|
|
105
|
-
|
|
106
|
-
describe Symbol do
|
|
107
|
-
|
|
108
|
-
it "should be able to call Symbol#to_proc" do
|
|
109
|
-
['foo', 'bar'].map(&:reverse).should == ['oof', 'rab']
|
|
110
|
-
end
|
|
111
|
-
|
|
112
|
-
end
|
|
113
|
-
|
|
114
|
-
# Class cattr_reader
|
|
115
|
-
|
|
116
|
-
class ClassWithCAttrReader
|
|
117
|
-
cattr_reader :bacon
|
|
118
|
-
def initialize; @@bacon = "chunky"; end
|
|
119
|
-
end
|
|
120
|
-
|
|
121
|
-
describe "Core Class with cattr_reader", :shared => true do
|
|
122
|
-
|
|
123
|
-
it "should read value from attribute" do
|
|
124
|
-
@klass.bacon.should == "chunky"
|
|
125
|
-
end
|
|
126
|
-
|
|
127
|
-
it "should not write to attribute" do
|
|
128
|
-
lambda {
|
|
129
|
-
@klass.bacon = "soggy"
|
|
130
|
-
}.should raise_error(NoMethodError)
|
|
131
|
-
end
|
|
132
|
-
|
|
133
|
-
end
|
|
134
|
-
|
|
135
|
-
describe Class, "with cattr_reader" do
|
|
136
|
-
|
|
137
|
-
before do
|
|
138
|
-
@klass = ClassWithCAttrReader.new.class
|
|
139
|
-
end
|
|
140
|
-
it_should_behave_like "Core Class with cattr_reader"
|
|
141
|
-
|
|
142
|
-
end
|
|
143
|
-
|
|
144
|
-
describe Class, "with cattr_reader (instantiated)" do
|
|
145
|
-
|
|
146
|
-
before do
|
|
147
|
-
@klass = ClassWithCAttrReader.new
|
|
148
|
-
end
|
|
149
|
-
it_should_behave_like "Core Class with cattr_reader"
|
|
150
|
-
|
|
151
|
-
end
|
|
152
|
-
|
|
153
|
-
# Class cattr_writer
|
|
154
|
-
|
|
155
|
-
class ClassWithCAttrWriter
|
|
156
|
-
cattr_writer :bacon
|
|
157
|
-
def self.chunky?; @@bacon == "chunky"; end
|
|
158
|
-
def chunky?; self.class.chunky?; end
|
|
159
|
-
end
|
|
160
|
-
|
|
161
|
-
describe "Core Class with cattr_writer", :shared => true do
|
|
162
|
-
|
|
163
|
-
it "should write value to attribute" do
|
|
164
|
-
@klass.should be_chunky
|
|
165
|
-
end
|
|
166
|
-
|
|
167
|
-
it "should not read attribute" do
|
|
168
|
-
lambda {
|
|
169
|
-
@klass.bacon
|
|
170
|
-
}.should raise_error(NoMethodError)
|
|
171
|
-
end
|
|
172
|
-
|
|
173
|
-
end
|
|
174
|
-
|
|
175
|
-
describe Class, "with cattr_writer" do
|
|
176
|
-
|
|
177
|
-
before do
|
|
178
|
-
@klass = ClassWithCAttrWriter.new.class
|
|
179
|
-
@klass.bacon = "chunky"
|
|
180
|
-
end
|
|
181
|
-
it_should_behave_like "Core Class with cattr_writer"
|
|
182
|
-
|
|
183
|
-
end
|
|
184
|
-
|
|
185
|
-
describe Class, "with cattr_writer (instantiated)" do
|
|
186
|
-
|
|
187
|
-
before do
|
|
188
|
-
@klass = ClassWithCAttrWriter.new
|
|
189
|
-
@klass.bacon = "chunky"
|
|
190
|
-
end
|
|
191
|
-
it_should_behave_like "Core Class with cattr_writer"
|
|
192
|
-
|
|
193
|
-
end
|
|
194
|
-
|
|
195
|
-
describe Hash, "environmentize_keys!" do
|
|
196
|
-
it "should transform keys to uppercase text" do
|
|
197
|
-
{ :test_1 => 'test', 'test_2' => 'test', 1 => 'test'}.environmentize_keys!.should ==
|
|
198
|
-
{ 'TEST_1' => 'test', 'TEST_2' => 'test', '1' => 'test'}
|
|
199
|
-
end
|
|
200
|
-
|
|
201
|
-
it "should only transform one level of keys" do
|
|
202
|
-
{ :test_1 => { :test2 => 'test'}}.environmentize_keys!.should ==
|
|
203
|
-
{ 'TEST_1' => { :test2 => 'test'}}
|
|
204
|
-
end
|
|
205
|
-
end
|
|
206
|
-
|
|
207
|
-
describe Hash, "to_xml_attributes" do
|
|
208
|
-
|
|
209
|
-
before do
|
|
210
|
-
@hash = { :one => "ONE", "two" => "TWO" }
|
|
211
|
-
end
|
|
212
|
-
|
|
213
|
-
it "should turn the hash into xml attributes" do
|
|
214
|
-
attrs = @hash.to_xml_attributes
|
|
215
|
-
attrs.should match( /one="ONE"/m )
|
|
216
|
-
attrs.should match( /two="TWO"/m )
|
|
217
|
-
end
|
|
218
|
-
|
|
219
|
-
end
|
|
220
|
-
|
|
221
|
-
describe Hash, "from_xml" do
|
|
222
|
-
|
|
223
|
-
it "should transform a simple tag with content" do
|
|
224
|
-
xml = "<tag>This is the contents</tag>"
|
|
225
|
-
Hash.from_xml( xml ).should == { 'tag' => 'This is the contents' }
|
|
226
|
-
end
|
|
227
|
-
|
|
228
|
-
it "should transform a simple tag with attributes" do
|
|
229
|
-
xml = "<tag attr1='1' attr2='2'></tag>"
|
|
230
|
-
Hash.from_xml( xml ).should == { 'tag' => {
|
|
231
|
-
'attr1' => '1',
|
|
232
|
-
'attr2' => '2'
|
|
233
|
-
}}
|
|
234
|
-
end
|
|
235
|
-
|
|
236
|
-
it "should transform repeating siblings into an array" do
|
|
237
|
-
xml =<<-XML
|
|
238
|
-
<opt>
|
|
239
|
-
<user login="grep" fullname="Gary R Epstein" />
|
|
240
|
-
<user login="stty" fullname="Simon T Tyson" />
|
|
241
|
-
</opt>
|
|
242
|
-
XML
|
|
243
|
-
|
|
244
|
-
Hash.from_xml( xml )['opt']['user'].should be_an_instance_of( Array )
|
|
245
|
-
|
|
246
|
-
Hash.from_xml( xml ).should =={ 'opt' => {'user' => [{
|
|
247
|
-
'login' => 'grep',
|
|
248
|
-
'fullname' => 'Gary R Epstein'
|
|
249
|
-
},{
|
|
250
|
-
'login' => 'stty',
|
|
251
|
-
'fullname' => 'Simon T Tyson'
|
|
252
|
-
}]
|
|
253
|
-
}}
|
|
254
|
-
|
|
255
|
-
end
|
|
256
|
-
|
|
257
|
-
it "should not transform non-repeating siblings into an array" do
|
|
258
|
-
xml =<<-XML
|
|
259
|
-
<opt>
|
|
260
|
-
<user login="grep" fullname="Gary R Epstein" />
|
|
261
|
-
</opt>
|
|
262
|
-
XML
|
|
263
|
-
|
|
264
|
-
Hash.from_xml( xml )['opt']['user'].should be_an_instance_of( Hash )
|
|
265
|
-
|
|
266
|
-
Hash.from_xml( xml ).should == { 'opt' => {
|
|
267
|
-
'user' => {
|
|
268
|
-
'login' => 'grep',
|
|
269
|
-
'fullname' => 'Gary R Epstein'
|
|
270
|
-
}
|
|
271
|
-
}}
|
|
272
|
-
end
|
|
273
|
-
|
|
274
|
-
it "should typecast an integer" do
|
|
275
|
-
xml = "<tag type='integer'>10</tag>"
|
|
276
|
-
Hash.from_xml(xml)['tag'].should == 10
|
|
277
|
-
end
|
|
278
|
-
|
|
279
|
-
it "should typecast a true boolean" do
|
|
280
|
-
xml = "<tag type='boolean'>true</tag>"
|
|
281
|
-
Hash.from_xml( xml )['tag'].should be_true
|
|
282
|
-
end
|
|
283
|
-
|
|
284
|
-
it "should typecast a false boolean" do
|
|
285
|
-
["false", "1", "0", "some word" ].each do |w|
|
|
286
|
-
Hash.from_xml( "<tag type='boolean'>#{w}</tag>" )['tag'].should be_false
|
|
287
|
-
end
|
|
288
|
-
end
|
|
289
|
-
|
|
290
|
-
it "should typecast a datetime" do
|
|
291
|
-
xml = "<tag type='datetime'>2007-12-31 10:32</tag>"
|
|
292
|
-
Hash.from_xml( xml )['tag'].should == Time.parse( '2007-12-31 10:32' ).utc
|
|
293
|
-
end
|
|
294
|
-
|
|
295
|
-
it "should typecast a date" do
|
|
296
|
-
xml = "<tag type='date'>2007-12-31</tag>"
|
|
297
|
-
Hash.from_xml( xml )['tag'].should == Date.parse( '2007-12-31' )
|
|
298
|
-
end
|
|
299
|
-
|
|
300
|
-
it "should unescape html entities" do
|
|
301
|
-
values = {
|
|
302
|
-
"<" => "<",
|
|
303
|
-
">" => ">",
|
|
304
|
-
'"' => """,
|
|
305
|
-
"'" => "'",
|
|
306
|
-
"&" => "&"
|
|
307
|
-
}
|
|
308
|
-
values.each do |k,v|
|
|
309
|
-
xml = "<tag>Some content #{v}</tag>"
|
|
310
|
-
Hash.from_xml( xml )['tag'].should match( Regexp.new( k ) )
|
|
311
|
-
end
|
|
312
|
-
end
|
|
313
|
-
|
|
314
|
-
it "should undasherize keys as tags" do
|
|
315
|
-
xml = "<tag-1>Stuff</tag-1>"
|
|
316
|
-
Hash.from_xml( xml ).keys.should include( 'tag_1' )
|
|
317
|
-
end
|
|
318
|
-
|
|
319
|
-
it "should undasherize keys as attributes" do
|
|
320
|
-
xml = "<tag1 attr-1='1'></tag1>"
|
|
321
|
-
Hash.from_xml( xml )['tag1'].keys.should include( 'attr_1')
|
|
322
|
-
end
|
|
323
|
-
|
|
324
|
-
it "should undasherize keys as tags and attributes" do
|
|
325
|
-
xml = "<tag-1 attr-1='1'></tag-1>"
|
|
326
|
-
Hash.from_xml( xml ).keys.should include( 'tag_1' )
|
|
327
|
-
Hash.from_xml( xml )['tag_1'].keys.should include( 'attr_1')
|
|
328
|
-
end
|
|
329
|
-
|
|
330
|
-
it "should render nested content correctly" do
|
|
331
|
-
xml = "<root><tag1>Tag1 Content <em><strong>This is strong</strong></em></tag1></root>"
|
|
332
|
-
Hash.from_xml( xml )['root']['tag1'].should == "Tag1 Content <em><strong>This is strong</strong></em>"
|
|
333
|
-
end
|
|
334
|
-
|
|
335
|
-
it "should render nested content with split text nodes correctly" do
|
|
336
|
-
xml = "<root>Tag1 Content<em>Stuff</em> Hi There</root>"
|
|
337
|
-
Hash.from_xml( xml )['root'].should == "Tag1 Content<em>Stuff</em> Hi There"
|
|
338
|
-
end
|
|
339
|
-
|
|
340
|
-
it "should ignore attributes when a child is a text node" do
|
|
341
|
-
xml = "<root attr1='1'>Stuff</root>"
|
|
342
|
-
Hash.from_xml( xml ).should == { "root" => "Stuff" }
|
|
343
|
-
end
|
|
344
|
-
|
|
345
|
-
it "should ignore attributes when any child is a text node" do
|
|
346
|
-
xml = "<root attr1='1'>Stuff <em>in italics</em></root>"
|
|
347
|
-
Hash.from_xml( xml ).should == { "root" => "Stuff <em>in italics</em>" }
|
|
348
|
-
end
|
|
349
|
-
|
|
350
|
-
it "should correctly transform multiple children" do
|
|
351
|
-
xml = <<-XML
|
|
352
|
-
<user gender='m'>
|
|
353
|
-
<age type='integer'>35</age>
|
|
354
|
-
<name>Home Simpson</name>
|
|
355
|
-
<dob type='date'>1988-01-01</dob>
|
|
356
|
-
<joined-at type='datetime'>2000-04-28 23:01</joined-at>
|
|
357
|
-
<is-cool type='boolean'>true</is-cool>
|
|
358
|
-
</user>
|
|
359
|
-
XML
|
|
360
|
-
Hash.from_xml( xml ).should == { "user" =>
|
|
361
|
-
{ "gender" => "m",
|
|
362
|
-
"age" => 35,
|
|
363
|
-
"name" => "Home Simpson",
|
|
364
|
-
"dob" => Date.parse( '1988-01-01' ),
|
|
365
|
-
"joined_at" => Time.parse( "2000-04-28 23:01"),
|
|
366
|
-
"is_cool" => true
|
|
367
|
-
}
|
|
368
|
-
}
|
|
369
|
-
end
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
end
|
|
374
|
-
|
|
375
|
-
class ClassWithAttrInitialize
|
|
376
|
-
attr_initialize :dog, :muppet
|
|
377
|
-
attr_accessor :dog, :muppet
|
|
378
|
-
end
|
|
379
|
-
|
|
380
|
-
describe ClassWithAttrInitialize do
|
|
381
|
-
|
|
382
|
-
it "should initialize with values" do
|
|
383
|
-
c = ClassWithAttrInitialize.new("louie", "bert")
|
|
384
|
-
c.dog.should == "louie"
|
|
385
|
-
c.muppet.should == "bert"
|
|
386
|
-
end
|
|
387
|
-
|
|
388
|
-
end
|
|
389
|
-
|
|
390
|
-
describe "A String" do
|
|
391
|
-
it "should convert a path/like/this to a Constant::String::Like::This" do
|
|
392
|
-
"path/like/this".to_const_string.should == "Path::Like::This"
|
|
393
|
-
"path".to_const_string.should == "Path"
|
|
394
|
-
"snake_case/path/with_several_parts".to_const_string.should == "SnakeCase::Path::WithSeveralParts"
|
|
395
|
-
end
|
|
396
|
-
|
|
397
|
-
it "should raise an error rather than freeze when trying to convert bad Paths/12Like/-this" do
|
|
398
|
-
Timeout::timeout(1) do
|
|
399
|
-
lambda do
|
|
400
|
-
"Paths/12Like/-this".to_const_string
|
|
401
|
-
end.should raise_error(String::InvalidPathConversion)
|
|
402
|
-
end.should_not raise_error(Timeout::Error)
|
|
403
|
-
end
|
|
404
|
-
|
|
405
|
-
it "should remove any indentation and add +indentation+ number of spaces" do
|
|
406
|
-
"foo\n bar\n".indent(3).should == " foo\n bar\n"
|
|
407
|
-
" foo\n bar\n".indent(3).should == " foo\n bar\n"
|
|
408
|
-
end
|
|
409
|
-
end
|
|
410
|
-
|
|
411
|
-
describe "extracting options from arguments" do
|
|
412
|
-
|
|
413
|
-
def the_method(*args)
|
|
414
|
-
[extract_options_from_args!(args),args]
|
|
415
|
-
end
|
|
416
|
-
|
|
417
|
-
it "should extract the hash if the last item is a hash" do
|
|
418
|
-
opts,args = the_method(:one, :two, :key => :value)
|
|
419
|
-
opts.should == {:key => :value}
|
|
420
|
-
args.should == [:one, :two]
|
|
421
|
-
end
|
|
422
|
-
|
|
423
|
-
it "should return nil for the opts if no hash is provided" do
|
|
424
|
-
opts,args = the_method(:one, :two)
|
|
425
|
-
opts.should be_nil
|
|
426
|
-
args.should == [:one, :two]
|
|
427
|
-
end
|
|
428
|
-
|
|
429
|
-
it "should return two hashes" do
|
|
430
|
-
opts,args = the_method( {:one => :two}, :key => :value)
|
|
431
|
-
opts.should == {:key => :value}
|
|
432
|
-
args.should == [{:one => :two}]
|
|
433
|
-
end
|
|
434
|
-
|
|
435
|
-
end
|
|
436
|
-
|
|
437
|
-
describe Inflector do
|
|
438
|
-
it "should transform words from singular to plural" do
|
|
439
|
-
"post".pluralize.should == "posts"
|
|
440
|
-
"octopus".pluralize.should =="octopi"
|
|
441
|
-
"the blue mailman".pluralize.should == "the blue mailmen"
|
|
442
|
-
"CamelOctopus".pluralize.should == "CamelOctopi"
|
|
443
|
-
end
|
|
444
|
-
it "should transform words from plural to singular" do
|
|
445
|
-
"posts".singularize.should == "post"
|
|
446
|
-
"octopi".singularize.should == "octopus"
|
|
447
|
-
"the blue mailmen".singularize.should == "the blue mailman"
|
|
448
|
-
"CamelOctopi".singularize.should == "CamelOctopus"
|
|
449
|
-
end
|
|
450
|
-
it "should transform class names to table names" do
|
|
451
|
-
"RawScaledScorer".tableize.should == "raw_scaled_scorers"
|
|
452
|
-
"egg_and_ham".tableize.should == "egg_and_hams"
|
|
453
|
-
"fancyCategory".tableize.should == "fancy_categories"
|
|
454
|
-
end
|
|
455
|
-
it "should tranform table names to class names" do
|
|
456
|
-
"egg_and_hams".classify.should == "EggAndHam"
|
|
457
|
-
"post".classify.should == "Post"
|
|
458
|
-
end
|
|
459
|
-
it "should create a foreign key name from a class name" do
|
|
460
|
-
"Message".foreign_key.should == "message_id"
|
|
461
|
-
"Message".foreign_key(false).should == "messageid"
|
|
462
|
-
"Admin::Post".foreign_key.should == "post_id"
|
|
463
|
-
end
|
|
464
|
-
end
|