GitHub Sale: sign up for any paid plan this week and pay nothing until January 1, 2009!  [ hide ]

public
Rubygem
Description: Resource-oriented open source Ruby framework for Web apps.
Homepage: http://rubywaves.com/
Clone URL: git://github.com/dyoder/waves.git
got the on() mappings working for evaluation and constraints specs
automatthew (author)
Thu Aug 21 19:40:02 -0700 2008
commit  07889d02b33d4b96e882c9ee963c158c20f3d229
tree    548a20c2a2642eddad7884aab0940b49fe11efd1
parent  abe88ed145d083a3ab29fdb359a4273f110fadf1
...
5
6
7
8
 
9
10
11
...
27
28
29
30
31
32
 
33
 
 
34
35
36
...
5
6
7
 
8
9
10
11
...
27
28
29
 
 
 
30
31
32
33
34
35
36
0
@@ -5,7 +5,7 @@ module Waves
0
     class Action
0
       
0
       def initialize( options )
0
- @name = name = options[:name] ; @pattern = pattern = Pattern.new( options )
0
+ @name = name = options[:as] ; @pattern = pattern = Pattern.new( options )
0
         @constraints = Constraints.new( options ) ; @descriptors = Descriptors.new( options )
0
         @block = block = options[:block]
0
         if rname = options[ :resource ]
0
@@ -27,10 +27,10 @@ module Waves
0
       
0
       def call( args )
0
         request = args.first
0
- if @name
0
- @resource.new( request ).send( @name )
0
- elsif @block
0
+ if @block
0
           @resource.new( request ).instance_eval( &@block )
0
+ elsif @name
0
+ @resource.new( request ).send( @name )
0
         end
0
       end
0
 
...
57
58
59
 
 
 
 
 
 
 
60
61
62
63
 
64
65
66
 
 
 
 
67
68
69
70
 
 
 
 
 
71
72
 
73
74
75
76
77
78
 
79
80
81
82
 
83
84
85
...
87
88
89
90
 
 
91
92
93
...
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
 
 
73
74
75
76
77
78
79
 
80
81
82
83
84
85
 
86
87
88
89
90
91
92
93
94
95
96
 
97
98
99
100
...
102
103
104
 
105
106
107
108
109
0
@@ -57,29 +57,44 @@ module Waves
0
       mappings[ name ] << map( *args )
0
     end
0
     
0
+ def on( options, &block )
0
+ args = [options, block].compact
0
+ mappings[ :response ] << map( *args )
0
+ end
0
+
0
+
0
+
0
     def with( options, &block )
0
       @options = options; yield if block_given? ; @options = nil
0
     end
0
 
0
+ # primary input like: response( :klump, :get => [ "foo" ] ) { bar }
0
     functor( :map, Symbol, Hash, Proc ) do | name, options, block |
0
- options[:name] = name ; options[:block] = block ; map( options )
0
- end
0
+ options[:as] = name ; options[:block] = block ; map( options )
0
+ end # no longer needed?
0
+
0
+ # primary input like: on( :get => [ "foo" ], :as => :klump ) { bar }
0
     functor( :map, Hash, Proc ) do | options, block |
0
       options[:block] = block; map( options )
0
     end
0
- functor( :map, Symbol, Hash ) { | name, options | options[:name] = name ; map( options ) }
0
+
0
+ # primary input like response( :klump, :get => [ "foo" ] ); missing a block
0
+ functor( :map, Symbol, Hash ) { | name, options | options[:as] = name ; map( options ) } # no longer needed?
0
+
0
+ # secondary input where &block has already been slurped into the options hash
0
     functor( :map, Hash ) do | options |
0
- raise ArgumentError, "A mapping must have a name or a block" if !options[:name] && !options[:block]
0
+ raise ArgumentError, "A mapping must have a block or an :as param" if !options[:as] && !options[:block]
0
       options = ( @options || {} ).merge( options )
0
       options[ :method ] = method = METHODS.find { |method| options[ method ] }
0
       options[ :path ] = options[ method ] if method
0
       Action.new( options )
0
     end
0
 
0
+ # section for Exception Handlers
0
     exception = lambda { | klass | klass.ancestors.include?( Exception ) if klass.is_a?( Class ) }
0
     
0
     functor( :map, exception, String, Hash, Proc ) do | e, name, options, block |
0
- options[ :name ] = name ; map( e, options, block )
0
+ options[ :as ] = name ; map( e, options, block )
0
     end
0
     
0
     functor( :map, exception, Hash, Proc ) do | e, options, block |
0
@@ -87,7 +102,8 @@ module Waves
0
     end
0
     functor( :map, exception, Proc ) { | e, block | map( e, { :block => block } ) }
0
     functor( :map, exception, Hash ) { | e, options | Handler.new( e, options ) }
0
-
0
+
0
+
0
     def []( request )
0
       results = Hash.new { |h,k| h[k] = [] }
0
       RULES.each do | rule |
...
23
24
25
 
26
27
28
...
23
24
25
26
27
28
29
0
@@ -23,6 +23,7 @@ module Waves
0
         end
0
       end
0
       
0
+ # Resources are initialized with a Waves::Request
0
       def initialize(request); @request = request ; end
0
       def singular ; self.class.singular ; end
0
       def plural ; self.class.plural ; end
...
21
22
23
 
 
 
24
25
26
...
21
22
23
24
25
26
27
28
29
0
@@ -21,6 +21,9 @@ module Waves
0
         params['resources'] || params['resource'].plural
0
       end
0
       
0
+ alias_method :singular, :resource
0
+ alias_method :plural, :resources
0
+
0
       def method_missing( name, *args, &block )
0
         @resource.send( name, *args, &block )
0
       end
...
36
37
38
39
40
 
 
 
 
 
 
41
42
43
44
45
 
46
47
48
...
36
37
38
 
 
39
40
41
42
43
44
45
46
47
48
 
49
50
51
52
0
@@ -36,13 +36,17 @@ module Waves
0
         Waves::Runtime.stub!(:instance).and_return(runtime)
0
       end
0
 
0
- def mapping
0
- ::Waves::Runtime.instance.mapping
0
+ def mappings(&block)
0
+ m = ::Waves::Runtime.instance.mapping
0
+ if block
0
+ m.instance_eval(&block)
0
+ end
0
+ m
0
       end
0
       
0
       # mapping helper methods (of dubious utility?)
0
       %w{ path url always handle threaded generator}.each do |method|
0
- module_eval "def #{method}(*args,&block); mapping.#{method}(*args,&block);end"
0
+ module_eval "def #{method}(*args,&block); mappings.#{method}(*args,&block);end"
0
       end
0
       
0
       # generate a mock Rack request against the default dispatcher.
...
4
5
6
7
 
8
9
10
11
12
 
 
 
13
14
15
16
17
18
19
20
21
 
 
 
 
 
22
23
24
25
26
 
 
 
27
28
29
30
31
32
33
 
 
 
34
35
36
37
38
39
40
41
 
 
 
 
42
43
44
...
4
5
6
 
7
8
9
10
11
 
12
13
14
15
16
17
18
19
20
 
 
 
21
22
23
24
25
26
27
28
29
 
30
31
32
33
34
35
36
37
38
 
39
40
41
42
43
44
45
46
47
 
 
48
49
50
51
52
53
54
0
@@ -4,41 +4,51 @@ require File.join(File.dirname(__FILE__) , "helpers")
0
 describe "A mapping" do
0
   
0
   before do
0
- mapping.clear
0
+ mappings.clear
0
     handle( Waves::Dispatchers::NotFoundError ) { response.status = 404 }
0
   end
0
   
0
   it "can match the URL scheme name" do
0
- mapping.response( :scheme => 'https' ) { "Timmmah!" }
0
+ mappings do
0
+ on( :scheme => 'https' ) { "Timmmah!" }
0
+ end
0
     
0
     mock_request.get("https://www.rubywaves.com/foo").status.should == 200
0
     mock_request.get("http://www.rubywaves.com/foo").status.should == 404
0
   end
0
   
0
   it "can match the domain name" do
0
- mapping.response( :domain => 'rubywaves.com' ) { 'Timmah!'}
0
- response = mock_request.get("http://rubywaves.com/foo" )
0
- response.status.should == 200
0
+ mappings do
0
+ on( :domain => 'rubywaves.com' ) { 'Timmah!'}
0
+ end
0
+
0
+ mock_request.get("http://rubywaves.com/foo" ).status.should == 200
0
     mock_request.get("http://www.microsoft.com/foo").status.should == 404
0
   end
0
   
0
   it "can match the Accepts header" do
0
- mapping.response( :accept => 'text/plain' ) { "boooring."}
0
+ mappings do
0
+ on( :accept => 'text/plain' ) { "boooring."}
0
+ end
0
     
0
     mock_request.get("/foo", 'HTTP_ACCEPT' => 'text/plain').status.should == 200
0
     mock_request.get("/foo", 'HTTP_ACCEPT' => 'text/xml').status.should == 404
0
   end
0
   
0
   it "can use a Regexp on any of the above" do
0
- mapping.response( :accept => /image|audio/ ) { "boooring."}
0
+ mappings do
0
+ on( :accept => /image|audio/ ) { "boooring."}
0
+ end
0
     
0
     mock_request.get("/foo", 'HTTP_ACCEPT' => 'image/jpeg').status.should == 200
0
     mock_request.get("/foo", 'HTTP_ACCEPT' => 'text/xml').status.should == 404
0
   end
0
   
0
   it "can use a lambda on any of the above" do
0
- mapping.response( :accept => lambda { |types| types.include? 'text/plain' } ) { "boooring."}
0
- mapping.response( :accept => lambda { |types| types.include? /image/ } ) { "cool."}
0
+ mappings do
0
+ on( :accept => lambda { |types| types.include? 'text/plain' } ) { "boooring."}
0
+ on( :accept => lambda { |types| types.include? /image/ } ) { "cool."}
0
+ end
0
     
0
     mock_request.get("/foo", 'HTTP_ACCEPT' => 'text/plain').status.should == 200
0
     mock_request.get("/foo", 'HTTP_ACCEPT' => 'image/jpeg').status.should == 200
...
7
8
9
10
 
11
12
13
14
15
16
17
18
19
 
 
 
20
21
22
 
23
24
25
26
27
 
 
28
29
30
31
32
33
34
35
36
37
38
 
 
 
 
 
 
 
39
40
41
42
43
 
44
45
46
 
47
48
49
50
51
52
 
53
54
55
 
 
 
 
56
57
58
59
60
61
 
62
63
 
 
 
 
 
 
 
64
65
 
66
67
 
 
 
68
69
70
...
75
76
77
78
 
79
80
81
82
83
 
 
 
84
85
86
87
 
 
 
88
89
90
...
7
8
9
 
10
11
 
12
13
14
15
 
 
 
16
17
18
19
20
 
21
22
23
24
 
 
25
26
27
28
29
30
31
32
 
 
33
 
 
34
35
36
37
38
39
40
41
42
43
44
 
45
46
47
 
48
49
50
51
52
53
 
54
55
 
 
56
57
58
59
60
 
 
 
 
 
61
62
 
63
64
65
66
67
68
69
70
71
72
73
 
74
75
76
77
78
79
...
84
85
86
 
87
88
89
90
91
 
92
93
94
95
96
97
 
98
99
100
101
102
103
0
@@ -7,64 +7,73 @@ require File.join(File.dirname(__FILE__) , "helpers")
0
 describe "A mapping declaration" do
0
   
0
   before do
0
- mapping.clear
0
+ mappings.clear
0
     handle( Waves::Dispatchers::NotFoundError ) { response.status = 404 }
0
- @resource = mock('resource')
0
     @default = MappingApp::Resources::Default
0
     
0
   end
0
   
0
- it "operates on app::Resources::Default when a resource is not specified" do
0
- mapping.response( :mapping_name, :get => [ "somewhere"] ) do
0
- self.class.inspect
0
+ it "operates on the default resource when a resource is not specified" do
0
+ mappings do
0
+ on( :get => [ "somewhere"] ) { resource }
0
     end
0
     
0
- mock_request.get("/somewhere").body.should == "MappingApp::Resources::Default"
0
+ mock_request.get("/somewhere").body.should == "default"
0
   end
0
   
0
   it "may specify a resource in the options with a key of :resource" do
0
- mapping.response( :mapping_name, :resource => :smurf, :get => [ "somewhere"] ) do
0
- self.class.inspect
0
+ mappings do
0
+ on( :get => [ "somewhere"], :resource => :smurf ) { self.class.inspect }
0
     end
0
     
0
     mock_request.get("/somewhere").body.should == "MappingApp::Resources::Smurf"
0
   end
0
   
0
   it "may determine the resource using a parameter match in the path pattern" do
0
- mapping.response( :mapping_name, :get => [ :resources ]) { self.class.inspect }
0
- mapping.response( :mapping_name, :get => [ :resource ]) { self.class.inspect }
0
     
0
- mock_request.get("/blankets").body.should == "MappingApp::Resources::Blanket"
0
- mock_request.get("/blanket").body.should == "MappingApp::Resources::Blanket"
0
+ mappings do
0
+ on( :get => [ :resource ]) { resources }
0
+ on( :get => [ "some", :resources ]) { singular }
0
+ end
0
+
0
+ mock_request.get("/blanket").body.should == "blankets"
0
+ mock_request.get("/some/blankets").body.should == "blanket"
0
   end
0
   
0
 end
0
 
0
-describe "A mapping given a name as the first argument" do
0
+describe "A mapping with an :as param" do
0
   
0
   before do
0
- mapping.clear
0
+ mappings.clear
0
     handle( Waves::Dispatchers::NotFoundError ) { response.status = 404 }
0
     @resource = mock('resource')
0
     @default = MappingApp::Resources::Default
0
   end
0
   
0
- it "calls the method with the action name on the Resource" do
0
+ it "calls the method with the action name on the Resource when no block is supplied" do
0
     @default.stub!(:new).and_return(@resource)
0
- @resource.should.receive(:smurf)
0
- mapping.response( :smurf, :get => [ "blue_critter" ] )
0
+ @resource.should.receive(:smurf).and_return("Smurfy")
0
+ mappings do
0
+ on( :get => [ "blue_critter" ], :as => :smurf )
0
+ end
0
     
0
- mock_request.get("/blue_critter").status.should == 200
0
- end
0
-
0
- it "defines a method on the Resource when a block is given" do
0
- mapping.response( :wizard, :get => [ :wizard ] ) { "Kill Smurfs!" }
0
+ mock_request.get("/blue_critter").body.should == "Smurfy"
0
     
0
- @default.new( mock('request') ).should.respond_to :wizard
0
+ mappings.clear
0
+ @resource.should.not.receive(:leprechaun)
0
+ mappings do
0
+ on( :get => [ "green_critter" ], :as => :leprechaun ) { "Gold!" }
0
+ end
0
+
0
+ mock_request.get("/green_critter").body.should == "Gold!"
0
   end
0
   
0
+
0
   it "defines a path generator on the Resource's Paths object" do
0
- mapping.response( :wizard, :get => [ :wizard ] ) { "Kill Smurfs!" }
0
+ mappings do
0
+ on( :get => [ :wizard ], :as => :wizard ) { "Kill Smurfs!" }
0
+ end
0
     
0
     paths = @default.new( mock('request') ).paths
0
     paths.should.respond_to :wizard
0
@@ -75,16 +84,20 @@ end
0
 describe "A mapping without a name" do
0
   
0
   before do
0
- mapping.clear
0
+ mappings.clear
0
     handle( Waves::Dispatchers::NotFoundError ) { response.status = 404 }
0
   end
0
   
0
   it "raises an ArgumentError when no block is supplied" do
0
- lambda { mapping.response( :get => [ "one" ] ) }.should.raise ArgumentError
0
+ lambda do
0
+ mappings { on( :get => [ "one" ] ) }
0
+ end.should.raise ArgumentError
0
   end
0
   
0
   it "evaluates the supplied block instead of calling a resource method" do
0
- mapping.response( :get => [ "two" ] ) { "Brainy" }
0
+ mappings do
0
+ on( :get => [ "two" ] ) { "Brainy" }
0
+ end
0
     
0
     mock_request.get("/two").body.should == "Brainy"
0
   end

Comments

    No one has commented yet.