rodakase 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.
- checksums.yaml +7 -0
- data/.gitignore +34 -0
- data/.rspec +3 -0
- data/.travis.yml +29 -0
- data/CHANGELOG.md +8 -0
- data/CODE_OF_CONDUCT.md +13 -0
- data/Gemfile +24 -0
- data/LICENSE +22 -0
- data/LICENSE.txt +22 -0
- data/README.md +114 -0
- data/Rakefile +4 -0
- data/benchmarks/templates/button.erb +1 -0
- data/benchmarks/view.rb +27 -0
- data/lib/roda/plugins/flow.rb +71 -0
- data/lib/rodakase.rb +8 -0
- data/lib/rodakase/application.rb +32 -0
- data/lib/rodakase/cli.rb +9 -0
- data/lib/rodakase/component.rb +40 -0
- data/lib/rodakase/config.rb +21 -0
- data/lib/rodakase/container.rb +127 -0
- data/lib/rodakase/transaction.rb +43 -0
- data/lib/rodakase/transaction/matcher.rb +31 -0
- data/lib/rodakase/transaction/result.rb +52 -0
- data/lib/rodakase/version.rb +3 -0
- data/lib/rodakase/view.rb +2 -0
- data/lib/rodakase/view/layout.rb +98 -0
- data/lib/rodakase/view/part.rb +53 -0
- data/lib/rodakase/view/renderer.rb +67 -0
- data/rodakase.gemspec +34 -0
- data/skeletons/simple/Gemfile +9 -0
- data/skeletons/simple/Rakefile +4 -0
- data/skeletons/simple/bin/console +6 -0
- data/skeletons/simple/config.ru +3 -0
- data/skeletons/simple/config/application.yml +4 -0
- data/skeletons/simple/core/boot.rb +12 -0
- data/skeletons/simple/core/simple/application.rb +16 -0
- data/skeletons/simple/core/simple/container.rb +11 -0
- data/skeletons/simple/core/simple/import.rb +9 -0
- data/skeletons/simple/lib/entities/user.rb +3 -0
- data/skeletons/simple/log/.gitkeep +0 -0
- data/skeletons/simple/spec/routes/heartbeat_spec.rb +9 -0
- data/skeletons/simple/spec/spec_helper.rb +12 -0
- data/skeletons/simple/spec/unit/user_spec.rb +17 -0
- data/skeletons/simple/spec/web_helper.rb +20 -0
- data/skeletons/simple/web/routes/root.rb +3 -0
- data/spec/dummy/apps/main/core/boot.rb +9 -0
- data/spec/dummy/apps/main/core/main/application.rb +17 -0
- data/spec/dummy/apps/main/core/main/container.rb +12 -0
- data/spec/dummy/apps/main/core/main/import.rb +9 -0
- data/spec/dummy/apps/main/core/main/requests.rb +21 -0
- data/spec/dummy/apps/main/core/main/view.rb +19 -0
- data/spec/dummy/apps/main/lib/entities/user.rb +3 -0
- data/spec/dummy/apps/main/lib/persistence/repositories/users.rb +14 -0
- data/spec/dummy/apps/main/lib/transaction.rb +11 -0
- data/spec/dummy/apps/main/lib/transactions/register_user.rb +17 -0
- data/spec/dummy/apps/main/lib/views/users/index.rb +15 -0
- data/spec/dummy/apps/main/requests/users.rb +5 -0
- data/spec/dummy/apps/main/web/routes/users.rb +21 -0
- data/spec/dummy/apps/main/web/templates/layouts/app.slim +6 -0
- data/spec/dummy/apps/main/web/templates/users/index.slim +3 -0
- data/spec/dummy/apps/main/web/templates/users/index/_list.slim +3 -0
- data/spec/dummy/apps/main/web/templates/users/index/_list_item.slim +1 -0
- data/spec/dummy/bin/console +6 -0
- data/spec/dummy/config.ru +3 -0
- data/spec/dummy/config/application.yml +4 -0
- data/spec/dummy/core/boot.rb +15 -0
- data/spec/dummy/core/dummy/container.rb +14 -0
- data/spec/dummy/core/dummy/import.rb +9 -0
- data/spec/dummy/lib/persistence/db.rb +13 -0
- data/spec/dummy/log/.gitkeep +0 -0
- data/spec/fixtures/templates/hello.slim +1 -0
- data/spec/fixtures/templates/layouts/app.slim +6 -0
- data/spec/fixtures/templates/shared/_index_table.slim +2 -0
- data/spec/fixtures/templates/shared/_shared_hello.slim +1 -0
- data/spec/fixtures/templates/tasks.slim +3 -0
- data/spec/fixtures/templates/user.slim +2 -0
- data/spec/fixtures/templates/users.slim +3 -0
- data/spec/fixtures/templates/users/_row.slim +2 -0
- data/spec/fixtures/templates/users/_tbody.slim +5 -0
- data/spec/fixtures/test/core/boot/bar.rb +5 -0
- data/spec/fixtures/test/lib/test/dep.rb +4 -0
- data/spec/fixtures/test/lib/test/foo.rb +5 -0
- data/spec/fixtures/test/lib/test/models.rb +4 -0
- data/spec/fixtures/test/lib/test/models/book.rb +6 -0
- data/spec/fixtures/test/lib/test/models/user.rb +6 -0
- data/spec/integration/application_spec.rb +21 -0
- data/spec/integration/transaction_spec.rb +85 -0
- data/spec/integration/view_spec.rb +65 -0
- data/spec/request/users_spec.rb +35 -0
- data/spec/spec_helper.rb +44 -0
- data/spec/support/helpers.rb +15 -0
- data/spec/unit/component_spec.rb +60 -0
- data/spec/unit/container_spec.rb +51 -0
- data/spec/unit/view/layout_spec.rb +49 -0
- data/spec/unit/view/part_spec.rb +55 -0
- data/spec/unit/view/renderer_spec.rb +29 -0
- metadata +359 -0
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
require 'tilt'
|
|
2
|
+
require 'dry-equalizer'
|
|
3
|
+
|
|
4
|
+
module Rodakase
|
|
5
|
+
module View
|
|
6
|
+
class Renderer
|
|
7
|
+
include Dry::Equalizer(:dir, :root, :engine)
|
|
8
|
+
|
|
9
|
+
TemplateNotFoundError = Class.new(StandardError)
|
|
10
|
+
|
|
11
|
+
attr_reader :dir, :root, :engine, :tilts
|
|
12
|
+
|
|
13
|
+
def self.tilts
|
|
14
|
+
@__engines__ ||= {}
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def initialize(dir, options = {})
|
|
18
|
+
@dir = dir
|
|
19
|
+
@root = options.fetch(:root, dir)
|
|
20
|
+
@engine = options[:engine]
|
|
21
|
+
@tilts = self.class.tilts
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def call(template, scope, &block)
|
|
25
|
+
path = lookup(template)
|
|
26
|
+
|
|
27
|
+
if path
|
|
28
|
+
render(path, scope, &block)
|
|
29
|
+
else
|
|
30
|
+
raise TemplateNotFoundError, "Template #{template} could not be looked up within #{root}"
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def render(path, scope, &block)
|
|
35
|
+
tilt(path).render(scope, &block)
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def tilt(path)
|
|
39
|
+
tilts.fetch(path) { tilts[path] = Tilt[engine].new(path) }
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def lookup(name)
|
|
43
|
+
template?(name) || template?("shared/#{name}") || !root? && chdir('..').lookup(name)
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def root?
|
|
47
|
+
dir == root
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def template?(name)
|
|
51
|
+
template_path = path(name)
|
|
52
|
+
|
|
53
|
+
if File.exist?(template_path)
|
|
54
|
+
template_path
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
def path(name)
|
|
59
|
+
dir.join("#{name}.#{engine}")
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
def chdir(dirname)
|
|
63
|
+
self.class.new(dir.join(dirname), engine: engine, root: root)
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
end
|
data/rodakase.gemspec
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
# coding: utf-8
|
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
|
4
|
+
require 'rodakase/version'
|
|
5
|
+
|
|
6
|
+
Gem::Specification.new do |spec|
|
|
7
|
+
spec.name = "rodakase"
|
|
8
|
+
spec.version = Rodakase::VERSION
|
|
9
|
+
spec.authors = ["Piotr Solnica"]
|
|
10
|
+
spec.email = ["piotr.solnica@gmail.com"]
|
|
11
|
+
spec.summary = "Lightweight web application stack on top of Roda"
|
|
12
|
+
spec.description = spec.summary
|
|
13
|
+
spec.homepage = "https://github.com/solnic/rodakase"
|
|
14
|
+
spec.license = "MIT"
|
|
15
|
+
|
|
16
|
+
spec.files = `git ls-files -z`.split("\x0")
|
|
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_runtime_dependency "inflecto", "~> 0"
|
|
22
|
+
spec.add_runtime_dependency "roda", "~> 2.7"
|
|
23
|
+
spec.add_runtime_dependency "tilt", "~> 2.0"
|
|
24
|
+
spec.add_runtime_dependency "dry-equalizer", "~> 0.2"
|
|
25
|
+
spec.add_runtime_dependency "dry-container", "~> 0.2"
|
|
26
|
+
spec.add_runtime_dependency "dry-configurable", "~> 0.1"
|
|
27
|
+
spec.add_runtime_dependency "dry-auto_inject", "~> 0.1"
|
|
28
|
+
spec.add_runtime_dependency "transflow", "~> 0.3"
|
|
29
|
+
|
|
30
|
+
spec.add_development_dependency "bundler", "~> 1.7"
|
|
31
|
+
spec.add_development_dependency "rake", "~> 10.0"
|
|
32
|
+
spec.add_development_dependency "rspec", "~> 3.1"
|
|
33
|
+
spec.add_development_dependency "capybara", "~> 2.5"
|
|
34
|
+
end
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
require_relative 'simple/container'
|
|
2
|
+
|
|
3
|
+
Simple::Container.finalize! do |container|
|
|
4
|
+
# Register your additional dependencies used by the web app
|
|
5
|
+
#
|
|
6
|
+
# In example a logger:
|
|
7
|
+
#
|
|
8
|
+
# require 'logger'
|
|
9
|
+
# container.register(:logger, Logger.new(container.root.join("log/#{container.config.env}.log")))
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
require 'simple/application'
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
require 'rodakase/application'
|
|
2
|
+
|
|
3
|
+
module Simple
|
|
4
|
+
class Application < Rodakase::Application
|
|
5
|
+
configure do |config|
|
|
6
|
+
config.routes = 'web/routes'.freeze
|
|
7
|
+
config.container = Container
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
route do |r|
|
|
11
|
+
r.multi_route
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
load_routes!
|
|
15
|
+
end
|
|
16
|
+
end
|
|
File without changes
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
# set the env here since the app config loaded by container uses this name by
|
|
2
|
+
# default
|
|
3
|
+
ENV['RACK_ENV'] = 'test'
|
|
4
|
+
|
|
5
|
+
# Only load the container, if a test needs the whole web stack it should require
|
|
6
|
+
# web_helper instead
|
|
7
|
+
require_relative '../core/simple/container'
|
|
8
|
+
|
|
9
|
+
RSpec.configure do |config|
|
|
10
|
+
# Obviously
|
|
11
|
+
config.disable_monkey_patching!
|
|
12
|
+
end
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
require 'entities/user'
|
|
2
|
+
|
|
3
|
+
RSpec.describe Entities::User do
|
|
4
|
+
subject(:user) { Entities::User.new(1, 'Jane') }
|
|
5
|
+
|
|
6
|
+
describe '#id' do
|
|
7
|
+
it 'works' do
|
|
8
|
+
expect(user.id).to be(1)
|
|
9
|
+
end
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
describe '#name' do
|
|
13
|
+
it 'works too' do
|
|
14
|
+
expect(user.name).to eql('Jane')
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
require 'rack/test'
|
|
4
|
+
|
|
5
|
+
require_relative '../core/boot'
|
|
6
|
+
|
|
7
|
+
module AppHelper
|
|
8
|
+
def app
|
|
9
|
+
Simple::Application.app
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
RSpec.configure do |config|
|
|
14
|
+
config.before(:suite) do
|
|
15
|
+
Simple::Application.freeze
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
config.include Rack::Test::Methods, type: :request
|
|
19
|
+
config.include AppHelper, type: :request
|
|
20
|
+
end
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
require 'rodakase/application'
|
|
2
|
+
require_relative 'container'
|
|
3
|
+
|
|
4
|
+
module Main
|
|
5
|
+
class Application < Rodakase::Application
|
|
6
|
+
configure do |config|
|
|
7
|
+
config.routes = 'web/routes'.freeze
|
|
8
|
+
config.container = Main::Container
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
route do |r|
|
|
12
|
+
r.multi_route
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
load_routes!
|
|
16
|
+
end
|
|
17
|
+
end
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
require_relative 'container'
|
|
2
|
+
|
|
3
|
+
module Main
|
|
4
|
+
module Requests
|
|
5
|
+
class Registrar
|
|
6
|
+
attr_reader :container
|
|
7
|
+
|
|
8
|
+
def initialize(container)
|
|
9
|
+
@container = container
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def define(identifier, &block)
|
|
13
|
+
container.register(identifier, container[:transaction].define(&block))
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def self.define(&block)
|
|
18
|
+
yield(Registrar.new(Container))
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
require 'rodakase/view'
|
|
2
|
+
require_relative 'container'
|
|
3
|
+
|
|
4
|
+
module Main
|
|
5
|
+
class Page
|
|
6
|
+
def title
|
|
7
|
+
'Woohaa'
|
|
8
|
+
end
|
|
9
|
+
end
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
module Main
|
|
13
|
+
class View < Rodakase::View::Layout
|
|
14
|
+
setting :root, Container.root.join('web/templates')
|
|
15
|
+
setting :scope, Page.new
|
|
16
|
+
setting :engine, :slim
|
|
17
|
+
setting :name, 'app'.freeze
|
|
18
|
+
end
|
|
19
|
+
end
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
require 'main/import'
|
|
2
|
+
require 'entities/user'
|
|
3
|
+
require 'transaction'
|
|
4
|
+
|
|
5
|
+
module Transactions
|
|
6
|
+
class RegisterUser < Transaction
|
|
7
|
+
include Main::Import(:db)
|
|
8
|
+
|
|
9
|
+
def call(params)
|
|
10
|
+
if params['name']
|
|
11
|
+
success(db[:users] << Entities::User.new(*params.values_at('id', 'name')))
|
|
12
|
+
else
|
|
13
|
+
failure(:validation, 'name is missing')
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
class Main::Application < Rodakase::Application
|
|
2
|
+
route('users') do |r|
|
|
3
|
+
r.get(to: 'views.users.index')
|
|
4
|
+
|
|
5
|
+
r.resolve('requests.users.create') do |t|
|
|
6
|
+
r.post do
|
|
7
|
+
t.(r[:user]) do |m|
|
|
8
|
+
m.success do
|
|
9
|
+
response.status = 201
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
m.failure do |err|
|
|
13
|
+
err.on(:validation) do |v|
|
|
14
|
+
r.redirect '/users'
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|