merb-core 0.9.2 → 0.9.3
Sign up to get free protection for your applications and to get access to all the features.
- data/Rakefile +61 -11
- data/bin/merb +5 -1
- data/lib/merb-core.rb +202 -25
- data/lib/merb-core/autoload.rb +19 -17
- data/lib/merb-core/bootloader.rb +84 -71
- data/lib/merb-core/config.rb +19 -14
- data/lib/merb-core/controller/abstract_controller.rb +16 -17
- data/lib/merb-core/controller/exceptions.rb +115 -70
- data/lib/merb-core/controller/merb_controller.rb +62 -38
- data/lib/merb-core/controller/mime.rb +1 -1
- data/lib/merb-core/controller/mixins/authentication.rb +87 -0
- data/lib/merb-core/controller/mixins/controller.rb +16 -15
- data/lib/merb-core/controller/mixins/render.rb +113 -19
- data/lib/merb-core/controller/mixins/responder.rb +8 -2
- data/lib/merb-core/controller/template.rb +1 -1
- data/lib/merb-core/core_ext.rb +1 -0
- data/lib/merb-core/core_ext/class.rb +113 -6
- data/lib/merb-core/core_ext/hash.rb +43 -39
- data/lib/merb-core/core_ext/kernel.rb +75 -38
- data/lib/merb-core/core_ext/mash.rb +4 -4
- data/lib/merb-core/core_ext/object.rb +18 -7
- data/lib/merb-core/core_ext/set.rb +9 -4
- data/lib/merb-core/core_ext/string.rb +29 -9
- data/lib/merb-core/core_ext/time.rb +13 -0
- data/lib/merb-core/dispatch/cookies.rb +1 -2
- data/lib/merb-core/dispatch/dispatcher.rb +18 -10
- data/lib/merb-core/dispatch/exceptions.html.erb +1 -1
- data/lib/merb-core/dispatch/request.rb +3 -0
- data/lib/merb-core/dispatch/router.rb +10 -7
- data/lib/merb-core/dispatch/router/behavior.rb +36 -27
- data/lib/merb-core/dispatch/router/route.rb +7 -2
- data/lib/merb-core/dispatch/session/cookie.rb +4 -4
- data/lib/merb-core/dispatch/session/memcached.rb +17 -5
- data/lib/merb-core/logger.rb +2 -2
- data/lib/merb-core/plugins.rb +16 -4
- data/lib/merb-core/rack/adapter/ebb.rb +4 -1
- data/lib/merb-core/rack/adapter/evented_mongrel.rb +2 -0
- data/lib/merb-core/rack/adapter/fcgi.rb +1 -0
- data/lib/merb-core/rack/adapter/mongrel.rb +1 -0
- data/lib/merb-core/rack/adapter/runner.rb +1 -0
- data/lib/merb-core/rack/adapter/thin.rb +3 -1
- data/lib/merb-core/rack/adapter/webrick.rb +1 -0
- data/lib/merb-core/rack/application.rb +17 -1
- data/lib/merb-core/server.rb +78 -28
- data/lib/merb-core/test/helpers/multipart_request_helper.rb +3 -3
- data/lib/merb-core/test/helpers/request_helper.rb +81 -27
- data/lib/merb-core/test/helpers/view_helper.rb +1 -1
- data/lib/merb-core/test/matchers/controller_matchers.rb +55 -5
- data/lib/merb-core/test/matchers/route_matchers.rb +8 -17
- data/lib/merb-core/test/matchers/view_matchers.rb +53 -11
- data/lib/merb-core/test/run_specs.rb +22 -14
- data/lib/merb-core/test/tasks/spectasks.rb +54 -33
- data/lib/merb-core/vendor/facets/inflect.rb +91 -2
- data/lib/merb-core/version.rb +2 -2
- data/spec/private/config/config_spec.rb +54 -26
- data/spec/private/core_ext/class_spec.rb +22 -0
- data/spec/private/core_ext/hash_spec.rb +70 -54
- data/spec/private/core_ext/kernel_spec.rb +149 -14
- data/spec/private/core_ext/object_spec.rb +92 -10
- data/spec/private/core_ext/string_spec.rb +162 -4
- data/spec/private/core_ext/time_spec.rb +16 -0
- data/spec/private/dispatch/bootloader_spec.rb +24 -0
- data/spec/private/dispatch/fixture/app/views/exeptions/client_error.html.erb +1 -1
- data/spec/private/dispatch/fixture/app/views/exeptions/internal_server_error.html.erb +1 -1
- data/spec/private/dispatch/fixture/app/views/exeptions/not_acceptable.html.erb +1 -1
- data/spec/private/dispatch/fixture/app/views/exeptions/not_found.html.erb +1 -1
- data/spec/private/dispatch/fixture/config/black_hole.rb +12 -0
- data/spec/private/dispatch/fixture/log/merb_test.log +138 -0
- data/spec/private/plugins/plugin_spec.rb +79 -8
- data/spec/private/rack/application_spec.rb +1 -1
- data/spec/public/abstract_controller/controllers/filters.rb +26 -0
- data/spec/public/abstract_controller/controllers/helpers.rb +2 -2
- data/spec/public/abstract_controller/controllers/partial.rb +2 -2
- data/spec/public/abstract_controller/controllers/render.rb +16 -4
- data/spec/public/abstract_controller/filter_spec.rb +8 -0
- data/spec/public/abstract_controller/render_spec.rb +12 -0
- data/spec/public/controller/authentication_spec.rb +103 -0
- data/spec/public/controller/base_spec.rb +4 -3
- data/spec/public/controller/controllers/authentication.rb +47 -0
- data/spec/public/controller/controllers/base.rb +1 -0
- data/spec/public/controller/controllers/display.rb +30 -0
- data/spec/public/controller/controllers/views/layout/custom_arg.html.erb +1 -0
- data/spec/public/controller/controllers/views/merb/test/fixtures/controllers/display_with_template_argument/index.html.erb +1 -0
- data/spec/public/controller/display_spec.rb +17 -0
- data/spec/public/controller/spec_helper.rb +1 -0
- data/spec/public/controller/url_spec.rb +25 -7
- data/spec/public/core/merb_core_spec.rb +34 -0
- data/spec/public/directory_structure/directory/app/controllers/custom.rb +2 -2
- data/spec/public/directory_structure/directory/log/merb_test.log +48 -0
- data/spec/public/logger/logger_spec.rb +10 -4
- data/spec/public/reloading/directory/app/controllers/reload.rb +1 -1
- data/spec/public/reloading/directory/log/merb_test.log +13 -0
- data/spec/public/reloading/reload_spec.rb +23 -22
- data/spec/public/request/request_spec.rb +2 -0
- data/spec/public/router/nested_resources_spec.rb +7 -0
- data/spec/public/router/resources_spec.rb +46 -1
- data/spec/public/router/special_spec.rb +5 -1
- data/spec/public/test/controller_matchers_spec.rb +25 -1
- data/spec/public/test/controllers/spec_helper_controller.rb +8 -0
- data/spec/public/test/request_helper_spec.rb +52 -1
- data/spec/public/test/route_matchers_spec.rb +27 -25
- data/spec/public/test/view_helper_spec.rb +1 -1
- data/spec/public/test/view_matchers_spec.rb +148 -72
- metadata +23 -3
data/lib/merb-core/version.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
module Merb
|
2
|
-
VERSION = '0.9.
|
2
|
+
VERSION = '0.9.3' unless defined?(Merb::VERSION)
|
3
3
|
|
4
4
|
# Merb::RELEASE meanings:
|
5
5
|
# 'dev' : unreleased
|
@@ -7,5 +7,5 @@ module Merb
|
|
7
7
|
# nil : released
|
8
8
|
# You should never check in to trunk with this changed. It should
|
9
9
|
# stay 'dev'. Change it to nil in release tags.
|
10
|
-
RELEASE =
|
10
|
+
RELEASE = '' unless defined?(Merb::RELEASE)
|
11
11
|
end
|
@@ -4,29 +4,29 @@ describe Merb::Config do
|
|
4
4
|
before do
|
5
5
|
Merb::Config.setup
|
6
6
|
end
|
7
|
-
|
7
|
+
|
8
8
|
it "should be able to yield the configuration via #use" do
|
9
9
|
res = nil
|
10
10
|
Merb::Config.use {|c| res = c}
|
11
11
|
res.should == Merb::Config.defaults
|
12
12
|
end
|
13
|
-
|
13
|
+
|
14
14
|
it "should be able to get a configuration key" do
|
15
15
|
Merb::Config[:host].should == "0.0.0.0"
|
16
16
|
end
|
17
|
-
|
17
|
+
|
18
18
|
it "should be able to set a configuration key" do
|
19
19
|
Merb::Config[:bar] = "Hello"
|
20
20
|
Merb::Config[:bar].should == "Hello"
|
21
21
|
end
|
22
|
-
|
22
|
+
|
23
23
|
it "should be able to #delete a configuration key" do
|
24
|
-
Merb::Config[:bar] = "Hello"
|
25
|
-
Merb::Config[:bar].should == "Hello"
|
24
|
+
Merb::Config[:bar] = "Hello"
|
25
|
+
Merb::Config[:bar].should == "Hello"
|
26
26
|
Merb::Config.delete(:bar)
|
27
|
-
Merb::Config[:bar].should == nil
|
27
|
+
Merb::Config[:bar].should == nil
|
28
28
|
end
|
29
|
-
|
29
|
+
|
30
30
|
it "should be able to #fetch a key that does exist" do
|
31
31
|
Merb::Config.fetch(:host, "192.168.2.1").should == "0.0.0.0"
|
32
32
|
end
|
@@ -43,68 +43,96 @@ describe Merb::Config do
|
|
43
43
|
Merb::Config.parse_args(["-u", "tester"])
|
44
44
|
Merb::Config[:user].should == "tester"
|
45
45
|
end
|
46
|
-
|
46
|
+
|
47
47
|
it "should support -G to set the group to run Merb as" do
|
48
48
|
Merb::Config.parse_args(["-G", "tester"])
|
49
|
-
Merb::Config[:group].should == "tester"
|
49
|
+
Merb::Config[:group].should == "tester"
|
50
50
|
end
|
51
51
|
|
52
52
|
it "should support -f to set the filename to run Merb as" do
|
53
53
|
Merb::Config.parse_args(["-d"])
|
54
54
|
Merb::Config[:daemonize].should == true
|
55
55
|
end
|
56
|
-
|
56
|
+
|
57
57
|
it "should support -c to set the number of cluster nodes" do
|
58
58
|
Merb::Config.parse_args(["-c", "4"])
|
59
59
|
Merb::Config[:cluster].should == "4"
|
60
60
|
end
|
61
|
-
|
61
|
+
|
62
62
|
it "should support -p to set the port number" do
|
63
63
|
Merb::Config.parse_args(["-p", "6000"])
|
64
|
-
Merb::Config[:port].should == "6000"
|
64
|
+
Merb::Config[:port].should == "6000"
|
65
65
|
end
|
66
|
-
|
66
|
+
|
67
67
|
it "should support -P to set the PIDfile" do
|
68
68
|
Merb::Config.parse_args(["-P", "pidfile"])
|
69
69
|
Merb::Config[:pid_file].should == "pidfile"
|
70
70
|
end
|
71
71
|
|
72
|
+
it "should have server return PIDfile setting as is with no cluster nodes" do
|
73
|
+
Merb::Config.parse_args(["-P", "pidfile", "-p", "6000"])
|
74
|
+
Merb::Server.pid_file(6000).should == "pidfile"
|
75
|
+
Merb::Server.pid_files.should == ["pidfile"]
|
76
|
+
end
|
77
|
+
|
78
|
+
it "should support setting of PIDfile with cluster nodes" do
|
79
|
+
Merb::Config.parse_args(["-P", "/tmp/merb.pidfile", "-c", "2", "-p", "6000"])
|
80
|
+
Merb::Server.pid_file(6000).should == "/tmp/merb.6000.pidfile"
|
81
|
+
Merb::Server.pid_file(6001).should == "/tmp/merb.6001.pidfile"
|
82
|
+
|
83
|
+
Dir.should_receive(:[]).with("/tmp/merb.*.pidfile")
|
84
|
+
Merb::Server.pid_files
|
85
|
+
end
|
86
|
+
|
87
|
+
it "should support default PIDfile setting" do
|
88
|
+
Merb::Config.parse_args(["-p", "6000"])
|
89
|
+
Merb::Server.pid_file(6000).should == Merb.log_path / "merb.6000.pid"
|
90
|
+
|
91
|
+
Dir.should_receive(:[]).with(Merb.log_path / "merb.*.pid")
|
92
|
+
Merb::Server.pid_files
|
93
|
+
end
|
94
|
+
|
72
95
|
it "should support -h to set the hostname" do
|
73
96
|
Merb::Config.parse_args(["-h", "hostname"])
|
74
97
|
Merb::Config[:host].should == "hostname"
|
75
98
|
end
|
76
|
-
|
99
|
+
|
77
100
|
it "should support -i to specify loading IRB" do
|
78
101
|
Merb::Config.parse_args(["-i"])
|
79
102
|
Merb::Config[:adapter].should == "irb"
|
80
103
|
end
|
81
|
-
|
104
|
+
|
82
105
|
it "should support -l to specify the log level" do
|
83
106
|
Merb::Config.parse_args(["-l", "debug"])
|
84
107
|
Merb::Config[:log_level].should == :debug
|
85
108
|
end
|
86
|
-
|
109
|
+
|
87
110
|
it "should support -L to specify the location of the log file" do
|
88
111
|
Merb::Config.parse_args(["-L", "log_file"])
|
89
112
|
Merb::Config[:log_file].should == "log_file"
|
90
113
|
end
|
91
|
-
|
114
|
+
|
92
115
|
it "should support -r to specify a runner" do
|
93
116
|
Merb::Config.parse_args(["-r", "foo_runner"])
|
94
117
|
Merb::Config[:runner_code].should == "foo_runner"
|
95
118
|
Merb::Config[:adapter].should == "runner"
|
96
119
|
end
|
97
|
-
|
120
|
+
|
121
|
+
it "should support -R to specify a rackup file" do
|
122
|
+
Merb::Config.parse_args(["-R", "config.ru"])
|
123
|
+
Merb::Config[:rackup].should == "config.ru"
|
124
|
+
end
|
125
|
+
|
98
126
|
it "should support -K for a graceful kill" do
|
99
127
|
Merb::Server.should_receive(:kill).with("all", 1)
|
100
|
-
Merb
|
128
|
+
Merb.start(["-K", "all"])
|
101
129
|
end
|
102
130
|
|
103
131
|
it "should support -k for a hard kill" do
|
104
132
|
Merb::Server.should_receive(:kill).with("all", 9)
|
105
|
-
Merb
|
133
|
+
Merb.start(["-k", "all"])
|
106
134
|
end
|
107
|
-
|
135
|
+
|
108
136
|
it "should support -X off to turn off the mutex" do
|
109
137
|
Merb::Config.parse_args(["-X", "off"])
|
110
138
|
Merb::Config[:use_mutex].should == false
|
@@ -114,7 +142,7 @@ describe Merb::Config do
|
|
114
142
|
Merb::Config.parse_args(["-X", "on"])
|
115
143
|
Merb::Config[:use_mutex].should == true
|
116
144
|
end
|
117
|
-
|
145
|
+
|
118
146
|
it "should take Merb.disable into account" do
|
119
147
|
Merb::Config[:disabled_components].should == []
|
120
148
|
Merb::Config[:disabled_components] << :foo
|
@@ -124,7 +152,7 @@ describe Merb::Config do
|
|
124
152
|
Merb.disabled?(:foo).should == true
|
125
153
|
Merb.disabled?(:foo, :buz).should == true
|
126
154
|
end
|
127
|
-
|
155
|
+
|
128
156
|
it "should take Merb.testing? into account" do
|
129
157
|
$TESTING.should == true
|
130
158
|
Merb::Config[:testing].should be_nil
|
@@ -135,5 +163,5 @@ describe Merb::Config do
|
|
135
163
|
Merb.should be_testing
|
136
164
|
$TESTING = true; Merb::Config[:testing] = false # reset
|
137
165
|
end
|
138
|
-
|
139
|
-
end
|
166
|
+
|
167
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../../spec_helper'
|
2
|
+
|
3
|
+
class ProphecyOfSmalltalk
|
4
|
+
end
|
5
|
+
|
6
|
+
describe Class, "#reset_inheritable_attributes" do
|
7
|
+
it "resets @inheritable_attributes to empty Hash unless EMPTY_INHERITABLE_ATTRIBUTES constant is defined" do
|
8
|
+
ProphecyOfSmalltalk.reset_inheritable_attributes
|
9
|
+
|
10
|
+
ProphecyOfSmalltalk.instance_variable_get("@inheritable_attributes").should == {}
|
11
|
+
end
|
12
|
+
|
13
|
+
it "resets @inheritable_attributes to whatever Class::EMPTY_INHERITABLE_ATTRIBUTES is" do
|
14
|
+
class Class
|
15
|
+
EMPTY_INHERITABLE_ATTRIBUTES = { :patience => "Is a virtue" }
|
16
|
+
end
|
17
|
+
|
18
|
+
ProphecyOfSmalltalk.reset_inheritable_attributes
|
19
|
+
|
20
|
+
ProphecyOfSmalltalk.instance_variable_get("@inheritable_attributes")[:patience].should == "Is a virtue"
|
21
|
+
end
|
22
|
+
end
|
@@ -7,40 +7,43 @@ describe Hash, "environmentize_keys!" do
|
|
7
7
|
{ :test_1 => 'test', 'test_2' => 'test', 1 => 'test' }.environmentize_keys!.should ==
|
8
8
|
{ 'TEST_1' => 'test', 'TEST_2' => 'test', '1' => 'test' }
|
9
9
|
end
|
10
|
-
|
10
|
+
|
11
11
|
it "should only transform one level of keys" do
|
12
|
-
{ :test_1 => { :test2 => 'test'} }.environmentize_keys!.should ==
|
12
|
+
{ :test_1 => { :test2 => 'test'} }.environmentize_keys!.should ==
|
13
13
|
{ 'TEST_1' => { :test2 => 'test'} }
|
14
14
|
end
|
15
15
|
end
|
16
16
|
|
17
|
+
|
17
18
|
describe Hash, "only" do
|
18
19
|
before do
|
19
20
|
@hash = { :one => 'ONE', 'two' => 'TWO', 3 => 'THREE' }
|
20
21
|
end
|
21
|
-
|
22
|
+
|
22
23
|
it "should return a hash with only the given key(s)" do
|
23
24
|
@hash.only(:one).should == { :one => 'ONE' }
|
24
25
|
@hash.only(:one, 3).should == { :one => 'ONE', 3 => 'THREE' }
|
25
26
|
end
|
26
27
|
end
|
27
28
|
|
29
|
+
|
28
30
|
describe Hash, "except" do
|
29
31
|
before do
|
30
32
|
@hash = { :one => 'ONE', 'two' => 'TWO', 3 => 'THREE' }
|
31
33
|
end
|
32
|
-
|
34
|
+
|
33
35
|
it "should return a hash without only the given key(s)" do
|
34
36
|
@hash.except(:one).should == { 'two' => 'TWO', 3 => 'THREE' }
|
35
37
|
@hash.except(:one, 3).should == { 'two' => 'TWO' }
|
36
38
|
end
|
37
39
|
end
|
38
40
|
|
41
|
+
|
39
42
|
describe Hash, "to_xml_attributes" do
|
40
43
|
before do
|
41
44
|
@hash = { :one => "ONE", "two" => "TWO" }
|
42
45
|
end
|
43
|
-
|
46
|
+
|
44
47
|
it "should turn the hash into xml attributes" do
|
45
48
|
attrs = @hash.to_xml_attributes
|
46
49
|
attrs.should match(/one="ONE"/m)
|
@@ -48,12 +51,13 @@ describe Hash, "to_xml_attributes" do
|
|
48
51
|
end
|
49
52
|
end
|
50
53
|
|
54
|
+
|
51
55
|
describe Hash, "from_xml" do
|
52
56
|
it "should transform a simple tag with content" do
|
53
57
|
xml = "<tag>This is the contents</tag>"
|
54
58
|
Hash.from_xml(xml).should == { 'tag' => 'This is the contents' }
|
55
59
|
end
|
56
|
-
|
60
|
+
|
57
61
|
it "should work with cdata tags" do
|
58
62
|
xml = <<-END
|
59
63
|
<tag>
|
@@ -64,13 +68,13 @@ describe Hash, "from_xml" do
|
|
64
68
|
END
|
65
69
|
Hash.from_xml(xml)["tag"].strip.should == "text inside cdata"
|
66
70
|
end
|
67
|
-
|
71
|
+
|
68
72
|
it "should transform a simple tag with attributes" do
|
69
73
|
xml = "<tag attr1='1' attr2='2'></tag>"
|
70
74
|
hash = { 'tag' => { 'attr1' => '1', 'attr2' => '2' } }
|
71
75
|
Hash.from_xml(xml).should == hash
|
72
|
-
end
|
73
|
-
|
76
|
+
end
|
77
|
+
|
74
78
|
it "should transform repeating siblings into an array" do
|
75
79
|
xml =<<-XML
|
76
80
|
<opt>
|
@@ -78,9 +82,9 @@ describe Hash, "from_xml" do
|
|
78
82
|
<user login="stty" fullname="Simon T Tyson" />
|
79
83
|
</opt>
|
80
84
|
XML
|
81
|
-
|
85
|
+
|
82
86
|
Hash.from_xml(xml)['opt']['user'].should be_an_instance_of(Array)
|
83
|
-
|
87
|
+
|
84
88
|
hash = {
|
85
89
|
'opt' => {
|
86
90
|
'user' => [{
|
@@ -92,57 +96,57 @@ describe Hash, "from_xml" do
|
|
92
96
|
}]
|
93
97
|
}
|
94
98
|
}
|
95
|
-
|
99
|
+
|
96
100
|
Hash.from_xml(xml).should == hash
|
97
101
|
end
|
98
|
-
|
102
|
+
|
99
103
|
it "should not transform non-repeating siblings into an array" do
|
100
104
|
xml =<<-XML
|
101
105
|
<opt>
|
102
106
|
<user login="grep" fullname="Gary R Epstein" />
|
103
107
|
</opt>
|
104
108
|
XML
|
105
|
-
|
109
|
+
|
106
110
|
Hash.from_xml(xml)['opt']['user'].should be_an_instance_of(Hash)
|
107
|
-
|
111
|
+
|
108
112
|
hash = {
|
109
|
-
'opt' => {
|
110
|
-
'user' => {
|
111
|
-
'login' => 'grep',
|
113
|
+
'opt' => {
|
114
|
+
'user' => {
|
115
|
+
'login' => 'grep',
|
112
116
|
'fullname' => 'Gary R Epstein'
|
113
117
|
}
|
114
118
|
}
|
115
119
|
}
|
116
|
-
|
120
|
+
|
117
121
|
Hash.from_xml(xml).should == hash
|
118
122
|
end
|
119
|
-
|
123
|
+
|
120
124
|
it "should typecast an integer" do
|
121
125
|
xml = "<tag type='integer'>10</tag>"
|
122
126
|
Hash.from_xml(xml)['tag'].should == 10
|
123
127
|
end
|
124
|
-
|
128
|
+
|
125
129
|
it "should typecast a true boolean" do
|
126
130
|
xml = "<tag type='boolean'>true</tag>"
|
127
131
|
Hash.from_xml(xml)['tag'].should be_true
|
128
132
|
end
|
129
|
-
|
133
|
+
|
130
134
|
it "should typecast a false boolean" do
|
131
135
|
["false"].each do |w|
|
132
136
|
Hash.from_xml("<tag type='boolean'>#{w}</tag>")['tag'].should be_false
|
133
137
|
end
|
134
138
|
end
|
135
|
-
|
139
|
+
|
136
140
|
it "should typecast a datetime" do
|
137
141
|
xml = "<tag type='datetime'>2007-12-31 10:32</tag>"
|
138
142
|
Hash.from_xml(xml)['tag'].should == Time.parse( '2007-12-31 10:32' ).utc
|
139
143
|
end
|
140
|
-
|
144
|
+
|
141
145
|
it "should typecast a date" do
|
142
146
|
xml = "<tag type='date'>2007-12-31</tag>"
|
143
147
|
Hash.from_xml(xml)['tag'].should == Date.parse('2007-12-31')
|
144
148
|
end
|
145
|
-
|
149
|
+
|
146
150
|
it "should unescape html entities" do
|
147
151
|
values = {
|
148
152
|
"<" => "<",
|
@@ -156,43 +160,43 @@ describe Hash, "from_xml" do
|
|
156
160
|
Hash.from_xml(xml)['tag'].should match(Regexp.new(k))
|
157
161
|
end
|
158
162
|
end
|
159
|
-
|
163
|
+
|
160
164
|
it "should undasherize keys as tags" do
|
161
165
|
xml = "<tag-1>Stuff</tag-1>"
|
162
166
|
Hash.from_xml(xml).keys.should include( 'tag_1' )
|
163
167
|
end
|
164
|
-
|
168
|
+
|
165
169
|
it "should undasherize keys as attributes" do
|
166
170
|
xml = "<tag1 attr-1='1'></tag1>"
|
167
171
|
Hash.from_xml(xml)['tag1'].keys.should include( 'attr_1')
|
168
172
|
end
|
169
|
-
|
173
|
+
|
170
174
|
it "should undasherize keys as tags and attributes" do
|
171
175
|
xml = "<tag-1 attr-1='1'></tag-1>"
|
172
176
|
Hash.from_xml(xml).keys.should include( 'tag_1' )
|
173
177
|
Hash.from_xml(xml)['tag_1'].keys.should include( 'attr_1')
|
174
178
|
end
|
175
|
-
|
179
|
+
|
176
180
|
it "should render nested content correctly" do
|
177
181
|
xml = "<root><tag1>Tag1 Content <em><strong>This is strong</strong></em></tag1></root>"
|
178
182
|
Hash.from_xml(xml)['root']['tag1'].should == "Tag1 Content <em><strong>This is strong</strong></em>"
|
179
183
|
end
|
180
|
-
|
184
|
+
|
181
185
|
it "should render nested content with split text nodes correctly" do
|
182
186
|
xml = "<root>Tag1 Content<em>Stuff</em> Hi There</root>"
|
183
187
|
Hash.from_xml(xml)['root'].should == "Tag1 Content<em>Stuff</em> Hi There"
|
184
188
|
end
|
185
|
-
|
189
|
+
|
186
190
|
it "should ignore attributes when a child is a text node" do
|
187
191
|
xml = "<root attr1='1'>Stuff</root>"
|
188
192
|
Hash.from_xml(xml).should == { "root" => "Stuff" }
|
189
193
|
end
|
190
|
-
|
194
|
+
|
191
195
|
it "should ignore attributes when any child is a text node" do
|
192
196
|
xml = "<root attr1='1'>Stuff <em>in italics</em></root>"
|
193
197
|
Hash.from_xml(xml).should == { "root" => "Stuff <em>in italics</em>" }
|
194
198
|
end
|
195
|
-
|
199
|
+
|
196
200
|
it "should correctly transform multiple children" do
|
197
201
|
xml = <<-XML
|
198
202
|
<user gender='m'>
|
@@ -203,7 +207,7 @@ describe Hash, "from_xml" do
|
|
203
207
|
<is-cool type='boolean'>true</is-cool>
|
204
208
|
</user>
|
205
209
|
XML
|
206
|
-
|
210
|
+
|
207
211
|
hash = {
|
208
212
|
"user" => {
|
209
213
|
"gender" => "m",
|
@@ -214,10 +218,10 @@ describe Hash, "from_xml" do
|
|
214
218
|
"is_cool" => true
|
215
219
|
}
|
216
220
|
}
|
217
|
-
|
221
|
+
|
218
222
|
Hash.from_xml(xml).should == hash
|
219
223
|
end
|
220
|
-
|
224
|
+
|
221
225
|
it "should properly handle nil values (ActiveSupport Compatible)" do
|
222
226
|
topic_xml = <<-EOT
|
223
227
|
<topic>
|
@@ -232,15 +236,15 @@ describe Hash, "from_xml" do
|
|
232
236
|
EOT
|
233
237
|
|
234
238
|
expected_topic_hash = {
|
235
|
-
'title' => nil,
|
239
|
+
'title' => nil,
|
236
240
|
'id' => nil,
|
237
241
|
'approved' => nil,
|
238
242
|
'written_on' => nil,
|
239
243
|
'viewed_at' => nil,
|
240
|
-
'content' => nil,
|
244
|
+
'content' => nil,
|
241
245
|
'parent_id' => nil
|
242
246
|
}
|
243
|
-
Hash.from_xml(topic_xml)["topic"].should == expected_topic_hash
|
247
|
+
Hash.from_xml(topic_xml)["topic"].should == expected_topic_hash
|
244
248
|
end
|
245
249
|
|
246
250
|
it "should handle a single record from xml (ActiveSupport Compatible)" do
|
@@ -362,7 +366,7 @@ describe Hash, "from_xml" do
|
|
362
366
|
v.should == expected_topic_hash[k]
|
363
367
|
end
|
364
368
|
end
|
365
|
-
|
369
|
+
|
366
370
|
it "should handle an emtpy array (ActiveSupport Compatible)" do
|
367
371
|
blog_xml = <<-XML
|
368
372
|
<blog>
|
@@ -406,7 +410,7 @@ describe Hash, "from_xml" do
|
|
406
410
|
</blog>
|
407
411
|
XML
|
408
412
|
expected_blog_hash = {"blog" => {"posts" => ["a post", "another post"]}}
|
409
|
-
Hash.from_xml(blog_xml).should == expected_blog_hash
|
413
|
+
Hash.from_xml(blog_xml).should == expected_blog_hash
|
410
414
|
end
|
411
415
|
|
412
416
|
it "should handle file types (ActiveSupport Compatible)" do
|
@@ -419,10 +423,10 @@ describe Hash, "from_xml" do
|
|
419
423
|
hash = Hash.from_xml(blog_xml)
|
420
424
|
hash.should have_key('blog')
|
421
425
|
hash['blog'].should have_key('logo')
|
422
|
-
|
426
|
+
|
423
427
|
file = hash['blog']['logo']
|
424
428
|
file.original_filename.should == 'logo.png'
|
425
|
-
file.content_type.should == 'image/png'
|
429
|
+
file.content_type.should == 'image/png'
|
426
430
|
end
|
427
431
|
|
428
432
|
it "should handle file from xml with defaults (ActiveSupport Compatible)" do
|
@@ -434,7 +438,7 @@ describe Hash, "from_xml" do
|
|
434
438
|
XML
|
435
439
|
file = Hash.from_xml(blog_xml)['blog']['logo']
|
436
440
|
file.original_filename.should == 'untitled'
|
437
|
-
file.content_type.should == 'application/octet-stream'
|
441
|
+
file.content_type.should == 'application/octet-stream'
|
438
442
|
end
|
439
443
|
|
440
444
|
it "should handle xsd like types from xml (ActiveSupport Compatible)" do
|
@@ -466,7 +470,7 @@ describe Hash, "from_xml" do
|
|
466
470
|
<product>
|
467
471
|
<weight type="double">0.5</weight>
|
468
472
|
<image type="ProductImage"><filename>image.gif</filename></image>
|
469
|
-
|
473
|
+
|
470
474
|
</product>
|
471
475
|
EOT
|
472
476
|
|
@@ -474,33 +478,45 @@ describe Hash, "from_xml" do
|
|
474
478
|
'weight' => 0.5,
|
475
479
|
'image' => {'type' => 'ProductImage', 'filename' => 'image.gif' },
|
476
480
|
}
|
477
|
-
|
481
|
+
|
478
482
|
Hash.from_xml(product_xml)["product"].should == expected_product_hash
|
479
483
|
end
|
480
484
|
|
481
485
|
it "should handle unescaping from xml (ActiveResource Compatible)" do
|
482
486
|
xml_string = '<person><bare-string>First & Last Name</bare-string><pre-escaped-string>First &amp; Last Name</pre-escaped-string></person>'
|
483
|
-
expected_hash = {
|
484
|
-
'bare_string' => 'First & Last Name',
|
487
|
+
expected_hash = {
|
488
|
+
'bare_string' => 'First & Last Name',
|
485
489
|
'pre_escaped_string' => 'First & Last Name'
|
486
490
|
}
|
487
|
-
|
488
|
-
Hash.from_xml(xml_string)['person'].should == expected_hash
|
489
|
-
end
|
490
491
|
|
492
|
+
Hash.from_xml(xml_string)['person'].should == expected_hash
|
493
|
+
end
|
491
494
|
end
|
492
495
|
|
496
|
+
|
493
497
|
describe Hash, 'to_params' do
|
494
498
|
before do
|
495
499
|
@hash = { :name => 'Bob', :address => { :street => '111 Ruby Ave.', :city => 'Ruby Central', :phones => ['111-111-1111', '222-222-2222'] } }
|
496
500
|
end
|
497
|
-
|
501
|
+
|
498
502
|
it 'should convert correctly into query parameters' do
|
499
503
|
@hash.to_params.split('&').sort.should ==
|
500
504
|
'name=Bob&address[city]=Ruby Central&address[phones]=111-111-1111222-222-2222&address[street]=111 Ruby Ave.'.split('&').sort
|
501
505
|
end
|
502
|
-
|
506
|
+
|
503
507
|
it 'should not leave a trailing &' do
|
504
508
|
@hash.to_params.should_not match(/&$/)
|
505
509
|
end
|
506
|
-
end
|
510
|
+
end
|
511
|
+
|
512
|
+
|
513
|
+
describe Hash, 'to_mash' do
|
514
|
+
before :each do
|
515
|
+
@hash = Hash.new(10)
|
516
|
+
end
|
517
|
+
|
518
|
+
it "copies default Hash value to Mash" do
|
519
|
+
@mash = @hash.to_mash
|
520
|
+
@mash[:merb].should == 10
|
521
|
+
end
|
522
|
+
end
|