kawaii-core 0.1.0

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.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 95acd16e37137a291448035f6d07d4e57fd176a8
4
+ data.tar.gz: 59e1181f5923fe52949358ef933b54979fd9e97c
5
+ SHA512:
6
+ metadata.gz: 82bc0bf00758bfc60a1659c6cf97e7de0a9252a1538a43ea8060b5742cc7d90dc6a146342c51c4fc1a046fd146904ae10c141f74d2a3d3bfbab090c8b24d0c1b
7
+ data.tar.gz: aae617e17cbc4c848d24c02f9d0aadfc6840d3986fcc79934f2811686d40843386d9a5d246aced280736cc29e20f02966ab892c2a02fa2229a4e7e4443970e42
data/.gitignore ADDED
@@ -0,0 +1,9 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --format documentation
2
+ --color
data/.travis.yml ADDED
@@ -0,0 +1,4 @@
1
+ language: ruby
2
+ rvm:
3
+ - 2.1.2
4
+ before_install: gem install bundler -v 1.10.6
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in kawaii.gemspec
4
+ gemspec
data/Guardfile ADDED
@@ -0,0 +1,42 @@
1
+ # A sample Guardfile
2
+ # More info at https://github.com/guard/guard#readme
3
+
4
+ ## Uncomment and set this to only include directories you want to watch
5
+ # directories %w(app lib config test spec features) \
6
+ # .select{|d| Dir.exists?(d) ? d : UI.warning("Directory #{d} does not exist")}
7
+
8
+ ## Note: if you are using the `directories` clause above and you are not
9
+ ## watching the project directory ('.'), then you will want to move
10
+ ## the Guardfile to a watched dir and symlink it back, e.g.
11
+ #
12
+ # $ mkdir config
13
+ # $ mv Guardfile config/
14
+ # $ ln -s config/Guardfile .
15
+ #
16
+ # and, you'll have to watch "config/Guardfile" instead of "Guardfile"
17
+
18
+ # Note: The cmd option is now required due to the increasing number of ways
19
+ # rspec may be run, below are examples of the most common uses.
20
+ # * bundler: 'bundle exec rspec'
21
+ # * bundler binstubs: 'bin/rspec'
22
+ # * spring: 'bin/rspec' (This will use spring if running and you have
23
+ # installed the spring binstubs per the docs)
24
+ # * zeus: 'zeus rspec' (requires the server to be started separately)
25
+ # * 'just' rspec: 'rspec'
26
+
27
+ guard :rspec, cmd: 'bundle exec rspec' do
28
+ require 'guard/rspec/dsl'
29
+ dsl = Guard::RSpec::Dsl.new(self)
30
+
31
+ # Feel free to open issues for suggestions and improvements
32
+
33
+ # RSpec files
34
+ rspec = dsl.rspec
35
+ watch(rspec.spec_helper) { rspec.spec_dir }
36
+ watch(rspec.spec_support) { rspec.spec_dir }
37
+ watch(rspec.spec_files)
38
+
39
+ # Ruby files
40
+ ruby = dsl.ruby
41
+ dsl.watch_spec_files_for(ruby.lib_files)
42
+ end
data/LICENSE.txt ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2015 Martin Bilski
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,372 @@
1
+
2
+ # Kawaii
3
+
4
+ Kawaii is a simple web framework based on Rack.
5
+
6
+ ** This is work in progress. The API is subject to change. **
7
+
8
+ ## Installation
9
+
10
+ Add this line to your application's Gemfile:
11
+
12
+ ```ruby
13
+ gem 'kawaii-core'
14
+ ```
15
+
16
+ And then execute:
17
+
18
+ $ bundle
19
+
20
+ Or install it yourself as:
21
+
22
+ $ gem install kawaii-core
23
+
24
+ ## Running examples
25
+
26
+ The `/examples` directory contains various basic usage examples.
27
+
28
+ Run the examples using rackup or directly:
29
+
30
+ ```
31
+ $ cd examples
32
+ $ rackup -r kawaii modular.ru
33
+ ```
34
+
35
+ Many examples can also be run directly without rackup, e.g.:
36
+
37
+ ```
38
+ $ cd examples
39
+ $ ruby -r kawaii hello_world.rb
40
+
41
+ ## Getting started
42
+
43
+ Kawaii's basic usage is very similar how you'd use Sinatra. You can define route handlers at the file scope. Here's an example:
44
+
45
+ ```
46
+ require 'kawaii'
47
+
48
+ get '/' do
49
+ 'Hello, world!'
50
+ end
51
+ ```
52
+
53
+ Save it to `hello.rb` and start the server like this:
54
+
55
+ ```
56
+ $ rackup -r kawaii hello.rb --port 8088
57
+ ```
58
+
59
+ Then navigate to `http://localhost:8088` to see the greeting.
60
+
61
+ ## Using rackup
62
+
63
+ To run the app you created in the "Getting started" section above using rackup, create the following `hello.ru` file:
64
+
65
+ ```
66
+ require 'kawaii'
67
+ require_relative 'hello'
68
+
69
+ run Kawaii::SingletonApp
70
+ ```
71
+
72
+ `SingletonApp` contains all routes defined at the file scope.
73
+
74
+ ## Defining routes
75
+
76
+ There are several methods you can use to build your routes, handle passed parameters and so on.
77
+
78
+ ### Supported HTTP methods
79
+
80
+ The basic way to add a route handler is to invoke a method corresponding to the given HTTP verb, e.g.:
81
+
82
+ ```
83
+ post '/users' do
84
+ # Some response
85
+ end
86
+ ```
87
+
88
+ Here, the `post` method corresponds to the `POST` HTTP verb.
89
+
90
+ Here's a list of supported HTTP verbs:
91
+
92
+ - get
93
+ - post
94
+ - put
95
+ - patch
96
+ - delete
97
+ - head
98
+ - options
99
+ - link
100
+ - unlink
101
+ - trace
102
+
103
+ ### Wildcard matching
104
+
105
+ Patterns in route definitions may contain wildcard characters `*` and `?`.
106
+
107
+ For example `get '/users/?'` matches both `/users/` and `/users` while `get '/users/*'` will match any path starting with '/users/' e.g. '/users/foo/bar'.
108
+
109
+ ### Parameters
110
+
111
+ Route patterns may contain named parameters, prefixed with a colon. Parameters are accessible through the `params` hash in handler:
112
+
113
+ ```
114
+ get '/users/:id' do
115
+ params[:id]
116
+ end
117
+ ```
118
+
119
+ (When requested with `/users/123`, the above route handler will render `"123"`.)
120
+
121
+ ### Regular expressions
122
+
123
+ Route patterns may contain regular expressions. Example:
124
+
125
+ ```
126
+ get %r{/users/.*} do
127
+ 'Hello, world'
128
+ end
129
+ ```
130
+
131
+ ### Nested routes
132
+
133
+ Routes may be nested using the `context` method. Example:
134
+
135
+ ```
136
+ context '/api' do
137
+ get '/users' do
138
+ 'Hello'
139
+ end
140
+ end
141
+ ```
142
+
143
+ Will above handler will be accessible through `/api/users`.
144
+
145
+ ### Custom matchers
146
+
147
+ If string patterns and regular expression are not flexible enough, you can create a custom matcher.
148
+
149
+ A matcher instance responds to `match` method and returns either a `Match` instance or nil if there's no match. See documentation for {Matcher#match} for more details.
150
+
151
+ ### Request object
152
+
153
+ Handlers can access the `Rack::Request` instance corresponding to the current request:
154
+
155
+ ```
156
+ get '/' do
157
+ request.host
158
+ end
159
+ ```
160
+
161
+ ### View templates
162
+
163
+ View templates must currently be stored in `views/` directory of the project using Kawaii. They can be rendered using the `render` method:
164
+
165
+ ```
166
+ get '/' do
167
+ render('index.html.erb')
168
+ end
169
+ ```
170
+
171
+ You can set instance variables and use them in the templates.
172
+
173
+ ```
174
+ get '/' do
175
+ @title = 'Hello, world'
176
+ render('index.html.erb')
177
+ end
178
+ ```
179
+
180
+ Let's say `views/index.html.erb` looks like this:
181
+
182
+ ```
183
+ <h1><%= @title %></h1>
184
+ ```
185
+
186
+ In that case, when you visit the page, you'll see **Hello, world**.
187
+
188
+ Supported templating engines include: ERB, Haml, Liquid, Builder, Kramdown and others. Note that you may need to include the specific gem implementing the given templating engine as inferred from the file name of the template.
189
+
190
+ ## Modular apps
191
+
192
+ For building more complex applications, you can split them into separate classes, each implementing a subset of functionality (e.g. website and an API).
193
+
194
+ To create an application, inherit from `Kawaii::Base` and define your routes inside the class.
195
+
196
+ Let's create `website.rb`:
197
+
198
+ ```ruby
199
+ require 'kawaii'
200
+
201
+ class Website < Kawaii::Base
202
+ get '/' do
203
+ 'Hello, world'
204
+ end
205
+ end
206
+ ```
207
+
208
+ Now here's how `api.rb` may look like:
209
+
210
+ ```ruby
211
+ require 'kawaii'
212
+
213
+ class API < Kawaii::Base
214
+ get '/info' do
215
+ 'This is some information'
216
+ end
217
+ end
218
+ ```
219
+
220
+ Let's use the apps in a `config.ru`:
221
+
222
+ ```ruby
223
+ require 'kawaii'
224
+ require_relative 'website'
225
+ require_relative 'api'
226
+
227
+ map '/' do
228
+ run Website
229
+ end
230
+
231
+ map '/api' do
232
+ run API
233
+ end
234
+ ```
235
+
236
+ ## Model-view-controller apps
237
+
238
+ Kawaii supports routing to controllers by either specifying the specific controller + action for a given route or by creating automatic Restful resources (via `route`).
239
+
240
+ Let's suppose we have a controller in `hello_world.rb` has typical CRUD methods that mimick Rails controllers:
241
+
242
+ ```ruby
243
+ class HelloWorld < Kawaii::Controller
244
+ def index
245
+ 'Hello, world'
246
+ end
247
+ end
248
+ ```
249
+
250
+ An in `users.rb`:
251
+
252
+ ```ruby
253
+ class Users < Kawaii::Controller
254
+ def index
255
+ 'GET /users'
256
+ end
257
+
258
+ def show
259
+ "GET /users/#{params[:id]}"
260
+ end
261
+
262
+ def create
263
+ 'POST /users'
264
+ end
265
+
266
+ def update
267
+ "PATCH /users/#{params[:id]}"
268
+ end
269
+
270
+ def destroy
271
+ "DELETE /users/#{params[:id]}"
272
+ end
273
+ end
274
+ ```
275
+
276
+ Here's how we can define routes (in `app.rb`):
277
+
278
+ ```ruby
279
+ require 'kawaii'
280
+ require_relative 'hello_world'
281
+ require_relative 'users'
282
+
283
+ get '/', 'hello_world#index' # Explicitly route to `HelloWorld#index` to show the welcome page
284
+
285
+ route '/users', 'users'
286
+ ```
287
+
288
+ You can run the app directly using `ruby` or create `config.ru`:
289
+
290
+ ```ruby
291
+ require_relative 'app.rb'
292
+
293
+ run Kawaii::SingletonApp
294
+ ```
295
+
296
+ Of course, you can
297
+
298
+ ## Testing
299
+
300
+ I recommend using `Rack::Test` for testing (see [here](https://github.com/brynary/rack-test)). Look at specs in `spec/` to see how you can use it.
301
+
302
+ To make a long story short, a class deriving from `Kawaii::Base` containing your routes is `app`. Let's suppose, your app class is `MyApp`, here's how you could test it:
303
+
304
+ ```ruby
305
+ describe MyApp
306
+ let(:app) { MyApp }
307
+ it 'renders home page' do
308
+ get '/'
309
+ expect(last_response).to be_ok
310
+ end
311
+ end
312
+ ```
313
+
314
+ ## Resources
315
+
316
+ See `/examples`
317
+ ### Reference
318
+
319
+ ## Contributing
320
+
321
+ Bug reports and pull requests are welcome on GitHub at https://github.com/bilus/kawaii.
322
+
323
+
324
+ ## License
325
+
326
+ The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
327
+
328
+
329
+ ## TODO
330
+
331
+ + Hello world app.
332
+ + Specs for the app.
333
+ + GET routes inside a class deriving from Base.
334
+ + Support for running apps without config.ru (ruby -I ./lib examples/hello_world.rb
335
+ + Top-level routes.
336
+ + Example for top-level routes.
337
+ + Nested routes.
338
+ + Modular apps (multiple modules via config.ru).
339
+ + Matchers.
340
+ + Wildcard regex routes, e.g. '/foo/bar/?'.
341
+ + Parameter-based routes. Unsupported in 'context'.
342
+ + Request object.
343
+ + Merge Rack Request params.
344
+ + String responses.
345
+ + Other HTTP verbs.
346
+ + Refactor & create individual files.
347
+ + Views (via `render` method in handlers) using Tilt.
348
+ + Rack route test helpers work.
349
+ + API reference.
350
+ + Check: References to methods defined in contexts and at class scope.
351
+ + Controllers - 'hello_world#index'
352
+ + 'route' to controllers (via class name or symbol references).
353
+ + Controllers - render.
354
+
355
+ - Readme - description and tutorial.
356
+ - Rubocop-compliant.
357
+ - Push gem.
358
+
359
+ - Example project using the gem and controllers (with views).
360
+
361
+ - Rack/custom global middleware.
362
+ - Route-specific middleware.
363
+ - Custom error handling (intercept exceptions, 404 what else?).
364
+ - Code review
365
+
366
+ ## Known issues
367
+
368
+ ### Rubocop
369
+
370
+ `lib/kawaii/routing_methods.rb:46:1: C: Extra blank line detected.`
371
+
372
+ The extra line is necessary for Yard to ignore the comment. Adjust Rubocop settings.