gurk 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/.gitignore +21 -0
- data/.rspec +2 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +112 -0
- data/Rakefile +7 -0
- data/bin/gurk +7 -0
- data/gurk.gemspec +30 -0
- data/lib/gurk.rb +65 -0
- data/lib/gurk/cli.rb +21 -0
- data/lib/gurk/page.rb +71 -0
- data/lib/gurk/parser.rb +82 -0
- data/lib/gurk/router.rb +31 -0
- data/lib/gurk/runner.rb +25 -0
- data/lib/gurk/version.rb +3 -0
- data/lib/templates/Gemfile +13 -0
- data/lib/templates/app.rb +6 -0
- data/lib/templates/app/views/home.erb +0 -0
- data/lib/templates/app/views/layout.erb +0 -0
- data/lib/templates/config.ru +3 -0
- data/lib/templates/features/home.feature +15 -0
- data/spec/example/Gemfile +3 -0
- data/spec/example/app.rb +6 -0
- data/spec/example/app/views/about.erb +11 -0
- data/spec/example/app/views/home.erb +11 -0
- data/spec/example/config.ru +3 -0
- data/spec/example/features/home.feature +15 -0
- data/spec/gurk/cli_spec.rb +33 -0
- data/spec/gurk/example_spec.rb +27 -0
- data/spec/gurk/gurk_spec.rb +22 -0
- data/spec/gurk/page_spec.rb +56 -0
- data/spec/gurk/parser_spec.rb +210 -0
- data/spec/gurk/router_spec.rb +44 -0
- data/spec/spec_helper.rb +8 -0
- data/spec/support/another_example.feature +8 -0
- data/spec/support/example.feature +8 -0
- data/spec/support/example_with_layout.feature +10 -0
- data/spec/support/views/about.erb +1 -0
- data/spec/support/views/layout.erb +6 -0
- metadata +192 -0
data/.gitignore
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
*.gem
|
2
|
+
*.rbc
|
3
|
+
.bundle
|
4
|
+
.config
|
5
|
+
.yardoc
|
6
|
+
Gemfile.lock
|
7
|
+
InstalledFiles
|
8
|
+
_yardoc
|
9
|
+
coverage
|
10
|
+
doc/
|
11
|
+
lib/bundler/man
|
12
|
+
pkg
|
13
|
+
rdoc
|
14
|
+
spec/reports
|
15
|
+
test/tmp
|
16
|
+
test/version_tmp
|
17
|
+
tmp
|
18
|
+
.rvmrc
|
19
|
+
.ruby-version
|
20
|
+
spec/support/testapp
|
21
|
+
**.DS_Store
|
data/.rspec
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2013 Jason Torres
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,112 @@
|
|
1
|
+
# Gurk
|
2
|
+
|
3
|
+
A ruby microframework for the masses. You don't need a programming background all you need is the english language.
|
4
|
+
|
5
|
+
Perfect for designers or any developers that don't want to write code at all.
|
6
|
+
|
7
|
+
## Installation
|
8
|
+
|
9
|
+
gem install gurk
|
10
|
+
|
11
|
+
Create a new gurk project by running
|
12
|
+
|
13
|
+
gurk new <appname>
|
14
|
+
cd <appname>
|
15
|
+
|
16
|
+
You should see a directory with the following structure
|
17
|
+
|
18
|
+
app/
|
19
|
+
assets/
|
20
|
+
views/
|
21
|
+
views/layouts/application.html.erb
|
22
|
+
features/
|
23
|
+
public/
|
24
|
+
vendor/
|
25
|
+
Gemfile
|
26
|
+
|
27
|
+
## Features
|
28
|
+
|
29
|
+
Create a basic feature file with the following
|
30
|
+
|
31
|
+
Given I have a home page
|
32
|
+
And with the path "/"
|
33
|
+
And with the title "Home Page"
|
34
|
+
And with the layout "
|
35
|
+
|
36
|
+
More information and examples can be found at the Wiki.
|
37
|
+
|
38
|
+
## Template Support
|
39
|
+
|
40
|
+
Gurk supports Tilt. A template wrapper that gives you the flexibility to choose which
|
41
|
+
|
42
|
+
If you're using haml, just add the following in your Gemfile
|
43
|
+
|
44
|
+
gem 'haml'
|
45
|
+
|
46
|
+
Don't forget to run bundle install
|
47
|
+
|
48
|
+
## Overiding generated pages
|
49
|
+
|
50
|
+
For each page generated from the feature scenarios. We create an object that you can easily override. For this feature.
|
51
|
+
|
52
|
+
|
53
|
+
Given I have a home page
|
54
|
+
And with the path "/"
|
55
|
+
And with the title "Home Page"
|
56
|
+
And with the layout "
|
57
|
+
|
58
|
+
Add a file called app/home.rb
|
59
|
+
|
60
|
+
class HomePage
|
61
|
+
include Gurk::Methods
|
62
|
+
|
63
|
+
local :page_title, 'This is the new title'
|
64
|
+
local :header, 'The most awesome site ever'
|
65
|
+
|
66
|
+
path '/homepage'
|
67
|
+
|
68
|
+
end
|
69
|
+
|
70
|
+
## Creating your own pages
|
71
|
+
|
72
|
+
Ok fine, you don't want to use the features feature. You are free to do so by doing the following
|
73
|
+
|
74
|
+
Create a file called app/contact.rb
|
75
|
+
|
76
|
+
class ContactPage
|
77
|
+
include Gurk::Methods
|
78
|
+
|
79
|
+
name 'contact'
|
80
|
+
local :title, "Contact Page"
|
81
|
+
path '/contact'
|
82
|
+
|
83
|
+
end
|
84
|
+
|
85
|
+
Don't forget to create your view. For example: app/views/contact.html.erb
|
86
|
+
|
87
|
+
Then register it to Gurk in your app.rb file.
|
88
|
+
|
89
|
+
Gurk::Router.register ContactPage
|
90
|
+
|
91
|
+
## Tests
|
92
|
+
|
93
|
+
Gurk supports tests! In fact we do sanity check per each request during development.
|
94
|
+
|
95
|
+
## Contributing
|
96
|
+
|
97
|
+
1. Fork it
|
98
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
99
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
100
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
101
|
+
5. Create new Pull Request
|
102
|
+
|
103
|
+
|
104
|
+
## Contributors
|
105
|
+
|
106
|
+
Vixon
|
107
|
+
|
108
|
+
## License
|
109
|
+
|
110
|
+
MIT License
|
111
|
+
|
112
|
+
|
data/Rakefile
ADDED
data/bin/gurk
ADDED
data/gurk.gemspec
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'gurk/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "gurk"
|
8
|
+
spec.version = Gurk::VERSION
|
9
|
+
spec.authors = ["Vixon"]
|
10
|
+
spec.email = ["vixonshow@gmail.com"]
|
11
|
+
spec.description = %q{Gurk}
|
12
|
+
spec.summary = %q{A plain english ruby microframework that makes sense}
|
13
|
+
spec.homepage = "http://github.com/vixon/gurk"
|
14
|
+
spec.license = "MIT"
|
15
|
+
|
16
|
+
spec.files = `git ls-files`.split($/)
|
17
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
|
+
spec.require_paths = ["lib"]
|
20
|
+
|
21
|
+
spec.add_development_dependency "bundler", "~> 1.3"
|
22
|
+
spec.add_development_dependency "rake"
|
23
|
+
spec.add_development_dependency "rspec"
|
24
|
+
spec.add_development_dependency "rack-test"
|
25
|
+
|
26
|
+
spec.add_dependency "gherkin"
|
27
|
+
spec.add_dependency 'http_router', '~> 0.11.0'
|
28
|
+
spec.add_dependency 'tilt'
|
29
|
+
spec.add_dependency 'thor'
|
30
|
+
end
|
data/lib/gurk.rb
ADDED
@@ -0,0 +1,65 @@
|
|
1
|
+
require "gurk/version"
|
2
|
+
require "gurk/router"
|
3
|
+
require "gurk/parser"
|
4
|
+
require "gurk/page"
|
5
|
+
require "tilt"
|
6
|
+
require "tilt/erb"
|
7
|
+
|
8
|
+
module Gurk
|
9
|
+
|
10
|
+
Tilt.register Tilt::ERBTemplate, '.html.erb'
|
11
|
+
|
12
|
+
def self.root
|
13
|
+
Dir.pwd
|
14
|
+
end
|
15
|
+
|
16
|
+
# The default template
|
17
|
+
@@default_view_engine = :erb
|
18
|
+
|
19
|
+
def self.default_view_engine
|
20
|
+
@@default_view_engine
|
21
|
+
end
|
22
|
+
|
23
|
+
def self.default_view_engine=(new_default_view_engine)
|
24
|
+
@@default_view_engine = new_default_view_engine
|
25
|
+
end
|
26
|
+
|
27
|
+
# The default view path
|
28
|
+
@@view_path = self.root + "/app/views"
|
29
|
+
|
30
|
+
def self.view_path
|
31
|
+
@@view_path
|
32
|
+
end
|
33
|
+
|
34
|
+
def self.view_path=(new_view_path)
|
35
|
+
@@view_path = new_view_path
|
36
|
+
end
|
37
|
+
|
38
|
+
@@feature_paths = Dir.glob("#{Dir.pwd}/features/*.feature")
|
39
|
+
|
40
|
+
def self.feature_paths
|
41
|
+
@@feature_paths
|
42
|
+
end
|
43
|
+
|
44
|
+
def self.feature_paths=(new_feature_path)
|
45
|
+
@@feature_paths = new_feature_path
|
46
|
+
end
|
47
|
+
|
48
|
+
@@router ||= Gurk::Router.new
|
49
|
+
|
50
|
+
def self.router
|
51
|
+
@@router
|
52
|
+
end
|
53
|
+
|
54
|
+
def self.run
|
55
|
+
puts self.feature_paths
|
56
|
+
parsed = Gurk::Parser.new(self.feature_paths).parse!
|
57
|
+
|
58
|
+
parsed.each do |p|
|
59
|
+
router.add Gurk::Page.new(p)
|
60
|
+
end
|
61
|
+
|
62
|
+
self.router
|
63
|
+
end
|
64
|
+
|
65
|
+
end
|
data/lib/gurk/cli.rb
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'thor'
|
2
|
+
module Gurk
|
3
|
+
class Cli < Thor::Group
|
4
|
+
include Thor::Actions
|
5
|
+
|
6
|
+
argument :name
|
7
|
+
|
8
|
+
def self.source_root
|
9
|
+
File.dirname(__FILE__)
|
10
|
+
end
|
11
|
+
|
12
|
+
def setup
|
13
|
+
directory "../templates", name, recursive: true
|
14
|
+
end
|
15
|
+
|
16
|
+
def bundle_install
|
17
|
+
system("cd #{name} && bundle install")
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|
21
|
+
end
|
data/lib/gurk/page.rb
ADDED
@@ -0,0 +1,71 @@
|
|
1
|
+
require 'erb'
|
2
|
+
require 'tilt'
|
3
|
+
|
4
|
+
module Gurk
|
5
|
+
class Page
|
6
|
+
attr_accessor :name, :route, :locals, :layout
|
7
|
+
|
8
|
+
def initialize(data)
|
9
|
+
@name = data[:name].downcase
|
10
|
+
@locals = data[:locals]
|
11
|
+
@route = data[:route]
|
12
|
+
@layout= data[:locals][:layout] if data[:locals] && data[:locals][:layout]
|
13
|
+
end
|
14
|
+
|
15
|
+
def render(env)
|
16
|
+
output = nil
|
17
|
+
|
18
|
+
if @layout
|
19
|
+
output = render_template_with_layout(env) do
|
20
|
+
render_template(env)
|
21
|
+
end
|
22
|
+
else
|
23
|
+
output = render_template(env)
|
24
|
+
end
|
25
|
+
|
26
|
+
[200, {'content_type' => 'text/html'}, [output]]
|
27
|
+
|
28
|
+
rescue Errno::ENOENT => e
|
29
|
+
raise Gurk::TemplateNotFound.new(e)
|
30
|
+
rescue RuntimeError, Exception => e
|
31
|
+
# TODO: Make this more sensible
|
32
|
+
raise e
|
33
|
+
end
|
34
|
+
|
35
|
+
def render_template_with_layout(env, &block)
|
36
|
+
tilt = Tilt.new(layout_path)
|
37
|
+
tilt.render(nil, locals) do
|
38
|
+
yield
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def render_template(env)
|
43
|
+
tilt = Tilt.new(view_path)
|
44
|
+
tilt.render(nil, locals)
|
45
|
+
end
|
46
|
+
|
47
|
+
def view_name
|
48
|
+
@view_name ||= @name
|
49
|
+
end
|
50
|
+
|
51
|
+
def view_path
|
52
|
+
Gurk.view_path + '/' + view_name + '.' + Gurk.default_view_engine.to_s
|
53
|
+
end
|
54
|
+
|
55
|
+
def layout_name
|
56
|
+
@locals[:layout]
|
57
|
+
end
|
58
|
+
|
59
|
+
def layout_path
|
60
|
+
if layout_name =~ /\.(erb|haml|)/
|
61
|
+
Gurk.view_path + '/' + layout_name
|
62
|
+
else
|
63
|
+
Gurk.view_path + '/' + layout_name + '.' + Gurk.default_view_engine.to_s
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
class Gurk::TemplateNotFound < Exception; end
|
71
|
+
class Gurk::TemplateEngineNotFound < Exception; end
|
data/lib/gurk/parser.rb
ADDED
@@ -0,0 +1,82 @@
|
|
1
|
+
require 'gherkin/parser/parser'
|
2
|
+
require 'gherkin/formatter/json_formatter'
|
3
|
+
require 'stringio'
|
4
|
+
require 'multi_json'
|
5
|
+
|
6
|
+
module Gurk
|
7
|
+
class Parser
|
8
|
+
VALID_STEPS = [
|
9
|
+
{ "^I have a page called '(.+)'$" => lambda { |k, _| { name: k } } },
|
10
|
+
{ "^it has a route of '(.+)'$" => lambda { |k, _| { route: k } } },
|
11
|
+
{ "^it has a (.+) called '(.+)'$" => lambda { |k, v| { k.to_sym => v } } }
|
12
|
+
]
|
13
|
+
|
14
|
+
attr_accessor :sources
|
15
|
+
|
16
|
+
def initialize(sources = Dir.glob("#{Dir.pwd}/features/*.feature"))
|
17
|
+
@parsed_names = []
|
18
|
+
@parsed_data = []
|
19
|
+
@sources = sources
|
20
|
+
io = StringIO.new
|
21
|
+
formatter = Gherkin::Formatter::JSONFormatter.new(io)
|
22
|
+
parser = Gherkin::Parser::Parser.new(formatter)
|
23
|
+
read_feature_files(io, parser, formatter, sources)
|
24
|
+
end
|
25
|
+
|
26
|
+
def parse!
|
27
|
+
@parsed_names.each { |name| parse_names(name) }
|
28
|
+
parse_locals(@parsed_data)
|
29
|
+
end
|
30
|
+
|
31
|
+
private
|
32
|
+
|
33
|
+
def read_feature_files(io, parser, formatter, sources)
|
34
|
+
sources.each { |s| parser.parse(IO.read(s), s, 0) }
|
35
|
+
formatter.done
|
36
|
+
process_data(MultiJson.load(io.string))
|
37
|
+
end
|
38
|
+
|
39
|
+
def process_data(data)
|
40
|
+
data.each { |feature| extract_steps_from feature['elements'] }
|
41
|
+
end
|
42
|
+
|
43
|
+
def extract_steps_from(element_nodes)
|
44
|
+
element_nodes.each { |element_node| @parsed_names << extract_names_from(element_node['steps']) }
|
45
|
+
end
|
46
|
+
|
47
|
+
def extract_names_from(steps)
|
48
|
+
[].tap { |name| steps.each { |step| name << step['name'] } }
|
49
|
+
end
|
50
|
+
|
51
|
+
def parse_names(name)
|
52
|
+
@parsed_data << name.map { |match| parse_steps(match) }.flatten.compact
|
53
|
+
end
|
54
|
+
|
55
|
+
def parse_steps(match)
|
56
|
+
VALID_STEPS.map { |step| step.values.first.call($1, $2) if /#{step.keys.first}/ =~ match }
|
57
|
+
end
|
58
|
+
|
59
|
+
def parse_locals(steps)
|
60
|
+
@parsed_data = [].tap do |data|
|
61
|
+
steps.map do |step|
|
62
|
+
locals = sanitize(step)
|
63
|
+
step << { locals: extract_locals_from(step, locals) }
|
64
|
+
data << merge_steps(step)
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
def sanitize(step)
|
70
|
+
step.dup.reject! { |h| h.key?(:route) || h.key?(:name) }
|
71
|
+
end
|
72
|
+
|
73
|
+
def extract_locals_from(step, locals)
|
74
|
+
step.reject! { |h| h == locals.first }
|
75
|
+
locals.first
|
76
|
+
end
|
77
|
+
|
78
|
+
def merge_steps(step)
|
79
|
+
{}.tap { |data| step.each { |h| data.merge! h } }
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
data/lib/gurk/router.rb
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
require 'http_router'
|
2
|
+
|
3
|
+
module Gurk
|
4
|
+
class Router
|
5
|
+
|
6
|
+
def initialize
|
7
|
+
http_router
|
8
|
+
end
|
9
|
+
|
10
|
+
def http_router
|
11
|
+
@http_router ||= HttpRouter.new
|
12
|
+
end
|
13
|
+
|
14
|
+
def add(page)
|
15
|
+
routes.push(page)
|
16
|
+
http_router.add(page.route).to { |env|
|
17
|
+
page.render env
|
18
|
+
}
|
19
|
+
end
|
20
|
+
|
21
|
+
def routes
|
22
|
+
@routes ||= []
|
23
|
+
end
|
24
|
+
|
25
|
+
def call(env)
|
26
|
+
http_router.call(env)
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
data/lib/gurk/runner.rb
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
require 'thor'
|
2
|
+
require 'gurk/cli'
|
3
|
+
|
4
|
+
module Gurk
|
5
|
+
|
6
|
+
class Runner < Thor
|
7
|
+
|
8
|
+
map "-T" => :list, "-i" => :install, "-u" => :update, "-v" => :version
|
9
|
+
|
10
|
+
desc "new app_name", "Generates a new Gurk application"
|
11
|
+
method_options :as => :string, :relative => :boolean, :force => :boolean
|
12
|
+
def new(name)
|
13
|
+
Gurk::Cli.new([name]).setup
|
14
|
+
say "New Gurk app generated. Now start Gurkin!"
|
15
|
+
end
|
16
|
+
|
17
|
+
desc "version", "Show Gurk version"
|
18
|
+
def version
|
19
|
+
require 'thor/version'
|
20
|
+
say "Gurk #{Gurk::VERSION}"
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
data/lib/gurk/version.rb
ADDED
File without changes
|
File without changes
|
@@ -0,0 +1,15 @@
|
|
1
|
+
Feature: My site
|
2
|
+
|
3
|
+
Scenario: Home Page
|
4
|
+
Given I have a page called 'Home'
|
5
|
+
And it has a title called 'home'
|
6
|
+
And it has a route of '/'
|
7
|
+
When I visit '/'
|
8
|
+
Then I should see 'home'
|
9
|
+
|
10
|
+
Scenario: About
|
11
|
+
Given I have a page called 'About'
|
12
|
+
And it has a title called 'About Us'
|
13
|
+
And it has a route of '/about'
|
14
|
+
When I visit '/about'
|
15
|
+
Then I should see 'About Us'
|
data/spec/example/app.rb
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
Feature: My site
|
2
|
+
|
3
|
+
Scenario: Home Page
|
4
|
+
Given I have a page called 'Home'
|
5
|
+
And it has a title called 'home'
|
6
|
+
And it has a route of '/'
|
7
|
+
When I visit '/'
|
8
|
+
Then I should see 'home'
|
9
|
+
|
10
|
+
Scenario: About
|
11
|
+
Given I have a page called 'About'
|
12
|
+
And it has a title called 'About Us'
|
13
|
+
And it has a route of '/about'
|
14
|
+
When I visit '/about'
|
15
|
+
Then I should see 'About Us'
|
@@ -0,0 +1,33 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Gurk::Cli do
|
4
|
+
|
5
|
+
let(:sample_directory) {
|
6
|
+
File.join(Dir.pwd, "spec", "support", "testapp")
|
7
|
+
}
|
8
|
+
|
9
|
+
before do
|
10
|
+
FileUtils.rm_rf sample_directory
|
11
|
+
|
12
|
+
ARGV.replace []
|
13
|
+
ARGV << sample_directory
|
14
|
+
|
15
|
+
cli = Gurk::Cli.new ARGV
|
16
|
+
cli.setup
|
17
|
+
end
|
18
|
+
|
19
|
+
describe "#setup" do
|
20
|
+
|
21
|
+
it 'creates the app directory' do
|
22
|
+
expect(File.exists?(sample_directory)).to be_true
|
23
|
+
end
|
24
|
+
|
25
|
+
it 'creates individual app files' do
|
26
|
+
expect(File.exists?(File.join(sample_directory, 'config.ru'))).to be_true
|
27
|
+
expect(File.exists?(File.join(sample_directory, 'app.rb'))).to be_true
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
33
|
+
|
@@ -0,0 +1,27 @@
|
|
1
|
+
require 'rack/test'
|
2
|
+
require File.join(File.dirname(__FILE__), '/../example/app.rb')
|
3
|
+
|
4
|
+
include Rack::Test::Methods
|
5
|
+
|
6
|
+
describe 'Gurk::Example' do
|
7
|
+
|
8
|
+
before do
|
9
|
+
Gurk.stub(:view_path).and_return File.join('spec', 'example', 'app', 'views')
|
10
|
+
Gurk.stub(:feature_paths).and_return Dir.glob("#{Dir.pwd}/spec/example/features/*.feature")
|
11
|
+
|
12
|
+
request '/'
|
13
|
+
end
|
14
|
+
|
15
|
+
def app
|
16
|
+
Gurk.run
|
17
|
+
end
|
18
|
+
|
19
|
+
it 'returns homepage successfully' do
|
20
|
+
expect(last_response.status).to eq(200)
|
21
|
+
end
|
22
|
+
|
23
|
+
it 'shows the title' do
|
24
|
+
expect(last_response.body).to include ('home')
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
include Rack::Test::Methods
|
4
|
+
|
5
|
+
describe Gurk do
|
6
|
+
|
7
|
+
describe '#run' do
|
8
|
+
|
9
|
+
before do
|
10
|
+
Gurk.stub(:feature_paths).and_return Dir.glob("#{Dir.pwd}/spec/support/*.feature")
|
11
|
+
Gurk.run
|
12
|
+
end
|
13
|
+
|
14
|
+
it 'creates routes from the array' do
|
15
|
+
expect(Gurk.router.routes.length).to_not be_zero
|
16
|
+
end
|
17
|
+
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|
21
|
+
|
22
|
+
|
@@ -0,0 +1,56 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Gurk::Page do
|
4
|
+
|
5
|
+
describe '#pages' do
|
6
|
+
|
7
|
+
Gurk.view_path = File.join(Dir.pwd, 'spec', 'support', 'views')
|
8
|
+
|
9
|
+
let(:page) {
|
10
|
+
Gurk::Page.new({name: 'about', path: '/pages/slug', locals: {title: 'lalala'}})
|
11
|
+
}
|
12
|
+
|
13
|
+
it 'returns the view name' do
|
14
|
+
expect(page.view_name).to eq('about')
|
15
|
+
end
|
16
|
+
|
17
|
+
context "nolayout" do
|
18
|
+
it 'returns the layout name' do
|
19
|
+
expect(page.layout_name).to be_nil
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
context "with a layout" do
|
24
|
+
it 'returns the layout name' do
|
25
|
+
page.locals.merge!(layout: 'wat')
|
26
|
+
expect(page.layout_name).to eq 'wat'
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
describe '#render' do
|
32
|
+
|
33
|
+
it 'render the page' do
|
34
|
+
page = Gurk::Page.new({name: 'about', path: '/pages/slug', locals: {title: 'lalala'}})
|
35
|
+
result = page.render nil
|
36
|
+
expect(result.last.first).to include 'lalala'
|
37
|
+
end
|
38
|
+
|
39
|
+
it 'renders the page with the layout' do
|
40
|
+
page = Gurk::Page.new({name: 'about', path: '/pages/slug', locals: {title: 'lalala', layout: 'layout.erb'}})
|
41
|
+
result = page.render nil
|
42
|
+
|
43
|
+
expect(result.last.first).to include 'This is the layout'
|
44
|
+
expect(result.last.first).to include 'lalala'
|
45
|
+
end
|
46
|
+
|
47
|
+
it 'raises an exception if the template is invalid' do
|
48
|
+
page = Gurk::Page.new({name: 'aboutlalala', path: '/pages/slug', locals: {title: 'lalala'}})
|
49
|
+
expect {
|
50
|
+
page.render nil
|
51
|
+
}.to raise_exception(Gurk::TemplateNotFound)
|
52
|
+
end
|
53
|
+
|
54
|
+
end
|
55
|
+
|
56
|
+
end
|
@@ -0,0 +1,210 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Gurk::Parser do
|
4
|
+
|
5
|
+
let(:sources) do
|
6
|
+
#Dir.glob("#{Dir.pwd}/spec/support/*.feature")
|
7
|
+
[ "#{Dir.pwd}/spec/support/another_example.feature", "#{Dir.pwd}/spec/support/example.feature" ]
|
8
|
+
end
|
9
|
+
|
10
|
+
let(:parsed_data) do
|
11
|
+
[
|
12
|
+
{ :name => "About", :route => "/about", :locals => { :title=>"about" } },
|
13
|
+
{ :name => "Home", :route => "/", :locals => { :title => "home" } }
|
14
|
+
]
|
15
|
+
end
|
16
|
+
|
17
|
+
let(:steps) do
|
18
|
+
[ ["I have a page called 'About'",
|
19
|
+
"it has a title called 'about'",
|
20
|
+
"it has a route of '/about'",
|
21
|
+
"I visit '/about'",
|
22
|
+
"I should see 'about'",],
|
23
|
+
["I have a page called 'Home'",
|
24
|
+
"it has a title called 'home'",
|
25
|
+
"it has a route of '/'",
|
26
|
+
"I visit '/'",
|
27
|
+
"I should see 'home'"] ]
|
28
|
+
end
|
29
|
+
|
30
|
+
let(:parsed_steps) do
|
31
|
+
[ {"keyword"=>"Given ", "name"=>"I have a page called 'About'", "line"=>4},
|
32
|
+
{"keyword"=>"And ", "name"=>"it has a title called 'about'", "line"=>5},
|
33
|
+
{"keyword"=>"And ", "name"=>"it has a route of '/about'", "line"=>6},
|
34
|
+
{"keyword"=>"When ", "name"=>"I visit '/about'", "line"=>7},
|
35
|
+
{"keyword"=>"Then ", "name"=>"I should see 'about'", "line"=>8}]
|
36
|
+
[ {"keyword"=>"Given ", "name"=>"I have a page called 'Home'", "line"=>4},
|
37
|
+
{"keyword"=>"And ", "name"=>"it has a title called 'home'", "line"=>5},
|
38
|
+
{"keyword"=>"And ", "name"=>"it has a route of '/'", "line"=>6},
|
39
|
+
{"keyword"=>"When ", "name"=>"I visit '/'", "line"=>7},
|
40
|
+
{"keyword"=>"Then ", "name"=>"I should see 'home'", "line"=>8}]
|
41
|
+
end
|
42
|
+
|
43
|
+
let(:parsed_names) do
|
44
|
+
[ ["I have a page called 'About'",
|
45
|
+
"it has a title called 'about'",
|
46
|
+
"it has a route of '/about'",
|
47
|
+
"I visit '/about'",
|
48
|
+
"I should see 'about'"],
|
49
|
+
["I have a page called 'Home'",
|
50
|
+
"it has a title called 'home'",
|
51
|
+
"it has a route of '/'",
|
52
|
+
"I visit '/'",
|
53
|
+
"I should see 'home'"] ]
|
54
|
+
end
|
55
|
+
|
56
|
+
describe '#initialize' do
|
57
|
+
it 'reads existing feature files' do
|
58
|
+
Gurk::Parser.any_instance.should_receive(:read_feature_files)
|
59
|
+
Gurk::Parser.new(sources)
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
describe '#parse!' do
|
64
|
+
it 'parses each set of names extracted from the feature files' do
|
65
|
+
Gurk::Parser
|
66
|
+
.any_instance
|
67
|
+
.should_receive(:parse_names)
|
68
|
+
.exactly(parsed_names.length)
|
69
|
+
.times
|
70
|
+
Gurk::Parser.new(sources).parse!
|
71
|
+
end
|
72
|
+
|
73
|
+
it 'passes the parsed data to #parse_locals' do
|
74
|
+
parser = Gurk::Parser.new(sources)
|
75
|
+
Gurk::Parser
|
76
|
+
.any_instance
|
77
|
+
.should_receive(:parse_locals)
|
78
|
+
.with(parser.instance_variable_get :@parsed_data)
|
79
|
+
parser.parse!
|
80
|
+
end
|
81
|
+
|
82
|
+
it 'returns a hash with the correct format' do
|
83
|
+
expect(Gurk::Parser.new(sources).parse!).to eq parsed_data
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
describe 'private methods' do
|
88
|
+
let(:parser) { Gurk::Parser.new(sources) }
|
89
|
+
|
90
|
+
describe '#read_feature_files' do
|
91
|
+
it 'parses the feature files' do
|
92
|
+
Gherkin::Parser::Parser
|
93
|
+
.any_instance
|
94
|
+
.should_receive(:parse)
|
95
|
+
.exactly(parsed_names.length)
|
96
|
+
.times
|
97
|
+
Gurk::Parser.new(sources)
|
98
|
+
end
|
99
|
+
|
100
|
+
it 'passes the result to #process_data' do
|
101
|
+
Gurk::Parser.any_instance.should_receive(:process_data)
|
102
|
+
Gurk::Parser.new(sources)
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
describe '#process_data' do
|
107
|
+
it 'finds all "elements" nodes in the given data and passes it to #extract_steps_from' do
|
108
|
+
Gurk::Parser
|
109
|
+
.any_instance
|
110
|
+
.should_receive(:extract_steps_from)
|
111
|
+
.twice # Two 'element' nodes
|
112
|
+
Gurk::Parser.new(sources)
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
describe '#extract_steps_from' do
|
117
|
+
it 'finds all "steps" nodes in the given data and passes it to #extract_names_from' do
|
118
|
+
Gurk::Parser
|
119
|
+
.any_instance
|
120
|
+
.should_receive(:extract_names_from)
|
121
|
+
.twice # Two 'steps' nodes
|
122
|
+
Gurk::Parser.new(sources)
|
123
|
+
end
|
124
|
+
|
125
|
+
it 'saves the return value of #extract_names_from' do
|
126
|
+
expect(parser.instance_variable_get :@parsed_names).to eq parsed_names
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
describe '#extract_names_from' do
|
131
|
+
it 'finds and returns all "name" nodes from the given data' do
|
132
|
+
expect(parser.send(:extract_names_from, parsed_steps)).to eq parsed_names.last
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
136
|
+
describe '#parse_names' do
|
137
|
+
it 'passes the given data to #parse_steps' do
|
138
|
+
Gurk::Parser
|
139
|
+
.any_instance
|
140
|
+
.should_receive(:parse_names)
|
141
|
+
.exactly(parsed_names.length)
|
142
|
+
.times
|
143
|
+
Gurk::Parser.new(sources).parse!
|
144
|
+
end
|
145
|
+
end
|
146
|
+
|
147
|
+
describe '#parse_steps' do
|
148
|
+
context 'with a matching step' do
|
149
|
+
it 'returns the parsed step' do
|
150
|
+
expect(parser.send(:parse_steps, "I have a page called 'About'")).to include name: 'About'
|
151
|
+
end
|
152
|
+
end
|
153
|
+
|
154
|
+
context 'with a non-matching step' do
|
155
|
+
it 'returns an array of nils' do
|
156
|
+
expect(parser.send(:parse_steps, "I visit '/about'")).to eq [nil, nil, nil]
|
157
|
+
end
|
158
|
+
end
|
159
|
+
end
|
160
|
+
|
161
|
+
describe '#parse_locals' do
|
162
|
+
let(:step) { [[{:name=>"About"}, {:title=>"about"}, {:route=>"/about"}]] }
|
163
|
+
|
164
|
+
it 'passes each given step to #sanitize' do
|
165
|
+
parser.stub(:extract_locals_from)
|
166
|
+
parser.should_receive(:sanitize)
|
167
|
+
parser.send :parse_locals, step
|
168
|
+
end
|
169
|
+
|
170
|
+
it 'passes sanitized steps to #extract_locals_from' do
|
171
|
+
parser.should_receive(:extract_locals_from)
|
172
|
+
parser.send :parse_locals, step
|
173
|
+
end
|
174
|
+
|
175
|
+
it 'passes extracted locals to #merge_steps' do
|
176
|
+
parser.should_receive(:merge_steps)
|
177
|
+
parser.send :parse_locals, step
|
178
|
+
end
|
179
|
+
|
180
|
+
it 'returns the result of the parsing' do
|
181
|
+
result = [{:name=>"About", :route=>"/about", :locals => {:title=>"about"}}]
|
182
|
+
parser.instance_variable_set(:@parsed_data, step)
|
183
|
+
expect(parser.send :parse_locals, step).to eq result
|
184
|
+
end
|
185
|
+
end
|
186
|
+
|
187
|
+
describe '#sanitize' do
|
188
|
+
it 'returns local variable pairs' do
|
189
|
+
step = [{:name=>"About"}, {:title=>"about"}, {:route=>"/about"}]
|
190
|
+
expect(parser.send :sanitize, step).to eq [{:title=>"about"}]
|
191
|
+
end
|
192
|
+
end
|
193
|
+
|
194
|
+
describe '#extract_locals_from' do
|
195
|
+
it 'returns parsed locals' do
|
196
|
+
step = [[{:name=>"About"}, {:title=>"about"}, {:route=>"/about"}]]
|
197
|
+
local = [{:title=>"about"}]
|
198
|
+
expect(parser.send :extract_locals_from, step, local).to eq local.first
|
199
|
+
end
|
200
|
+
end
|
201
|
+
|
202
|
+
describe '#merge_steps' do
|
203
|
+
it 'returns merged steps' do
|
204
|
+
step = [{:name=>"About"}, {:route=>"/about"}, {:locals=>[{:title=>"about"}]}]
|
205
|
+
result = { :name => "About", :route => "/about", :locals => [ { :title=>"about" } ] }
|
206
|
+
expect(parser.send :merge_steps, step).to eq result
|
207
|
+
end
|
208
|
+
end
|
209
|
+
end
|
210
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), '/../', 'spec_helper')
|
2
|
+
|
3
|
+
include Rack::Test::Methods
|
4
|
+
|
5
|
+
describe Gurk::Router do
|
6
|
+
|
7
|
+
before do
|
8
|
+
@router = Gurk::Router.new
|
9
|
+
end
|
10
|
+
|
11
|
+
def app
|
12
|
+
@router
|
13
|
+
end
|
14
|
+
|
15
|
+
it 'returns a valid instance' do
|
16
|
+
expect(@router).to be_instance_of Gurk::Router
|
17
|
+
end
|
18
|
+
|
19
|
+
it 'returns a valid http_router instance' do
|
20
|
+
expect(@router.http_router).to be_instance_of HttpRouter
|
21
|
+
end
|
22
|
+
|
23
|
+
it 'adds a page with a valid content' do
|
24
|
+
page = Gurk::Page.new({name: 'about', path: '/about', locals: {title: 'lalala'}})
|
25
|
+
|
26
|
+
@router.add page
|
27
|
+
|
28
|
+
request "/about"
|
29
|
+
|
30
|
+
expect(last_response.status).to eq(200)
|
31
|
+
end
|
32
|
+
|
33
|
+
it 'adds a page with a valid content with params' do
|
34
|
+
|
35
|
+
page = Gurk::Page.new({name: 'about', path: '/pages/slug', locals: {title: 'lalala'}})
|
36
|
+
|
37
|
+
@router.add page
|
38
|
+
|
39
|
+
request '/pages/this-is-a-slug'
|
40
|
+
|
41
|
+
expect(last_response.status).to eq(200)
|
42
|
+
end
|
43
|
+
|
44
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,10 @@
|
|
1
|
+
Feature: Home Page
|
2
|
+
|
3
|
+
Scenario:
|
4
|
+
Given I have a page called 'Home'
|
5
|
+
And it has a title called 'home'
|
6
|
+
And it has a layout called 'home'
|
7
|
+
And it has a template called 'home.html.erb'
|
8
|
+
And it has a route of '/'
|
9
|
+
When I visit '/'
|
10
|
+
Then I should see 'home'
|
@@ -0,0 +1 @@
|
|
1
|
+
Title: <%= title %>
|
metadata
ADDED
@@ -0,0 +1,192 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: gurk
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Vixon
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2013-09-17 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: bundler
|
16
|
+
requirement: &70173898733100 !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ~>
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '1.3'
|
22
|
+
type: :development
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: *70173898733100
|
25
|
+
- !ruby/object:Gem::Dependency
|
26
|
+
name: rake
|
27
|
+
requirement: &70173898732340 !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: *70173898732340
|
36
|
+
- !ruby/object:Gem::Dependency
|
37
|
+
name: rspec
|
38
|
+
requirement: &70173898731580 !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: *70173898731580
|
47
|
+
- !ruby/object:Gem::Dependency
|
48
|
+
name: rack-test
|
49
|
+
requirement: &70173898731080 !ruby/object:Gem::Requirement
|
50
|
+
none: false
|
51
|
+
requirements:
|
52
|
+
- - ! '>='
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
type: :development
|
56
|
+
prerelease: false
|
57
|
+
version_requirements: *70173898731080
|
58
|
+
- !ruby/object:Gem::Dependency
|
59
|
+
name: gherkin
|
60
|
+
requirement: &70173898730580 !ruby/object:Gem::Requirement
|
61
|
+
none: false
|
62
|
+
requirements:
|
63
|
+
- - ! '>='
|
64
|
+
- !ruby/object:Gem::Version
|
65
|
+
version: '0'
|
66
|
+
type: :runtime
|
67
|
+
prerelease: false
|
68
|
+
version_requirements: *70173898730580
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: http_router
|
71
|
+
requirement: &70173898729900 !ruby/object:Gem::Requirement
|
72
|
+
none: false
|
73
|
+
requirements:
|
74
|
+
- - ~>
|
75
|
+
- !ruby/object:Gem::Version
|
76
|
+
version: 0.11.0
|
77
|
+
type: :runtime
|
78
|
+
prerelease: false
|
79
|
+
version_requirements: *70173898729900
|
80
|
+
- !ruby/object:Gem::Dependency
|
81
|
+
name: tilt
|
82
|
+
requirement: &70173898729400 !ruby/object:Gem::Requirement
|
83
|
+
none: false
|
84
|
+
requirements:
|
85
|
+
- - ! '>='
|
86
|
+
- !ruby/object:Gem::Version
|
87
|
+
version: '0'
|
88
|
+
type: :runtime
|
89
|
+
prerelease: false
|
90
|
+
version_requirements: *70173898729400
|
91
|
+
- !ruby/object:Gem::Dependency
|
92
|
+
name: thor
|
93
|
+
requirement: &70173898728840 !ruby/object:Gem::Requirement
|
94
|
+
none: false
|
95
|
+
requirements:
|
96
|
+
- - ! '>='
|
97
|
+
- !ruby/object:Gem::Version
|
98
|
+
version: '0'
|
99
|
+
type: :runtime
|
100
|
+
prerelease: false
|
101
|
+
version_requirements: *70173898728840
|
102
|
+
description: Gurk
|
103
|
+
email:
|
104
|
+
- vixonshow@gmail.com
|
105
|
+
executables:
|
106
|
+
- gurk
|
107
|
+
extensions: []
|
108
|
+
extra_rdoc_files: []
|
109
|
+
files:
|
110
|
+
- .gitignore
|
111
|
+
- .rspec
|
112
|
+
- Gemfile
|
113
|
+
- LICENSE.txt
|
114
|
+
- README.md
|
115
|
+
- Rakefile
|
116
|
+
- bin/gurk
|
117
|
+
- gurk.gemspec
|
118
|
+
- lib/gurk.rb
|
119
|
+
- lib/gurk/cli.rb
|
120
|
+
- lib/gurk/page.rb
|
121
|
+
- lib/gurk/parser.rb
|
122
|
+
- lib/gurk/router.rb
|
123
|
+
- lib/gurk/runner.rb
|
124
|
+
- lib/gurk/version.rb
|
125
|
+
- lib/templates/Gemfile
|
126
|
+
- lib/templates/app.rb
|
127
|
+
- lib/templates/app/views/home.erb
|
128
|
+
- lib/templates/app/views/layout.erb
|
129
|
+
- lib/templates/config.ru
|
130
|
+
- lib/templates/features/home.feature
|
131
|
+
- spec/example/Gemfile
|
132
|
+
- spec/example/app.rb
|
133
|
+
- spec/example/app/views/about.erb
|
134
|
+
- spec/example/app/views/home.erb
|
135
|
+
- spec/example/config.ru
|
136
|
+
- spec/example/features/home.feature
|
137
|
+
- spec/gurk/cli_spec.rb
|
138
|
+
- spec/gurk/example_spec.rb
|
139
|
+
- spec/gurk/gurk_spec.rb
|
140
|
+
- spec/gurk/page_spec.rb
|
141
|
+
- spec/gurk/parser_spec.rb
|
142
|
+
- spec/gurk/router_spec.rb
|
143
|
+
- spec/spec_helper.rb
|
144
|
+
- spec/support/another_example.feature
|
145
|
+
- spec/support/example.feature
|
146
|
+
- spec/support/example_with_layout.feature
|
147
|
+
- spec/support/views/about.erb
|
148
|
+
- spec/support/views/layout.erb
|
149
|
+
homepage: http://github.com/vixon/gurk
|
150
|
+
licenses:
|
151
|
+
- MIT
|
152
|
+
post_install_message:
|
153
|
+
rdoc_options: []
|
154
|
+
require_paths:
|
155
|
+
- lib
|
156
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
157
|
+
none: false
|
158
|
+
requirements:
|
159
|
+
- - ! '>='
|
160
|
+
- !ruby/object:Gem::Version
|
161
|
+
version: '0'
|
162
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
163
|
+
none: false
|
164
|
+
requirements:
|
165
|
+
- - ! '>='
|
166
|
+
- !ruby/object:Gem::Version
|
167
|
+
version: '0'
|
168
|
+
requirements: []
|
169
|
+
rubyforge_project:
|
170
|
+
rubygems_version: 1.8.15
|
171
|
+
signing_key:
|
172
|
+
specification_version: 3
|
173
|
+
summary: A plain english ruby microframework that makes sense
|
174
|
+
test_files:
|
175
|
+
- spec/example/Gemfile
|
176
|
+
- spec/example/app.rb
|
177
|
+
- spec/example/app/views/about.erb
|
178
|
+
- spec/example/app/views/home.erb
|
179
|
+
- spec/example/config.ru
|
180
|
+
- spec/example/features/home.feature
|
181
|
+
- spec/gurk/cli_spec.rb
|
182
|
+
- spec/gurk/example_spec.rb
|
183
|
+
- spec/gurk/gurk_spec.rb
|
184
|
+
- spec/gurk/page_spec.rb
|
185
|
+
- spec/gurk/parser_spec.rb
|
186
|
+
- spec/gurk/router_spec.rb
|
187
|
+
- spec/spec_helper.rb
|
188
|
+
- spec/support/another_example.feature
|
189
|
+
- spec/support/example.feature
|
190
|
+
- spec/support/example_with_layout.feature
|
191
|
+
- spec/support/views/about.erb
|
192
|
+
- spec/support/views/layout.erb
|