woah 0.0.2 → 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +67 -2
- data/lib/woah.rb +1 -1
- data/lib/woah/base.rb +62 -28
- data/lib/woah/route.rb +16 -0
- data/lib/woah/version.rb +2 -1
- data/test/before_after_test.rb +4 -2
- data/test/on_method_test.rb +30 -0
- data/test/testapp.rb +7 -7
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1f1640d590890f586e4b4d0f4a05fb83bc47d4e3a444496eaa634def37be851d
|
4
|
+
data.tar.gz: cf163513135e99c8998c317a70bfb120849d15c835164ebcb5f01787db6a8d6e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e98ff9bee429818defe3dd9582059cb2949b10cfd1b8c85bdd2c84c8aabac4bf354d84f474d5852cee5261d6e083d52d0b53f86f460aba736dc7d4fb3bb2e3fa
|
7
|
+
data.tar.gz: c956a1ae35bf2a132aab05fbd10a27c72b2da3bd2d73adb5e917e187203dd7e21d191c85506187bd1c40e2f2cda2daf736a76d88a420a45fda0c32fd9dc2f988
|
data/README.md
CHANGED
@@ -8,7 +8,7 @@ Woah! is a minimal web framework built on Rack. It's primary design goal is to b
|
|
8
8
|
`gem install woah`
|
9
9
|
|
10
10
|
## What now???
|
11
|
-
|
11
|
+
Simple. You're gonna want to extend Woah::Base, which will be your app's, er, base.
|
12
12
|
|
13
13
|
```ruby
|
14
14
|
require 'woah'
|
@@ -55,4 +55,69 @@ end
|
|
55
55
|
|
56
56
|
There's two new blocks here: `before` and `after`. They do things before and after the relevant route gets executed (duh!). This example will increment a counter everytime a page is hit, regardless of what page it is.
|
57
57
|
|
58
|
-
|
58
|
+
Of course, getting pages isn't everything you can do on the Internet. There's other HTTP verbs as well, like POST. Behold:
|
59
|
+
|
60
|
+
```ruby
|
61
|
+
require 'woah'
|
62
|
+
|
63
|
+
class MyApp < Woah::Base
|
64
|
+
before do
|
65
|
+
@@content ||=
|
66
|
+
'<form action="/" method="post">'\
|
67
|
+
'<input type="submit" value="click me please" />'\
|
68
|
+
'</form>'
|
69
|
+
end
|
70
|
+
|
71
|
+
on '/' do
|
72
|
+
@@content
|
73
|
+
end
|
74
|
+
|
75
|
+
on '/', 'POST' do
|
76
|
+
@@content = 'thanks for clicking!'
|
77
|
+
end
|
78
|
+
end
|
79
|
+
```
|
80
|
+
|
81
|
+
As soon as you click the button on `/`, the message on the page will transform.
|
82
|
+
|
83
|
+
Of course, sometimes you want routes to be flexible, and to catch more than one expression. For this, you can use regular expressions instead of strings as your routes, just like this:
|
84
|
+
|
85
|
+
```ruby
|
86
|
+
require 'woah'
|
87
|
+
|
88
|
+
class MyApp < Woah::Base
|
89
|
+
on %{^/greet/(\w+)$} do
|
90
|
+
"oh, hello, I didn't see you there #{match[1]}"
|
91
|
+
end
|
92
|
+
end
|
93
|
+
```
|
94
|
+
|
95
|
+
Now, visiting `/greet/Socrates` will greet you with your own name. Wonderful. By the way, you may have noticed we're using `%r{}` to delimit our regex, instead of the more common `//`. This is because of how common slashes are in routes, so it's recommended to use this syntax. You can use slashes to delimit your regex though, if you like. I won't judge you.
|
96
|
+
|
97
|
+
We're nearing the end of this little guide already, I'm afraid. However, there's still one more trick you need to see. Look, sometimes, you might disagree with the things Woah! thinks up for you. That's why you can override everything Woah! is about to send, if you so please. Por exemplo:
|
98
|
+
|
99
|
+
```ruby
|
100
|
+
require_relative 'lib/woah'
|
101
|
+
|
102
|
+
class MyApp < Woah::Base
|
103
|
+
on '/' do
|
104
|
+
'(insert super secret information)'
|
105
|
+
end
|
106
|
+
|
107
|
+
on %r{^/pass/(\w+)$} do
|
108
|
+
@password = match[1]
|
109
|
+
'logged in! <a href="/">back to root</a>'
|
110
|
+
end
|
111
|
+
|
112
|
+
after do
|
113
|
+
unless @password && @password == 'penguin'
|
114
|
+
set :status, 403
|
115
|
+
set :body, 'log in first!'
|
116
|
+
end
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
MyApp.run!
|
121
|
+
```
|
122
|
+
|
123
|
+
That's all. Have fun!
|
data/lib/woah.rb
CHANGED
data/lib/woah/base.rb
CHANGED
@@ -5,53 +5,87 @@ module Woah
|
|
5
5
|
class Base
|
6
6
|
@@before = nil
|
7
7
|
@@after = nil
|
8
|
-
@@
|
8
|
+
@@match_data = nil
|
9
|
+
@@routes = []
|
9
10
|
|
10
|
-
|
11
|
-
def self.call(env)
|
12
|
-
route = @@routes[[env['REQUEST_URI'], env['REQUEST_METHOD']]]
|
11
|
+
def call(env)
|
13
12
|
@@override = {}
|
13
|
+
@@match_data = nil
|
14
14
|
|
15
15
|
@@before&.call
|
16
16
|
|
17
|
-
|
17
|
+
response = handle_route env
|
18
|
+
|
19
|
+
@@after&.call
|
18
20
|
|
19
|
-
response = route.execute
|
20
21
|
%i[status headers body].each do |r|
|
21
22
|
response[r] = @@override[r] unless @@override[r].nil?
|
22
23
|
end
|
23
|
-
@@after&.call
|
24
24
|
|
25
25
|
response.values
|
26
26
|
end
|
27
27
|
|
28
|
-
|
29
|
-
def self.on(path, method = 'GET', &action)
|
30
|
-
raise 'unknown method' unless %w[DELETE GET HEAD OPTIONS PATCH POST PUT].include? method
|
31
|
-
@@routes[[path, method]] = Route.new(path, method, &action)
|
32
|
-
end
|
28
|
+
private
|
33
29
|
|
34
|
-
|
35
|
-
|
36
|
-
@@before = action
|
37
|
-
end
|
30
|
+
def handle_route(env)
|
31
|
+
route = @@routes.select { |r| r.matches?(env['REQUEST_METHOD'], env['REQUEST_URI']) }[0]
|
38
32
|
|
39
|
-
|
40
|
-
|
41
|
-
|
33
|
+
if route.nil?
|
34
|
+
return {
|
35
|
+
status: 404,
|
36
|
+
headers: { 'Content-Type' => 'text/html; charset=utf-8' },
|
37
|
+
body: 'not found L:'
|
38
|
+
}
|
39
|
+
end
|
40
|
+
|
41
|
+
@@match_data = route.match_data if route.match_data
|
42
|
+
|
43
|
+
route.execute
|
42
44
|
end
|
43
45
|
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
46
|
+
class << self
|
47
|
+
# Get this show on the road.
|
48
|
+
def run!(port = 4422)
|
49
|
+
Rack::Handler.pick(%w[thin webrick]).run new, Port: port
|
50
|
+
end
|
51
|
+
|
52
|
+
# Answer the phone.
|
53
|
+
# Finds a relevant route for the parameters in env,
|
54
|
+
# and builds a response.
|
55
|
+
def call(env)
|
56
|
+
new.call env
|
48
57
|
end
|
49
|
-
@@override[item] = content
|
50
|
-
end
|
51
58
|
|
52
|
-
|
53
|
-
|
54
|
-
|
59
|
+
# Register new routes. The optional method argument can be used to specify a method.
|
60
|
+
def on(path, method = 'GET', &action)
|
61
|
+
raise 'unknown method' unless %w[DELETE GET HEAD OPTIONS PATCH POST PUT].include? method
|
62
|
+
|
63
|
+
@@routes.push Route.new(path, method, &action)
|
64
|
+
end
|
65
|
+
|
66
|
+
# Action that will be called before every route.
|
67
|
+
def before(&action)
|
68
|
+
@@before = action
|
69
|
+
end
|
70
|
+
|
71
|
+
# Action that will be called after every route.
|
72
|
+
def after(&action)
|
73
|
+
@@after = action
|
74
|
+
end
|
75
|
+
|
76
|
+
# Override an item in the response.
|
77
|
+
def set(item, content)
|
78
|
+
unless %i[status headers body].include? item
|
79
|
+
raise 'unknown item ' + item.to_s + ', cannot override'
|
80
|
+
end
|
81
|
+
|
82
|
+
@@override[item] = content
|
83
|
+
end
|
84
|
+
|
85
|
+
# Get match data from Regexp routes.
|
86
|
+
def match
|
87
|
+
@@match_data
|
88
|
+
end
|
55
89
|
end
|
56
90
|
end
|
57
91
|
end
|
data/lib/woah/route.rb
CHANGED
@@ -3,12 +3,28 @@
|
|
3
3
|
module Woah
|
4
4
|
# Holds Woah! routes
|
5
5
|
class Route
|
6
|
+
attr_accessor :match_data
|
7
|
+
|
6
8
|
def initialize(path, method, &action)
|
9
|
+
raise 'only strings and regexps are valid paths' unless [String, Regexp].include? path.class
|
7
10
|
@path = path
|
8
11
|
@method = method
|
9
12
|
@action = action
|
13
|
+
@match_data = nil
|
14
|
+
end
|
15
|
+
|
16
|
+
# Returns true if the combination of method and path matches this route.
|
17
|
+
def matches?(method, path)
|
18
|
+
case @path
|
19
|
+
when String
|
20
|
+
@method == method && @path == path
|
21
|
+
when Regexp
|
22
|
+
@match_data = @path.match path
|
23
|
+
@method == method && @match_data
|
24
|
+
end
|
10
25
|
end
|
11
26
|
|
27
|
+
# Execute this route's actions.
|
12
28
|
def execute
|
13
29
|
status = 200
|
14
30
|
headers = { 'Content-Type' => 'text/html; charset=utf-8' }
|
data/lib/woah/version.rb
CHANGED
data/test/before_after_test.rb
CHANGED
@@ -6,7 +6,7 @@ class BeforeAfterTest < MiniTest::Test
|
|
6
6
|
end
|
7
7
|
|
8
8
|
def test_get_before
|
9
|
-
@env['REQUEST_URI'] = '/
|
9
|
+
@env['REQUEST_URI'] = '/before'
|
10
10
|
@env['REQUEST_METHOD'] = 'GET'
|
11
11
|
|
12
12
|
response = TestApp.call @env
|
@@ -14,9 +14,11 @@ class BeforeAfterTest < MiniTest::Test
|
|
14
14
|
assert_equal 200, response[0]
|
15
15
|
assert_equal 'chunky', response[2]
|
16
16
|
|
17
|
+
@env['REQUEST_URI'] = '/after'
|
18
|
+
|
17
19
|
response = TestApp.call @env
|
18
20
|
|
19
21
|
assert_equal 200, response[0]
|
20
|
-
assert_equal 'bacon',
|
22
|
+
assert_equal 'bacon', response[2]
|
21
23
|
end
|
22
24
|
end
|
data/test/on_method_test.rb
CHANGED
@@ -19,6 +19,36 @@ class OnMethodTest < MiniTest::Test
|
|
19
19
|
assert_equal "it's a secret to everybody", response[2]
|
20
20
|
end
|
21
21
|
|
22
|
+
def test_regexp_path
|
23
|
+
TestApp.on %r{^/regex/[0-9]+$} do
|
24
|
+
'heya'
|
25
|
+
end
|
26
|
+
|
27
|
+
@env['REQUEST_URI'] = '/regex/22'
|
28
|
+
@env['REQUEST_METHOD'] = 'GET'
|
29
|
+
response = TestApp.call @env
|
30
|
+
|
31
|
+
assert_equal 200, response[0]
|
32
|
+
|
33
|
+
@env['REQUEST_URI'] = '/regex/seventy'
|
34
|
+
response = TestApp.call @env
|
35
|
+
|
36
|
+
assert_equal 404, response[0]
|
37
|
+
end
|
38
|
+
|
39
|
+
def test_regexp_match_data
|
40
|
+
TestApp.on %r{^/myname/(\w+)$} do
|
41
|
+
'hi there, ' + TestApp.match[1]
|
42
|
+
end
|
43
|
+
|
44
|
+
@env['REQUEST_URI'] = '/myname/Charles'
|
45
|
+
@env['REQUEST_METHOD'] = 'GET'
|
46
|
+
response = TestApp.call @env
|
47
|
+
|
48
|
+
assert_equal 200, response[0]
|
49
|
+
assert_equal 'hi there, Charles', response[2]
|
50
|
+
end
|
51
|
+
|
22
52
|
def test_illegal_method
|
23
53
|
assert_raises RuntimeError do
|
24
54
|
TestApp.on '/', 'BUBBLES' do
|
data/test/testapp.rb
CHANGED
@@ -4,7 +4,7 @@ require_relative '../lib/woah'
|
|
4
4
|
|
5
5
|
class TestApp < Woah::Base
|
6
6
|
before do
|
7
|
-
|
7
|
+
@a = 'chunky'
|
8
8
|
end
|
9
9
|
|
10
10
|
on '/' do
|
@@ -15,15 +15,15 @@ class TestApp < Woah::Base
|
|
15
15
|
'got post!'
|
16
16
|
end
|
17
17
|
|
18
|
-
on '/
|
19
|
-
|
18
|
+
on '/before' do
|
19
|
+
@a
|
20
20
|
end
|
21
21
|
|
22
|
-
after do
|
23
|
-
|
22
|
+
on '/after' do
|
23
|
+
@b
|
24
24
|
end
|
25
25
|
|
26
|
-
|
27
|
-
|
26
|
+
after do
|
27
|
+
@b = 'bacon'
|
28
28
|
end
|
29
29
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: woah
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0
|
4
|
+
version: 1.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- knarka
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-06-
|
11
|
+
date: 2018-06-24 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rack
|