orange-core 0.5.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (72) hide show
  1. data/README.markdown +145 -0
  2. data/lib/orange-core.rb +8 -0
  3. data/lib/orange-core/application.rb +132 -0
  4. data/lib/orange-core/assets/css/exceptions.css +50 -0
  5. data/lib/orange-core/assets/js/exceptions.js +44 -0
  6. data/lib/orange-core/carton.rb +178 -0
  7. data/lib/orange-core/core.rb +266 -0
  8. data/lib/orange-core/magick.rb +270 -0
  9. data/lib/orange-core/middleware/base.rb +96 -0
  10. data/lib/orange-core/middleware/database.rb +45 -0
  11. data/lib/orange-core/middleware/four_oh_four.rb +45 -0
  12. data/lib/orange-core/middleware/globals.rb +17 -0
  13. data/lib/orange-core/middleware/loader.rb +13 -0
  14. data/lib/orange-core/middleware/rerouter.rb +53 -0
  15. data/lib/orange-core/middleware/restful_router.rb +99 -0
  16. data/lib/orange-core/middleware/route_context.rb +39 -0
  17. data/lib/orange-core/middleware/route_site.rb +51 -0
  18. data/lib/orange-core/middleware/show_exceptions.rb +80 -0
  19. data/lib/orange-core/middleware/static.rb +67 -0
  20. data/lib/orange-core/middleware/static_file.rb +32 -0
  21. data/lib/orange-core/middleware/template.rb +60 -0
  22. data/lib/orange-core/packet.rb +232 -0
  23. data/lib/orange-core/plugin.rb +172 -0
  24. data/lib/orange-core/resource.rb +96 -0
  25. data/lib/orange-core/resources/mapper.rb +36 -0
  26. data/lib/orange-core/resources/model_resource.rb +228 -0
  27. data/lib/orange-core/resources/not_found.rb +10 -0
  28. data/lib/orange-core/resources/page_parts.rb +68 -0
  29. data/lib/orange-core/resources/parser.rb +113 -0
  30. data/lib/orange-core/resources/routable_resource.rb +16 -0
  31. data/lib/orange-core/resources/scaffold.rb +106 -0
  32. data/lib/orange-core/stack.rb +226 -0
  33. data/lib/orange-core/templates/exceptions.haml +111 -0
  34. data/lib/orange-core/views/default_resource/create.haml +4 -0
  35. data/lib/orange-core/views/default_resource/edit.haml +9 -0
  36. data/lib/orange-core/views/default_resource/list.haml +10 -0
  37. data/lib/orange-core/views/default_resource/show.haml +4 -0
  38. data/lib/orange-core/views/default_resource/table_row.haml +7 -0
  39. data/lib/orange-core/views/not_found/404.haml +2 -0
  40. data/spec/orange-core/application_spec.rb +183 -0
  41. data/spec/orange-core/carton_spec.rb +136 -0
  42. data/spec/orange-core/core_spec.rb +248 -0
  43. data/spec/orange-core/magick_spec.rb +96 -0
  44. data/spec/orange-core/middleware/base_spec.rb +38 -0
  45. data/spec/orange-core/middleware/globals_spec.rb +3 -0
  46. data/spec/orange-core/middleware/rerouter_spec.rb +3 -0
  47. data/spec/orange-core/middleware/restful_router_spec.rb +3 -0
  48. data/spec/orange-core/middleware/route_context_spec.rb +3 -0
  49. data/spec/orange-core/middleware/route_site_spec.rb +3 -0
  50. data/spec/orange-core/middleware/show_exceptions_spec.rb +3 -0
  51. data/spec/orange-core/middleware/static_file_spec.rb +3 -0
  52. data/spec/orange-core/middleware/static_spec.rb +3 -0
  53. data/spec/orange-core/mock/mock_app.rb +16 -0
  54. data/spec/orange-core/mock/mock_carton.rb +43 -0
  55. data/spec/orange-core/mock/mock_core.rb +2 -0
  56. data/spec/orange-core/mock/mock_middleware.rb +25 -0
  57. data/spec/orange-core/mock/mock_mixins.rb +19 -0
  58. data/spec/orange-core/mock/mock_model_resource.rb +47 -0
  59. data/spec/orange-core/mock/mock_pulp.rb +24 -0
  60. data/spec/orange-core/mock/mock_resource.rb +26 -0
  61. data/spec/orange-core/mock/mock_router.rb +10 -0
  62. data/spec/orange-core/orange_spec.rb +19 -0
  63. data/spec/orange-core/packet_spec.rb +203 -0
  64. data/spec/orange-core/resource_spec.rb +96 -0
  65. data/spec/orange-core/resources/mapper_spec.rb +5 -0
  66. data/spec/orange-core/resources/model_resource_spec.rb +246 -0
  67. data/spec/orange-core/resources/parser_spec.rb +5 -0
  68. data/spec/orange-core/resources/routable_resource_spec.rb +5 -0
  69. data/spec/orange-core/spec_helper.rb +53 -0
  70. data/spec/orange-core/stack_spec.rb +232 -0
  71. data/spec/stats.rb +182 -0
  72. metadata +227 -0
@@ -0,0 +1,2 @@
1
+ class MockCoreSubclass < Orange::Core
2
+ end
@@ -0,0 +1,25 @@
1
+ class MockOrangeBasedMiddleware < Orange::Middleware::Base
2
+ def packet_call(packet)
3
+ raise "It's over 9000 #{@core.class.to_s}s!"
4
+ end
5
+ end
6
+
7
+ class MockMiddleware
8
+ def initialize(app)
9
+ end
10
+ def call(env)
11
+ raise "I'm in ur #{env[:test]}"
12
+ end
13
+ end
14
+
15
+ class MockOrangeBasedMiddlewareTwo < Orange::Middleware::Base; end
16
+ class MockOrangeBasedMiddlewareThree < Orange::Middleware::Base
17
+ def stack_init
18
+ end
19
+ end
20
+ class MockOrangeDeathMiddleware < Orange::Middleware::Base
21
+ def init(*args)
22
+ opts = args.extract_options!
23
+ raise "middleware_init with foo=#{opts[:foo]}"
24
+ end
25
+ end
@@ -0,0 +1,19 @@
1
+ module MockMixinOrange1
2
+ def mixin_orange_one
3
+ end
4
+ end
5
+
6
+ module MockMixinOrange2
7
+ def mixin_orange_two
8
+ end
9
+ end
10
+
11
+ module MockMixinCore1
12
+ def mixin_core_one
13
+ end
14
+ end
15
+
16
+ module MockMixinCore2
17
+ def mixin_core_two
18
+ end
19
+ end
@@ -0,0 +1,47 @@
1
+ class MockModelResource < Orange::ModelResource
2
+ use MockCarton
3
+ end
4
+
5
+ class MockModelResourceOne < Orange::ModelResource
6
+ use MockCarton
7
+ def index(packet, *args)
8
+ raise 'I see you\'re using index'
9
+ end
10
+ def show(packet, *args)
11
+ raise 'I see you\'re using show'
12
+ end
13
+ def other(packet, *args)
14
+ raise 'I see you\'re using other'
15
+ end
16
+ def find_one(packet, mode, resource_id =false)
17
+ raise 'calling find_one'
18
+ end
19
+ def find_list(packet, mode)
20
+ raise 'calling find_list'
21
+ end
22
+ end
23
+
24
+ class MockModelResourceTwo < Orange::ModelResource
25
+ use MockCartonTwo
26
+ end
27
+
28
+ class MockModelResourceThree < Orange::ModelResource
29
+ use MockCarton
30
+ def find_extras(packet, mode)
31
+ raise 'calling find_extras'
32
+ end
33
+ end
34
+
35
+ class MockModelResourceFour < Orange::ModelResource
36
+ use MockCarton
37
+ def find_one(packet, mode, resource_id =false)
38
+ 'mock_one'
39
+ end
40
+ def find_list(packet, mode)
41
+ 'mock_list'
42
+ end
43
+ end
44
+
45
+ class MockModelResourceExtreme < Orange::ModelResource
46
+
47
+ end
@@ -0,0 +1,24 @@
1
+ module MockPulpOrange1
2
+ def pulp_orange_one
3
+ end
4
+ end
5
+
6
+ module MockPulpOrange2
7
+ def pulp_orange_two
8
+ end
9
+ end
10
+
11
+ module MockPulpCore1
12
+ def pulp_core_one
13
+ end
14
+ end
15
+
16
+ module MockPulpCore2
17
+ def pulp_core_two
18
+ end
19
+ end
20
+
21
+ module MockPulp
22
+ def my_new_mock_method
23
+ end
24
+ end
@@ -0,0 +1,26 @@
1
+ class MockResource < Orange::Resource
2
+ def mock_method
3
+ 'MockResource#mock_method'
4
+ end
5
+ def afterLoad
6
+ @options[:mocked] = true
7
+ end
8
+ end
9
+
10
+ class MockResourceTwo < Orange::Resource
11
+ def mock_method
12
+ 'MockResource#mock_method'
13
+ end
14
+ def afterLoad
15
+ @options[:mocked] = true
16
+ end
17
+ def stack_init
18
+ true
19
+ end
20
+ end
21
+
22
+ class MockHamlParser < Orange::Resource
23
+ def haml(template, packet, opts)
24
+ [template, packet, opts]
25
+ end
26
+ end
@@ -0,0 +1,10 @@
1
+
2
+ class TestRouter
3
+ attr_accessor :x
4
+ def initialize
5
+ @x = 0
6
+ end
7
+ def route(packet)
8
+ @x += 1
9
+ end
10
+ end
@@ -0,0 +1,19 @@
1
+ describe Orange do
2
+ it "should allow core mixin via mixin method" do
3
+ c= Orange::Core.new
4
+ c.should_not respond_to(:mixin_orange_one)
5
+ Orange.mixin MockMixinOrange1
6
+ c2= Orange::Core.new
7
+ c.should respond_to(:mixin_orange_one)
8
+ c2.should respond_to(:mixin_orange_one)
9
+ end
10
+ it "should allow pulp mixin via pulp method" do
11
+ c= Orange::Core.new
12
+ p= Orange::Packet.new(c, {})
13
+ p.should_not respond_to(:pulp_orange_one)
14
+ Orange.add_pulp MockPulpOrange1
15
+ p2= Orange::Packet.new(c, {})
16
+ p.should respond_to(:pulp_orange_one)
17
+ p2.should respond_to(:pulp_orange_one)
18
+ end
19
+ end
@@ -0,0 +1,203 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
+
3
+ describe Orange::Packet do
4
+ it "should return a default header content type of html" do
5
+ p= Orange::Packet.new(Orange::Core.new, {})
6
+ p.finish[1].should have_key("Content-Type")
7
+ p.finish[1]["Content-Type"].should eql("text/html")
8
+ end
9
+
10
+ it "should not create a new object for env if one already exists" do
11
+ p= Orange::Packet.new(Orange::Core.new, {})
12
+ env = p.env
13
+ p2= Orange::Packet.new(Orange::Core.new, env)
14
+ p.should equal p2 # Exact equality - same instances
15
+ end
16
+
17
+ it "should save core passed to it on initialization" do
18
+ c= Orange::Core.new
19
+ p= Orange::Packet.new(c, {})
20
+ p.orange.should equal c
21
+ end
22
+
23
+ it "should save the env passed to it on init" do
24
+ p= Orange::Packet.new(Orange::Core.new, {:test => :foo})
25
+ p.env.should have_key(:test)
26
+ p.env[:test].should == :foo
27
+ p.env.should_not be_empty
28
+ end
29
+
30
+ it "should add orange.packet and orange.env to env on init" do
31
+ p= Orange::Packet.new(Orange::Core.new, {})
32
+ p.env.should have_key('orange.packet')
33
+ p.env['orange.packet'].should equal p
34
+ p.env.should have_key('orange.env')
35
+ p.env['orange.env'].should have_key(:request)
36
+ p.env['orange.env'][:request].should be_an_instance_of(Rack::Request)
37
+ p.env['orange.env'].should have_key(:headers)
38
+ p.env['orange.env'][:headers].should be_an_instance_of(Hash)
39
+ end
40
+
41
+ it "should have access to the orange.env through []" do
42
+ p= Orange::Packet.new(Orange::Core.new, {'orange.env' => {'foo' => :true}})
43
+ p['foo'].should == :true
44
+ p['foo'] = 'banana'
45
+ p.env['orange.env']['foo'].should == 'banana'
46
+ p['foo'].should == 'banana'
47
+ end
48
+
49
+ it "should allow defaults through [] calls" do
50
+ p= Orange::Packet.new(Orange::Core.new, {})
51
+ p['nonexistent'].should be_false
52
+ p['nonexistent', true].should be_true
53
+ p['nonexistent', true].should_not be_an_instance_of Hash
54
+ p['nonexistent', {}].should be_an_instance_of Hash
55
+ end
56
+
57
+ it "should give access to the rack.session env" do
58
+ p= Orange::Packet.new(Orange::Core.new, {'rack.session' => {'foo' => 'banana'}})
59
+ p.session.should have_key 'foo'
60
+ p.session.should have_key 'flash'
61
+ end
62
+
63
+ it "should give always have a flash" do
64
+ p= Orange::Packet.new(Orange::Core.new, {'rack.session' => {}})
65
+ p.session.should have_key 'flash'
66
+ p.flash.should == {}
67
+ end
68
+
69
+ it "should destruct a flash value upon reading" do
70
+ p= Orange::Packet.new(Orange::Core.new, {'rack.session' => {}})
71
+ p.session.should have_key 'flash'
72
+ p.session["flash"]["foo"] = "bar"
73
+ p.flash("foo").should == "bar"
74
+ p.flash("foo").should be_nil
75
+ p.session["flash"].should_not have_key("foo")
76
+ p.flash("foo", "bar")
77
+ p.flash("foo").should == "bar"
78
+ p.flash("foo").should be_nil
79
+ p.session["flash"].should_not have_key("foo")
80
+ p.flash["foo"] = "bar"
81
+ p.flash("foo").should == "bar"
82
+ p.flash("foo").should be_nil
83
+ p.flash.should_not have_key("foo")
84
+ end
85
+
86
+ it "should give headers by combining :headers with defaults" do
87
+ p= Orange::Packet.new(Orange::Core.new, {})
88
+ p.headers.should == p[:headers, {}].with_defaults(Orange::Packet::DEFAULT_HEADERS)
89
+ end
90
+
91
+ it "should allow setting headers via header(key, val)" do
92
+ p= Orange::Packet.new(Orange::Core.new, {})
93
+ p.header('Content-Type', 'text/plain')
94
+ p.headers['Content-Type'].should == 'text/plain'
95
+ end
96
+
97
+ it "should allow adding headers with add_header" do
98
+ p1= Orange::Packet.new(Orange::Core.new, {})
99
+ p2= Orange::Packet.new(Orange::Core.new, {})
100
+ p1.add_header('Content-Type', 'text/plain')
101
+ p2.header('Content-Type', 'text/plain')
102
+ p1.headers['Content-Type'].should == p2.headers['Content-Type']
103
+ end
104
+
105
+ it "should give access to the core object via orange" do
106
+ c= Orange::Core.new
107
+ p= Orange::Packet.new(c, {})
108
+ p.orange.should equal c
109
+ p.orange.should be_an_instance_of(Orange::Core)
110
+ end
111
+
112
+ it "should create a triple according to rack standards on #finish" do
113
+ p= Orange::Packet.new(Orange::Core.new, {})
114
+ fin = p.finish
115
+ fin[0].should be_a_kind_of Integer
116
+ fin[1].should be_a_kind_of Hash
117
+ fin[2].should be_a_kind_of Array
118
+ end
119
+
120
+ it "should give self when using packet" do
121
+ p= Orange::Packet.new(Orange::Core.new, {})
122
+ p.packet.should equal p
123
+ end
124
+
125
+ it "should mixin when calling mixin" do
126
+ p= Orange::Packet.new(Orange::Core.new, {})
127
+ p.should_not respond_to(:pulp_orange_two)
128
+ Orange::Packet.mixin MockPulpOrange2
129
+ p.should respond_to(:pulp_orange_two)
130
+ end
131
+
132
+ it "should raise an error if no router set" do
133
+ p= Orange::Packet.new(Orange::Core.new, {})
134
+ lambda{
135
+ p.route
136
+ }.should raise_error(RuntimeError, 'Router not found')
137
+ end
138
+
139
+ it "should pass self to assigned router's route method" do
140
+ class MockDeathRouter
141
+ def route(p); raise "die, die, death, #{p[:lame]}"; end
142
+ end
143
+ p= Orange::Packet.new(Orange::Core.new, {})
144
+ p['route.router'] = MockDeathRouter.new
145
+ p[:lame] = 'death'
146
+ lambda{
147
+ p.route
148
+ }.should_not raise_error(RuntimeError, 'Router not found')
149
+ lambda{
150
+ p.route
151
+ }.should raise_error(RuntimeError, 'die, die, death, death')
152
+ end
153
+
154
+ it "should give a request object" do
155
+ p= Orange::Packet.new(Orange::Core.new, {})
156
+ p.request.should be_an_instance_of Rack::Request
157
+ end
158
+
159
+ it "should store method matchers for extending method_missing handlers" do
160
+ class Orange::Packet
161
+ meta_methods(/pretend_method_we_dont_want/) do |match, args|
162
+ "my mock meta method"
163
+ end
164
+
165
+ meta_methods(/pretend_method_we_dont_want(\w+)/) do |match, args|
166
+ "my mock meta method"
167
+ end
168
+ end
169
+ p= Orange::Packet.new(Orange::Core.new, {})
170
+ p.matchers.size.should >= 2
171
+ end
172
+
173
+ it "should have method_missing capabilities" do
174
+ p= Orange::Packet.new(Orange::Core.new, {})
175
+ p.should respond_to(:method_missing)
176
+ lambda {
177
+ p.my_mock_meta_method
178
+ p.mock_meta_test
179
+ p.mock_meta_test_with_args
180
+ }.should raise_error(NoMethodError)
181
+ class Orange::Packet
182
+ meta_methods(/my_mock_meta_method/) do
183
+ "my mock meta method"
184
+ end
185
+
186
+ meta_methods(/mock_meta_(\w+)/) do |packet, match|
187
+ "my mock #{match[1]} method"
188
+ end
189
+
190
+ meta_methods(/mock_meta_(\w+)_with_args/) do |packet, match, args|
191
+ "my mock #{match[1]} method args0 = #{args[0]}"
192
+ end
193
+ end
194
+ lambda {
195
+ p.my_mock_meta_method
196
+ p.mock_meta_test
197
+ p.mock_meta_test_with_args 'test'
198
+ }.should_not raise_error(NoMethodError)
199
+ p.my_mock_meta_method.should == "my mock meta method"
200
+ p.mock_meta_test.should == "my mock test method"
201
+ p.mock_meta_test_with_args('test').should == "my mock test method args0 = test"
202
+ end
203
+ end
@@ -0,0 +1,96 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
+
3
+ describe Orange::Resource do
4
+ it "should allow options" do
5
+ r= Orange::Resource.new(:opt_1 => true){ opt_2 true }
6
+ r.options[:opt_1].should == true
7
+ r.options[:opt_2].should == true
8
+ r.options.should have_key(:opt_1)
9
+ r.options.should_not have_key(:opt_3)
10
+ end
11
+
12
+ it "should accept an orange core on set_orange" do
13
+ c= Orange::Core.new
14
+ r= Orange::Resource.new
15
+ r.set_orange(c, :name)
16
+ r.orange.should equal(c)
17
+ r.orange.should be_a_kind_of(Orange::Core)
18
+ end
19
+
20
+ it "should call afterLoad after calling set_orange" do
21
+ c= Orange::Core.new
22
+ r= MockResource.new
23
+ r.options.should_not have_key(:mocked)
24
+ r.set_orange(c, :name)
25
+ r.options.should have_key(:mocked)
26
+ r.options[:mocked].should == true
27
+ end
28
+
29
+ it "should set the orange_name after calling set_orange" do
30
+ c= Orange::Core.new
31
+ r= Orange::Resource.new
32
+ r2= Orange::Resource.new
33
+ r.set_orange(c, :name)
34
+ r2.set_orange(c, 'name')
35
+ r.orange_name.should == :name
36
+ r2.orange_name.should_not == :name
37
+ r2.orange_name.should == 'name'
38
+ end
39
+
40
+ it "should return self after set_orange" do
41
+ c= Orange::Core.new
42
+ r= Orange::Resource.new
43
+ me = r.set_orange(c, :name)
44
+ me.should equal r
45
+ end
46
+
47
+ it "should register for stack_loaded iff stack_init method present" do
48
+ c = Orange::Core.new
49
+ c.should_receive(:register).with(:stack_loaded).once
50
+ mid1 = c.load MockResource.new
51
+ mid2 = c.load MockResourceTwo.new
52
+ end
53
+
54
+ it "should return an error if setting orange on a class" do
55
+ lambda {
56
+ Orange::Resource.set_orange(Orange::Core.new, :mock)
57
+ }.should raise_error(RuntimeError, "instantiate the resource before calling set orange")
58
+ end
59
+
60
+ it "should give access to the core through orange" do
61
+ c= Orange::Core.new
62
+ r= Orange::Resource.new
63
+ r.set_orange(c, :name)
64
+ r.orange.should equal(c)
65
+ r.orange.should be_a_kind_of(Orange::Core)
66
+ end
67
+
68
+ it "should respond to routable" do
69
+ r = Orange::Resource.new
70
+ r.should respond_to(:routable)
71
+ r.routable.should be_false
72
+ end
73
+
74
+ it "should return an empty string on calling view" do
75
+ r = Orange::Resource.new
76
+ r.view.should == ''
77
+ r.view(Orange::Packet.new(Orange::Core.new, {})).should == ''
78
+ end
79
+
80
+ it "should accept an options hash to view" do
81
+ p = Orange::Packet.new(Orange::Core.new, {})
82
+ r = Orange::Resource.new
83
+ lambda{
84
+ r.view(p, :opts => 'foo', :test => 'bar')
85
+ }.should_not raise_error
86
+ end
87
+
88
+ it "should give access to the orange name attribute" do
89
+ c= Orange::Core.new
90
+ r= Orange::Resource.new
91
+ r.set_orange(c, :name)
92
+ r.orange_name.should == :name
93
+ end
94
+
95
+
96
+ end