frankrb 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/frank.gemspec +22 -0
- data/lib/frank.rb +54 -0
- data/rakefile +8 -0
- data/test/frank.rb +109 -0
- data/test/helper.rb +8 -0
- metadata +83 -0
data/frank.gemspec
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Gem::Specification.new do |s|
|
2
|
+
s.name = "frankrb"
|
3
|
+
s.version = "0.0.1"
|
4
|
+
s.summary = "A proof of concept originally conceived while writing a blog post."
|
5
|
+
s.description = "Frank tries to demonstrate how to write a basic Sinatra-ish clone."
|
6
|
+
s.authors = ["Cyril David"]
|
7
|
+
s.email = ["me@cyrildavid.com"]
|
8
|
+
s.homepage = "http://github.com/cyx/frankrb"
|
9
|
+
|
10
|
+
s.files = Dir[
|
11
|
+
"LICENSE",
|
12
|
+
"README",
|
13
|
+
"rakefile",
|
14
|
+
"lib/**/*.rb",
|
15
|
+
"*.gemspec",
|
16
|
+
"test/*.*"
|
17
|
+
]
|
18
|
+
|
19
|
+
s.add_dependency "rack"
|
20
|
+
s.add_development_dependency "cutest"
|
21
|
+
s.add_development_dependency "capybara"
|
22
|
+
end
|
data/lib/frank.rb
ADDED
@@ -0,0 +1,54 @@
|
|
1
|
+
require "rack"
|
2
|
+
|
3
|
+
class Frank
|
4
|
+
def self.get(path, &block)
|
5
|
+
handlers["GET"] << [matcher(path), block]
|
6
|
+
end
|
7
|
+
|
8
|
+
def self.post(path, &block)
|
9
|
+
handlers["POST"] << [matcher(path), block]
|
10
|
+
end
|
11
|
+
|
12
|
+
def self.put(path, &block)
|
13
|
+
handlers["PUT"] << [matcher(path), block]
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.delete(path, &block)
|
17
|
+
handlers["DELETE"] << [matcher(path), block]
|
18
|
+
end
|
19
|
+
|
20
|
+
def self.matcher(path)
|
21
|
+
# handle the case where the path has a variable
|
22
|
+
# e.g. /post/:id
|
23
|
+
re = path.gsub(/\:[^\/]+/, "([^\\/]+)")
|
24
|
+
|
25
|
+
%r{\A#{trim_trailing_slash(re)}\z}
|
26
|
+
end
|
27
|
+
|
28
|
+
def self.trim_trailing_slash(str)
|
29
|
+
str.gsub(/\/$/, "")
|
30
|
+
end
|
31
|
+
|
32
|
+
def self.handlers
|
33
|
+
@handlers ||= Hash.new { |h, k| h[k] = [] }
|
34
|
+
end
|
35
|
+
|
36
|
+
def self.request
|
37
|
+
Thread.current[:request]
|
38
|
+
end
|
39
|
+
|
40
|
+
def self.call(env)
|
41
|
+
res = Rack::Response.new
|
42
|
+
|
43
|
+
handlers[env["REQUEST_METHOD"]].each do |matcher, block|
|
44
|
+
if match = trim_trailing_slash(env["PATH_INFO"]).match(matcher)
|
45
|
+
Thread.current[:request] = Rack::Request.new(env)
|
46
|
+
|
47
|
+
break res.write(block.call(*match.captures))
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
res.status = 404 if res.empty?
|
52
|
+
res.finish
|
53
|
+
end
|
54
|
+
end
|
data/rakefile
ADDED
data/test/frank.rb
ADDED
@@ -0,0 +1,109 @@
|
|
1
|
+
require_relative "helper"
|
2
|
+
|
3
|
+
class Blog < Frank
|
4
|
+
get "/" do
|
5
|
+
"Main Blog"
|
6
|
+
end
|
7
|
+
|
8
|
+
get "/post/:id" do |id|
|
9
|
+
"Displaying post #{id}"
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
class Support < Frank
|
14
|
+
get "/" do
|
15
|
+
"Main Support Site"
|
16
|
+
end
|
17
|
+
|
18
|
+
get "/submit" do
|
19
|
+
"<form method='post'><textarea name='issue'></textarea>" +
|
20
|
+
"<input type='submit' name='submit' value='Help'></form>"
|
21
|
+
end
|
22
|
+
|
23
|
+
post "/submit" do
|
24
|
+
"Received issue: %s" % request.params["issue"]
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
class Docs < Frank
|
29
|
+
get "/" do
|
30
|
+
"We're here to help!"
|
31
|
+
end
|
32
|
+
|
33
|
+
get "/download" do
|
34
|
+
"Download our documentation in PDF or read it online!"
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
class Home < Frank
|
39
|
+
get "/" do
|
40
|
+
"Homepage"
|
41
|
+
end
|
42
|
+
|
43
|
+
get "/about" do
|
44
|
+
"About"
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
def helloapp
|
49
|
+
builder = Rack::Builder.new
|
50
|
+
|
51
|
+
builder.map "/blog" do
|
52
|
+
run Blog
|
53
|
+
end
|
54
|
+
|
55
|
+
builder.map "/docs" do
|
56
|
+
run Docs
|
57
|
+
end
|
58
|
+
|
59
|
+
builder.map "/support" do
|
60
|
+
run Support
|
61
|
+
end
|
62
|
+
|
63
|
+
builder.run Home
|
64
|
+
|
65
|
+
return builder.to_app
|
66
|
+
end
|
67
|
+
|
68
|
+
prepare do
|
69
|
+
Capybara.app = helloapp
|
70
|
+
end
|
71
|
+
|
72
|
+
scope do
|
73
|
+
test "home" do
|
74
|
+
visit "/"
|
75
|
+
assert_equal "Homepage", page.source
|
76
|
+
end
|
77
|
+
|
78
|
+
test "about" do
|
79
|
+
visit "/about"
|
80
|
+
assert_equal "About", page.source
|
81
|
+
end
|
82
|
+
|
83
|
+
test "docs" do
|
84
|
+
visit "/docs"
|
85
|
+
assert_equal "We're here to help!", page.source
|
86
|
+
|
87
|
+
# Also works with trailing slashes
|
88
|
+
visit "/docs/"
|
89
|
+
assert_equal "We're here to help!", page.source
|
90
|
+
|
91
|
+
# Also works with trailing slash + a query string
|
92
|
+
visit "/docs/?foo=bar"
|
93
|
+
assert_equal "We're here to help!", page.source
|
94
|
+
end
|
95
|
+
|
96
|
+
test "support" do
|
97
|
+
visit "/support/submit"
|
98
|
+
|
99
|
+
fill_in "issue", with: "I need help!"
|
100
|
+
click_button "Help"
|
101
|
+
|
102
|
+
assert_equal "Received issue: I need help!", page.source
|
103
|
+
end
|
104
|
+
|
105
|
+
test "blog" do
|
106
|
+
visit "/blog/post/1234/"
|
107
|
+
assert_equal "Displaying post 1234", page.source
|
108
|
+
end
|
109
|
+
end
|
data/test/helper.rb
ADDED
metadata
ADDED
@@ -0,0 +1,83 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: frankrb
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Cyril David
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2012-02-16 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: rack
|
16
|
+
requirement: &2156228740 !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '0'
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: *2156228740
|
25
|
+
- !ruby/object:Gem::Dependency
|
26
|
+
name: cutest
|
27
|
+
requirement: &2156228100 !ruby/object:Gem::Requirement
|
28
|
+
none: false
|
29
|
+
requirements:
|
30
|
+
- - ! '>='
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: '0'
|
33
|
+
type: :development
|
34
|
+
prerelease: false
|
35
|
+
version_requirements: *2156228100
|
36
|
+
- !ruby/object:Gem::Dependency
|
37
|
+
name: capybara
|
38
|
+
requirement: &2156264720 !ruby/object:Gem::Requirement
|
39
|
+
none: false
|
40
|
+
requirements:
|
41
|
+
- - ! '>='
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
version: '0'
|
44
|
+
type: :development
|
45
|
+
prerelease: false
|
46
|
+
version_requirements: *2156264720
|
47
|
+
description: Frank tries to demonstrate how to write a basic Sinatra-ish clone.
|
48
|
+
email:
|
49
|
+
- me@cyrildavid.com
|
50
|
+
executables: []
|
51
|
+
extensions: []
|
52
|
+
extra_rdoc_files: []
|
53
|
+
files:
|
54
|
+
- rakefile
|
55
|
+
- lib/frank.rb
|
56
|
+
- frank.gemspec
|
57
|
+
- test/frank.rb
|
58
|
+
- test/helper.rb
|
59
|
+
homepage: http://github.com/cyx/frankrb
|
60
|
+
licenses: []
|
61
|
+
post_install_message:
|
62
|
+
rdoc_options: []
|
63
|
+
require_paths:
|
64
|
+
- lib
|
65
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
66
|
+
none: false
|
67
|
+
requirements:
|
68
|
+
- - ! '>='
|
69
|
+
- !ruby/object:Gem::Version
|
70
|
+
version: '0'
|
71
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
72
|
+
none: false
|
73
|
+
requirements:
|
74
|
+
- - ! '>='
|
75
|
+
- !ruby/object:Gem::Version
|
76
|
+
version: '0'
|
77
|
+
requirements: []
|
78
|
+
rubyforge_project:
|
79
|
+
rubygems_version: 1.8.16
|
80
|
+
signing_key:
|
81
|
+
specification_version: 3
|
82
|
+
summary: A proof of concept originally conceived while writing a blog post.
|
83
|
+
test_files: []
|