trailblazer 1.1.2 → 2.0.0.beta1
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 +4 -4
 - data/.travis.yml +10 -7
 - data/CHANGES.md +108 -0
 - data/COMM-LICENSE +91 -0
 - data/Gemfile +18 -4
 - data/LICENSE.txt +7 -20
 - data/README.md +55 -15
 - data/Rakefile +21 -2
 - data/draft-1.2.rb +7 -0
 - data/lib/trailblazer.rb +17 -4
 - data/lib/trailblazer/dsl.rb +47 -0
 - data/lib/trailblazer/operation/auto_inject.rb +47 -0
 - data/lib/trailblazer/operation/builder.rb +18 -18
 - data/lib/trailblazer/operation/callback.rb +31 -38
 - data/lib/trailblazer/operation/contract.rb +46 -0
 - data/lib/trailblazer/operation/controller.rb +45 -27
 - data/lib/trailblazer/operation/guard.rb +24 -0
 - data/lib/trailblazer/operation/model.rb +41 -33
 - data/lib/trailblazer/operation/nested.rb +43 -0
 - data/lib/trailblazer/operation/params.rb +13 -0
 - data/lib/trailblazer/operation/persist.rb +13 -0
 - data/lib/trailblazer/operation/policy.rb +26 -72
 - data/lib/trailblazer/operation/present.rb +19 -0
 - data/lib/trailblazer/operation/procedural/contract.rb +15 -0
 - data/lib/trailblazer/operation/procedural/validate.rb +22 -0
 - data/lib/trailblazer/operation/pundit.rb +42 -0
 - data/lib/trailblazer/operation/representer.rb +25 -92
 - data/lib/trailblazer/operation/rescue.rb +23 -0
 - data/lib/trailblazer/operation/resolver.rb +18 -24
 - data/lib/trailblazer/operation/validate.rb +50 -0
 - data/lib/trailblazer/operation/wrap.rb +37 -0
 - data/lib/trailblazer/version.rb +1 -1
 - data/test/{operation/controller_test.rb → controller_test.rb} +8 -4
 - data/test/docs/auto_inject_test.rb +30 -0
 - data/test/docs/contract_test.rb +429 -0
 - data/test/docs/dry_test.rb +31 -0
 - data/test/docs/guard_test.rb +143 -0
 - data/test/docs/nested_test.rb +117 -0
 - data/test/docs/policy_test.rb +2 -0
 - data/test/docs/pundit_test.rb +109 -0
 - data/test/docs/representer_test.rb +268 -0
 - data/test/docs/rescue_test.rb +153 -0
 - data/test/docs/wrap_test.rb +174 -0
 - data/test/gemfiles/Gemfile.ruby-1.9 +3 -0
 - data/test/gemfiles/Gemfile.ruby-2.0 +12 -0
 - data/test/gemfiles/Gemfile.ruby-2.3 +12 -0
 - data/test/module_test.rb +22 -15
 - data/test/operation/builder_test.rb +66 -18
 - data/test/operation/callback_test.rb +70 -0
 - data/test/operation/contract_test.rb +385 -15
 - data/test/operation/dsl/callback_test.rb +18 -30
 - data/test/operation/dsl/contract_test.rb +209 -19
 - data/test/operation/dsl/representer_test.rb +42 -15
 - data/test/operation/guard_test.rb +1 -147
 - data/test/operation/model_test.rb +105 -0
 - data/test/operation/params_test.rb +36 -0
 - data/test/operation/persist_test.rb +44 -0
 - data/test/operation/pipedream_test.rb +59 -0
 - data/test/operation/pipetree_test.rb +104 -0
 - data/test/operation/present_test.rb +24 -0
 - data/test/operation/pundit_test.rb +104 -0
 - data/test/{representer_test.rb → operation/representer_test.rb} +58 -42
 - data/test/operation/resolver_test.rb +34 -70
 - data/test/operation_test.rb +57 -189
 - data/test/test_helper.rb +23 -3
 - data/trailblazer.gemspec +8 -7
 - metadata +91 -59
 - data/gemfiles/Gemfile.rails.lock +0 -130
 - data/gemfiles/Gemfile.reform-2.0 +0 -6
 - data/gemfiles/Gemfile.reform-2.1 +0 -7
 - data/lib/trailblazer/autoloading.rb +0 -15
 - data/lib/trailblazer/endpoint.rb +0 -31
 - data/lib/trailblazer/operation.rb +0 -175
 - data/lib/trailblazer/operation/collection.rb +0 -6
 - data/lib/trailblazer/operation/dispatch.rb +0 -3
 - data/lib/trailblazer/operation/model/dsl.rb +0 -29
 - data/lib/trailblazer/operation/model/external.rb +0 -34
 - data/lib/trailblazer/operation/policy/guard.rb +0 -35
 - data/lib/trailblazer/operation/uploaded_file.rb +0 -77
 - data/test/callback_test.rb +0 -104
 - data/test/collection_test.rb +0 -57
 - data/test/model_test.rb +0 -148
 - data/test/operation/external_model_test.rb +0 -71
 - data/test/operation/policy_test.rb +0 -97
 - data/test/operation/reject_test.rb +0 -34
 - data/test/rollback_test.rb +0 -47
 
| 
         @@ -1,35 +0,0 @@ 
     | 
|
| 
       1 
     | 
    
         
            -
            module Trailblazer
         
     | 
| 
       2 
     | 
    
         
            -
              # Policy::Guard is a very simple policy implementation.
         
     | 
| 
       3 
     | 
    
         
            -
              # It adds #evaluate_policy to Operation#setup! and calls whatever
         
     | 
| 
       4 
     | 
    
         
            -
              # you provided to ::policy.
         
     | 
| 
       5 
     | 
    
         
            -
              #
         
     | 
| 
       6 
     | 
    
         
            -
              # http://trailblazer.to/gems/operation/policy.html#guard
         
     | 
| 
       7 
     | 
    
         
            -
              module Operation::Policy
         
     | 
| 
       8 
     | 
    
         
            -
                module Guard
         
     | 
| 
       9 
     | 
    
         
            -
                  def self.included(includer)
         
     | 
| 
       10 
     | 
    
         
            -
                    includer.extend(DSL) # Provides ::policy(CallableObject)
         
     | 
| 
       11 
     | 
    
         
            -
                    includer.extend(ClassMethods)
         
     | 
| 
       12 
     | 
    
         
            -
                    includer.send(:include, Setup)
         
     | 
| 
       13 
     | 
    
         
            -
                  end
         
     | 
| 
       14 
     | 
    
         
            -
             
     | 
| 
       15 
     | 
    
         
            -
                  module ClassMethods
         
     | 
| 
       16 
     | 
    
         
            -
                    def policy(callable=nil, &block)
         
     | 
| 
       17 
     | 
    
         
            -
                      self.policy_config = Uber::Options::Value.new(callable || block)
         
     | 
| 
       18 
     | 
    
         
            -
                    end
         
     | 
| 
       19 
     | 
    
         
            -
                  end
         
     | 
| 
       20 
     | 
    
         
            -
             
     | 
| 
       21 
     | 
    
         
            -
                  def evaluate_policy(params)
         
     | 
| 
       22 
     | 
    
         
            -
                    call_policy(params) or raise policy_exception
         
     | 
| 
       23 
     | 
    
         
            -
                  end
         
     | 
| 
       24 
     | 
    
         
            -
             
     | 
| 
       25 
     | 
    
         
            -
                  # Override if you want your own policy invocation, e.g. with more args.
         
     | 
| 
       26 
     | 
    
         
            -
                  def call_policy(params)
         
     | 
| 
       27 
     | 
    
         
            -
                    self.class.policy_config.(self, params)
         
     | 
| 
       28 
     | 
    
         
            -
                  end
         
     | 
| 
       29 
     | 
    
         
            -
             
     | 
| 
       30 
     | 
    
         
            -
                  def policy_exception
         
     | 
| 
       31 
     | 
    
         
            -
                    NotAuthorizedError.new
         
     | 
| 
       32 
     | 
    
         
            -
                  end
         
     | 
| 
       33 
     | 
    
         
            -
                end
         
     | 
| 
       34 
     | 
    
         
            -
              end
         
     | 
| 
       35 
     | 
    
         
            -
            end
         
     | 
| 
         @@ -1,77 +0,0 @@ 
     | 
|
| 
       1 
     | 
    
         
            -
            require 'trailblazer/operation'
         
     | 
| 
       2 
     | 
    
         
            -
            require 'action_dispatch/http/upload'
         
     | 
| 
       3 
     | 
    
         
            -
            require 'tempfile'
         
     | 
| 
       4 
     | 
    
         
            -
             
     | 
| 
       5 
     | 
    
         
            -
            module Trailblazer
         
     | 
| 
       6 
     | 
    
         
            -
              # TODO: document:
         
     | 
| 
       7 
     | 
    
         
            -
              # to_hash
         
     | 
| 
       8 
     | 
    
         
            -
              # from_hash
         
     | 
| 
       9 
     | 
    
         
            -
              # initialize/tmp_dir
         
     | 
| 
       10 
     | 
    
         
            -
              class Operation::UploadedFile
         
     | 
| 
       11 
     | 
    
         
            -
                def initialize(uploaded, options={})
         
     | 
| 
       12 
     | 
    
         
            -
                  @uploaded = uploaded
         
     | 
| 
       13 
     | 
    
         
            -
                  @options  = options
         
     | 
| 
       14 
     | 
    
         
            -
                  @tmp_dir  = options[:tmp_dir]
         
     | 
| 
       15 
     | 
    
         
            -
                end
         
     | 
| 
       16 
     | 
    
         
            -
             
     | 
| 
       17 
     | 
    
         
            -
                def to_hash
         
     | 
| 
       18 
     | 
    
         
            -
                  path = persist!
         
     | 
| 
       19 
     | 
    
         
            -
             
     | 
| 
       20 
     | 
    
         
            -
                  hash = {
         
     | 
| 
       21 
     | 
    
         
            -
                    filename: @uploaded.original_filename,
         
     | 
| 
       22 
     | 
    
         
            -
                    type: @uploaded.content_type,
         
     | 
| 
       23 
     | 
    
         
            -
                    tempfile_path: path
         
     | 
| 
       24 
     | 
    
         
            -
                  }
         
     | 
| 
       25 
     | 
    
         
            -
             
     | 
| 
       26 
     | 
    
         
            -
                  cleanup!
         
     | 
| 
       27 
     | 
    
         
            -
             
     | 
| 
       28 
     | 
    
         
            -
                  hash
         
     | 
| 
       29 
     | 
    
         
            -
                end
         
     | 
| 
       30 
     | 
    
         
            -
             
     | 
| 
       31 
     | 
    
         
            -
                # Returns a ActionDispatch::Http::UploadedFile as if the upload was in the same request.
         
     | 
| 
       32 
     | 
    
         
            -
                def self.from_hash(hash)
         
     | 
| 
       33 
     | 
    
         
            -
                  suffix = File.extname(hash[:filename])
         
     | 
| 
       34 
     | 
    
         
            -
             
     | 
| 
       35 
     | 
    
         
            -
                  # we need to create a Tempfile to make Http::UploadedFile work.
         
     | 
| 
       36 
     | 
    
         
            -
                  tmp  = Tempfile.new(["bla", suffix]) # always force file suffix to avoid problems with imagemagick etc.
         
     | 
| 
       37 
     | 
    
         
            -
                  file = File.open(hash[:tempfile_path])# doesn't close automatically :( # fixme: introduce strategy (Tempfile:=>slow, File:=> hopefully less memory footprint)
         
     | 
| 
       38 
     | 
    
         
            -
                  tmp.write(file.read) # DISCUSS: We need Tempfile.new(<File>) to avoid this slow and memory-consuming mechanics.
         
     | 
| 
       39 
     | 
    
         
            -
             
     | 
| 
       40 
     | 
    
         
            -
                  file.close # TODO: can we test that?
         
     | 
| 
       41 
     | 
    
         
            -
                  File.unlink(file)
         
     | 
| 
       42 
     | 
    
         
            -
             
     | 
| 
       43 
     | 
    
         
            -
                  ActionDispatch::Http::UploadedFile.new(hash.merge(tempfile: tmp))
         
     | 
| 
       44 
     | 
    
         
            -
                end
         
     | 
| 
       45 
     | 
    
         
            -
             
     | 
| 
       46 
     | 
    
         
            -
              private
         
     | 
| 
       47 
     | 
    
         
            -
                attr_reader :tmp_dir
         
     | 
| 
       48 
     | 
    
         
            -
             
     | 
| 
       49 
     | 
    
         
            -
                 # convert Tempfile from Rails upload into persistent "temp" file so it is available in workers.
         
     | 
| 
       50 
     | 
    
         
            -
                def persist!
         
     | 
| 
       51 
     | 
    
         
            -
                  path = @uploaded.path # original Tempfile path (from Rails).
         
     | 
| 
       52 
     | 
    
         
            -
                  path = path_with_tmp_dir(path)
         
     | 
| 
       53 
     | 
    
         
            -
             
     | 
| 
       54 
     | 
    
         
            -
                  path = path + "_trailblazer_upload"
         
     | 
| 
       55 
     | 
    
         
            -
             
     | 
| 
       56 
     | 
    
         
            -
                  FileUtils.mv(@uploaded.path, path) # move Rails upload file into persistent `path`.
         
     | 
| 
       57 
     | 
    
         
            -
                  path
         
     | 
| 
       58 
     | 
    
         
            -
                end
         
     | 
| 
       59 
     | 
    
         
            -
             
     | 
| 
       60 
     | 
    
         
            -
                def path_with_tmp_dir(path)
         
     | 
| 
       61 
     | 
    
         
            -
                  return path unless tmp_dir # if tmp_dir set, create path in it.
         
     | 
| 
       62 
     | 
    
         
            -
             
     | 
| 
       63 
     | 
    
         
            -
                  @with_tmp_dir = Tempfile.new(File.basename(path), tmp_dir)
         
     | 
| 
       64 
     | 
    
         
            -
                  @with_tmp_dir.path # use Tempfile to create nested dirs (os-dependent.)
         
     | 
| 
       65 
     | 
    
         
            -
                end
         
     | 
| 
       66 
     | 
    
         
            -
             
     | 
| 
       67 
     | 
    
         
            -
                def delete!(file)
         
     | 
| 
       68 
     | 
    
         
            -
                  file.close
         
     | 
| 
       69 
     | 
    
         
            -
                  file.unlink # the Rails uploaded file is already unlinked since moved.
         
     | 
| 
       70 
     | 
    
         
            -
                end
         
     | 
| 
       71 
     | 
    
         
            -
             
     | 
| 
       72 
     | 
    
         
            -
                def cleanup!
         
     | 
| 
       73 
     | 
    
         
            -
                  delete!(@uploaded.tempfile) if @uploaded.respond_to?(:tempfile) # this is Rails' uploaded file, not sure if we need to do that. in 3.2, we don't have UploadedFile#close, yet.
         
     | 
| 
       74 
     | 
    
         
            -
                  delete!(@with_tmp_dir) if @with_tmp_dir # we used that file to create a tmp file path below tmp_dir.
         
     | 
| 
       75 
     | 
    
         
            -
                end
         
     | 
| 
       76 
     | 
    
         
            -
              end
         
     | 
| 
       77 
     | 
    
         
            -
            end
         
     | 
    
        data/test/callback_test.rb
    DELETED
    
    | 
         @@ -1,104 +0,0 @@ 
     | 
|
| 
       1 
     | 
    
         
            -
            require 'test_helper'
         
     | 
| 
       2 
     | 
    
         
            -
            require "trailblazer/operation/callback"
         
     | 
| 
       3 
     | 
    
         
            -
             
     | 
| 
       4 
     | 
    
         
            -
            # callbacks are tested in Disposable::Callback::Group.
         
     | 
| 
       5 
     | 
    
         
            -
            class OperationCallbackTest < MiniTest::Spec
         
     | 
| 
       6 
     | 
    
         
            -
              Song = Struct.new(:name)
         
     | 
| 
       7 
     | 
    
         
            -
             
     | 
| 
       8 
     | 
    
         
            -
              class Create < Trailblazer::Operation
         
     | 
| 
       9 
     | 
    
         
            -
                include Trailblazer::Operation::Callback
         
     | 
| 
       10 
     | 
    
         
            -
             
     | 
| 
       11 
     | 
    
         
            -
                contract do
         
     | 
| 
       12 
     | 
    
         
            -
                  property :name
         
     | 
| 
       13 
     | 
    
         
            -
                end
         
     | 
| 
       14 
     | 
    
         
            -
             
     | 
| 
       15 
     | 
    
         
            -
                callback do
         
     | 
| 
       16 
     | 
    
         
            -
                  on_change :notify_me!
         
     | 
| 
       17 
     | 
    
         
            -
                  on_change :notify_you!
         
     | 
| 
       18 
     | 
    
         
            -
                end
         
     | 
| 
       19 
     | 
    
         
            -
             
     | 
| 
       20 
     | 
    
         
            -
                # TODO: always dispatch, pass params.
         
     | 
| 
       21 
     | 
    
         
            -
             
     | 
| 
       22 
     | 
    
         
            -
                def process(params)
         
     | 
| 
       23 
     | 
    
         
            -
                  @model = Song.new
         
     | 
| 
       24 
     | 
    
         
            -
             
     | 
| 
       25 
     | 
    
         
            -
                  validate(params, @model) do
         
     | 
| 
       26 
     | 
    
         
            -
                    callback!
         
     | 
| 
       27 
     | 
    
         
            -
                  end
         
     | 
| 
       28 
     | 
    
         
            -
                end
         
     | 
| 
       29 
     | 
    
         
            -
             
     | 
| 
       30 
     | 
    
         
            -
                def dispatched
         
     | 
| 
       31 
     | 
    
         
            -
                  @dispatched ||= []
         
     | 
| 
       32 
     | 
    
         
            -
                end
         
     | 
| 
       33 
     | 
    
         
            -
             
     | 
| 
       34 
     | 
    
         
            -
              private
         
     | 
| 
       35 
     | 
    
         
            -
                def notify_me!(*)
         
     | 
| 
       36 
     | 
    
         
            -
                  dispatched << :notify_me!
         
     | 
| 
       37 
     | 
    
         
            -
                end
         
     | 
| 
       38 
     | 
    
         
            -
             
     | 
| 
       39 
     | 
    
         
            -
                def notify_you!(*)
         
     | 
| 
       40 
     | 
    
         
            -
                  dispatched << :notify_you!
         
     | 
| 
       41 
     | 
    
         
            -
                end
         
     | 
| 
       42 
     | 
    
         
            -
              end
         
     | 
| 
       43 
     | 
    
         
            -
             
     | 
| 
       44 
     | 
    
         
            -
             
     | 
| 
       45 
     | 
    
         
            -
              class Update < Create
         
     | 
| 
       46 
     | 
    
         
            -
                # TODO: allow skipping groups.
         
     | 
| 
       47 
     | 
    
         
            -
                # skip_dispatch :notify_me!
         
     | 
| 
       48 
     | 
    
         
            -
             
     | 
| 
       49 
     | 
    
         
            -
                callback do
         
     | 
| 
       50 
     | 
    
         
            -
                  remove! :on_change, :notify_me!
         
     | 
| 
       51 
     | 
    
         
            -
                end
         
     | 
| 
       52 
     | 
    
         
            -
              end
         
     | 
| 
       53 
     | 
    
         
            -
             
     | 
| 
       54 
     | 
    
         
            -
             
     | 
| 
       55 
     | 
    
         
            -
              it "invokes all callbacks" do
         
     | 
| 
       56 
     | 
    
         
            -
                op = Create.({"name"=>"Keep On Running"})
         
     | 
| 
       57 
     | 
    
         
            -
                op.dispatched.must_equal [:notify_me!, :notify_you!]
         
     | 
| 
       58 
     | 
    
         
            -
              end
         
     | 
| 
       59 
     | 
    
         
            -
             
     | 
| 
       60 
     | 
    
         
            -
              it "does not invoke removed callbacks" do
         
     | 
| 
       61 
     | 
    
         
            -
                op = Update.({"name"=>"Keep On Running"})
         
     | 
| 
       62 
     | 
    
         
            -
                op.dispatched.must_equal [:notify_you!]
         
     | 
| 
       63 
     | 
    
         
            -
              end
         
     | 
| 
       64 
     | 
    
         
            -
            end
         
     | 
| 
       65 
     | 
    
         
            -
             
     | 
| 
       66 
     | 
    
         
            -
            # TODO: remove in 1.2.
         
     | 
| 
       67 
     | 
    
         
            -
            require "trailblazer/operation/dispatch"
         
     | 
| 
       68 
     | 
    
         
            -
            class OperationDeprecatedDispatchTest < MiniTest::Spec
         
     | 
| 
       69 
     | 
    
         
            -
              Song = Struct.new(:name)
         
     | 
| 
       70 
     | 
    
         
            -
             
     | 
| 
       71 
     | 
    
         
            -
              class Create < Trailblazer::Operation
         
     | 
| 
       72 
     | 
    
         
            -
                include Trailblazer::Operation::Dispatch
         
     | 
| 
       73 
     | 
    
         
            -
             
     | 
| 
       74 
     | 
    
         
            -
                contract do
         
     | 
| 
       75 
     | 
    
         
            -
                  property :name
         
     | 
| 
       76 
     | 
    
         
            -
                end
         
     | 
| 
       77 
     | 
    
         
            -
             
     | 
| 
       78 
     | 
    
         
            -
                callback do
         
     | 
| 
       79 
     | 
    
         
            -
                  on_change :notify_me!
         
     | 
| 
       80 
     | 
    
         
            -
                end
         
     | 
| 
       81 
     | 
    
         
            -
             
     | 
| 
       82 
     | 
    
         
            -
                def process(params)
         
     | 
| 
       83 
     | 
    
         
            -
                  @model = Song.new
         
     | 
| 
       84 
     | 
    
         
            -
             
     | 
| 
       85 
     | 
    
         
            -
                  validate(params, @model) do
         
     | 
| 
       86 
     | 
    
         
            -
                    dispatch!
         
     | 
| 
       87 
     | 
    
         
            -
                  end
         
     | 
| 
       88 
     | 
    
         
            -
                end
         
     | 
| 
       89 
     | 
    
         
            -
             
     | 
| 
       90 
     | 
    
         
            -
                def dispatched
         
     | 
| 
       91 
     | 
    
         
            -
                  @dispatched ||= []
         
     | 
| 
       92 
     | 
    
         
            -
                end
         
     | 
| 
       93 
     | 
    
         
            -
             
     | 
| 
       94 
     | 
    
         
            -
              private
         
     | 
| 
       95 
     | 
    
         
            -
                def notify_me!(*)
         
     | 
| 
       96 
     | 
    
         
            -
                  dispatched << :notify_me!
         
     | 
| 
       97 
     | 
    
         
            -
                end
         
     | 
| 
       98 
     | 
    
         
            -
              end
         
     | 
| 
       99 
     | 
    
         
            -
             
     | 
| 
       100 
     | 
    
         
            -
              it "invokes all callbacks [deprecated]" do
         
     | 
| 
       101 
     | 
    
         
            -
                op = Create.({"name"=>"Keep On Running"})
         
     | 
| 
       102 
     | 
    
         
            -
                op.dispatched.must_equal [:notify_me!]
         
     | 
| 
       103 
     | 
    
         
            -
              end
         
     | 
| 
       104 
     | 
    
         
            -
            end
         
     | 
    
        data/test/collection_test.rb
    DELETED
    
    | 
         @@ -1,57 +0,0 @@ 
     | 
|
| 
       1 
     | 
    
         
            -
            require "test_helper"
         
     | 
| 
       2 
     | 
    
         
            -
            require "trailblazer/operation/collection"
         
     | 
| 
       3 
     | 
    
         
            -
            require "trailblazer/operation/model"
         
     | 
| 
       4 
     | 
    
         
            -
             
     | 
| 
       5 
     | 
    
         
            -
            class CollectionTest < MiniTest::Spec
         
     | 
| 
       6 
     | 
    
         
            -
              Song = Struct.new(:title, :id) do
         
     | 
| 
       7 
     | 
    
         
            -
                class << self
         
     | 
| 
       8 
     | 
    
         
            -
                  attr_accessor :all_records
         
     | 
| 
       9 
     | 
    
         
            -
             
     | 
| 
       10 
     | 
    
         
            -
                  def all
         
     | 
| 
       11 
     | 
    
         
            -
                    all_records
         
     | 
| 
       12 
     | 
    
         
            -
                  end
         
     | 
| 
       13 
     | 
    
         
            -
                end
         
     | 
| 
       14 
     | 
    
         
            -
              end
         
     | 
| 
       15 
     | 
    
         
            -
             
     | 
| 
       16 
     | 
    
         
            -
             
     | 
| 
       17 
     | 
    
         
            -
              class CreateOperation < Trailblazer::Operation
         
     | 
| 
       18 
     | 
    
         
            -
                include Model
         
     | 
| 
       19 
     | 
    
         
            -
                model Song
         
     | 
| 
       20 
     | 
    
         
            -
                action :create
         
     | 
| 
       21 
     | 
    
         
            -
             
     | 
| 
       22 
     | 
    
         
            -
                contract do
         
     | 
| 
       23 
     | 
    
         
            -
                  property :title
         
     | 
| 
       24 
     | 
    
         
            -
                  validates :title, presence: true
         
     | 
| 
       25 
     | 
    
         
            -
                end
         
     | 
| 
       26 
     | 
    
         
            -
             
     | 
| 
       27 
     | 
    
         
            -
                def process(params)
         
     | 
| 
       28 
     | 
    
         
            -
                  validate(params[:song]) do |f|
         
     | 
| 
       29 
     | 
    
         
            -
                    f.sync
         
     | 
| 
       30 
     | 
    
         
            -
                  end
         
     | 
| 
       31 
     | 
    
         
            -
                end
         
     | 
| 
       32 
     | 
    
         
            -
              end
         
     | 
| 
       33 
     | 
    
         
            -
             
     | 
| 
       34 
     | 
    
         
            -
              class FetchCollectionOperation < CreateOperation
         
     | 
| 
       35 
     | 
    
         
            -
                include Trailblazer::Operation::Collection
         
     | 
| 
       36 
     | 
    
         
            -
             
     | 
| 
       37 
     | 
    
         
            -
                model Song
         
     | 
| 
       38 
     | 
    
         
            -
             
     | 
| 
       39 
     | 
    
         
            -
                contract do
         
     | 
| 
       40 
     | 
    
         
            -
                  property :title
         
     | 
| 
       41 
     | 
    
         
            -
                end
         
     | 
| 
       42 
     | 
    
         
            -
             
     | 
| 
       43 
     | 
    
         
            -
                def model!(params)
         
     | 
| 
       44 
     | 
    
         
            -
                  Song.all
         
     | 
| 
       45 
     | 
    
         
            -
                end
         
     | 
| 
       46 
     | 
    
         
            -
              end
         
     | 
| 
       47 
     | 
    
         
            -
             
     | 
| 
       48 
     | 
    
         
            -
              # ::present.
         
     | 
| 
       49 
     | 
    
         
            -
              it do
         
     | 
| 
       50 
     | 
    
         
            -
                Song.all_records = [
         
     | 
| 
       51 
     | 
    
         
            -
                  CreateOperation.(song: {title: "Blue Rondo a la Turk"}).model,
         
     | 
| 
       52 
     | 
    
         
            -
                  CreateOperation.(song: {title: "Mercy Day For Mr. Vengeance"}).model
         
     | 
| 
       53 
     | 
    
         
            -
                ]
         
     | 
| 
       54 
     | 
    
         
            -
                op = FetchCollectionOperation.present(user_id: 0)
         
     | 
| 
       55 
     | 
    
         
            -
                op.model.must_equal Song.all_records
         
     | 
| 
       56 
     | 
    
         
            -
              end
         
     | 
| 
       57 
     | 
    
         
            -
            end
         
     | 
    
        data/test/model_test.rb
    DELETED
    
    | 
         @@ -1,148 +0,0 @@ 
     | 
|
| 
       1 
     | 
    
         
            -
            require 'test_helper'
         
     | 
| 
       2 
     | 
    
         
            -
            require 'trailblazer/operation'
         
     | 
| 
       3 
     | 
    
         
            -
             
     | 
| 
       4 
     | 
    
         
            -
            class ModelTest < MiniTest::Spec
         
     | 
| 
       5 
     | 
    
         
            -
              Song = Struct.new(:title, :id) do
         
     | 
| 
       6 
     | 
    
         
            -
                class << self
         
     | 
| 
       7 
     | 
    
         
            -
                  attr_accessor :find_result # TODO: eventually, replace with AR test.
         
     | 
| 
       8 
     | 
    
         
            -
                  attr_accessor :all_records
         
     | 
| 
       9 
     | 
    
         
            -
             
     | 
| 
       10 
     | 
    
         
            -
                  def find(id)
         
     | 
| 
       11 
     | 
    
         
            -
                    find_result
         
     | 
| 
       12 
     | 
    
         
            -
                  end
         
     | 
| 
       13 
     | 
    
         
            -
                end
         
     | 
| 
       14 
     | 
    
         
            -
              end
         
     | 
| 
       15 
     | 
    
         
            -
             
     | 
| 
       16 
     | 
    
         
            -
              class CreateOperation < Trailblazer::Operation
         
     | 
| 
       17 
     | 
    
         
            -
                include Model
         
     | 
| 
       18 
     | 
    
         
            -
                model Song
         
     | 
| 
       19 
     | 
    
         
            -
                action :create
         
     | 
| 
       20 
     | 
    
         
            -
             
     | 
| 
       21 
     | 
    
         
            -
                contract do
         
     | 
| 
       22 
     | 
    
         
            -
                  property :title
         
     | 
| 
       23 
     | 
    
         
            -
                  validates :title, presence: true
         
     | 
| 
       24 
     | 
    
         
            -
                end
         
     | 
| 
       25 
     | 
    
         
            -
             
     | 
| 
       26 
     | 
    
         
            -
                def process(params)
         
     | 
| 
       27 
     | 
    
         
            -
                  validate(params[:song]) do |f|
         
     | 
| 
       28 
     | 
    
         
            -
                    f.sync
         
     | 
| 
       29 
     | 
    
         
            -
                  end
         
     | 
| 
       30 
     | 
    
         
            -
                end
         
     | 
| 
       31 
     | 
    
         
            -
              end
         
     | 
| 
       32 
     | 
    
         
            -
             
     | 
| 
       33 
     | 
    
         
            -
             
     | 
| 
       34 
     | 
    
         
            -
              # creates model for you.
         
     | 
| 
       35 
     | 
    
         
            -
              it { CreateOperation.(song: {title: "Blue Rondo a la Turk"}).model.title.must_equal "Blue Rondo a la Turk" }
         
     | 
| 
       36 
     | 
    
         
            -
              # exposes #model.
         
     | 
| 
       37 
     | 
    
         
            -
              it { CreateOperation.(song: {title: "Blue Rondo a la Turk"}).model.must_be_instance_of Song }
         
     | 
| 
       38 
     | 
    
         
            -
             
     | 
| 
       39 
     | 
    
         
            -
              class ModifyingCreateOperation < CreateOperation
         
     | 
| 
       40 
     | 
    
         
            -
                def process(params)
         
     | 
| 
       41 
     | 
    
         
            -
                  model.instance_eval { def genre; "Punkrock"; end }
         
     | 
| 
       42 
     | 
    
         
            -
             
     | 
| 
       43 
     | 
    
         
            -
                  validate(params[:song]) do |f|
         
     | 
| 
       44 
     | 
    
         
            -
                    f.sync
         
     | 
| 
       45 
     | 
    
         
            -
                  end
         
     | 
| 
       46 
     | 
    
         
            -
                end
         
     | 
| 
       47 
     | 
    
         
            -
              end
         
     | 
| 
       48 
     | 
    
         
            -
             
     | 
| 
       49 
     | 
    
         
            -
              # lets you modify model.
         
     | 
| 
       50 
     | 
    
         
            -
              it { ModifyingCreateOperation.(song: {title: "Blue Rondo a la Turk"}).model.title.must_equal "Blue Rondo a la Turk" }
         
     | 
| 
       51 
     | 
    
         
            -
              it { ModifyingCreateOperation.(song: {title: "Blue Rondo a la Turk"}).model.genre.must_equal "Punkrock" }
         
     | 
| 
       52 
     | 
    
         
            -
             
     | 
| 
       53 
     | 
    
         
            -
              # Update
         
     | 
| 
       54 
     | 
    
         
            -
              class UpdateOperation < CreateOperation
         
     | 
| 
       55 
     | 
    
         
            -
                action :update
         
     | 
| 
       56 
     | 
    
         
            -
              end
         
     | 
| 
       57 
     | 
    
         
            -
             
     | 
| 
       58 
     | 
    
         
            -
              # finds model and updates.
         
     | 
| 
       59 
     | 
    
         
            -
              it do
         
     | 
| 
       60 
     | 
    
         
            -
                song = CreateOperation.(song: {title: "Anchor End"}).model
         
     | 
| 
       61 
     | 
    
         
            -
                Song.find_result = song
         
     | 
| 
       62 
     | 
    
         
            -
             
     | 
| 
       63 
     | 
    
         
            -
                UpdateOperation.(id: song.id, song: {title: "The Rip"}).model.title.must_equal "The Rip"
         
     | 
| 
       64 
     | 
    
         
            -
                song.title.must_equal "The Rip"
         
     | 
| 
       65 
     | 
    
         
            -
              end
         
     | 
| 
       66 
     | 
    
         
            -
             
     | 
| 
       67 
     | 
    
         
            -
              # Find == Update
         
     | 
| 
       68 
     | 
    
         
            -
              class FindOperation < CreateOperation
         
     | 
| 
       69 
     | 
    
         
            -
                action :find
         
     | 
| 
       70 
     | 
    
         
            -
              end
         
     | 
| 
       71 
     | 
    
         
            -
             
     | 
| 
       72 
     | 
    
         
            -
              # finds model and updates.
         
     | 
| 
       73 
     | 
    
         
            -
              it do
         
     | 
| 
       74 
     | 
    
         
            -
                song = CreateOperation.(song: {title: "Anchor End"}).model
         
     | 
| 
       75 
     | 
    
         
            -
                Song.find_result = song
         
     | 
| 
       76 
     | 
    
         
            -
             
     | 
| 
       77 
     | 
    
         
            -
                FindOperation.(id: song.id, song: {title: "The Rip"}).model.title.must_equal "The Rip"
         
     | 
| 
       78 
     | 
    
         
            -
                song.title.must_equal "The Rip"
         
     | 
| 
       79 
     | 
    
         
            -
              end
         
     | 
| 
       80 
     | 
    
         
            -
             
     | 
| 
       81 
     | 
    
         
            -
             
     | 
| 
       82 
     | 
    
         
            -
              class DefaultCreateOperation < Trailblazer::Operation
         
     | 
| 
       83 
     | 
    
         
            -
                include Model
         
     | 
| 
       84 
     | 
    
         
            -
                model Song
         
     | 
| 
       85 
     | 
    
         
            -
             
     | 
| 
       86 
     | 
    
         
            -
                def process(params)
         
     | 
| 
       87 
     | 
    
         
            -
                  self
         
     | 
| 
       88 
     | 
    
         
            -
                end
         
     | 
| 
       89 
     | 
    
         
            -
              end
         
     | 
| 
       90 
     | 
    
         
            -
             
     | 
| 
       91 
     | 
    
         
            -
              # uses :create as default if not set via ::action.
         
     | 
| 
       92 
     | 
    
         
            -
              it { DefaultCreateOperation.({}).model.must_equal Song.new }
         
     | 
| 
       93 
     | 
    
         
            -
             
     | 
| 
       94 
     | 
    
         
            -
              # model Song, :action
         
     | 
| 
       95 
     | 
    
         
            -
              class ModelUpdateOperation < CreateOperation
         
     | 
| 
       96 
     | 
    
         
            -
                model Song, :update
         
     | 
| 
       97 
     | 
    
         
            -
              end
         
     | 
| 
       98 
     | 
    
         
            -
             
     | 
| 
       99 
     | 
    
         
            -
              # allows ::model, :action.
         
     | 
| 
       100 
     | 
    
         
            -
              it do
         
     | 
| 
       101 
     | 
    
         
            -
                Song.find_result = song = Song.new
         
     | 
| 
       102 
     | 
    
         
            -
                ModelUpdateOperation.({id: 1, song: {title: "Mercy Day For Mr. Vengeance"}}).model.must_equal song
         
     | 
| 
       103 
     | 
    
         
            -
              end
         
     | 
| 
       104 
     | 
    
         
            -
             
     | 
| 
       105 
     | 
    
         
            -
             
     | 
| 
       106 
     | 
    
         
            -
             
     | 
| 
       107 
     | 
    
         
            -
              # Op#setup_model!
         
     | 
| 
       108 
     | 
    
         
            -
              class SetupModelOperation < CreateOperation
         
     | 
| 
       109 
     | 
    
         
            -
                def setup_model!(params)
         
     | 
| 
       110 
     | 
    
         
            -
                  model.instance_eval { @params = params; def params; @params.to_s; end }
         
     | 
| 
       111 
     | 
    
         
            -
                end
         
     | 
| 
       112 
     | 
    
         
            -
              end
         
     | 
| 
       113 
     | 
    
         
            -
             
     | 
| 
       114 
     | 
    
         
            -
              it { SetupModelOperation.(song: {title: "Emily Kane"}).model.params.must_equal "{:song=>{:title=>\"Emily Kane\"}}" }
         
     | 
| 
       115 
     | 
    
         
            -
             
     | 
| 
       116 
     | 
    
         
            -
             
     | 
| 
       117 
     | 
    
         
            -
             
     | 
| 
       118 
     | 
    
         
            -
              # no call to ::model raises error.
         
     | 
| 
       119 
     | 
    
         
            -
              class NoModelOperation < Trailblazer::Operation
         
     | 
| 
       120 
     | 
    
         
            -
                include Model
         
     | 
| 
       121 
     | 
    
         
            -
             
     | 
| 
       122 
     | 
    
         
            -
                def process(params)
         
     | 
| 
       123 
     | 
    
         
            -
                  self
         
     | 
| 
       124 
     | 
    
         
            -
                end
         
     | 
| 
       125 
     | 
    
         
            -
              end
         
     | 
| 
       126 
     | 
    
         
            -
             
     | 
| 
       127 
     | 
    
         
            -
              # uses :create as default if not set via ::action.
         
     | 
| 
       128 
     | 
    
         
            -
              it { assert_raises(RuntimeError){ NoModelOperation.({}) } }
         
     | 
| 
       129 
     | 
    
         
            -
             
     | 
| 
       130 
     | 
    
         
            -
              # allow passing validate(params, model, contract_class)
         
     | 
| 
       131 
     | 
    
         
            -
              class OperationWithPrivateContract < Trailblazer::Operation
         
     | 
| 
       132 
     | 
    
         
            -
                include Model
         
     | 
| 
       133 
     | 
    
         
            -
                model Song
         
     | 
| 
       134 
     | 
    
         
            -
             
     | 
| 
       135 
     | 
    
         
            -
                class Contract < Reform::Form
         
     | 
| 
       136 
     | 
    
         
            -
                  property :title
         
     | 
| 
       137 
     | 
    
         
            -
                end
         
     | 
| 
       138 
     | 
    
         
            -
             
     | 
| 
       139 
     | 
    
         
            -
                def process(params)
         
     | 
| 
       140 
     | 
    
         
            -
                  validate(params[:song], model, Contract) do |f|
         
     | 
| 
       141 
     | 
    
         
            -
                    f.sync
         
     | 
| 
       142 
     | 
    
         
            -
                  end
         
     | 
| 
       143 
     | 
    
         
            -
                end
         
     | 
| 
       144 
     | 
    
         
            -
              end
         
     | 
| 
       145 
     | 
    
         
            -
             
     | 
| 
       146 
     | 
    
         
            -
              # uses private Contract class.
         
     | 
| 
       147 
     | 
    
         
            -
              it { OperationWithPrivateContract.(song: {title: "Blue Rondo a la Turk"}).model.title.must_equal "Blue Rondo a la Turk" }
         
     | 
| 
       148 
     | 
    
         
            -
            end
         
     | 
| 
         @@ -1,71 +0,0 @@ 
     | 
|
| 
       1 
     | 
    
         
            -
            require "test_helper"
         
     | 
| 
       2 
     | 
    
         
            -
            require "trailblazer/operation/model/external"
         
     | 
| 
       3 
     | 
    
         
            -
             
     | 
| 
       4 
     | 
    
         
            -
            class ExternalModelTest < MiniTest::Spec
         
     | 
| 
       5 
     | 
    
         
            -
               Song = Struct.new(:title, :id) do
         
     | 
| 
       6 
     | 
    
         
            -
                class << self
         
     | 
| 
       7 
     | 
    
         
            -
                  attr_accessor :find_result # TODO: eventually, replace with AR test.
         
     | 
| 
       8 
     | 
    
         
            -
                  attr_accessor :all_records
         
     | 
| 
       9 
     | 
    
         
            -
             
     | 
| 
       10 
     | 
    
         
            -
                  def find(id)
         
     | 
| 
       11 
     | 
    
         
            -
                    find_result.tap do |song|
         
     | 
| 
       12 
     | 
    
         
            -
                      song.id = id
         
     | 
| 
       13 
     | 
    
         
            -
                    end
         
     | 
| 
       14 
     | 
    
         
            -
                  end
         
     | 
| 
       15 
     | 
    
         
            -
                end
         
     | 
| 
       16 
     | 
    
         
            -
              end # FIXME: use from CrudTest.
         
     | 
| 
       17 
     | 
    
         
            -
             
     | 
| 
       18 
     | 
    
         
            -
             
     | 
| 
       19 
     | 
    
         
            -
             
     | 
| 
       20 
     | 
    
         
            -
             
     | 
| 
       21 
     | 
    
         
            -
              class Bla < Trailblazer::Operation
         
     | 
| 
       22 
     | 
    
         
            -
                include Model::External
         
     | 
| 
       23 
     | 
    
         
            -
                model Song, :update
         
     | 
| 
       24 
     | 
    
         
            -
             
     | 
| 
       25 
     | 
    
         
            -
                def process(params)
         
     | 
| 
       26 
     | 
    
         
            -
                end
         
     | 
| 
       27 
     | 
    
         
            -
              end
         
     | 
| 
       28 
     | 
    
         
            -
             
     | 
| 
       29 
     | 
    
         
            -
              let (:song) { Song.new("Numbers") }
         
     | 
| 
       30 
     | 
    
         
            -
             
     | 
| 
       31 
     | 
    
         
            -
              before do
         
     | 
| 
       32 
     | 
    
         
            -
                Song.find_result = song
         
     | 
| 
       33 
     | 
    
         
            -
              end
         
     | 
| 
       34 
     | 
    
         
            -
             
     | 
| 
       35 
     | 
    
         
            -
              # ::model!
         
     | 
| 
       36 
     | 
    
         
            -
              it do
         
     | 
| 
       37 
     | 
    
         
            -
                Bla.model!(id: 1).must_equal song
         
     | 
| 
       38 
     | 
    
         
            -
                song.id.must_equal 1
         
     | 
| 
       39 
     | 
    
         
            -
              end
         
     | 
| 
       40 
     | 
    
         
            -
             
     | 
| 
       41 
     | 
    
         
            -
              # call style.
         
     | 
| 
       42 
     | 
    
         
            -
              it do
         
     | 
| 
       43 
     | 
    
         
            -
                Bla.(id: 2).model.must_equal song
         
     | 
| 
       44 
     | 
    
         
            -
                song.id.must_equal 2
         
     | 
| 
       45 
     | 
    
         
            -
              end
         
     | 
| 
       46 
     | 
    
         
            -
             
     | 
| 
       47 
     | 
    
         
            -
              # #present.
         
     | 
| 
       48 
     | 
    
         
            -
              it do
         
     | 
| 
       49 
     | 
    
         
            -
                Bla.present({}).model.must_equal song
         
     | 
| 
       50 
     | 
    
         
            -
              end
         
     | 
| 
       51 
     | 
    
         
            -
             
     | 
| 
       52 
     | 
    
         
            -
             
     | 
| 
       53 
     | 
    
         
            -
              class OpWithBuilder < Bla
         
     | 
| 
       54 
     | 
    
         
            -
                class A < self
         
     | 
| 
       55 
     | 
    
         
            -
                end
         
     | 
| 
       56 
     | 
    
         
            -
             
     | 
| 
       57 
     | 
    
         
            -
                builds -> (model, params) do
         
     | 
| 
       58 
     | 
    
         
            -
                  return A if model.id == 1 and params[:user] == 2
         
     | 
| 
       59 
     | 
    
         
            -
                end
         
     | 
| 
       60 
     | 
    
         
            -
              end
         
     | 
| 
       61 
     | 
    
         
            -
             
     | 
| 
       62 
     | 
    
         
            -
              describe "::builds args" do
         
     | 
| 
       63 
     | 
    
         
            -
                it do
         
     | 
| 
       64 
     | 
    
         
            -
                  OpWithBuilder.(id: 1, user: "different").must_be_instance_of OpWithBuilder
         
     | 
| 
       65 
     | 
    
         
            -
                end
         
     | 
| 
       66 
     | 
    
         
            -
             
     | 
| 
       67 
     | 
    
         
            -
                it do
         
     | 
| 
       68 
     | 
    
         
            -
                  OpWithBuilder.(id: 1, user: 2).must_be_instance_of OpWithBuilder::A
         
     | 
| 
       69 
     | 
    
         
            -
                end
         
     | 
| 
       70 
     | 
    
         
            -
              end
         
     | 
| 
       71 
     | 
    
         
            -
            end
         
     |