bats 0.0.1

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/README ADDED
@@ -0,0 +1,16 @@
1
+ ~~~(^._.^)~~~ Bats!
2
+
3
+ A micro-framework.
4
+
5
+ Bats! implements an easy to use router on top of Rack for handling REST
6
+ requests. This makes getting an app up and running ridiculously easy.
7
+
8
+ Bats! stays out of your way. It doesn't ask you to use any particular
9
+ development methodology, templating framework, or other such tom-foolery.
10
+
11
+ Example usage:
12
+
13
+ # config.ru
14
+
15
+ require 'bats'
16
+
@@ -0,0 +1,87 @@
1
+ %w( httpresponse wizarding ).each do |f|
2
+ require 'bats/modules/httpresponse'
3
+ end
4
+
5
+ class Bats
6
+ extend Wizarding
7
+
8
+ traits :routes
9
+
10
+ def self.inherited c
11
+ c.traits *traits.keys
12
+ end
13
+
14
+ def self.addRoute m, p, o = nil, &b
15
+ @traits[ :routes ] ||= {}
16
+ @traits[ :routes ][ m ] ||= {}
17
+ @traits[ :routes ][ m ][ p ] = ( block_given? ) ? b : o
18
+ end
19
+
20
+ def self.get p, o = nil, &b; addRoute( :get, p, o, &b ); end
21
+ def self.post p, o = nil, &b; addRoute( :post, p, o, &b ); end
22
+ def self.put p, o = nil, &b; addRoute( :put, p, o, &b ); end
23
+ def self.delete p, o = nil, &b; addRoute( :delete, p, o, &b ); end
24
+
25
+ def self.redirect l, isTemporary = true
26
+ i = ( isTemporary ) ? '307' : '301'
27
+ statusCode( i ).headers( :Location => l )
28
+ end
29
+
30
+ def self.call env; new.call( env ); end
31
+
32
+ def statusCode i
33
+ ::HTTPResponse.const_get( "Status#{i}" )
34
+ end
35
+
36
+ def self.statusCode i
37
+ ::HTTPResponse.const_get( "Status#{i}" )
38
+ end
39
+
40
+ def self.pubDir
41
+ File.expand_path( '../../public', __FILE__ )
42
+ end
43
+
44
+ def pubDir
45
+ File.expand_path( '../../public', __FILE__ )
46
+ end
47
+
48
+ def call env
49
+ method = env[ 'REQUEST_METHOD' ].downcase.to_sym
50
+ path = env[ 'PATH_INFO' ]
51
+ matches ||= nil
52
+ if @routes && @routes[method] then
53
+ if @routes[method].include?( path ) then
54
+ route = @routes[method][ path ]
55
+ else
56
+ @routes[method].each do | p, b |
57
+ if p.kind_of?( Regexp ) then
58
+ if matches = path.match( p ) then
59
+ matches = matches[ 1, matches.length - 1 ]
60
+ matches.map! do | i |
61
+ i = ( i ) ? i : ''
62
+ i = i.to_i if i =~ /^[\d]+$/
63
+ i
64
+ end
65
+ route = b
66
+ break # Eh! give me a break here!
67
+ end
68
+ end
69
+ end
70
+ end
71
+ end
72
+ if !route && path =~ /\./ then
73
+ route = ::Rack::File.new( pubDir ) if File.exist?( "#{pubDir}/#{path}" )
74
+ end
75
+ route ||= statusCode( 404 )
76
+ args = ( matches ) ? [ env, *matches ] : [ env ]
77
+ begin
78
+ route = route.call( args ) if route.kind_of?( Proc )
79
+ route.call( env )
80
+ rescue
81
+ b = '<h1>Ooops... The code broke.</h1>'
82
+ b += "<h3>#{$!.to_s}</h3>#{$!.backtrace.join( '<br/>' )}"
83
+ route = statusCode(500).body b
84
+ route.call( env )
85
+ end
86
+ end
87
+ end
@@ -0,0 +1,26 @@
1
+ %w( metaid wizarding ).each { | f | require "bats/modules/#{f}" }
2
+
3
+ module ClassBaker
4
+ include Metaid
5
+
6
+ def makeClass n, c = nil
7
+ c = ( c.nil? ) ? Class.new : c
8
+ c = ( c.is_a?( String ) ) ? Class.new( const_get( c ) ) : c
9
+ const_set n, c
10
+ c
11
+ end
12
+
13
+ def bakeClass h
14
+ h.each do | c, o |
15
+ t = o.include?( :inherit ) ? o[ :inherit ] : nil
16
+ o.delete( :inherit )
17
+ i = makeClass( c, t )
18
+ i.extend( Wizarding )
19
+ unless o.empty? then
20
+ i.traits *o.keys
21
+ o.each { | k, v | i.send( k, v ) }
22
+ end
23
+ end
24
+ end
25
+
26
+ end
@@ -0,0 +1,36 @@
1
+ require 'bats/modules/classbaker'
2
+
3
+ module HTTPResponse
4
+ extend ClassBaker
5
+
6
+ class Response
7
+ extend ::Wizarding
8
+
9
+ traits :status, :headers, :body
10
+
11
+ def self.headers h
12
+ @traits[ :headers ] ||= {}
13
+ @traits[ :headers ].merge!( h )
14
+ end
15
+
16
+ def self.call env; new.call( env ); end
17
+
18
+ def call env
19
+ [ @status, @headers, @body ]
20
+ end
21
+ end
22
+
23
+ require 'yaml'
24
+ statuses = YAML.load_file( "#{File.expand_path( '../yaml', File.dirname( __FILE__ ) )}/statuses.yaml" ) # Somewhere in the nether regions beyond column 80!
25
+ statuses.each do | k, v |
26
+ bakeClass(
27
+ "Status#{k}" => {
28
+ :inherit => 'Response',
29
+ :status => k,
30
+ :headers => v[0],
31
+ :body => v[1]
32
+ }
33
+ )
34
+ end
35
+
36
+ end
@@ -0,0 +1,16 @@
1
+ # Sorry _why I don't feel like extending Ruby's Object class.
2
+ module Metaid
3
+ def metaclass; class << self; self; end; end
4
+
5
+ def meta_eval &b
6
+ metaclass.instance_eval &b
7
+ end
8
+
9
+ def meta_def( n, &b )
10
+ meta_eval { define_method( n, &b ) }
11
+ end
12
+
13
+ def class_def( n, &b )
14
+ class_eval { define_method( n, &b ) }
15
+ end
16
+ end
@@ -0,0 +1,28 @@
1
+ require 'bats/modules/metaid'
2
+
3
+ module Wizarding
4
+ include Metaid
5
+
6
+ def traits *a
7
+ return @traits if a.empty?
8
+ attr_accessor *a
9
+ a.each do | m |
10
+ @traits ||= {}
11
+ @traits[m] = nil
12
+ meta_def m do | *v |
13
+ @traits[m] = v[0] unless v.empty?
14
+ ( v.empty? ) ? @traits[m] : self
15
+ end
16
+ end
17
+ class_def :initialize do
18
+ self.class.traits.each do | k, v |
19
+ instance_variable_set( "@#{k}", v )
20
+ end
21
+ end
22
+ end
23
+
24
+ def inherited c
25
+ c.traits *traits.keys
26
+ c.instance_variable_set( :@traits, traits.dup )
27
+ end
28
+ end
@@ -0,0 +1,17 @@
1
+ 404:
2
+ - Content-Type: text/plain
3
+ - '404: Page not found.'
4
+ 301:
5
+ - Content-Type: text/html
6
+ Location: '/'
7
+ - '301: Moved Permanently.'
8
+ 307:
9
+ - Content-Type: text/html
10
+ Location: '/'
11
+ - '307: Moved Temporarily.'
12
+ 200:
13
+ - Content-Type: text/html
14
+ - '200: Page Successfully Loaded.'
15
+ 500:
16
+ - Content-Type: text/html
17
+ - '500: Oh noes... an error.'
metadata ADDED
@@ -0,0 +1,70 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: bats
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Hans Oksendahl
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2009-10-07 00:00:00 -07:00
13
+ default_executable:
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: rack
17
+ type: :runtime
18
+ version_requirement:
19
+ version_requirements: !ruby/object:Gem::Requirement
20
+ requirements:
21
+ - - ">="
22
+ - !ruby/object:Gem::Version
23
+ version: "0"
24
+ version:
25
+ description:
26
+ email: hansoksendahl@gmail.com
27
+ executables: []
28
+
29
+ extensions: []
30
+
31
+ extra_rdoc_files:
32
+ - README
33
+ files:
34
+ - lib/bats.rb
35
+ - lib/bats/yaml/statuses.yaml
36
+ - lib/bats/modules/httpresponse.rb
37
+ - lib/bats/modules/classbaker.rb
38
+ - lib/bats/modules/wizarding.rb
39
+ - lib/bats/modules/metaid.rb
40
+ - README
41
+ has_rdoc: true
42
+ homepage: http://hansoksendahl.com/
43
+ licenses: []
44
+
45
+ post_install_message:
46
+ rdoc_options: []
47
+
48
+ require_paths:
49
+ - - lib
50
+ required_ruby_version: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: "0"
55
+ version:
56
+ required_rubygems_version: !ruby/object:Gem::Requirement
57
+ requirements:
58
+ - - ">="
59
+ - !ruby/object:Gem::Version
60
+ version: "0"
61
+ version:
62
+ requirements: []
63
+
64
+ rubyforge_project:
65
+ rubygems_version: 1.3.5
66
+ signing_key:
67
+ specification_version: 3
68
+ summary: A microframework built on Rack.
69
+ test_files: []
70
+