trailblazer 0.0.1 → 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 +7 -0
- data/.gitignore +1 -1
- data/.travis.yml +5 -0
- data/CHANGES.md +3 -0
- data/Gemfile +4 -0
- data/README.md +417 -16
- data/Rakefile +14 -0
- data/THOUGHTS +12 -0
- data/TODO.md +6 -0
- data/doc/Trb-The-Stack.png +0 -0
- data/doc/trb.jpg +0 -0
- data/gemfiles/Gemfile.rails +7 -0
- data/gemfiles/Gemfile.rails.lock +99 -0
- data/lib/trailblazer.rb +2 -0
- data/lib/trailblazer/autoloading.rb +5 -0
- data/lib/trailblazer/operation.rb +124 -0
- data/lib/trailblazer/operation/controller.rb +76 -0
- data/lib/trailblazer/operation/crud.rb +61 -0
- data/lib/trailblazer/operation/representer.rb +18 -0
- data/lib/trailblazer/operation/responder.rb +24 -0
- data/lib/trailblazer/operation/uploaded_file.rb +77 -0
- data/lib/trailblazer/operation/worker.rb +96 -0
- data/lib/trailblazer/version.rb +1 -1
- data/test/crud_test.rb +115 -0
- data/test/fixtures/apotomo.png +0 -0
- data/test/fixtures/cells.png +0 -0
- data/test/operation_test.rb +334 -0
- data/test/rails/controller_test.rb +175 -0
- data/test/rails/fake_app/app-cells/.gitkeep +0 -0
- data/test/rails/fake_app/cells.rb +21 -0
- data/test/rails/fake_app/config.rb +3 -0
- data/test/rails/fake_app/controllers.rb +101 -0
- data/test/rails/fake_app/models.rb +13 -0
- data/test/rails/fake_app/rails_app.rb +57 -0
- data/test/rails/fake_app/song/operations.rb +63 -0
- data/test/rails/fake_app/views/bands/show.html.erb +1 -0
- data/test/rails/fake_app/views/songs/new.html.erb +1 -0
- data/test/rails/test_helper.rb +4 -0
- data/test/responder_test.rb +77 -0
- data/test/test_helper.rb +15 -0
- data/test/uploaded_file_test.rb +85 -0
- data/test/worker_test.rb +116 -0
- data/trailblazer.gemspec +10 -2
- metadata +160 -23
@@ -0,0 +1,175 @@
|
|
1
|
+
# BUNDLE_GEMFILE=gemfiles/Gemfile.rails bundle exec rake rails
|
2
|
+
require 'test_helper'
|
3
|
+
|
4
|
+
ActionController::TestCase.class_eval do
|
5
|
+
setup do
|
6
|
+
@routes = Rails.application.routes
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
class GenericResponderTest < ActionController::TestCase
|
11
|
+
tests SongsController
|
12
|
+
|
13
|
+
setup do
|
14
|
+
@routes = Rails.application.routes
|
15
|
+
end
|
16
|
+
|
17
|
+
test "Create with params" do
|
18
|
+
post :create_with_params, {song: {title: "You're Going Down", length: 120}}
|
19
|
+
assert_response 302
|
20
|
+
|
21
|
+
song = Song.last
|
22
|
+
assert_equal "A Beautiful Indifference", song.title
|
23
|
+
assert_equal nil, song.length # params overwritten from controller.
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
# overriding Controller#process_params.
|
28
|
+
class ProcessParamsTest < ActionController::TestCase
|
29
|
+
tests BandsController
|
30
|
+
|
31
|
+
setup do
|
32
|
+
@routes = Rails.application.routes
|
33
|
+
end
|
34
|
+
|
35
|
+
test "Create with overridden #process_params" do
|
36
|
+
post :create, band: {name: "Kreator"}
|
37
|
+
|
38
|
+
band = Band.last
|
39
|
+
assert_equal "Kreator", band.name
|
40
|
+
assert_equal "Essen", band.locality
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
class ResponderRespondTest < ActionController::TestCase
|
45
|
+
tests SongsController
|
46
|
+
|
47
|
+
setup do
|
48
|
+
@routes = Rails.application.routes
|
49
|
+
end
|
50
|
+
|
51
|
+
# HTML
|
52
|
+
# #respond Create [valid]
|
53
|
+
test "Create [html/valid]" do
|
54
|
+
post :create, {song: {title: "You're Going Down"}}
|
55
|
+
assert_redirected_to song_path(Song.last)
|
56
|
+
end
|
57
|
+
|
58
|
+
test "Create [html/invalid]" do
|
59
|
+
post :create, {song: {title: ""}}
|
60
|
+
assert_equal @response.body, "{:title=>["can't be blank"]}"
|
61
|
+
end
|
62
|
+
|
63
|
+
test "Delete [html/valid]" do
|
64
|
+
song = Song::Create[song: {title: "You're Going Down"}].model
|
65
|
+
delete :destroy, id: song.id
|
66
|
+
assert_redirected_to songs_path
|
67
|
+
# assert that model is deleted.
|
68
|
+
end
|
69
|
+
|
70
|
+
test "respond with block [html/valid]" do
|
71
|
+
post :create_with_block, {song: {title: "You're Going Down"}}
|
72
|
+
assert_equal "block run, valid: true", response.body
|
73
|
+
end
|
74
|
+
|
75
|
+
test "respond with block [html/invalid]" do
|
76
|
+
post :create_with_block, {song: {title: ""}}
|
77
|
+
assert_equal "block run, valid: false", response.body
|
78
|
+
end
|
79
|
+
|
80
|
+
# JSON
|
81
|
+
test "Delete [json/valid]" do
|
82
|
+
song = Song::Create[song: {title: "You're Going Down"}].model
|
83
|
+
delete :destroy, id: song.id, format: :json
|
84
|
+
assert_response 204 # no content.
|
85
|
+
end
|
86
|
+
|
87
|
+
# JS
|
88
|
+
test "Delete [js/valid]" do
|
89
|
+
song = Song::Create[song: {title: "You're Going Down"}].model
|
90
|
+
assert_raises ActionView::MissingTemplate do
|
91
|
+
# js wants to render destroy.js.erb
|
92
|
+
delete :destroy, id: song.id, format: :js
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
test "Delete with formats [js/valid]" do
|
97
|
+
song = Song::Create[song: {title: "You're Going Down"}].model
|
98
|
+
|
99
|
+
delete :destroy_with_formats, id: song.id, format: :js
|
100
|
+
assert_response 200
|
101
|
+
assert_equal "Song slayer!", response.body
|
102
|
+
end
|
103
|
+
|
104
|
+
# TODO: #present
|
105
|
+
# TODO: #run
|
106
|
+
|
107
|
+
# describe "#run" do
|
108
|
+
# test "#run" do
|
109
|
+
|
110
|
+
# end
|
111
|
+
# end
|
112
|
+
|
113
|
+
|
114
|
+
|
115
|
+
end
|
116
|
+
|
117
|
+
|
118
|
+
class ResponderRunTest < ActionController::TestCase
|
119
|
+
tests BandsController
|
120
|
+
|
121
|
+
test "[html/valid]" do
|
122
|
+
put :update, {id: 1, band: {name: "Nofx"}}
|
123
|
+
assert_equal "no block: Nofx, Essen", response.body
|
124
|
+
end
|
125
|
+
|
126
|
+
test "with block [html/valid]" do
|
127
|
+
put :update_with_block, {id: 1, band: {name: "Nofx"}}
|
128
|
+
assert_equal "[valid] with block: Nofx, Essen", response.body
|
129
|
+
end
|
130
|
+
|
131
|
+
test "with block [html/invalid]" do
|
132
|
+
put :update_with_block, {id: 1, band: {name: ""}}
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
136
|
+
#present.
|
137
|
+
class ControllerPresentTest < ActionController::TestCase
|
138
|
+
tests BandsController
|
139
|
+
|
140
|
+
# let (:band) { }
|
141
|
+
|
142
|
+
test "#present" do
|
143
|
+
band = Band::Create[band: {name: "Nofx"}].model
|
144
|
+
|
145
|
+
get :show, id: band.id
|
146
|
+
|
147
|
+
assert_equal "bands/show.html: Band,Band,true,Band::Create,Essen\n", response.body
|
148
|
+
end
|
149
|
+
|
150
|
+
test "#present [JSON]" do
|
151
|
+
band = Band::Create[band: {name: "Nofx"}].model
|
152
|
+
|
153
|
+
get :show, id: band.id, format: :json
|
154
|
+
assert_equal "{\"name\":\"Nofx\"}", response.body
|
155
|
+
end
|
156
|
+
end
|
157
|
+
|
158
|
+
|
159
|
+
# #form.
|
160
|
+
class ControllerFormTest < ActionController::TestCase
|
161
|
+
tests BandsController
|
162
|
+
|
163
|
+
test "#form" do
|
164
|
+
get :new
|
165
|
+
|
166
|
+
assert_select "form input#band_name"
|
167
|
+
assert_select "b", ",Band,true,Band::Create"
|
168
|
+
end
|
169
|
+
|
170
|
+
test "#form with block" do
|
171
|
+
get :new_with_block
|
172
|
+
|
173
|
+
assert_select "b", "Band,Band,true,Band::Create,Essen"
|
174
|
+
end
|
175
|
+
end
|
File without changes
|
@@ -0,0 +1,21 @@
|
|
1
|
+
class UserCell < Cell::Rails
|
2
|
+
include Kaminari::Cells
|
3
|
+
|
4
|
+
def show(users)
|
5
|
+
@users = users
|
6
|
+
|
7
|
+
render :inline => <<-ERB
|
8
|
+
<%= paginate @users %>
|
9
|
+
ERB
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
class ViewModelCell < Cell::ViewModel
|
14
|
+
include Kaminari::Cells
|
15
|
+
|
16
|
+
def show
|
17
|
+
render :inline => <<-ERB
|
18
|
+
<%= paginate model %>
|
19
|
+
ERB
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,101 @@
|
|
1
|
+
# controllers
|
2
|
+
class ApplicationController < ActionController::Base
|
3
|
+
append_view_path "test/rails/fake_app/views"
|
4
|
+
end
|
5
|
+
|
6
|
+
class SongsController < ApplicationController
|
7
|
+
respond_to :json, :js
|
8
|
+
|
9
|
+
def index
|
10
|
+
@users = Song.all.page params[:page]
|
11
|
+
render inline: <<-ERB
|
12
|
+
<%= render_cell(:user, :show, @users) %>
|
13
|
+
ERB
|
14
|
+
end
|
15
|
+
|
16
|
+
include Trailblazer::Operation::Controller
|
17
|
+
respond_to :html
|
18
|
+
|
19
|
+
def create
|
20
|
+
respond Song::Create
|
21
|
+
end
|
22
|
+
|
23
|
+
def create_with_params
|
24
|
+
respond Song::Create, song: {title: "A Beautiful Indifference"}
|
25
|
+
end
|
26
|
+
|
27
|
+
def create_with_block
|
28
|
+
respond Song::Create do |op, formats|
|
29
|
+
return render text: "block run, valid: #{op.valid?}"
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def destroy
|
34
|
+
respond Song::Delete
|
35
|
+
end
|
36
|
+
|
37
|
+
def destroy_with_formats
|
38
|
+
respond Song::Delete do |op, formats|
|
39
|
+
formats.js { render text: "#{op.model.class} slayer!" }
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
class BandsController < ApplicationController
|
45
|
+
include Trailblazer::Operation::Controller
|
46
|
+
respond_to :html, :json
|
47
|
+
|
48
|
+
def show
|
49
|
+
present Band::Create do |op|
|
50
|
+
@klass = op.model.class
|
51
|
+
@locality = params[:band][:locality]
|
52
|
+
end # respond_to
|
53
|
+
end
|
54
|
+
|
55
|
+
def new
|
56
|
+
form Band::Create
|
57
|
+
|
58
|
+
render inline: <<-ERB
|
59
|
+
<%= form_for @form do |f| %>
|
60
|
+
<%= f.text_field :name %>
|
61
|
+
<% end %>
|
62
|
+
|
63
|
+
<b><%= [@klass, @model.class, @form.is_a?(Reform::Form), @operation.class].join(",") %></b>
|
64
|
+
ERB
|
65
|
+
end
|
66
|
+
|
67
|
+
def new_with_block
|
68
|
+
form Band::Create do |op|
|
69
|
+
@klass = op.model.class
|
70
|
+
@locality = params[:band][:locality]
|
71
|
+
end
|
72
|
+
|
73
|
+
render inline: <<-ERB
|
74
|
+
<b><%= [@klass, @model.class, @form.is_a?(Reform::Form), @operation.class, @locality].join(",") %></b>
|
75
|
+
ERB
|
76
|
+
end
|
77
|
+
|
78
|
+
def create
|
79
|
+
respond Band::Create
|
80
|
+
end
|
81
|
+
|
82
|
+
def update
|
83
|
+
run Band::Create
|
84
|
+
|
85
|
+
render text: "no block: #{@operation.model.name}, #{params[:band][:locality]}"
|
86
|
+
end
|
87
|
+
|
88
|
+
def update_with_block
|
89
|
+
run Band::Create do |op|
|
90
|
+
return render text: "[valid] with block: #{op.model.name}, #{params[:band][:locality]}"
|
91
|
+
end
|
92
|
+
|
93
|
+
render text: "[invalid] with block: #{@operation.model.name}, #{params[:band][:locality]}"
|
94
|
+
end
|
95
|
+
|
96
|
+
private
|
97
|
+
def process_params!(params) # this is where you set :current_user, etc.
|
98
|
+
params[:band] ||= {}
|
99
|
+
params[:band][:locality] = "Essen"
|
100
|
+
end
|
101
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
# models
|
2
|
+
class Song < ActiveRecord::Base
|
3
|
+
end
|
4
|
+
|
5
|
+
# migrations
|
6
|
+
class CreateAllTables < ActiveRecord::Migration
|
7
|
+
def self.up
|
8
|
+
create_table(:songs) { |t| t.string :title; t.integer :length }
|
9
|
+
create_table(:bands) { |t| t.string :name; t.string :locality }
|
10
|
+
end
|
11
|
+
end
|
12
|
+
ActiveRecord::Migration.verbose = false
|
13
|
+
CreateAllTables.up
|
@@ -0,0 +1,57 @@
|
|
1
|
+
# BUNDLE_GEMFILE=gemfiles/Gemfile.rails bundle exec rake rails
|
2
|
+
# TODO: how does rails handle all the different rake test tasks?
|
3
|
+
|
4
|
+
# require 'rails/all'
|
5
|
+
require 'action_controller/railtie'
|
6
|
+
require 'action_view/railtie'
|
7
|
+
require 'active_record'
|
8
|
+
|
9
|
+
require 'fake_app/config'
|
10
|
+
|
11
|
+
|
12
|
+
# config
|
13
|
+
app = Class.new(Rails::Application)
|
14
|
+
app.config.secret_token = '3b7cd727ee24e8444053437c36cc66c4'
|
15
|
+
app.config.session_store :cookie_store, :key => '_myapp_session'
|
16
|
+
app.config.active_support.deprecation = :log
|
17
|
+
app.config.eager_load = false
|
18
|
+
# Rais.root
|
19
|
+
app.config.root = File.dirname(__FILE__)
|
20
|
+
Rails.backtrace_cleaner.remove_silencers!
|
21
|
+
app.initialize!
|
22
|
+
|
23
|
+
# routes
|
24
|
+
app.routes.draw do
|
25
|
+
resources :songs do
|
26
|
+
member do # argh.
|
27
|
+
delete :destroy_with_formats
|
28
|
+
end
|
29
|
+
|
30
|
+
collection do
|
31
|
+
post :create_with_params
|
32
|
+
post :create_with_block
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
resources :bands do
|
37
|
+
collection do
|
38
|
+
post :create
|
39
|
+
get :new_with_block
|
40
|
+
end
|
41
|
+
|
42
|
+
member do
|
43
|
+
post :update_with_block
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
require 'trailblazer/operation/responder'
|
49
|
+
require 'trailblazer/operation/controller'
|
50
|
+
require 'trailblazer/operation/representer'
|
51
|
+
|
52
|
+
require 'fake_app/controllers'
|
53
|
+
require 'fake_app/models'
|
54
|
+
require 'fake_app/song/operations.rb'
|
55
|
+
|
56
|
+
# helpers
|
57
|
+
Object.const_set(:ApplicationHelper, Module.new)
|
@@ -0,0 +1,63 @@
|
|
1
|
+
class Song < ActiveRecord::Base
|
2
|
+
class Create < Trailblazer::Operation
|
3
|
+
include CRUD
|
4
|
+
include Responder
|
5
|
+
model Song, :create
|
6
|
+
|
7
|
+
|
8
|
+
contract do
|
9
|
+
property :title, validates: {presence: true}
|
10
|
+
property :length
|
11
|
+
end
|
12
|
+
|
13
|
+
def process(params)
|
14
|
+
validate(params[:song]) do
|
15
|
+
contract.save
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
|
21
|
+
class Delete < Create
|
22
|
+
action :find
|
23
|
+
|
24
|
+
def process(params)
|
25
|
+
model.destroy
|
26
|
+
self
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
class Band < ActiveRecord::Base
|
32
|
+
class Create < Trailblazer::Operation
|
33
|
+
include CRUD, Responder
|
34
|
+
model Band, :create
|
35
|
+
|
36
|
+
contract do
|
37
|
+
include Reform::Form::ActiveModel
|
38
|
+
model Band
|
39
|
+
|
40
|
+
property :name, validates: {presence: true}
|
41
|
+
property :locality
|
42
|
+
end
|
43
|
+
|
44
|
+
def process(params)
|
45
|
+
validate(params[:band]) do
|
46
|
+
contract.save
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
class JSON < self
|
51
|
+
action :find
|
52
|
+
include Representer
|
53
|
+
# self.representer_class = Class.new(contract_class)
|
54
|
+
# representer_class do
|
55
|
+
# include Reform::Form::JSON
|
56
|
+
# end
|
57
|
+
end
|
58
|
+
|
59
|
+
builds do |params|
|
60
|
+
JSON if params[:format] == "json"
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
bands/show.html: <%= [@klass, @model.class, @form.is_a?(Reform::Form), @operation.class, @locality].join(",") %>
|