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.
Files changed (44) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +1 -1
  3. data/.travis.yml +5 -0
  4. data/CHANGES.md +3 -0
  5. data/Gemfile +4 -0
  6. data/README.md +417 -16
  7. data/Rakefile +14 -0
  8. data/THOUGHTS +12 -0
  9. data/TODO.md +6 -0
  10. data/doc/Trb-The-Stack.png +0 -0
  11. data/doc/trb.jpg +0 -0
  12. data/gemfiles/Gemfile.rails +7 -0
  13. data/gemfiles/Gemfile.rails.lock +99 -0
  14. data/lib/trailblazer.rb +2 -0
  15. data/lib/trailblazer/autoloading.rb +5 -0
  16. data/lib/trailblazer/operation.rb +124 -0
  17. data/lib/trailblazer/operation/controller.rb +76 -0
  18. data/lib/trailblazer/operation/crud.rb +61 -0
  19. data/lib/trailblazer/operation/representer.rb +18 -0
  20. data/lib/trailblazer/operation/responder.rb +24 -0
  21. data/lib/trailblazer/operation/uploaded_file.rb +77 -0
  22. data/lib/trailblazer/operation/worker.rb +96 -0
  23. data/lib/trailblazer/version.rb +1 -1
  24. data/test/crud_test.rb +115 -0
  25. data/test/fixtures/apotomo.png +0 -0
  26. data/test/fixtures/cells.png +0 -0
  27. data/test/operation_test.rb +334 -0
  28. data/test/rails/controller_test.rb +175 -0
  29. data/test/rails/fake_app/app-cells/.gitkeep +0 -0
  30. data/test/rails/fake_app/cells.rb +21 -0
  31. data/test/rails/fake_app/config.rb +3 -0
  32. data/test/rails/fake_app/controllers.rb +101 -0
  33. data/test/rails/fake_app/models.rb +13 -0
  34. data/test/rails/fake_app/rails_app.rb +57 -0
  35. data/test/rails/fake_app/song/operations.rb +63 -0
  36. data/test/rails/fake_app/views/bands/show.html.erb +1 -0
  37. data/test/rails/fake_app/views/songs/new.html.erb +1 -0
  38. data/test/rails/test_helper.rb +4 -0
  39. data/test/responder_test.rb +77 -0
  40. data/test/test_helper.rb +15 -0
  41. data/test/uploaded_file_test.rb +85 -0
  42. data/test/worker_test.rb +116 -0
  43. data/trailblazer.gemspec +10 -2
  44. metadata +160 -23
@@ -0,0 +1 @@
1
+ <%= @form.errors.to_s %>
@@ -0,0 +1,4 @@
1
+ require 'trailblazer'
2
+ require 'minitest/autorun'
3
+
4
+ require 'fake_app/rails_app.rb'
@@ -0,0 +1,77 @@
1
+ require 'test_helper'
2
+ require 'trailblazer/operation/responder'
3
+
4
+ class Song
5
+ extend ActiveModel::Naming
6
+
7
+ class Operation < Trailblazer::Operation
8
+ include CRUD
9
+ model Song
10
+ include Responder
11
+
12
+ def process(params)
13
+ invalid!(self) if params == false
14
+ self
15
+ end
16
+ end
17
+ end
18
+
19
+ module MyApp
20
+ class Song
21
+ extend ActiveModel::Naming
22
+
23
+ class Operation < Trailblazer::Operation
24
+ include CRUD
25
+ include Responder
26
+ model Song
27
+
28
+ def process(params)
29
+ invalid!(self) if params == false
30
+ self
31
+ end
32
+ end
33
+ end
34
+ end
35
+
36
+ class ResponderTestForModelWithoutNamespace < MiniTest::Spec
37
+
38
+ # test ::model_name
39
+ it { Song::Operation.model_name.name.must_equal "Song" }
40
+ it { Song::Operation.model_name.singular.must_equal "song" }
41
+ it { Song::Operation.model_name.plural.must_equal "songs" }
42
+ it { Song::Operation.model_name.element.must_equal "song" }
43
+ it { Song::Operation.model_name.human.must_equal "Song" }
44
+ it { Song::Operation.model_name.collection.must_equal "songs" }
45
+ it { Song::Operation.model_name.param_key.must_equal "song" }
46
+ it { Song::Operation.model_name.i18n_key.must_equal :"song" }
47
+ it { Song::Operation.model_name.route_key.must_equal "songs" }
48
+ it { Song::Operation.model_name.singular_route_key.must_equal "song" }
49
+
50
+ # #errors
51
+ it { Song::Operation[true].errors.must_equal [] }
52
+ it { Song::Operation[false].errors.must_equal [1] } # TODO: since we don't want responder to render anything, just return _one_ error. :)
53
+
54
+ # TODO: integration test with Controller.
55
+ end
56
+
57
+
58
+ class ResponderTestForModelWitNamespace < MiniTest::Spec
59
+
60
+ # test ::model_name
61
+ it { MyApp::Song::Operation.model_name.name.must_equal "MyApp::Song" }
62
+ it { MyApp::Song::Operation.model_name.singular.must_equal "my_app_song" }
63
+ it { MyApp::Song::Operation.model_name.plural.must_equal "my_app_songs" }
64
+ it { MyApp::Song::Operation.model_name.element.must_equal "song" }
65
+ it { MyApp::Song::Operation.model_name.human.must_equal "Song" }
66
+ it { MyApp::Song::Operation.model_name.collection.must_equal "my_app/songs" }
67
+ it { MyApp::Song::Operation.model_name.param_key.must_equal "my_app_song" } # "song" for AR.
68
+ it { MyApp::Song::Operation.model_name.i18n_key.must_equal :"my_app/song" }
69
+ it { MyApp::Song::Operation.model_name.route_key.must_equal "my_app_songs" } # "songs" for AR.
70
+ it { MyApp::Song::Operation.model_name.singular_route_key.must_equal "my_app_song" } # "song" for AR.
71
+
72
+ # #errors
73
+ it { MyApp::Song::Operation[true].errors.must_equal [] }
74
+ it { MyApp::Song::Operation[false].errors.must_equal [1] } # TODO: since we don't want responder to render anything, just return _one_ error. :)
75
+
76
+ # TODO: integration test with Controller.
77
+ end
@@ -0,0 +1,15 @@
1
+ require 'trailblazer'
2
+ require 'minitest/autorun'
3
+
4
+ module TmpUploads
5
+ extend ActiveSupport::Concern
6
+
7
+ included do
8
+ let (:tmp_dir) { "/tmp/uploads" }
9
+ before { Dir.mkdir(tmp_dir) unless File.exists?(tmp_dir) }
10
+ end
11
+ end
12
+
13
+ MiniTest::Spec.class_eval do
14
+ include TmpUploads
15
+ end
@@ -0,0 +1,85 @@
1
+ require 'test_helper'
2
+ require 'trailblazer/operation/uploaded_file'
3
+
4
+ class TempfileTest < MiniTest::Spec
5
+
6
+ end
7
+
8
+ class UploadedFileTest < MiniTest::Spec
9
+ let (:image) { File.open("test/fixtures/apotomo.png") }
10
+ let (:tempfile) { tmp = Tempfile.new("bla")
11
+ tmp.write image.read
12
+ tmp
13
+ }
14
+
15
+ let (:upload) { ActionDispatch::Http::UploadedFile.new(
16
+ :tempfile => tempfile,
17
+ :filename => "apotomo.png",
18
+ :type => "image/png")
19
+ }
20
+
21
+ describe "#to_hash" do
22
+ before {
23
+ @uploaded_path = upload.tempfile.path
24
+ @subject = Trailblazer::Operation::UploadedFile.new(upload).to_hash
25
+ }
26
+
27
+ it { @subject[:filename].must_equal "apotomo.png" }
28
+ it { @subject[:type].must_equal "image/png" }
29
+ it { @subject[:tempfile_path].must_match /\w+_trailblazer_upload$/ }
30
+
31
+
32
+ # Rails upload file must be removed.
33
+ it {
34
+ File.exists?(@uploaded_path).must_equal false }
35
+
36
+ it { File.exists?(@subject[:tempfile_path]).must_equal true }
37
+ it { File.size(@subject[:tempfile_path]).must_equal image.size }
38
+ end
39
+
40
+ describe "::from_hash" do
41
+ let (:data) { Trailblazer::Operation::UploadedFile.new(upload).to_hash }
42
+ subject { Trailblazer::Operation::UploadedFile.from_hash(data) }
43
+
44
+
45
+ it { subject.original_filename.must_equal "apotomo.png" }
46
+ it { subject.content_type.must_equal "image/png" }
47
+ it { subject.tempfile.must_be_kind_of File }
48
+ it { subject.size.must_equal image.size }
49
+
50
+ # params is not modified.
51
+ it { params = data.clone and subject; data.must_equal params }
52
+
53
+ # Tempfile must have proper extension for further processing (sidekiq/imagemagick, etc).
54
+ it { subject.tempfile.path.must_match /\.png$/ }
55
+
56
+ # Tempfile must be unlinked after process is finished.
57
+ it do
58
+ @subject = Trailblazer::Operation::UploadedFile.from_hash(data)
59
+
60
+ processable_file = @subject.tempfile.path
61
+ File.exists?(processable_file).must_equal true # this file must be GCed since it's a Tempfile, that's the whole point.
62
+ # @subject = nil
63
+ # GC.start
64
+ # File.exists?(processable_file).must_equal false
65
+ end
66
+ end
67
+
68
+
69
+ describe "with custom tmp directory" do
70
+ describe "#to_hash" do
71
+ before {
72
+ @uploaded = Trailblazer::Operation::UploadedFile.new(upload, :tmp_dir => tmp_dir)
73
+ @subject = @uploaded.to_hash[:tempfile_path]
74
+ }
75
+
76
+ it { @subject.must_match /\w+_trailblazer_upload$/ }
77
+ it { @subject.must_match /^\/tmp\/uploads\// }
78
+
79
+ it { File.exists?(@subject).must_equal true }
80
+ it { File.size(@subject).must_equal image.size }
81
+
82
+ it { @uploaded.instance_variable_get(:@with_tmp_dir).path.must_equal nil }
83
+ end
84
+ end
85
+ end
@@ -0,0 +1,116 @@
1
+ # make sure #run always returns model
2
+
3
+ # in test with sidekiq/testing
4
+ # Operation.run #=> call perform_one and return [result, model] (model?)
5
+
6
+ require 'test_helper'
7
+ require 'trailblazer/operation'
8
+ require 'trailblazer/operation/worker'
9
+ require 'sidekiq/testing'
10
+
11
+
12
+ class WorkerTest < MiniTest::Spec
13
+ class Operation < Trailblazer::Operation
14
+ include Worker
15
+
16
+ def run(params)
17
+ with_symbol = params[:title]
18
+ with_string = params["title"]
19
+ "I was working hard on #{params.inspect}. title:#{with_symbol} \"title\"=>#{with_string}"
20
+ end
21
+ end
22
+
23
+ class NoBackgroundOperation < Operation
24
+ def self.background?
25
+ false
26
+ end
27
+ end
28
+
29
+ # test basic worker functionality.
30
+ describe "with sidekiq" do
31
+ before { @res = Operation.run(:title => "Dragonfly") }
32
+
33
+ it { @res.kind_of?(String).must_equal true } # for now, we return the job from sidekiq.
34
+ it { Operation.jobs[0]["args"].must_equal([{"title"=>"Dragonfly"}]) }
35
+ it { Operation.perform_one.must_equal "I was working hard on {\"title\"=>\"Dragonfly\"}. title:Dragonfly \"title\"=>Dragonfly" }
36
+ end
37
+
38
+ # without sidekiq, we don't have indifferent_access automatically.
39
+ it { NoBackgroundOperation.run(:title => "Dragonfly").must_equal "I was working hard on {:title=>\"Dragonfly\"}. title:Dragonfly \"title\"=>" }
40
+
41
+
42
+ # test manual serialisation (to be done with UploadedFile etc automatically).
43
+ class SerializingOperation < Operation
44
+ include Worker
45
+
46
+ def self.serializable(params)
47
+ {:wrap => params}
48
+ end
49
+
50
+ def deserializable(params)
51
+ params[:wrap]
52
+ end
53
+ end
54
+
55
+ describe "with serialization in sidekiq" do
56
+ before { @res = SerializingOperation.run(:title => "Dragonfly") }
57
+
58
+ it { @res.kind_of?(String).must_equal true } # for now, we return the job from sidekiq.
59
+ it { SerializingOperation.jobs[0]["args"].must_equal([{"wrap"=>{"title"=>"Dragonfly"}}]) }
60
+ it { SerializingOperation.perform_one.must_equal "I was working hard on {\"title\"=>\"Dragonfly\"}. title:Dragonfly \"title\"=>Dragonfly" }
61
+ end
62
+ end
63
+
64
+
65
+ class WorkerFileMarshallerTest < MiniTest::Spec
66
+ def uploaded_file(name)
67
+ tmp = Tempfile.new("bla")
68
+ tmp.write File.open("test/fixtures/#{name}").read
69
+
70
+ ActionDispatch::Http::UploadedFile.new(
71
+ :tempfile => tmp,
72
+ :filename => name,
73
+ :type => "image/png")
74
+ end
75
+
76
+ class Operation < Trailblazer::Operation
77
+ contract do
78
+ property :title
79
+ property :image, file: true
80
+
81
+ property :album do
82
+ property :image, file: true
83
+ end
84
+ end
85
+
86
+ include Worker
87
+ include Worker::FileMarshaller # should be ContractFileMarshaller
88
+
89
+ def process(params)
90
+ params
91
+ end
92
+ end
93
+
94
+ # TODO: no image
95
+
96
+ # with image serializes the file for later retrieval.
97
+ it do
98
+ Operation.run(title: "Dragonfly", image: uploaded_file("apotomo.png"), album: {image: uploaded_file("cells.png")})
99
+
100
+ args = Operation.jobs[0]["args"].first
101
+ args["title"].must_equal("Dragonfly")
102
+ args["image"]["filename"].must_equal "apotomo.png"
103
+ args["image"]["tempfile_path"].must_match /trailblazer_upload/
104
+
105
+ args["album"]["image"]["filename"].must_equal "cells.png"
106
+
107
+ _, params = Operation.perform_one # deserialize.
108
+
109
+ params["title"].must_equal("Dragonfly")
110
+ params[:title].must_equal("Dragonfly") # must allow indifferent_access.
111
+ params["image"].must_be_kind_of ActionDispatch::Http::UploadedFile
112
+ params["image"].original_filename.must_equal "apotomo.png"
113
+ params["album"]["image"].must_be_kind_of ActionDispatch::Http::UploadedFile
114
+ params["album"]["image"].original_filename.must_equal "cells.png"
115
+ end
116
+ end
data/trailblazer.gemspec CHANGED
@@ -8,8 +8,8 @@ Gem::Specification.new do |spec|
8
8
  spec.version = Trailblazer::VERSION
9
9
  spec.authors = ["Nick Sutterer"]
10
10
  spec.email = ["apotonick@gmail.com"]
11
- spec.description = %q{A thin OOP framework on top of Rails that brings you form objects, view models, cells, decorators, representers, services and more.}
12
- spec.summary = %q{A thin OOP framework on top of Rails that brings you form objects, view models, cells, decorators, representers, services and more.}
11
+ spec.description = %q{Trailblazer is a thin layer on top of Rails. It gently enforces encapsulation, an intuitive code structure and gives you an object-oriented architecture.}
12
+ spec.summary = %q{A New Architecture For Rails.}
13
13
  spec.homepage = ""
14
14
  spec.license = "MIT"
15
15
 
@@ -18,6 +18,14 @@ Gem::Specification.new do |spec|
18
18
  spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
19
  spec.require_paths = ["lib"]
20
20
 
21
+ spec.add_dependency "actionpack", '>= 3.0.0' # this framework works on Rails.
22
+ spec.add_dependency "uber", ">= 0.0.10" # no builder inheritance.
23
+ spec.add_dependency "representable", ">= 2.1.1", "<2.2.0" # Representable::apply.
24
+ spec.add_dependency "reform", "1.2.0.beta1"
25
+
21
26
  spec.add_development_dependency "bundler", "~> 1.3"
22
27
  spec.add_development_dependency "rake"
28
+ spec.add_development_dependency "minitest"
29
+ # spec.add_development_dependency "minitest-spec-rails" # TODO: can anyone make this work (test/rails).
30
+ spec.add_development_dependency "sidekiq", "~> 3.1.0"
23
31
  end
metadata CHANGED
@@ -1,88 +1,225 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: trailblazer
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
5
- prerelease:
4
+ version: 0.1.0
6
5
  platform: ruby
7
6
  authors:
8
7
  - Nick Sutterer
9
8
  autorequire:
10
9
  bindir: bin
11
10
  cert_chain: []
12
- date: 2013-06-26 00:00:00.000000000 Z
11
+ date: 2014-11-04 00:00:00.000000000 Z
13
12
  dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: actionpack
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: 3.0.0
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: 3.0.0
27
+ - !ruby/object:Gem::Dependency
28
+ name: uber
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: 0.0.10
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: 0.0.10
41
+ - !ruby/object:Gem::Dependency
42
+ name: representable
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: 2.1.1
48
+ - - "<"
49
+ - !ruby/object:Gem::Version
50
+ version: 2.2.0
51
+ type: :runtime
52
+ prerelease: false
53
+ version_requirements: !ruby/object:Gem::Requirement
54
+ requirements:
55
+ - - ">="
56
+ - !ruby/object:Gem::Version
57
+ version: 2.1.1
58
+ - - "<"
59
+ - !ruby/object:Gem::Version
60
+ version: 2.2.0
61
+ - !ruby/object:Gem::Dependency
62
+ name: reform
63
+ requirement: !ruby/object:Gem::Requirement
64
+ requirements:
65
+ - - '='
66
+ - !ruby/object:Gem::Version
67
+ version: 1.2.0.beta1
68
+ type: :runtime
69
+ prerelease: false
70
+ version_requirements: !ruby/object:Gem::Requirement
71
+ requirements:
72
+ - - '='
73
+ - !ruby/object:Gem::Version
74
+ version: 1.2.0.beta1
14
75
  - !ruby/object:Gem::Dependency
15
76
  name: bundler
16
77
  requirement: !ruby/object:Gem::Requirement
17
- none: false
18
78
  requirements:
19
- - - ~>
79
+ - - "~>"
20
80
  - !ruby/object:Gem::Version
21
81
  version: '1.3'
22
82
  type: :development
23
83
  prerelease: false
24
84
  version_requirements: !ruby/object:Gem::Requirement
25
- none: false
26
85
  requirements:
27
- - - ~>
86
+ - - "~>"
28
87
  - !ruby/object:Gem::Version
29
88
  version: '1.3'
30
89
  - !ruby/object:Gem::Dependency
31
90
  name: rake
32
91
  requirement: !ruby/object:Gem::Requirement
33
- none: false
34
92
  requirements:
35
- - - ! '>='
93
+ - - ">="
36
94
  - !ruby/object:Gem::Version
37
95
  version: '0'
38
96
  type: :development
39
97
  prerelease: false
40
98
  version_requirements: !ruby/object:Gem::Requirement
41
- none: false
42
99
  requirements:
43
- - - ! '>='
100
+ - - ">="
44
101
  - !ruby/object:Gem::Version
45
102
  version: '0'
46
- description: A thin OOP framework on top of Rails that brings you form objects, view
47
- models, cells, decorators, representers, services and more.
103
+ - !ruby/object:Gem::Dependency
104
+ name: minitest
105
+ requirement: !ruby/object:Gem::Requirement
106
+ requirements:
107
+ - - ">="
108
+ - !ruby/object:Gem::Version
109
+ version: '0'
110
+ type: :development
111
+ prerelease: false
112
+ version_requirements: !ruby/object:Gem::Requirement
113
+ requirements:
114
+ - - ">="
115
+ - !ruby/object:Gem::Version
116
+ version: '0'
117
+ - !ruby/object:Gem::Dependency
118
+ name: sidekiq
119
+ requirement: !ruby/object:Gem::Requirement
120
+ requirements:
121
+ - - "~>"
122
+ - !ruby/object:Gem::Version
123
+ version: 3.1.0
124
+ type: :development
125
+ prerelease: false
126
+ version_requirements: !ruby/object:Gem::Requirement
127
+ requirements:
128
+ - - "~>"
129
+ - !ruby/object:Gem::Version
130
+ version: 3.1.0
131
+ description: Trailblazer is a thin layer on top of Rails. It gently enforces encapsulation,
132
+ an intuitive code structure and gives you an object-oriented architecture.
48
133
  email:
49
134
  - apotonick@gmail.com
50
135
  executables: []
51
136
  extensions: []
52
137
  extra_rdoc_files: []
53
138
  files:
54
- - .gitignore
139
+ - ".gitignore"
140
+ - ".travis.yml"
141
+ - CHANGES.md
55
142
  - Gemfile
56
143
  - LICENSE.txt
57
144
  - README.md
58
145
  - Rakefile
146
+ - THOUGHTS
147
+ - TODO.md
148
+ - doc/Trb-The-Stack.png
149
+ - doc/trb.jpg
150
+ - gemfiles/Gemfile.rails
151
+ - gemfiles/Gemfile.rails.lock
59
152
  - lib/trailblazer.rb
153
+ - lib/trailblazer/autoloading.rb
154
+ - lib/trailblazer/operation.rb
155
+ - lib/trailblazer/operation/controller.rb
156
+ - lib/trailblazer/operation/crud.rb
157
+ - lib/trailblazer/operation/representer.rb
158
+ - lib/trailblazer/operation/responder.rb
159
+ - lib/trailblazer/operation/uploaded_file.rb
160
+ - lib/trailblazer/operation/worker.rb
60
161
  - lib/trailblazer/version.rb
162
+ - test/crud_test.rb
163
+ - test/fixtures/apotomo.png
164
+ - test/fixtures/cells.png
165
+ - test/operation_test.rb
166
+ - test/rails/controller_test.rb
167
+ - test/rails/fake_app/app-cells/.gitkeep
168
+ - test/rails/fake_app/cells.rb
169
+ - test/rails/fake_app/config.rb
170
+ - test/rails/fake_app/controllers.rb
171
+ - test/rails/fake_app/models.rb
172
+ - test/rails/fake_app/rails_app.rb
173
+ - test/rails/fake_app/song/operations.rb
174
+ - test/rails/fake_app/views/bands/show.html.erb
175
+ - test/rails/fake_app/views/songs/new.html.erb
176
+ - test/rails/test_helper.rb
177
+ - test/responder_test.rb
178
+ - test/test_helper.rb
179
+ - test/uploaded_file_test.rb
180
+ - test/worker_test.rb
61
181
  - trailblazer.gemspec
62
182
  homepage: ''
63
183
  licenses:
64
184
  - MIT
185
+ metadata: {}
65
186
  post_install_message:
66
187
  rdoc_options: []
67
188
  require_paths:
68
189
  - lib
69
190
  required_ruby_version: !ruby/object:Gem::Requirement
70
- none: false
71
191
  requirements:
72
- - - ! '>='
192
+ - - ">="
73
193
  - !ruby/object:Gem::Version
74
194
  version: '0'
75
195
  required_rubygems_version: !ruby/object:Gem::Requirement
76
- none: false
77
196
  requirements:
78
- - - ! '>='
197
+ - - ">="
79
198
  - !ruby/object:Gem::Version
80
199
  version: '0'
81
200
  requirements: []
82
201
  rubyforge_project:
83
- rubygems_version: 1.8.25
202
+ rubygems_version: 2.2.2
84
203
  signing_key:
85
- specification_version: 3
86
- summary: A thin OOP framework on top of Rails that brings you form objects, view models,
87
- cells, decorators, representers, services and more.
88
- test_files: []
204
+ specification_version: 4
205
+ summary: A New Architecture For Rails.
206
+ test_files:
207
+ - test/crud_test.rb
208
+ - test/fixtures/apotomo.png
209
+ - test/fixtures/cells.png
210
+ - test/operation_test.rb
211
+ - test/rails/controller_test.rb
212
+ - test/rails/fake_app/app-cells/.gitkeep
213
+ - test/rails/fake_app/cells.rb
214
+ - test/rails/fake_app/config.rb
215
+ - test/rails/fake_app/controllers.rb
216
+ - test/rails/fake_app/models.rb
217
+ - test/rails/fake_app/rails_app.rb
218
+ - test/rails/fake_app/song/operations.rb
219
+ - test/rails/fake_app/views/bands/show.html.erb
220
+ - test/rails/fake_app/views/songs/new.html.erb
221
+ - test/rails/test_helper.rb
222
+ - test/responder_test.rb
223
+ - test/test_helper.rb
224
+ - test/uploaded_file_test.rb
225
+ - test/worker_test.rb