pavlov 0.1.2 → 0.1.3

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: f2b9bba30f2268ca3a5856559682efa6e6e2c98a
4
- data.tar.gz: f8f72d801376e12afb4594c339fa77f787089729
3
+ metadata.gz: 8366cdc29ed0e3cf7c91b3d2d106b4cac9df808f
4
+ data.tar.gz: 882f35ce53f6c187d7d67293db6b70a8589554f8
5
5
  SHA512:
6
- metadata.gz: 758db67e6925e9810c81ab0745d5741158152c3f5e1b573c6fc9859b457fc750552557f5da539eb55f1e89f5e56b8701917d1822ae95164fac23f71491044e36
7
- data.tar.gz: 43662dcef18148abb292bc2aeb6767ede94cf8664e41254eb08c44ad0cc2dab955f0cb44fab9d1676fb93294aa701717d6ce63a0e56f5dcd59bfda090b89f239
6
+ metadata.gz: 543829b42a71cf377f77bad528bf06cbf2cefc1ff6c534d863a54d036493e77e9a4efd797894b7b91ede168a2093ab7a2576ccdc8dbbb6bf6bad6661613a2117
7
+ data.tar.gz: fe236450becb09aee747e8c0571b6563323f78a36fe54b74dda601c17ff34b07ff283a006be2b1222dfe7836d2520983679b38e87cb1995360efcbad7d8a1eca
@@ -0,0 +1,17 @@
1
+ require 'rails/generators'
2
+
3
+ module Pavlov
4
+ class InstallGenerator < Rails::Generators::Base
5
+ def self.source_root
6
+ @source_root ||= File.expand_path(File.join(File.dirname(__FILE__), 'templates'))
7
+ end
8
+
9
+ def copy_backend_directory
10
+ directory 'backend', 'app/backend', recursive: true
11
+ end
12
+
13
+ def add_backend_to_autoload_paths
14
+ application "config.autoload_paths += %W(\#{config.root}/app/backend)"
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,3 @@
1
+ class Backend
2
+ # This class is a placeholder that will be expanded by a later feature branch
3
+ end
@@ -0,0 +1,3 @@
1
+ class Command
2
+ include Pavlov::Operation
3
+ end
@@ -0,0 +1,16 @@
1
+ class Interactor
2
+ include Pavlov::Operation
3
+
4
+ # If you want your interactors to be compatible with a backgrounding
5
+ # daemon, you can use this base class to add support.
6
+ #
7
+ # Example for Resque:
8
+ #
9
+ # def self.perform(*args)
10
+ # new(*args).call
11
+ # end
12
+
13
+ def authorized?
14
+ raise NotImplementedError
15
+ end
16
+ end
@@ -0,0 +1,3 @@
1
+ class Query
2
+ include Pavlov::Operation
3
+ end
@@ -28,6 +28,7 @@ module Pavlov
28
28
  end
29
29
  end
30
30
 
31
+ require_relative 'pavlov/engine' if defined?(Rails)
31
32
  require_relative 'pavlov/helpers'
32
33
  require_relative 'pavlov/access_denied'
33
34
  require_relative 'pavlov/validation_error'
@@ -1,39 +1,78 @@
1
1
  require 'pavlov'
2
2
 
3
3
  module Pavlov
4
- module Operation
5
- def pavlov_options
6
- @options
7
- end
8
- def pavlov_options=(options)
9
- @options = options
10
- end
4
+ def self.old_command command_name, *args
5
+ class_name = "Commands::"+string_to_classname(command_name)
6
+ klass = get_class_by_string(class_name)
7
+ attributes = arguments_to_attributes(klass, args)
8
+ klass.new(attributes).call
11
9
  end
12
10
 
13
- def self.old_command *arguments
14
- command *arguments
11
+ def self.old_interactor command_name, *args
12
+ class_name = "Interactors::"+string_to_classname(command_name)
13
+ klass = get_class_by_string class_name
14
+ attributes = arguments_to_attributes(klass, args)
15
+ klass.new(attributes).call
15
16
  end
16
- def self.old_query *arguments
17
- query *arguments
17
+
18
+ def self.old_query command_name, *args
19
+ class_name = "Queries::"+string_to_classname(command_name)
20
+ klass = get_class_by_string class_name
21
+ attributes = arguments_to_attributes(klass, args)
22
+ klass.new(attributes).call
18
23
  end
19
- def self.old_interactor *arguments
20
- interactor *arguments
24
+
25
+ def self.arguments_to_attributes(operation_class, arguments)
26
+ attribute_keys = operation_class.attribute_set.map(&:name)
27
+
28
+ # TODO: this can be done so much better, but I don't know how.
29
+ hash={}
30
+ arguments.each_with_index do |value, index|
31
+ hash[attribute_keys[index].to_sym] = value
32
+ end
33
+ return hash
21
34
  end
22
35
 
23
36
  module Helpers
24
37
  def old_interactor name, *args
25
- args = add_pavlov_options args
38
+ args = add_compatibility_pavlov_options args
26
39
  Pavlov.old_interactor name, *args
27
40
  end
28
41
 
29
42
  def old_query name, *args
30
- args = add_pavlov_options args
43
+ args = add_compatibility_pavlov_options args
31
44
  Pavlov.old_query name, *args
32
45
  end
33
46
 
34
47
  def old_command name, *args
35
- args = add_pavlov_options args
48
+ args = add_compatibility_pavlov_options args
36
49
  Pavlov.old_command name, *args
37
50
  end
51
+
52
+ private
53
+ def add_compatibility_pavlov_options args
54
+ # TODO: we should do this at a point where we know how many arguments we need
55
+ # so we can decide if we need to merge with another options object or
56
+ # just add it.
57
+ new_args = Array(args)
58
+ if pavlov_options != {}
59
+ new_args << pavlov_options
60
+ end
61
+ new_args
62
+ end
63
+ end
64
+
65
+ module Operation
66
+ module ClassMethods
67
+ def arguments(*args)
68
+ # Add generic attribute for each argument
69
+ args.each do |argument|
70
+ attribute argument, Object
71
+ end
72
+
73
+ # Add attribute for pavlov_options
74
+ attribute :pavlov_options, Hash, default: {}
75
+ end
76
+ end
38
77
  end
39
78
  end
@@ -0,0 +1,6 @@
1
+ require 'rails'
2
+
3
+ module Pavlov
4
+ class Engine < Rails::Engine
5
+ end
6
+ end
@@ -1,18 +1,18 @@
1
1
  module Pavlov
2
2
  module Helpers
3
- def interactor name, *args
4
- args = add_pavlov_options args
5
- Pavlov.interactor name, *args
3
+ def interactor name, hash
4
+ hash = add_pavlov_options hash
5
+ Pavlov.interactor name, hash
6
6
  end
7
7
 
8
- def query name, *args
9
- args = add_pavlov_options args
10
- Pavlov.query name, *args
8
+ def query name, hash
9
+ hash = add_pavlov_options hash
10
+ Pavlov.query name, hash
11
11
  end
12
12
 
13
- def command name, *args
14
- args = add_pavlov_options args
15
- Pavlov.command name, *args
13
+ def command name, hash
14
+ hash = add_pavlov_options hash
15
+ Pavlov.command name, hash
16
16
  end
17
17
 
18
18
  def pavlov_options
@@ -20,14 +20,17 @@ module Pavlov
20
20
  end
21
21
 
22
22
  private
23
- def add_pavlov_options args
24
- # TODO: we should do this at a point where we know how many arguments we need
25
- # so we can decide if we need to merge with another options object or
26
- # just add it.
23
+ def add_pavlov_options hash
27
24
  if pavlov_options != {}
28
- args << pavlov_options
25
+ hash ||= {}
26
+
27
+ if hash.has_key? 'pavlov_options'
28
+ hash[:pavlov_options] = pavlov_options.merge(hash[:pavlov_options])
29
+ else
30
+ hash[:pavlov_options] = pavlov_options
31
+ end
29
32
  end
30
- args
33
+ hash
31
34
  end
32
35
  end
33
36
  end
@@ -1,6 +1,7 @@
1
1
  require 'active_support/concern'
2
2
  require 'pavlov/validations'
3
3
  require 'pavlov/helpers'
4
+ require 'virtus'
4
5
  require_relative 'access_denied'
5
6
 
6
7
  module Pavlov
@@ -8,58 +9,25 @@ module Pavlov
8
9
  extend ActiveSupport::Concern
9
10
  include Pavlov::Helpers
10
11
  include Pavlov::Validations
11
-
12
- def initialize(*params)
13
- keys, names, @options = extract_arguments(params)
14
- set_instance_variables keys, names
15
- validate
16
-
17
- check_authorization
18
-
19
- finish_initialize if respond_to? :finish_initialize
20
- end
12
+ include Virtus
21
13
 
22
14
  def validate
15
+ return false unless attributes_without_defaults_have_values
23
16
  if respond_to? :valid?
24
- valid?
17
+ raise Pavlov::ValidationError, "an argument is invalid" unless valid?
25
18
  else
26
19
  true
27
20
  end
28
21
  end
29
22
 
30
23
  def call(*args, &block)
24
+ validate
25
+ check_authorization
31
26
  execute(*args, &block)
32
27
  end
33
28
 
34
29
  private
35
30
 
36
- def pavlov_options
37
- @options
38
- end
39
-
40
- def extract_arguments(params)
41
- keys = (respond_to? :arguments) ? arguments : []
42
- names = params.first(keys.length)
43
-
44
- if params.length == keys.length + 1
45
- options = params.last
46
- elsif params.length == keys.length
47
- options = {}
48
- else
49
- raise "wrong number of arguments."
50
- end
51
-
52
- [keys, names, options]
53
- end
54
-
55
- def set_instance_variables(keys, names)
56
- (keys.zip names).each do |pair|
57
- name = "@" + pair[0].to_s
58
- value = pair[1]
59
- instance_variable_set(name, value)
60
- end
61
- end
62
-
63
31
  def raise_unauthorized(message='Unauthorized')
64
32
  raise Pavlov::AccessDenied, message
65
33
  end
@@ -68,25 +36,14 @@ module Pavlov
68
36
  raise_unauthorized if respond_to? :authorized?, true and not authorized?
69
37
  end
70
38
 
71
- module ClassMethods
72
- # arguments :foo, :bar
73
- #
74
- # results in
75
- #
76
- # def initialize(foo, bar)
77
- # @foo = foo
78
- # @bar = bar
79
- # end
80
- def arguments *keys
81
- define_method :arguments do
82
- keys
83
- end
84
-
85
- class_eval do
86
- attr_reader(*keys)
87
- end
39
+ def attributes_without_defaults_have_values
40
+ attributes_without_value = attribute_set.select do |attribute|
41
+ not attribute.options.has_key?(:default) and send(attribute.name).nil?
88
42
  end
43
+ attributes_without_value.empty?
44
+ end
89
45
 
46
+ module ClassMethods
90
47
  # make our interactors behave as Resque jobs
91
48
  def perform(*args)
92
49
  new(*args).call
@@ -1,3 +1,5 @@
1
+ require 'pavlov/validation_error'
2
+
1
3
  module Pavlov
2
4
  module Validations
3
5
  def validate_hexadecimal_string param_name, param
@@ -2,5 +2,5 @@ module Pavlov
2
2
  # We're doing this because we might write tests that deal
3
3
  # with other versions of bundler and we are unsure how to
4
4
  # handle this better.
5
- VERSION = "0.1.2"
5
+ VERSION = "0.1.3"
6
6
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pavlov
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.2
4
+ version: 0.1.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - marten@veldthuis.com
@@ -43,20 +43,34 @@ dependencies:
43
43
  - - '>='
44
44
  - !ruby/object:Gem::Version
45
45
  version: 3.2.7
46
+ - !ruby/object:Gem::Dependency
47
+ name: virtus
48
+ requirement: !ruby/object:Gem::Requirement
49
+ requirements:
50
+ - - '='
51
+ - !ruby/object:Gem::Version
52
+ version: 0.5.5
53
+ type: :runtime
54
+ prerelease: false
55
+ version_requirements: !ruby/object:Gem::Requirement
56
+ requirements:
57
+ - - '='
58
+ - !ruby/object:Gem::Version
59
+ version: 0.5.5
46
60
  - !ruby/object:Gem::Dependency
47
61
  name: rspec
48
62
  requirement: !ruby/object:Gem::Requirement
49
63
  requirements:
50
- - - '>='
64
+ - - ~>
51
65
  - !ruby/object:Gem::Version
52
- version: '0'
66
+ version: 2.14.0
53
67
  type: :development
54
68
  prerelease: false
55
69
  version_requirements: !ruby/object:Gem::Requirement
56
70
  requirements:
57
- - - '>='
71
+ - - ~>
58
72
  - !ruby/object:Gem::Version
59
- version: '0'
73
+ version: 2.14.0
60
74
  - !ruby/object:Gem::Dependency
61
75
  name: guard
62
76
  requirement: !ruby/object:Gem::Requirement
@@ -176,10 +190,16 @@ executables: []
176
190
  extensions: []
177
191
  extra_rdoc_files: []
178
192
  files:
193
+ - lib/generators/pavlov/install_generator.rb
194
+ - lib/generators/pavlov/templates/backend/backend.rb
195
+ - lib/generators/pavlov/templates/backend/command.rb
196
+ - lib/generators/pavlov/templates/backend/interactor.rb
197
+ - lib/generators/pavlov/templates/backend/query.rb
179
198
  - lib/pavlov.rb
180
199
  - lib/pavlov/access_denied.rb
181
200
  - lib/pavlov/alpha_compatibility.rb
182
201
  - lib/pavlov/command.rb
202
+ - lib/pavlov/engine.rb
183
203
  - lib/pavlov/helpers.rb
184
204
  - lib/pavlov/interactor.rb
185
205
  - lib/pavlov/operation.rb