merb-core 0.9.2 → 0.9.3
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/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
|