orange 0.0.2

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.
Files changed (53) hide show
  1. data/README.markdown +154 -0
  2. data/lib/orange.rb +7 -0
  3. data/lib/orange/application.rb +125 -0
  4. data/lib/orange/carton.rb +114 -0
  5. data/lib/orange/cartons/site_carton.rb +9 -0
  6. data/lib/orange/core.rb +197 -0
  7. data/lib/orange/magick.rb +91 -0
  8. data/lib/orange/middleware/access_control.rb +100 -0
  9. data/lib/orange/middleware/base.rb +41 -0
  10. data/lib/orange/middleware/database.rb +22 -0
  11. data/lib/orange/middleware/globals.rb +18 -0
  12. data/lib/orange/middleware/recapture.rb +19 -0
  13. data/lib/orange/middleware/rerouter.rb +13 -0
  14. data/lib/orange/middleware/restful_router.rb +59 -0
  15. data/lib/orange/middleware/route_context.rb +39 -0
  16. data/lib/orange/middleware/route_site.rb +51 -0
  17. data/lib/orange/middleware/show_exceptions.rb +78 -0
  18. data/lib/orange/middleware/site_load.rb +33 -0
  19. data/lib/orange/middleware/static.rb +81 -0
  20. data/lib/orange/middleware/static_file.rb +32 -0
  21. data/lib/orange/middleware/template.rb +61 -0
  22. data/lib/orange/model_resource.rb +170 -0
  23. data/lib/orange/packet.rb +88 -0
  24. data/lib/orange/resource.rb +37 -0
  25. data/lib/orange/resources/flex_router.rb +13 -0
  26. data/lib/orange/resources/mapper.rb +55 -0
  27. data/lib/orange/resources/page_parts.rb +54 -0
  28. data/lib/orange/resources/parser.rb +60 -0
  29. data/lib/orange/routable_resource.rb +16 -0
  30. data/lib/orange/stack.rb +201 -0
  31. data/spec/application_spec.rb +146 -0
  32. data/spec/carton_spec.rb +5 -0
  33. data/spec/core_spec.rb +231 -0
  34. data/spec/magick_spec.rb +89 -0
  35. data/spec/mock/mock_app.rb +17 -0
  36. data/spec/mock/mock_core.rb +2 -0
  37. data/spec/mock/mock_middleware.rb +13 -0
  38. data/spec/mock/mock_mixins.rb +19 -0
  39. data/spec/mock/mock_pulp.rb +24 -0
  40. data/spec/mock/mock_resource.rb +5 -0
  41. data/spec/mock/mock_router.rb +10 -0
  42. data/spec/model_resource_spec.rb +5 -0
  43. data/spec/orange_spec.rb +19 -0
  44. data/spec/packet_spec.rb +134 -0
  45. data/spec/resource_spec.rb +5 -0
  46. data/spec/resources/flex_router_spec.rb +5 -0
  47. data/spec/resources/mapper_spec.rb +5 -0
  48. data/spec/resources/parser_spec.rb +5 -0
  49. data/spec/routable_resource_spec.rb +5 -0
  50. data/spec/spec_helper.rb +16 -0
  51. data/spec/stack_spec.rb +202 -0
  52. data/spec/stats.rb +182 -0
  53. metadata +194 -0
@@ -0,0 +1,146 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
+
3
+ describe Orange::Application do
4
+ before(:all) do
5
+ class MockApplication
6
+ set :banana, 'foo'
7
+ attr_accessor :quux, :wibble
8
+ def init
9
+ opts[:init] = true
10
+ @quux = true
11
+ end
12
+ def stack_init
13
+ opts[:stack_init] = true
14
+ @wibble = true
15
+ end
16
+ end
17
+ end
18
+
19
+ def app
20
+ MockApplication.app
21
+ end
22
+
23
+ it "should be a subclass of Orange::Application" do
24
+ MockApplication.new(Orange::Core.new).should be_a_kind_of(Orange::Application)
25
+ end
26
+
27
+ it "should have a stack method" do
28
+ MockApplication.should respond_to(:stack)
29
+ end
30
+
31
+ it "should have a different app stack after using stack method" do
32
+ lambda {
33
+ MockApplication.stack do
34
+ end
35
+ }.should change(MockApplication, :app)
36
+ end
37
+
38
+ it "should respond to the app method" do
39
+ MockApplication.should respond_to(:app)
40
+ end
41
+
42
+ it "should return an Orange::Stack with the app method" do
43
+ MockApplication.stack do
44
+ end
45
+ MockApplication.app.should be_an_instance_of(Orange::Stack)
46
+ end
47
+
48
+ it "should be able to set options" do
49
+ MockApplication.set(:test4, Time.now.to_f-5)
50
+ opts_test4 = MockApplication.opts[:test4]
51
+ MockApplication.set(:test4, Time.now.to_f)
52
+ MockApplication.opts[:test4].should_not == opts_test4
53
+ MockApplication.opts[:banana].should == 'foo'
54
+ end
55
+
56
+ it "should be able to accept instance option setting" do
57
+ x= MockApplication.new(Orange::Core.new, {:test => 'go'}){
58
+ baz 'bar'
59
+ }
60
+ x.opts.should have_key(:baz)
61
+ x.opts.should have_key(:banana)
62
+ x.opts[:baz].should == 'bar'
63
+ x.opts[:test].should == 'go'
64
+ end
65
+
66
+ it "should override class variables with instance ones" do
67
+ x= MockApplication.new(Orange::Core.new)
68
+ y= MockApplication.new(Orange::Core.new){
69
+ banana 'bar'
70
+ }
71
+ x.opts.should have_key(:banana)
72
+ y.opts.should have_key(:banana)
73
+ x.opts[:banana].should == 'foo'
74
+ y.opts[:banana].should == 'bar'
75
+ x.opts[:banana].should_not == y.opts[:banana]
76
+ end
77
+
78
+ it "should be able to access options via #opts" do
79
+ x= MockApplication.new(Orange::Core.new){
80
+ baz 'bar'
81
+ }
82
+ x.opts.should be_an_instance_of(Hash)
83
+ x.opts.should respond_to(:[])
84
+ x.opts.should have_key(:baz)
85
+ x.opts[:baz].should == 'bar'
86
+ end
87
+
88
+ it "should call init after being initialized" do
89
+ x=MockApplication.new(Orange::Core.new){
90
+ init false
91
+ }
92
+ x.opts[:init].should be_true
93
+ x.quux.should be_true
94
+ end
95
+
96
+ it "should call stack_init after stack loaded" do
97
+ c = Orange::Core.new
98
+ app = MockApplication.new(c){
99
+ stack_init false
100
+ }
101
+ c.fire(:stack_loaded, false) # Falsify the stack_load call
102
+ app.opts[:stack_init].should be_true
103
+ app.wibble.should be_true
104
+ end
105
+
106
+ it "should raise a default error if route isn't redefined" do
107
+ x= MockApplication.new(Orange::Core.new)
108
+ lambda{
109
+ x.route(Orange::Packet.new(x.orange, {}))
110
+ }.should raise_error(Exception, 'default response from Orange::Application.route')
111
+ end
112
+
113
+ it "should return the orange core on #orange" do
114
+ c = Orange::Core.new
115
+ x= MockApplication.new(c)
116
+ x.orange.should eql(c)
117
+ end
118
+
119
+ it "should change the core on #set_core(orange_core)" do
120
+ c1 = Orange::Core.new
121
+ c2 = Orange::Core.new
122
+ x= MockApplication.new(c1)
123
+ c1.should_not eql(c2)
124
+ lambda {
125
+ x.set_core(c2)
126
+ }.should change(x, :orange)
127
+ end
128
+
129
+ it "should respond correctly to call" do
130
+ x= MockApplication.new(Orange::Core.new)
131
+ lambda{
132
+ x.call({})
133
+ }.should raise_error(Exception, 'default response from Orange::Application.route')
134
+ r = TestRouter.new
135
+ lambda{
136
+ x.call({'orange.env' => {'route.router' => r}})
137
+ }.should change(r, :x)
138
+ end
139
+
140
+ it "should auto initialize the self.opts" do
141
+ lambda{
142
+ MockApplication2.opts
143
+ }.should_not raise_error
144
+ end
145
+
146
+ end
@@ -0,0 +1,5 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
+
3
+ describe Orange::Carton do
4
+ it "should be spec'ed"
5
+ end
@@ -0,0 +1,231 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
+
3
+ describe Orange::Core do
4
+ before(:all) do
5
+ class Orange::Core; attr_reader :resources, :events, :file; end;
6
+ end
7
+
8
+ it "should allow core mixin via class mixin method" do
9
+ c= Orange::Core.new
10
+ c.should_not respond_to(:mixin_core_one)
11
+ Orange::Core.mixin MockMixinCore1
12
+ c2= Orange::Core.new
13
+ c.should respond_to(:mixin_core_one)
14
+ c2.should respond_to(:mixin_core_one)
15
+ end
16
+
17
+ it "should allow pulp mixin via class pulp method" do
18
+ c= Orange::Core.new
19
+ p= Orange::Packet.new(c, {})
20
+ p.should_not respond_to(:pulp_core_one)
21
+ Orange::Core.add_pulp MockPulpCore1
22
+ p2= Orange::Packet.new(c, {})
23
+ p.should respond_to(:pulp_core_one)
24
+ p2.should respond_to(:pulp_core_one)
25
+ end
26
+
27
+ it "should allow core mixin via instance mixin method" do
28
+ c= Orange::Core.new
29
+ c.should_not respond_to(:mixin_core_two)
30
+ c.mixin MockMixinCore2
31
+ c2= Orange::Core.new
32
+ c.should respond_to(:mixin_core_two)
33
+ c2.should respond_to(:mixin_core_two)
34
+ end
35
+
36
+ it "should allow pulp mixin via instance pulp method" do
37
+ c= Orange::Core.new
38
+ p= Orange::Packet.new(c, {})
39
+ p.should_not respond_to(:pulp_core_two)
40
+ c.add_pulp MockPulpCore2
41
+ p2= Orange::Packet.new(c, {})
42
+ p.should respond_to(:pulp_core_two)
43
+ p2.should respond_to(:pulp_core_two)
44
+ end
45
+
46
+ it "should have three contexts by default" do
47
+ Orange::Core::DEFAULT_CORE_OPTIONS.should have_key(:contexts)
48
+ Orange::Core::DEFAULT_CORE_OPTIONS[:contexts].should have(3).items
49
+ end
50
+
51
+ it "should default to live context" do
52
+ Orange::Core::DEFAULT_CORE_OPTIONS.should have_key(:default_context)
53
+ Orange::Core::DEFAULT_CORE_OPTIONS[:default_context].should == :live
54
+ end
55
+
56
+ it "should load at least two resources by default" do
57
+ c= Orange::Core.new
58
+ c.resources.size.should >= 2
59
+ c.loaded?(:mapper).should be_true
60
+ c.loaded?(:parser).should be_true
61
+ end
62
+
63
+ it "should have no events by default" do
64
+ c= Orange::Core.new
65
+ c.events.should have(0).events
66
+ end
67
+
68
+ it "should return a directory that contains core.rb when calling core_dir" do
69
+ c= Orange::Core.new
70
+ c.core_dir.should match(/orange$/)
71
+ File.should exist(File.join(c.core_dir, 'core.rb'))
72
+ File.should exist(File.join(c.core_dir, 'stack.rb'))
73
+ File.should exist(File.join(c.core_dir, 'application.rb'))
74
+ File.should exist(File.join(c.core_dir, 'carton.rb'))
75
+ File.should exist(File.join(c.core_dir, 'views'))
76
+ File.should exist(File.join(c.core_dir, 'templates'))
77
+ File.should exist(File.join(c.core_dir, 'assets'))
78
+ end
79
+
80
+ it "should return the directory of the super class when calling core_dir on subclass" do
81
+ c= MockCoreSubclass.new
82
+ c.core_dir.should match(/orange$/)
83
+ File.should exist(File.join(c.core_dir, 'core.rb'))
84
+ File.should exist(File.join(c.core_dir, 'stack.rb'))
85
+ File.should exist(File.join(c.core_dir, 'application.rb'))
86
+ File.should exist(File.join(c.core_dir, 'carton.rb'))
87
+ File.should exist(File.join(c.core_dir, 'views'))
88
+ File.should exist(File.join(c.core_dir, 'templates'))
89
+ File.should exist(File.join(c.core_dir, 'assets'))
90
+ end
91
+
92
+ it "should call afterLoad after init" do
93
+ c1= MockCoreSubclass.new
94
+ class MockCoreSubclass
95
+ def afterLoad
96
+ options[:called_afterload_for_subclass] = true
97
+ end
98
+ end
99
+ c2= MockCoreSubclass.new
100
+ c1.options[:called_afterload_for_subclass].should_not == c2.options[:called_afterload_for_subclass]
101
+ c1.options.should_not have_key(:called_afterload_for_subclass)
102
+ c2.options.should have_key(:called_afterload_for_subclass)
103
+ c2.options[:called_afterload_for_subclass].should be_true
104
+ end
105
+
106
+ it "should allow changing of default core_dir" do
107
+ c= Orange::Core.new
108
+ c.options[:core_dir] = "/non/existent/dir"
109
+ c.core_dir.should_not == File.dirname(c.file)
110
+ c.core_dir.should == "/non/existent/dir"
111
+ File.should exist(File.join(File.dirname(c.file), 'core.rb'))
112
+ end
113
+
114
+ it "should return Dir.pwd for app_dir by default" do
115
+ Orange::Core.new.app_dir.should == Dir.pwd
116
+ end
117
+
118
+ it "should return assigned app_dir if option set" do
119
+ c= Orange::Core.new
120
+ c.options[:app_dir] = "/non/existent/dir"
121
+ c.app_dir.should_not == Dir.pwd
122
+ c.app_dir.should == "/non/existent/dir"
123
+ end
124
+
125
+ it "should allow options" do
126
+ c= Orange::Core.new(:opt_1 => true){ opt_2 true }
127
+ c.options[:opt_1].should == true
128
+ c.options[:opt_2].should == true
129
+ c.options.should have_key(:opt_1)
130
+ c.options.should_not have_key(:opt_3)
131
+ end
132
+
133
+ it "should load a resource when passed resource instance" do
134
+ c= Orange::Core.new
135
+ c.load(MockResource.new, :mock_one)
136
+ c.resources.should have_key(:mock_one)
137
+ c.resources[:mock_one].should be_an_instance_of(MockResource)
138
+
139
+ end
140
+
141
+ it "should default to lowercase resource name to symbol as resource short name" do
142
+ c= Orange::Core.new
143
+ c.load(MockResource.new)
144
+ sym = MockResource.to_s.gsub(/::/, '_').downcase.to_sym
145
+ c.resources.should have_key(sym)
146
+ c.should be_loaded(sym)
147
+ end
148
+
149
+ it "should say a resource is loaded after calling load for resource" do
150
+ c= Orange::Core.new
151
+ c.load(MockResource.new, :mock_one)
152
+ c.should be_loaded(:mock_one)
153
+ c.resources.should have_key(:mock_one)
154
+ end
155
+
156
+ it "should return self on orange" do
157
+ c= Orange::Core.new
158
+ c.orange.should eql(c)
159
+ end
160
+
161
+ it "should add event to events list when register called" do
162
+ c= Orange::Core.new
163
+ c.events.should be_empty
164
+ c.register(:mock_event) {|x| x }
165
+ c.events.should_not be_empty
166
+ c.events.should have_key(:mock_event)
167
+ c.events[:mock_event].should be_an_instance_of(Array)
168
+ c.events[:mock_event].should have(1).callback
169
+ c.register(:mock_event) {|x| x }
170
+ c.events[:mock_event].should have(2).callbacks
171
+ end
172
+
173
+ it "should add events in specified order when registered with position" do
174
+ c= Orange::Core.new
175
+ c.events.should be_empty
176
+ c.register(:mock_event, 5) {|x| '5' }
177
+ c.events.should_not be_empty
178
+ c.events.should have_key(:mock_event)
179
+ c.events[:mock_event].compact.should have(1).callback
180
+ 5.times{ |i| c.events[:mock_event][i].should be_nil }
181
+ c.register(:mock_event, 2) {|x| '2' }
182
+ c.events[:mock_event].compact.should have(2).callbacks
183
+ c.events[:mock_event][2].call(nil).should eql '2'
184
+ c.events[:mock_event][6].call(nil).should eql '5'
185
+ c.events[:mock_event].compact.first.call(nil).should eql '2'
186
+ c.events[:mock_event].compact.last.call(nil).should eql '5'
187
+ c.register(:mock_event, 5) {|x| '5.2' }
188
+ c.events[:mock_event].compact.should have(3).callbacks
189
+ c.events[:mock_event][2].call(nil).should eql '2'
190
+ c.events[:mock_event][5].call(nil).should eql '5.2'
191
+ c.events[:mock_event][7].call(nil).should eql '5'
192
+ c.events[:mock_event].compact.first.call(nil).should eql '2'
193
+ c.events[:mock_event].compact.last.call(nil).should eql '5'
194
+ end
195
+
196
+ it "should fire registered events when fire called" do
197
+ class OtherMockCore < Orange::Core
198
+ attr_accessor :mock_counter
199
+ def afterLoad
200
+ @mock_counter = 0
201
+ end
202
+ end
203
+ c= OtherMockCore.new
204
+ c.mock_counter.should == 0
205
+ c.register(:mock_event) {|i| c.mock_counter += i }
206
+ c.register(:mock_event_two) {|i| c.mock_counter -= i }
207
+ c.mock_counter.should == 0
208
+ c.fire(:mock_event, 3)
209
+ c.mock_counter.should_not == 0
210
+ c.mock_counter.should == 3
211
+ c.fire(:mock_event_two, 2)
212
+ c.mock_counter.should_not == 0
213
+ c.mock_counter.should == 1
214
+ c.register(:mock_event) {|i| c.mock_counter += i }
215
+ c.fire(:mock_event, 3)
216
+ c.mock_counter.should_not == 1
217
+ c.mock_counter.should == 7
218
+ end
219
+
220
+ it "should have an options hash" do
221
+ Orange::Core.new.options.should be_an_instance_of(Hash)
222
+ end
223
+
224
+ it "should allow access to the resources via []" do
225
+ c= Orange::Core.new
226
+ c.load(MockResource.new, :mock)
227
+ c[:mock].should be_an_instance_of(MockResource)
228
+ c[:mock].should be_an_kind_of(Orange::Resource)
229
+ c[:mock].mock_method.should eql 'MockResource#mock_method'
230
+ end
231
+ end
@@ -0,0 +1,89 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
+
3
+ describe "Black::Magick" do
4
+ it "should be spec'ed"
5
+ end
6
+
7
+ describe Orange::DefaultHash do
8
+ it "should be a kind of Hash" do
9
+ Orange::DefaultHash.new.should be_a_kind_of Hash
10
+ end
11
+ it "should handle setting default" do
12
+ x = Orange::DefaultHash.new
13
+ y = Orange::DefaultHash.new
14
+ x.default = true
15
+ y.default = false
16
+ x[:not_there].should be_true
17
+ y[:not_there].should be_false
18
+ end
19
+
20
+ it "should handle default in key access []" do
21
+ x = Orange::DefaultHash.new
22
+ x.default = 'baz'
23
+ x[:not_there].should == 'baz'
24
+ x[:not_there, 'bar'].should == 'bar'
25
+ end
26
+ end
27
+
28
+ describe "Orange::Options" do
29
+ it "should give a hash on hash" do
30
+ Orange::Options.new.hash.should be_an_instance_of(Hash)
31
+ end
32
+
33
+ it "should accept hash key options" do
34
+ hash1 = Orange::Options.new(:one => '1', :two => ['foo']).hash
35
+ hash2 = Orange::Options.new(:one => '1').hash
36
+ hash3 = Orange::Options.new({:one => '1', :two => ['foo']}).hash
37
+ hash4 = Orange::Options.new({:one => '1'}).hash
38
+ hash5 = Orange::Options.new(1,2, {:one => '1', :two => ['foo']}).hash
39
+ hash6 = Orange::Options.new(1,2, {:one => '1'}).hash
40
+ [hash2, hash4, hash6].each{ |hash|
41
+ hash.should have_key(:one)
42
+ hash.should_not have_key(:three)
43
+ hash[:one].should == '1'
44
+ }
45
+ [hash1, hash3, hash5].each{ |hash|
46
+ hash.should have_key(:one)
47
+ hash.should have_key(:two)
48
+ hash.should_not have_key(:three)
49
+ hash[:one].should == '1'
50
+ hash[:two].should == ['foo']
51
+ }
52
+ end
53
+
54
+ it "should accept block options" do
55
+ hash = Orange::Options.new {
56
+ one '1'
57
+ two ['foo']
58
+ }.hash
59
+ hash.should have_key(:one)
60
+ hash.should have_key(:two)
61
+ hash.should_not have_key(:three)
62
+ hash[:one].should == '1'
63
+ hash[:two].should == ['foo']
64
+ end
65
+
66
+ it "should accept both kinds of options" do
67
+ hash = Orange::Options.new(:one => '1'){
68
+ two ['foo']
69
+ }.hash
70
+
71
+ hash.should have_key(:one)
72
+ hash.should have_key(:two)
73
+ hash.should_not have_key(:three)
74
+ hash[:one].should == '1'
75
+ hash[:two].should == ['foo']
76
+ end
77
+
78
+ it "should override hash key options with block options" do
79
+ hash = Orange::Options.new(:one => '1', :two => [:baz]){
80
+ two ['foo']
81
+ }.hash
82
+
83
+ hash.should have_key(:one)
84
+ hash.should have_key(:two)
85
+ hash.should_not have_key(:three)
86
+ hash[:one].should == '1'
87
+ hash[:two].should == ['foo']
88
+ end
89
+ end