merb-core 0.9.3 → 0.9.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (178) hide show
  1. data/LICENSE +1 -1
  2. data/README +3 -3
  3. data/Rakefile +144 -33
  4. data/bin/merb +0 -0
  5. data/bin/merb-specs +0 -0
  6. data/docs/bootloading.dox +1 -0
  7. data/docs/merb-core-call-stack-diagram.mmap +0 -0
  8. data/docs/merb-core-call-stack-diagram.pdf +0 -0
  9. data/docs/merb-core-call-stack-diagram.png +0 -0
  10. data/lib/merb-core.rb +159 -37
  11. data/lib/merb-core/autoload.rb +1 -0
  12. data/lib/merb-core/bootloader.rb +208 -92
  13. data/lib/merb-core/config.rb +20 -6
  14. data/lib/merb-core/controller/abstract_controller.rb +113 -61
  15. data/lib/merb-core/controller/exceptions.rb +28 -13
  16. data/lib/merb-core/controller/merb_controller.rb +73 -44
  17. data/lib/merb-core/controller/mime.rb +25 -7
  18. data/lib/merb-core/controller/mixins/authentication.rb +1 -1
  19. data/lib/merb-core/controller/mixins/controller.rb +44 -8
  20. data/lib/merb-core/controller/mixins/render.rb +191 -128
  21. data/lib/merb-core/controller/mixins/responder.rb +65 -63
  22. data/lib/merb-core/controller/template.rb +103 -54
  23. data/lib/merb-core/core_ext.rb +7 -12
  24. data/lib/merb-core/core_ext/kernel.rb +128 -136
  25. data/lib/merb-core/dispatch/cookies.rb +26 -4
  26. data/lib/merb-core/dispatch/default_exception/default_exception.rb +93 -0
  27. data/lib/merb-core/dispatch/default_exception/views/_css.html.erb +198 -0
  28. data/lib/merb-core/dispatch/default_exception/views/_javascript.html.erb +73 -0
  29. data/lib/merb-core/dispatch/default_exception/views/index.html.erb +92 -0
  30. data/lib/merb-core/dispatch/dispatcher.rb +156 -224
  31. data/lib/merb-core/dispatch/request.rb +126 -25
  32. data/lib/merb-core/dispatch/router.rb +61 -6
  33. data/lib/merb-core/dispatch/router/behavior.rb +122 -41
  34. data/lib/merb-core/dispatch/router/route.rb +147 -22
  35. data/lib/merb-core/dispatch/session.rb +52 -2
  36. data/lib/merb-core/dispatch/session/cookie.rb +4 -2
  37. data/lib/merb-core/dispatch/session/memcached.rb +38 -27
  38. data/lib/merb-core/dispatch/session/memory.rb +18 -11
  39. data/lib/merb-core/dispatch/worker.rb +28 -0
  40. data/lib/merb-core/gem_ext/erubis.rb +58 -0
  41. data/lib/merb-core/logger.rb +3 -31
  42. data/lib/merb-core/plugins.rb +25 -3
  43. data/lib/merb-core/rack.rb +18 -12
  44. data/lib/merb-core/rack/adapter.rb +10 -8
  45. data/lib/merb-core/rack/adapter/ebb.rb +2 -2
  46. data/lib/merb-core/rack/adapter/irb.rb +31 -21
  47. data/lib/merb-core/rack/adapter/swiftiplied_mongrel.rb +26 -0
  48. data/lib/merb-core/rack/adapter/thin.rb +19 -9
  49. data/lib/merb-core/rack/adapter/thin_turbo.rb +24 -0
  50. data/lib/merb-core/rack/application.rb +9 -84
  51. data/lib/merb-core/rack/middleware.rb +26 -0
  52. data/lib/merb-core/rack/middleware/path_prefix.rb +31 -0
  53. data/lib/merb-core/rack/middleware/profiler.rb +19 -0
  54. data/lib/merb-core/rack/middleware/static.rb +45 -0
  55. data/lib/merb-core/server.rb +27 -9
  56. data/lib/merb-core/tasks/audit.rake +68 -0
  57. data/lib/merb-core/tasks/merb.rb +1 -0
  58. data/lib/merb-core/tasks/merb_rake_helper.rb +12 -0
  59. data/lib/merb-core/tasks/stats.rake +71 -0
  60. data/lib/merb-core/test.rb +2 -1
  61. data/lib/merb-core/test/helpers/multipart_request_helper.rb +3 -3
  62. data/lib/merb-core/test/helpers/request_helper.rb +66 -24
  63. data/lib/merb-core/test/matchers/controller_matchers.rb +36 -4
  64. data/lib/merb-core/test/matchers/route_matchers.rb +12 -3
  65. data/lib/merb-core/test/matchers/view_matchers.rb +3 -3
  66. data/lib/merb-core/test/run_specs.rb +1 -0
  67. data/lib/merb-core/test/tasks/spectasks.rb +13 -5
  68. data/lib/merb-core/test/test_ext/string.rb +14 -0
  69. data/lib/merb-core/vendor/facets/dictionary.rb +3 -3
  70. data/lib/merb-core/vendor/facets/inflect.rb +82 -37
  71. data/lib/merb-core/version.rb +2 -2
  72. data/spec/private/config/config_spec.rb +39 -4
  73. data/spec/private/core_ext/kernel_spec.rb +3 -14
  74. data/spec/private/dispatch/bootloader_spec.rb +1 -1
  75. data/spec/private/dispatch/cookies_spec.rb +181 -69
  76. data/spec/private/dispatch/fixture/app/controllers/exceptions.rb +0 -2
  77. data/spec/private/dispatch/fixture/app/controllers/foo.rb +0 -2
  78. data/spec/private/dispatch/fixture/config/rack.rb +10 -0
  79. data/spec/private/dispatch/fixture/log/merb_test.log +7054 -1802
  80. data/spec/private/dispatch/route_params_spec.rb +2 -3
  81. data/spec/private/dispatch/session_mixin_spec.rb +47 -0
  82. data/spec/private/plugins/plugin_spec.rb +73 -59
  83. data/spec/private/router/behavior_spec.rb +60 -0
  84. data/spec/private/router/fixture/log/merb_test.log +1693 -0
  85. data/spec/private/router/route_spec.rb +414 -0
  86. data/spec/private/router/router_spec.rb +175 -0
  87. data/spec/private/vendor/facets/plural_spec.rb +564 -0
  88. data/spec/private/vendor/facets/singular_spec.rb +489 -0
  89. data/spec/public/abstract_controller/controllers/cousins.rb +41 -0
  90. data/spec/public/abstract_controller/controllers/helpers.rb +12 -2
  91. data/spec/public/abstract_controller/controllers/partial.rb +17 -2
  92. data/spec/public/abstract_controller/controllers/render.rb +16 -1
  93. data/spec/public/abstract_controller/controllers/views/helpers/capture_eq/index.erb +1 -0
  94. data/spec/public/abstract_controller/controllers/views/helpers/capture_with_args/index.erb +1 -0
  95. data/spec/public/abstract_controller/controllers/views/merb/test/fixtures/abstract/render_two_throw_contents/index.erb +1 -0
  96. data/spec/public/abstract_controller/controllers/views/partial/partial_with_collections_and_counter/_collection.erb +1 -0
  97. data/spec/public/abstract_controller/controllers/views/partial/partial_with_collections_and_counter/index.erb +1 -0
  98. data/spec/public/abstract_controller/controllers/views/partial/with_absolute_partial/_partial.erb +1 -0
  99. data/spec/public/abstract_controller/controllers/views/partial/with_absolute_partial/index.erb +1 -0
  100. data/spec/public/abstract_controller/filter_spec.rb +20 -1
  101. data/spec/public/abstract_controller/helper_spec.rb +10 -2
  102. data/spec/public/abstract_controller/partial_spec.rb +8 -0
  103. data/spec/public/abstract_controller/render_spec.rb +8 -0
  104. data/spec/public/abstract_controller/spec_helper.rb +7 -3
  105. data/spec/public/boot_loader/boot_loader_spec.rb +2 -2
  106. data/spec/public/controller/base_spec.rb +10 -2
  107. data/spec/public/controller/config/init.rb +6 -0
  108. data/spec/public/controller/controllers/authentication.rb +9 -11
  109. data/spec/public/controller/controllers/base.rb +2 -8
  110. data/spec/public/controller/controllers/cookies.rb +16 -0
  111. data/spec/public/controller/controllers/dispatcher.rb +35 -0
  112. data/spec/public/controller/controllers/display.rb +62 -14
  113. data/spec/public/controller/controllers/redirect.rb +36 -0
  114. data/spec/public/controller/controllers/responder.rb +37 -11
  115. data/spec/public/controller/controllers/views/layout/custom_arg.json.erb +1 -0
  116. data/spec/public/controller/controllers/views/merb/test/fixtures/controllers/class_and_local_provides/index.html.erb +1 -0
  117. data/spec/public/controller/controllers/views/merb/test/fixtures/controllers/class_and_local_provides/index.xml.erb +1 -0
  118. data/spec/public/controller/controllers/views/merb/test/fixtures/controllers/display_with_template/no_layout.html.erb +1 -0
  119. data/spec/public/controller/cookies_spec.rb +23 -0
  120. data/spec/public/controller/dispatcher_spec.rb +411 -0
  121. data/spec/public/controller/display_spec.rb +43 -10
  122. data/spec/public/controller/redirect_spec.rb +33 -0
  123. data/spec/public/controller/responder_spec.rb +79 -11
  124. data/spec/public/controller/spec_helper.rb +3 -1
  125. data/spec/public/controller/url_spec.rb +10 -0
  126. data/spec/public/core/merb_core_spec.rb +11 -0
  127. data/spec/public/core_ext/fixtures/core_ext_dependency.rb +2 -0
  128. data/spec/public/core_ext/kernel_spec.rb +9 -0
  129. data/spec/public/core_ext/spec_helper.rb +1 -0
  130. data/spec/public/directory_structure/directory/log/merb_test.log +3729 -272
  131. data/spec/public/directory_structure/directory_spec.rb +3 -4
  132. data/spec/public/logger/logger_spec.rb +4 -4
  133. data/spec/public/reloading/directory/log/merb_test.log +288066 -15
  134. data/spec/public/reloading/reload_spec.rb +49 -27
  135. data/spec/public/request/multipart_spec.rb +26 -0
  136. data/spec/public/request/request_spec.rb +21 -2
  137. data/spec/public/router/fixation_spec.rb +27 -0
  138. data/spec/public/router/fixture/log/merb_test.log +30050 -0
  139. data/spec/public/router/nested_matches_spec.rb +97 -0
  140. data/spec/public/router/resource_spec.rb +1 -9
  141. data/spec/public/router/resources_spec.rb +0 -20
  142. data/spec/public/router/spec_helper.rb +27 -9
  143. data/spec/public/router/special_spec.rb +21 -8
  144. data/spec/public/template/template_spec.rb +17 -5
  145. data/spec/public/test/controller_matchers_spec.rb +10 -0
  146. data/spec/public/test/request_helper_spec.rb +29 -0
  147. data/spec/public/test/route_helper_spec.rb +18 -1
  148. data/spec/public/test/route_matchers_spec.rb +28 -1
  149. data/spec/public/test/view_matchers_spec.rb +3 -3
  150. data/spec/spec_helper.rb +56 -12
  151. metadata +89 -47
  152. data/lib/merb-core/core_ext/class.rb +0 -299
  153. data/lib/merb-core/core_ext/hash.rb +0 -426
  154. data/lib/merb-core/core_ext/mash.rb +0 -154
  155. data/lib/merb-core/core_ext/object.rb +0 -147
  156. data/lib/merb-core/core_ext/object_space.rb +0 -14
  157. data/lib/merb-core/core_ext/rubygems.rb +0 -28
  158. data/lib/merb-core/core_ext/set.rb +0 -46
  159. data/lib/merb-core/core_ext/string.rb +0 -89
  160. data/lib/merb-core/core_ext/time.rb +0 -13
  161. data/lib/merb-core/dispatch/exceptions.html.erb +0 -297
  162. data/spec/private/core_ext/class_spec.rb +0 -22
  163. data/spec/private/core_ext/hash_spec.rb +0 -522
  164. data/spec/private/core_ext/object_spec.rb +0 -121
  165. data/spec/private/core_ext/set_spec.rb +0 -26
  166. data/spec/private/core_ext/string_spec.rb +0 -167
  167. data/spec/private/core_ext/time_spec.rb +0 -16
  168. data/spec/private/dispatch/dispatch_spec.rb +0 -26
  169. data/spec/private/dispatch/fixture/log/development.log +0 -1
  170. data/spec/private/dispatch/fixture/log/merb.4000.pid +0 -1
  171. data/spec/private/dispatch/fixture/log/production.log +0 -1
  172. data/spec/private/dispatch/fixture/merb.4000.pid +0 -1
  173. data/spec/private/rack/application_spec.rb +0 -43
  174. data/spec/public/controller/log/merb.4000.pid +0 -1
  175. data/spec/public/directory_structure/directory/log/merb.4000.pid +0 -1
  176. data/spec/public/directory_structure/directory/merb.4000.pid +0 -1
  177. data/spec/public/reloading/directory/log/merb.4000.pid +0 -1
  178. data/spec/public/reloading/directory/merb.4000.pid +0 -1
@@ -1,13 +0,0 @@
1
- class Time
2
-
3
- # ==== Returns
4
- # String::
5
- # ISO 8601 compatible rendering of the Time object's properties.
6
- #
7
- # ==== Examples
8
- # Time.now.to_json # => "\"2008-03-28T17:54:20-05:00\""
9
- def to_json
10
- self.xmlschema.to_json
11
- end
12
-
13
- end
@@ -1,297 +0,0 @@
1
- <html>
2
- <head>
3
- <meta http-equiv="Content-type" content="text/html; charset=utf-8">
4
- <title><%= @exception_name %></title>
5
- <style type="text/css" media="screen">
6
- body {
7
- font-family:arial;
8
- font-size:11px;
9
- }
10
- h1 {
11
- font-size:48px;
12
- letter-spacing:-4px;
13
- margin:0;
14
- line-height:36px;
15
- color:#333;
16
- }
17
- h1 sup {
18
- font-size: 0.5em;
19
- }
20
- h1 sup.error_500, h1 sup.error_400 {
21
- color:#990E05;
22
- }
23
- h1 sup.error_100, h1 sup.error_200 {
24
- color:#00BF10;
25
- }
26
- h1 sup.error_300 {
27
- /* pretty sure you cant 'see' status 300
28
- errors but if you could I think they
29
- would be blue */
30
- color:#1B2099;
31
- }
32
- h2 {
33
- font-size:36px;
34
- letter-spacing:-3px;
35
- margin:0;
36
- line-height:28px;
37
- color:#444;
38
- }
39
- h3 {
40
- cursor: pointer;
41
- color: #006;
42
- text-decoration: underline;
43
- }
44
- a, a:visited {
45
- color:#00BF10;
46
- }
47
- .internalError {
48
- width:800px;
49
- margin:50px auto;
50
- }
51
- .header {
52
- border-bottom:10px solid #333;
53
- margin-bottom:1px;
54
- background-image: url("data:image/gif;base64,R0lGODlhAwADAIAAAP///8zMzCH5BAAAAAAALAAAAAADAAMAAAIEBHIJBQA7");
55
- padding:20px;
56
- }
57
- table.listing {
58
- border-collapse: collapse;
59
- font-size: 12px;
60
- width: 100%;
61
- }
62
-
63
- table.listing th {
64
- background-color: #000;
65
- color: #fff;
66
- }
67
-
68
- table.listing td, table.listing th {
69
- padding: 5px;
70
- text-align: left;
71
- vertical-align: top;
72
- }
73
-
74
- table.listing tr.odd {
75
- background-color: #ccc;
76
- }
77
-
78
- table.listing tr.even {
79
- background-color: #aaa;
80
- }
81
-
82
- table.listing td[colspan=2] {
83
- text-align: center;
84
- }
85
-
86
- table.trace {
87
- width:100%;
88
- font-family:courier, monospace;
89
- letter-spacing:-1px;
90
- border-collapse: collapse;
91
- border-spacing:0;
92
- }
93
- table.trace tr td{
94
- padding:0;
95
- height:26px;
96
- font-size:13px;
97
- vertical-align:middle;
98
- }
99
- table.trace tr.file{
100
- border-top:2px solid #fff;
101
- background-color:#F3F3F3;
102
- }
103
- table.trace tr.source {
104
- background-color:#F8F8F8;
105
- display:none;
106
- }
107
- table.trace .open tr.source {
108
- display:table-row;
109
- }
110
- table.trace tr.file td.expand {
111
- width:23px;
112
- background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABcAAAAXCAIAAABvSEP3AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAdVJREFUeNqMVL+TwUAYxaRIOlEhlZHGDAUzzOQ61+AqXMV1lJSU7q/QRqm8KFUcJTNn5qJkaPyoKKVz7y4mF8na5Kt29tt9+/Z97/u81+vVQ4r9frdarS6Xi7ETDIZisRjxMGPfmk4niNPpZE+xLAugbPaZ53nzvtfMBe/3+/3dbuehBrAKhZdUKkVAWa9Xsiybv0CPZDJZLr/qa5/BwgwRjYqOKIvFYjQa/aNommZh0Ww2K5UqzwfoQOPxaLPZ3FAmk0+7lplMpt1u53J5OpBOR0eZEE9wHJfP5zud93g88QhluwWbjW+5VOmKBgKBer3eaDTDYeGBQF8+x7rqIYoiPgixWJazpA6HA+MSxRArkUgMh0M409g8Ho8+9wYxxCqVSq1W26EDHGM2m4HOHQrEc38f/Yn7cLmlIRhBENzcx8cVRZnPZ/YUep2BWkjTIfA+PKVpZAXR5QxsjiqCKvGEqqp443w+0dvy17swqD0HB3S73V5PpkNg1qBqt8kwGCjmPkinM0QJbIoEa7U6UG6ToVgs4V9G2g0ESoP5Aoi7KYX5oCgf8IKbkvn9/mr1LRQKESamzgJy0g0tSZIuB3nuGqRU9Vv9C4sKkUhEkp4soxvxI8AAhWrrtXa3X8EAAAAASUVORK5CYII=);
113
- background-position:top left;
114
- background-repeat:no-repeat;
115
- }
116
- table.trace tr.file td.expand div {
117
- width:23px;
118
- }
119
- table.trace .open tr.file td.expand {
120
- width:19px;
121
- background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABcAAAB1CAIAAAAqdO2mAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAXZJREFUeNrslK1ywkAUhcMOBomEOiSdqLxEBJX0NaijOsjyHGGmCGyQQYaiiiw4gktkcOmZbpsuuzQ/M5XnqJ2d3S/n3nM3rTzPLUP7/Tt0+pLcGQwG3W53OLyHzPMtjYL7q9UqSRLrD4E1Gj1orCvKYuFHUWTVkOM44/HjDcp8/lL4r6NerzeZPMm1KFw0QkDn83m5fP2lHA4fNQvRtNvtjsfDd0WzmSfb2e/fdTqdOvdh/HLJZLOn0+d2HJ+KRGzbdl23EpFlmed5cp2maRzHQq1lvQ5KMi6EUZBGfup6E1pTfd+vrGW7jbQ2C9hTt9BpqNyIWaAwAy6xg2eBz5iRC/NomiZhGN5sqmnkauo0BUGgVQoBjQ80oCACgNQdZHfTYBkF2mxCtWWAqunWpahxIDUt3QYUxIFQpJHyIWpXjinabKbbwItMHT+NyjchrP8QKaSQQgoppJBCCimkkEIKKaSQQgoppJBCCimkkEIKKaSo+hRgAEFD17X08O2NAAAAAElFTkSuQmCC);
122
- background-position:top left;
123
- background-repeat:no-repeat;
124
- }
125
- table.trace .open tr.file td.expand div {
126
- width:19px;
127
- }
128
- table.trace tr.source td.collapse {
129
- width:19px;
130
- background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABcAAAB1CAIAAAAqdO2mAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAVxJREFUeNrs0zFygkAUBmBlUkgJHdABlQwVkVJKKUxBYWbkALTxMJwhltyDFkss03IF8pudIcwaDaDl/6pd2P327b7d+eHwMXs4lNkzggoVKlSoUKFChQoVKlSoUKFChQoVKlSoUKFChQqVEYqm6ft9+qiSJEkYho7jTlcw2fd9NOI4nq4gEdFwXXe1Cqco63VkWVbXRTqLhTpOwQRpF7quR1E0TgGhqvLKUFCyoQqG/rks3O6kZKW/eRFpevOCoGTXVTcMQ5EyxyDEkML1c5RzuZOICIyXqn7JBVez6282MWrx731HOv2qB8Hri2lamNk0DfpVVdV1Peodappmmua8bdvzuc7zfNprzrLMth1FnGh/X8MjCAIQv/cFz/+65PcDh7rbvYv2ZUfdj+PxsyzLgVl0hKwgTqeqKApx2LeOc7t98zyv/1FWOgvx9RPii23bmL9cetJ8Ed8CDAC6aFW8bCzFhwAAAABJRU5ErkJggg==);
131
- background-position:bottom left;
132
- background-repeat:no-repeat;
133
- background-color:#6F706F;
134
- }
135
- table.trace tr td.path {
136
- padding-left:10px;
137
- }
138
- table.trace tr td.code {
139
- padding-left:35px;
140
- white-space: pre;
141
- line-height:9px;
142
- padding-bottom:10px;
143
- }
144
- table.trace tr td.code em {
145
- font-weight:bold;
146
- color:#00BF10;
147
- }
148
- table.trace tr td.code a {
149
- width: 20px;
150
- float: left;
151
- }
152
- table.trace tr td.code .more {
153
- color:#666;
154
- }
155
- table.trace tr td.line {
156
- width:30px;
157
- text-align:right;
158
- padding-right:4px;
159
- }
160
- .footer {
161
- margin-top:5px;
162
- font-size:11px;
163
- color:#444;
164
- text-align:right;
165
- }
166
- </style>
167
- </head>
168
- <body>
169
- <div class="internalError">
170
-
171
- <div class="header">
172
- <h1><%= @exception_name %> <sup class="error_<%= @exception.class.status %>"><%= @exception.class.status %></sup></h1>
173
- <% if show_details = ::Merb::Config[:exception_details] -%>
174
- <h2><%= html_escape(@exception.message) %></h2>
175
- <% else -%>
176
- <h2>Sorry about that...</h2>
177
- <% end -%>
178
-
179
- <h3>Parameters</h3>
180
- <table class="listing" style="display: none">
181
- <thead>
182
- <tr><th width="25%">Parameter</th><th width="75%">Value</th></tr>
183
- </thead>
184
- <tbody>
185
- <% params[:original_params].each_with_index do |param_value, i| %>
186
- <tr class="<%= i % 2 == 0 ? "even" : "odd" %>"><td><%= param_value.first %></td><td><%= param_value.last.inspect %></td></tr>
187
- <% end %>
188
- <%= "<tr class='odd'><td colspan='2'>None</td></tr>" if params[:original_params].empty? %>
189
- </tbody>
190
- </table>
191
-
192
- <h3>Session</h3>
193
- <table class="listing" style="display: none">
194
- <thead>
195
- <tr><th width="25%">Key</th><th width="75%">Value</th></tr>
196
- </thead>
197
- <tbody>
198
- <% params[:original_session].each_with_index do |param_value, i| %>
199
- <tr class="<%= i % 2 == 0 ? "even" : "odd" %>"><td><%= param_value.first %></td><td><%= param_value.last.inspect %></td></tr>
200
- <% end %>
201
- <%= "<tr class='odd'><td colspan='2'>None</td></tr>" if params[:original_session].empty? %>
202
- </tbody>
203
- </table>
204
-
205
- <h3>Cookies</h3>
206
- <table class="listing" style="display: none">
207
- <thead>
208
- <tr><th width="25%">Cookie</th><th width="75%">Value</th></tr>
209
- </thead>
210
- <tbody>
211
- <% params[:original_cookies].each_with_index do |param_value, i| %>
212
- <tr class="<%= i % 2 == 0 ? "even" : "odd" %>"><td><%= param_value.first %></td><td><%= param_value.last.inspect %></td></tr>
213
- <% end %>
214
- <%= "<tr class='odd'><td colspan='2'>None</td></tr>" if params[:original_cookies].empty? %>
215
- </tbody>
216
- </table>
217
-
218
- <h3>Named Routes</h3>
219
- <table class="listing" style="display: none">
220
- <% unless Merb::Router.named_routes.empty? %>
221
- <thead>
222
- <tr><th width="25%">Name</th><th width="75%">Route</th></tr>
223
- </thead>
224
- <tbody>
225
- <% Merb::Router.named_routes.each_with_index do |name_route, i| %>
226
- <tr class="<%= i % 2 == 0 ? "even" : "odd" %>"><td><%= name_route.first %></td><td><%= name_route.last %></td></tr>
227
- <% end %>
228
- </tbody>
229
- <% else %>
230
- <tr><td colspan="2">None</td></tr>
231
- <% end %>
232
- </table>
233
- </div>
234
-
235
- <% if show_details %>
236
- <table class="trace">
237
- <% @exception.backtrace.each_with_index do |line, index| %>
238
- <tbody class="close">
239
- <tr class="file">
240
- <td class="expand"><div>&nbsp;</div></td>
241
- <td class="path">
242
- <%= (line.match(/^([^:]+)/)[1] rescue 'unknown').sub(/\/((opt|usr)\/local\/lib\/(ruby\/)?(gems\/)?(1.8\/)?(gems\/)?|.+\/app\/)/, '') %>
243
- <% unless line.match(/\.erb:/) %>
244
- in "<strong><%= line.match(/:in `(.+)'$/)[1] rescue '?' %></strong>"
245
- <% else %>
246
- (<strong>ERB Template</strong>)
247
- <% end %>
248
- </td>
249
- <td class="line">
250
- <a href="txmt://open?url=file://<%=file = (line.match(/^([^:]+)/)[1] rescue 'unknown')%>&amp;line=<%= lineno = line.match(/:([0-9]+):/)[1] rescue '?' %>"><%=lineno%></a>&nbsp;
251
- </td>
252
- </tr>
253
- <tr class="source">
254
- <td class="collapse">
255
- </td>
256
- <td class="code" colspan="2"><% (__caller_lines__(file, lineno, 5) rescue []).each do |llineno, lcode, lcurrent| %>
257
- <a href="txmt://open?url=file://<%=file%>&amp;line=<%=llineno%>"><%= llineno %></a><%='<em>' if llineno==lineno.to_i %><%= lcode.size > 90 ? Erubis::XmlHelper.escape_xml(lcode[0..90])+'<span class="more">......</span>' : Erubis::XmlHelper.escape_xml(lcode) %><%='</em>' if llineno==lineno.to_i %>
258
- <% end %>
259
-
260
- </td>
261
- </tr>
262
- </tbody>
263
- <% end %>
264
- </table>
265
- <script type="text/javascript" charset="utf-8">
266
- els = document.getElementsByTagName('td');
267
- for(i=0; i<els.length; i++){
268
- // swap the open & closed classes
269
- if(els[i].className=='expand' || els[i].className=='collapse'){
270
- els[i].onclick = function(e){
271
- tbody = this.parentNode.parentNode;
272
- if(tbody.className=='open'){
273
- tbody.className='closed';
274
- }else{
275
- tbody.className='open';
276
- }
277
- }
278
- }
279
- }
280
- els = document.getElementsByTagName("h3");
281
- for(i=0; i<els.length; i++) {
282
- els[i].onclick = function(e) {
283
- var tag = this.nextSibling;
284
- while(tag.nodeType != 1) {
285
- tag = tag.nextSibling;
286
- }
287
- tag.style.display = tag.style.display == "none" ? "" : "none";
288
- }
289
- }
290
- </script>
291
- <% end %>
292
- <div class="footer">
293
- lots of love, from <a href="#">merb</a>
294
- </div>
295
- </div>
296
- </body>
297
- </html>
@@ -1,22 +0,0 @@
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
@@ -1,522 +0,0 @@
1
- require File.dirname(__FILE__) + '/../../spec_helper'
2
- require "date"
3
- require 'bigdecimal'
4
-
5
- describe Hash, "environmentize_keys!" do
6
- it "should transform keys to uppercase text" do
7
- { :test_1 => 'test', 'test_2' => 'test', 1 => 'test' }.environmentize_keys!.should ==
8
- { 'TEST_1' => 'test', 'TEST_2' => 'test', '1' => 'test' }
9
- end
10
-
11
- it "should only transform one level of keys" do
12
- { :test_1 => { :test2 => 'test'} }.environmentize_keys!.should ==
13
- { 'TEST_1' => { :test2 => 'test'} }
14
- end
15
- end
16
-
17
-
18
- describe Hash, "only" do
19
- before do
20
- @hash = { :one => 'ONE', 'two' => 'TWO', 3 => 'THREE' }
21
- end
22
-
23
- it "should return a hash with only the given key(s)" do
24
- @hash.only(:one).should == { :one => 'ONE' }
25
- @hash.only(:one, 3).should == { :one => 'ONE', 3 => 'THREE' }
26
- end
27
- end
28
-
29
-
30
- describe Hash, "except" do
31
- before do
32
- @hash = { :one => 'ONE', 'two' => 'TWO', 3 => 'THREE' }
33
- end
34
-
35
- it "should return a hash without only the given key(s)" do
36
- @hash.except(:one).should == { 'two' => 'TWO', 3 => 'THREE' }
37
- @hash.except(:one, 3).should == { 'two' => 'TWO' }
38
- end
39
- end
40
-
41
-
42
- describe Hash, "to_xml_attributes" do
43
- before do
44
- @hash = { :one => "ONE", "two" => "TWO" }
45
- end
46
-
47
- it "should turn the hash into xml attributes" do
48
- attrs = @hash.to_xml_attributes
49
- attrs.should match(/one="ONE"/m)
50
- attrs.should match(/two="TWO"/m)
51
- end
52
- end
53
-
54
-
55
- describe Hash, "from_xml" do
56
- it "should transform a simple tag with content" do
57
- xml = "<tag>This is the contents</tag>"
58
- Hash.from_xml(xml).should == { 'tag' => 'This is the contents' }
59
- end
60
-
61
- it "should work with cdata tags" do
62
- xml = <<-END
63
- <tag>
64
- <![CDATA[
65
- text inside cdata
66
- ]]>
67
- </tag>
68
- END
69
- Hash.from_xml(xml)["tag"].strip.should == "text inside cdata"
70
- end
71
-
72
- it "should transform a simple tag with attributes" do
73
- xml = "<tag attr1='1' attr2='2'></tag>"
74
- hash = { 'tag' => { 'attr1' => '1', 'attr2' => '2' } }
75
- Hash.from_xml(xml).should == hash
76
- end
77
-
78
- it "should transform repeating siblings into an array" do
79
- xml =<<-XML
80
- <opt>
81
- <user login="grep" fullname="Gary R Epstein" />
82
- <user login="stty" fullname="Simon T Tyson" />
83
- </opt>
84
- XML
85
-
86
- Hash.from_xml(xml)['opt']['user'].should be_an_instance_of(Array)
87
-
88
- hash = {
89
- 'opt' => {
90
- 'user' => [{
91
- 'login' => 'grep',
92
- 'fullname' => 'Gary R Epstein'
93
- },{
94
- 'login' => 'stty',
95
- 'fullname' => 'Simon T Tyson'
96
- }]
97
- }
98
- }
99
-
100
- Hash.from_xml(xml).should == hash
101
- end
102
-
103
- it "should not transform non-repeating siblings into an array" do
104
- xml =<<-XML
105
- <opt>
106
- <user login="grep" fullname="Gary R Epstein" />
107
- </opt>
108
- XML
109
-
110
- Hash.from_xml(xml)['opt']['user'].should be_an_instance_of(Hash)
111
-
112
- hash = {
113
- 'opt' => {
114
- 'user' => {
115
- 'login' => 'grep',
116
- 'fullname' => 'Gary R Epstein'
117
- }
118
- }
119
- }
120
-
121
- Hash.from_xml(xml).should == hash
122
- end
123
-
124
- it "should typecast an integer" do
125
- xml = "<tag type='integer'>10</tag>"
126
- Hash.from_xml(xml)['tag'].should == 10
127
- end
128
-
129
- it "should typecast a true boolean" do
130
- xml = "<tag type='boolean'>true</tag>"
131
- Hash.from_xml(xml)['tag'].should be_true
132
- end
133
-
134
- it "should typecast a false boolean" do
135
- ["false"].each do |w|
136
- Hash.from_xml("<tag type='boolean'>#{w}</tag>")['tag'].should be_false
137
- end
138
- end
139
-
140
- it "should typecast a datetime" do
141
- xml = "<tag type='datetime'>2007-12-31 10:32</tag>"
142
- Hash.from_xml(xml)['tag'].should == Time.parse( '2007-12-31 10:32' ).utc
143
- end
144
-
145
- it "should typecast a date" do
146
- xml = "<tag type='date'>2007-12-31</tag>"
147
- Hash.from_xml(xml)['tag'].should == Date.parse('2007-12-31')
148
- end
149
-
150
- it "should unescape html entities" do
151
- values = {
152
- "<" => "&lt;",
153
- ">" => "&gt;",
154
- '"' => "&quot;",
155
- "'" => "&apos;",
156
- "&" => "&amp;"
157
- }
158
- values.each do |k,v|
159
- xml = "<tag>Some content #{v}</tag>"
160
- Hash.from_xml(xml)['tag'].should match(Regexp.new(k))
161
- end
162
- end
163
-
164
- it "should undasherize keys as tags" do
165
- xml = "<tag-1>Stuff</tag-1>"
166
- Hash.from_xml(xml).keys.should include( 'tag_1' )
167
- end
168
-
169
- it "should undasherize keys as attributes" do
170
- xml = "<tag1 attr-1='1'></tag1>"
171
- Hash.from_xml(xml)['tag1'].keys.should include( 'attr_1')
172
- end
173
-
174
- it "should undasherize keys as tags and attributes" do
175
- xml = "<tag-1 attr-1='1'></tag-1>"
176
- Hash.from_xml(xml).keys.should include( 'tag_1' )
177
- Hash.from_xml(xml)['tag_1'].keys.should include( 'attr_1')
178
- end
179
-
180
- it "should render nested content correctly" do
181
- xml = "<root><tag1>Tag1 Content <em><strong>This is strong</strong></em></tag1></root>"
182
- Hash.from_xml(xml)['root']['tag1'].should == "Tag1 Content <em><strong>This is strong</strong></em>"
183
- end
184
-
185
- it "should render nested content with split text nodes correctly" do
186
- xml = "<root>Tag1 Content<em>Stuff</em> Hi There</root>"
187
- Hash.from_xml(xml)['root'].should == "Tag1 Content<em>Stuff</em> Hi There"
188
- end
189
-
190
- it "should ignore attributes when a child is a text node" do
191
- xml = "<root attr1='1'>Stuff</root>"
192
- Hash.from_xml(xml).should == { "root" => "Stuff" }
193
- end
194
-
195
- it "should ignore attributes when any child is a text node" do
196
- xml = "<root attr1='1'>Stuff <em>in italics</em></root>"
197
- Hash.from_xml(xml).should == { "root" => "Stuff <em>in italics</em>" }
198
- end
199
-
200
- it "should correctly transform multiple children" do
201
- xml = <<-XML
202
- <user gender='m'>
203
- <age type='integer'>35</age>
204
- <name>Home Simpson</name>
205
- <dob type='date'>1988-01-01</dob>
206
- <joined-at type='datetime'>2000-04-28 23:01</joined-at>
207
- <is-cool type='boolean'>true</is-cool>
208
- </user>
209
- XML
210
-
211
- hash = {
212
- "user" => {
213
- "gender" => "m",
214
- "age" => 35,
215
- "name" => "Home Simpson",
216
- "dob" => Date.parse('1988-01-01'),
217
- "joined_at" => Time.parse("2000-04-28 23:01"),
218
- "is_cool" => true
219
- }
220
- }
221
-
222
- Hash.from_xml(xml).should == hash
223
- end
224
-
225
- it "should properly handle nil values (ActiveSupport Compatible)" do
226
- topic_xml = <<-EOT
227
- <topic>
228
- <title></title>
229
- <id type="integer"></id>
230
- <approved type="boolean"></approved>
231
- <written-on type="date"></written-on>
232
- <viewed-at type="datetime"></viewed-at>
233
- <content type="yaml"></content>
234
- <parent-id></parent-id>
235
- </topic>
236
- EOT
237
-
238
- expected_topic_hash = {
239
- 'title' => nil,
240
- 'id' => nil,
241
- 'approved' => nil,
242
- 'written_on' => nil,
243
- 'viewed_at' => nil,
244
- 'content' => nil,
245
- 'parent_id' => nil
246
- }
247
- Hash.from_xml(topic_xml)["topic"].should == expected_topic_hash
248
- end
249
-
250
- it "should handle a single record from xml (ActiveSupport Compatible)" do
251
- topic_xml = <<-EOT
252
- <topic>
253
- <title>The First Topic</title>
254
- <author-name>David</author-name>
255
- <id type="integer">1</id>
256
- <approved type="boolean"> true </approved>
257
- <replies-count type="integer">0</replies-count>
258
- <replies-close-in type="integer">2592000000</replies-close-in>
259
- <written-on type="date">2003-07-16</written-on>
260
- <viewed-at type="datetime">2003-07-16T09:28:00+0000</viewed-at>
261
- <content type="yaml">--- \n1: should be an integer\n:message: Have a nice day\narray: \n- should-have-dashes: true\n should_have_underscores: true\n</content>
262
- <author-email-address>david@loudthinking.com</author-email-address>
263
- <parent-id></parent-id>
264
- <ad-revenue type="decimal">1.5</ad-revenue>
265
- <optimum-viewing-angle type="float">135</optimum-viewing-angle>
266
- <resident type="symbol">yes</resident>
267
- </topic>
268
- EOT
269
-
270
- expected_topic_hash = {
271
- 'title' => "The First Topic",
272
- 'author_name' => "David",
273
- 'id' => 1,
274
- 'approved' => true,
275
- 'replies_count' => 0,
276
- 'replies_close_in' => 2592000000,
277
- 'written_on' => Date.new(2003, 7, 16),
278
- 'viewed_at' => Time.utc(2003, 7, 16, 9, 28),
279
- # Changed this line where the key is :message. The yaml specifies this as a symbol, and who am I to change what you specify
280
- # The line in ActiveSupport is
281
- # 'content' => { 'message' => "Have a nice day", 1 => "should be an integer", "array" => [{ "should-have-dashes" => true, "should_have_underscores" => true }] },
282
- 'content' => { :message => "Have a nice day", 1 => "should be an integer", "array" => [{ "should-have-dashes" => true, "should_have_underscores" => true }] },
283
- 'author_email_address' => "david@loudthinking.com",
284
- 'parent_id' => nil,
285
- 'ad_revenue' => BigDecimal("1.50"),
286
- 'optimum_viewing_angle' => 135.0,
287
- 'resident' => :yes
288
- }
289
-
290
- Hash.from_xml(topic_xml)["topic"].each do |k,v|
291
- v.should == expected_topic_hash[k]
292
- end
293
- end
294
-
295
- it "should handle multiple records (ActiveSupport Compatible)" do
296
- topics_xml = <<-EOT
297
- <topics type="array">
298
- <topic>
299
- <title>The First Topic</title>
300
- <author-name>David</author-name>
301
- <id type="integer">1</id>
302
- <approved type="boolean">false</approved>
303
- <replies-count type="integer">0</replies-count>
304
- <replies-close-in type="integer">2592000000</replies-close-in>
305
- <written-on type="date">2003-07-16</written-on>
306
- <viewed-at type="datetime">2003-07-16T09:28:00+0000</viewed-at>
307
- <content>Have a nice day</content>
308
- <author-email-address>david@loudthinking.com</author-email-address>
309
- <parent-id nil="true"></parent-id>
310
- </topic>
311
- <topic>
312
- <title>The Second Topic</title>
313
- <author-name>Jason</author-name>
314
- <id type="integer">1</id>
315
- <approved type="boolean">false</approved>
316
- <replies-count type="integer">0</replies-count>
317
- <replies-close-in type="integer">2592000000</replies-close-in>
318
- <written-on type="date">2003-07-16</written-on>
319
- <viewed-at type="datetime">2003-07-16T09:28:00+0000</viewed-at>
320
- <content>Have a nice day</content>
321
- <author-email-address>david@loudthinking.com</author-email-address>
322
- <parent-id></parent-id>
323
- </topic>
324
- </topics>
325
- EOT
326
-
327
- expected_topic_hash = {
328
- 'title' => "The First Topic",
329
- 'author_name' => "David",
330
- 'id' => 1,
331
- 'approved' => false,
332
- 'replies_count' => 0,
333
- 'replies_close_in' => 2592000000,
334
- 'written_on' => Date.new(2003, 7, 16),
335
- 'viewed_at' => Time.utc(2003, 7, 16, 9, 28),
336
- 'content' => "Have a nice day",
337
- 'author_email_address' => "david@loudthinking.com",
338
- 'parent_id' => nil
339
- }
340
- # puts Hash.from_xml(topics_xml)['topics'].first.inspect
341
- Hash.from_xml(topics_xml)["topics"].first.each do |k,v|
342
- v.should == expected_topic_hash[k]
343
- end
344
- end
345
-
346
- it "should handle a single record from_xml with attributes other than type (ActiveSupport Compatible)" do
347
- topic_xml = <<-EOT
348
- <rsp stat="ok">
349
- <photos page="1" pages="1" perpage="100" total="16">
350
- <photo id="175756086" owner="55569174@N00" secret="0279bf37a1" server="76" title="Colored Pencil PhotoBooth Fun" ispublic="1" isfriend="0" isfamily="0"/>
351
- </photos>
352
- </rsp>
353
- EOT
354
-
355
- expected_topic_hash = {
356
- 'id' => "175756086",
357
- 'owner' => "55569174@N00",
358
- 'secret' => "0279bf37a1",
359
- 'server' => "76",
360
- 'title' => "Colored Pencil PhotoBooth Fun",
361
- 'ispublic' => "1",
362
- 'isfriend' => "0",
363
- 'isfamily' => "0",
364
- }
365
- Hash.from_xml(topic_xml)["rsp"]["photos"]["photo"].each do |k,v|
366
- v.should == expected_topic_hash[k]
367
- end
368
- end
369
-
370
- it "should handle an emtpy array (ActiveSupport Compatible)" do
371
- blog_xml = <<-XML
372
- <blog>
373
- <posts type="array"></posts>
374
- </blog>
375
- XML
376
- expected_blog_hash = {"blog" => {"posts" => []}}
377
- Hash.from_xml(blog_xml).should == expected_blog_hash
378
- end
379
-
380
- it "should handle empty array with whitespace from xml (ActiveSupport Compatible)" do
381
- blog_xml = <<-XML
382
- <blog>
383
- <posts type="array">
384
- </posts>
385
- </blog>
386
- XML
387
- expected_blog_hash = {"blog" => {"posts" => []}}
388
- Hash.from_xml(blog_xml).should == expected_blog_hash
389
- end
390
-
391
- it "should handle array with one entry from_xml (ActiveSupport Compatible)" do
392
- blog_xml = <<-XML
393
- <blog>
394
- <posts type="array">
395
- <post>a post</post>
396
- </posts>
397
- </blog>
398
- XML
399
- expected_blog_hash = {"blog" => {"posts" => ["a post"]}}
400
- Hash.from_xml(blog_xml).should == expected_blog_hash
401
- end
402
-
403
- it "should handle array with multiple entries from xml (ActiveSupport Compatible)" do
404
- blog_xml = <<-XML
405
- <blog>
406
- <posts type="array">
407
- <post>a post</post>
408
- <post>another post</post>
409
- </posts>
410
- </blog>
411
- XML
412
- expected_blog_hash = {"blog" => {"posts" => ["a post", "another post"]}}
413
- Hash.from_xml(blog_xml).should == expected_blog_hash
414
- end
415
-
416
- it "should handle file types (ActiveSupport Compatible)" do
417
- blog_xml = <<-XML
418
- <blog>
419
- <logo type="file" name="logo.png" content_type="image/png">
420
- </logo>
421
- </blog>
422
- XML
423
- hash = Hash.from_xml(blog_xml)
424
- hash.should have_key('blog')
425
- hash['blog'].should have_key('logo')
426
-
427
- file = hash['blog']['logo']
428
- file.original_filename.should == 'logo.png'
429
- file.content_type.should == 'image/png'
430
- end
431
-
432
- it "should handle file from xml with defaults (ActiveSupport Compatible)" do
433
- blog_xml = <<-XML
434
- <blog>
435
- <logo type="file">
436
- </logo>
437
- </blog>
438
- XML
439
- file = Hash.from_xml(blog_xml)['blog']['logo']
440
- file.original_filename.should == 'untitled'
441
- file.content_type.should == 'application/octet-stream'
442
- end
443
-
444
- it "should handle xsd like types from xml (ActiveSupport Compatible)" do
445
- bacon_xml = <<-EOT
446
- <bacon>
447
- <weight type="double">0.5</weight>
448
- <price type="decimal">12.50</price>
449
- <chunky type="boolean"> 1 </chunky>
450
- <expires-at type="dateTime">2007-12-25T12:34:56+0000</expires-at>
451
- <notes type="string"></notes>
452
- <illustration type="base64Binary">YmFiZS5wbmc=</illustration>
453
- </bacon>
454
- EOT
455
-
456
- expected_bacon_hash = {
457
- 'weight' => 0.5,
458
- 'chunky' => true,
459
- 'price' => BigDecimal("12.50"),
460
- 'expires_at' => Time.utc(2007,12,25,12,34,56),
461
- 'notes' => "",
462
- 'illustration' => "babe.png"
463
- }
464
-
465
- Hash.from_xml(bacon_xml)["bacon"].should == expected_bacon_hash
466
- end
467
-
468
- it "should let type trickle through when unknown (ActiveSupport Compatible)" do
469
- product_xml = <<-EOT
470
- <product>
471
- <weight type="double">0.5</weight>
472
- <image type="ProductImage"><filename>image.gif</filename></image>
473
-
474
- </product>
475
- EOT
476
-
477
- expected_product_hash = {
478
- 'weight' => 0.5,
479
- 'image' => {'type' => 'ProductImage', 'filename' => 'image.gif' },
480
- }
481
-
482
- Hash.from_xml(product_xml)["product"].should == expected_product_hash
483
- end
484
-
485
- it "should handle unescaping from xml (ActiveResource Compatible)" do
486
- xml_string = '<person><bare-string>First &amp; Last Name</bare-string><pre-escaped-string>First &amp;amp; Last Name</pre-escaped-string></person>'
487
- expected_hash = {
488
- 'bare_string' => 'First & Last Name',
489
- 'pre_escaped_string' => 'First &amp; Last Name'
490
- }
491
-
492
- Hash.from_xml(xml_string)['person'].should == expected_hash
493
- end
494
- end
495
-
496
-
497
- describe Hash, 'to_params' do
498
- before do
499
- @hash = { :name => 'Bob', :address => { :street => '111 Ruby Ave.', :city => 'Ruby Central', :phones => ['111-111-1111', '222-222-2222'] } }
500
- end
501
-
502
- it 'should convert correctly into query parameters' do
503
- @hash.to_params.split('&').sort.should ==
504
- 'name=Bob&address[city]=Ruby Central&address[phones]=111-111-1111222-222-2222&address[street]=111 Ruby Ave.'.split('&').sort
505
- end
506
-
507
- it 'should not leave a trailing &' do
508
- @hash.to_params.should_not match(/&$/)
509
- 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