hecks-application 0.1.16.rc → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: e835d560fad82657aced9156d3b9d73c3089d7a0
4
- data.tar.gz: 77a0909656ab8e840583cf33e312f0f9386ecfd0
3
+ metadata.gz: 5ea1241067264baa88f4ba4e89d1dcaf09fad09e
4
+ data.tar.gz: af63582186c185435e111912570f8eb23a8c6b06
5
5
  SHA512:
6
- metadata.gz: '019ef6624b3e1bbe7eb2c5d3806f258e9497a6219a501caf3604d1b9a3a20373fafabb27c6a5f18bcf91a04cb1f2361e7845ccbf0d45b433a2c630d5bb6358ea'
7
- data.tar.gz: '056639fa7558ec83222497faf09348c433b240e83a26121b170cdaeae42fec9aa0b69588b8db74a1e4acfceec2be9379542282bd7c95fe4287b704c9b5b6ddf4'
6
+ metadata.gz: d8c0a05ecae96f05662a2aad3e7b39b149df2bbbd20f927955a33821122c6e4d79281a854e3849903126afb2310fec9b076c202935360e1f47481163f36894db
7
+ data.tar.gz: fc16e2f199eb5199d7de6c5f9cd3b4b410f045d3d3a2e12b239f094b0e48952149d0da02c00201b1bcc253c7fcb9f8896e9865684bc55d80cde57b3054e4a1b1
@@ -0,0 +1,55 @@
1
+ require 'digest'
2
+
3
+ class HecksApplication
4
+ # Run an application command, with validations and broacast lifecycle events
5
+ class CommandRunner
6
+ attr_reader :module_name, :command
7
+
8
+ def initialize(command_name:, module_name:, args:, application:, async: false)
9
+ @command_name = command_name
10
+ @module_name = module_name
11
+ @args = args
12
+ @application = application
13
+ @domain_spec = application.domain_spec
14
+ @async = async
15
+ end
16
+
17
+ def call()
18
+ fetch_command
19
+ run_command
20
+ broadcast
21
+ command
22
+ end
23
+
24
+ private
25
+
26
+ attr_reader :command_name, :args, :application, :domain_spec, :async
27
+
28
+ def broadcast
29
+ application.events_port.send(command: command, module_name: module_name)
30
+ end
31
+
32
+ def fetch_command
33
+ args.merge!(id: SecureRandom.uuid) if command_name == :create
34
+ @command = Commands.const_get(command_name.to_s.camelcase).new(
35
+ repository: application.database[module_name],
36
+ args: args,
37
+ domain_module: fetch_module
38
+ )
39
+ end
40
+
41
+ def fetch_module
42
+ domain_spec.domain_modules[module_name.to_s.camelize.to_sym]
43
+ end
44
+
45
+ def run_command
46
+ if async
47
+ Thread::new { command.call }
48
+ else
49
+ command.call
50
+ end
51
+
52
+ command
53
+ end
54
+ end
55
+ end
@@ -2,4 +2,3 @@ require_relative 'update'
2
2
  require_relative 'create'
3
3
  require_relative 'delete'
4
4
  require_relative 'crud_handler'
5
- require_relative 'runner'
@@ -1,49 +1,49 @@
1
1
  # frozen_string_literal: true
2
- module Hecks
3
- class Application
4
- module Commands
5
- class Create
6
- attr_accessor :args, :id, :errors, :repository, :domain_module
7
-
8
- def initialize(args:, repository:, domain_module: )
9
- @repository = repository
10
- @args = args
11
- @errors = {}
12
- @validator = Hecks::Adapters::Validator
13
- @domain_module = domain_module
14
- end
15
-
16
- def call
17
- validate
18
- create
19
- self
20
- end
21
-
22
- def to_h
23
- { errors: errors, id: repository_result, args: args }
24
- end
25
-
26
- def name
27
- self.class.to_s.split('::').last.underscore
28
- end
29
-
30
- def result
31
- { id: id, success: !id.nil?, errors: errors, args: args }
32
- end
33
-
34
- private
35
-
36
- attr_reader :repository_result
37
-
38
- def create
39
- return if @errors.count.positive?
40
- @id = @repository_result = repository.create(args).id
41
- end
42
-
43
- def validate
44
- return if @validator.nil?
45
- @errors = @validator.new(command: self).call.errors
46
- end
2
+ class HecksApplication
3
+ module Commands
4
+ # Create a resource
5
+ class Create
6
+ attr_accessor :args, :result, :errors, :repository, :domain_module, :id
7
+
8
+ def initialize(args:, repository:, domain_module:, validator: HecksApplication::Validator)
9
+ @repository = repository
10
+ @args = args
11
+ @errors = {}
12
+ @validator = validator
13
+ @domain_module = domain_module
14
+ end
15
+
16
+ def call
17
+ validate
18
+ create
19
+ self
20
+ end
21
+
22
+ def to_h
23
+ { errors: errors, id: repository_result, args: args }
24
+ end
25
+
26
+ def name
27
+ self.class.to_s.split('::').last.underscore
28
+ end
29
+
30
+ def result
31
+ { id: id, success: !id.nil?, errors: errors, args: args }
32
+ end
33
+
34
+ private
35
+
36
+ attr_reader :repository_result
37
+
38
+ def create
39
+ return if @errors.count.positive?
40
+ @id = args[:id]
41
+ repository.create(args)
42
+ end
43
+
44
+ def validate
45
+ return if @validator.nil?
46
+ @errors = @validator.new(command: self).call.errors
47
47
  end
48
48
  end
49
49
  end
@@ -1,45 +1,45 @@
1
- module Hecks
2
- class Application
3
- module Commands
4
- class CRUDHandler
5
- attr_reader :module_name, :application
1
+ class HecksApplication
2
+ module Commands
3
+ # Map resourceful methods to the domain
4
+ class CRUDHandler
5
+ attr_reader :module_name, :application, :validator
6
6
 
7
- def initialize(module_name:, application:)
8
- @module_name = module_name
9
- @application = application
10
- end
7
+ def initialize(module_name:, application:, validator:)
8
+ @module_name = module_name
9
+ @application = application
10
+ @validator = validator
11
+ end
11
12
 
12
- def create(attributes)
13
- application.call(
14
- module_name: module_name,
15
- command_name: :create,
16
- args: attributes
17
- )
18
- end
13
+ def create(args)
14
+ application.call(
15
+ module_name: module_name,
16
+ command_name: :create,
17
+ args: args
18
+ )
19
+ end
19
20
 
20
- def read(id)
21
- application.query(
22
- module_name: module_name,
23
- query_name: :find_by_id,
24
- args: { id: id }
25
- )
26
- end
21
+ def read(id)
22
+ application.query(
23
+ module_name: module_name,
24
+ query_name: :find_by_id,
25
+ args: { id: id }
26
+ )
27
+ end
27
28
 
28
- def update(id, attributes)
29
- application.call(
30
- module_name: module_name,
31
- command_name: :update,
32
- args: attributes.merge(id: id)
33
- )
34
- end
29
+ def update(attributes)
30
+ application.call(
31
+ module_name: module_name,
32
+ command_name: :update,
33
+ args: attributes
34
+ )
35
+ end
35
36
 
36
- def delete(id)
37
- application.call(
38
- module_name: module_name,
39
- command_name: :delete,
40
- args: { id: id }
41
- )
42
- end
37
+ def delete(id)
38
+ application.call(
39
+ module_name: module_name,
40
+ command_name: :delete,
41
+ args: { id: id }
42
+ )
43
43
  end
44
44
  end
45
45
  end
@@ -1,37 +1,40 @@
1
1
  # frozen_string_literal: true
2
- module Hecks
3
- class Application
4
- module Commands
5
- class Delete
6
- attr_accessor :args, :errors, :repository
7
-
8
- def initialize(args: nil, repository:, domain_module:)
9
- @args = args || chained_command.args
10
- @repository = repository
11
- @errors = { base: [] }
12
- end
13
-
14
- def call
15
- delete
16
- self
17
- end
18
-
19
- def name
20
- self.class.to_s.split('::').last.underscore
21
- end
22
-
23
- def to_h
24
- { errors: errors, args: args }
25
- end
26
-
27
- private
28
-
29
- attr_accessor :command_result, :repository
30
-
31
- def delete
32
- @result = repository.delete(args[:id])
33
- @errors[:base] << "cound not find #{args[:id]}" unless @result
34
- end
2
+ class HecksApplication
3
+ module Commands
4
+ # Delete a resource.
5
+ class Delete
6
+ attr_accessor :args, :errors, :repository
7
+
8
+ def initialize(args: nil, repository:, domain_module:)
9
+ @args = args || chained_command.args
10
+ @repository = repository
11
+ @errors = { base: [] }
12
+ end
13
+
14
+ def call
15
+ delete
16
+ self
17
+ end
18
+
19
+ def name
20
+ self.class.to_s.split('::').last.underscore
21
+ end
22
+
23
+ def to_h
24
+ { errors: errors, args: args }
25
+ end
26
+
27
+ def result
28
+ { id: args[:id], errors: errors, args: args }
29
+ end
30
+
31
+ private
32
+
33
+ attr_accessor :command_result, :repository
34
+
35
+ def delete
36
+ @result = repository.delete(args[:id])
37
+ @errors[:base] << "cound not find #{args[:id]}" unless @result
35
38
  end
36
39
  end
37
40
  end
@@ -1,38 +1,41 @@
1
1
  # frozen_string_literal: true
2
- module Hecks
3
- class Application
4
- module Commands
5
- class Update
6
- attr_accessor :args, :errors, :id, :repository
7
-
8
- def initialize(args: nil, repository: Repository, domain_module:)
9
- @repository = repository
10
- @args = args
11
- @errors = []
12
- @id = @args.delete(:id)
13
- end
14
-
15
- def name
16
- self.class.to_s.split('::').last.underscore
17
- end
18
-
19
- def call
20
- update
21
- self
22
- end
23
-
24
- def to_h
25
- { id: id, args: args }
26
- end
27
-
28
- private
29
-
30
- attr_reader :repository_result
31
-
32
- def update
33
- return if @errors.count.positive?
34
- @repository_result = repository.update(id, args)
35
- end
2
+ class HecksApplication
3
+ module Commands
4
+ # Update a resource
5
+ class Update
6
+ attr_accessor :args, :repository
7
+
8
+ def initialize(args: nil, repository: Repository, domain_module:)
9
+ @repository = repository
10
+ @args = args
11
+ @errors = []
12
+ @id = @args.delete(:id)
13
+ end
14
+
15
+ def name
16
+ self.class.to_s.split('::').last.underscore
17
+ end
18
+
19
+ def call
20
+ update
21
+ self
22
+ end
23
+
24
+ def result
25
+ { success: errors.empty?, errors: errors, args: args }
26
+ end
27
+
28
+ def to_h
29
+ { id: id, args: args }
30
+ end
31
+
32
+ private
33
+
34
+ attr_reader :repository_result, :id, :errors
35
+
36
+ def update
37
+ return if @errors.count.positive?
38
+ @repository_result = repository.update(id, args)
36
39
  end
37
40
  end
38
41
  end
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Send lifecycle events to listeners
4
+ class HecksEvents
5
+ def initialize(listeners: [])
6
+ @listeners = listeners
7
+ end
8
+
9
+ def send(module_name:, command:)
10
+ @command = command
11
+ @module_name = module_name
12
+ listeners.each do |listener|
13
+ next unless listener.respond_to?(event_name)
14
+ listener.public_send(event_name, command)
15
+ end
16
+ end
17
+
18
+ private
19
+
20
+ attr_reader :listeners, :command, :module_name
21
+
22
+ def event_name
23
+ "#{module_name}_#{command.name}".to_sym
24
+ end
25
+ end
@@ -1,49 +1,57 @@
1
1
  # frozen_string_literal: true
2
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
3
+
4
+ require 'hecks-memory-database'
5
+ require 'hecks-domain'
6
+
2
7
  require_relative 'commands/commands'
8
+ require_relative 'command_runner'
3
9
  require_relative 'queries/queries'
4
- require 'hecks-domain'
10
+ require_relative 'events'
11
+ require_relative 'logger'
12
+ require_relative 'validator'
5
13
 
6
- module Hecks
7
- def self.version
8
- path = "#{File.dirname(__FILE__)}/Version"
9
- File.read(path).gsub("\n", '')
14
+ # The Applicaiton port. Adapters usually talk to the domain through
15
+ # HecksApplication
16
+ class HecksApplication
17
+ attr_reader :database, :domain_spec, :events_port, :validator
18
+ def initialize(database: nil, listeners: [], domain:, validator: HecksApplication::Validator)
19
+ load(domain.spec_path)
20
+ @domain = domain
21
+ @database = database
22
+ @events_port = HecksEvents.new(listeners: listeners)
23
+ @domain_spec = DOMAIN
24
+ @validator = validator
10
25
  end
11
26
 
12
- class Application
13
- attr_reader :database, :domain_spec, :events_port
14
- def initialize(database: nil, listeners: [], domain:)
15
- load(domain.spec_path)
16
- @domain = domain
17
- @database = database
18
- @events_port = Adapters::Events.new(listeners: listeners)
19
- @domain_spec = DOMAIN
20
- end
21
-
22
- def call(command_name:, module_name:, args: {})
23
- Runner.new(
24
- command_name: command_name,
25
- module_name: module_name,
26
- args: args,
27
- application: self
28
- ).call
29
- end
27
+ def call(command_name:, module_name:, args: {})
28
+ CommandRunner.new(
29
+ command_name: command_name,
30
+ module_name: module_name,
31
+ args: args,
32
+ application: self
33
+ ).call
34
+ end
30
35
 
31
- def [](module_name)
32
- Commands::CRUDHandler.new(module_name: module_name, application: self)
33
- end
36
+ def [](module_name)
37
+ Commands::CRUDHandler.new(
38
+ module_name: module_name,
39
+ application: self,
40
+ validator: validator
41
+ )
42
+ end
34
43
 
35
- def query(query_name:, module_name:, args: {})
36
- QueryRunner.new(
37
- module_name: module_name,
38
- query_name: query_name,
39
- args: args,
40
- application: self
41
- ).call
42
- end
44
+ def query(query_name:, module_name:, args: {})
45
+ QueryRunner.new(
46
+ module_name: module_name,
47
+ query_name: query_name,
48
+ args: args,
49
+ application: self
50
+ ).call
51
+ end
43
52
 
44
- def database
45
- return @database.new(domain: @domain) if @database
46
- return Hecks::Adapters::MemoryDatabase.new(domain: @domain)
47
- end
53
+ def database
54
+ return @database.new(domain: @domain) if @database
55
+ return HecksAdapters::MemoryDatabase.new(domain: @domain)
48
56
  end
49
57
  end
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Simple logger
4
+ class HecksLogger
5
+ def initialize(output: [])
6
+ @output = output
7
+ end
8
+
9
+ def method_missing(name, *args, &block)
10
+ @output << {name: name, command: args.first.to_h.to_s}.to_s
11
+ end
12
+
13
+ def respond_to?(name)
14
+ true
15
+ end
16
+ end
@@ -1,16 +1,15 @@
1
1
  # frozen_string_literal: true
2
- module Hecks
3
- class Application
4
- module Queries
5
- class FindById
6
- def initialize(repository:)
7
- @repository = repository
8
- end
2
+ class HecksApplication
3
+ module Queries
4
+ # Find a resource by id
5
+ class FindById
6
+ def initialize(repository:)
7
+ @repository = repository
8
+ end
9
9
 
10
- def call(params)
11
- return unless params.keys == [:id]
12
- @repository.read(params[:id])
13
- end
10
+ def call(params)
11
+ return unless params.keys == [:id]
12
+ @repository.read(params[:id])
14
13
  end
15
14
  end
16
15
  end
@@ -1,26 +1,26 @@
1
- module Hecks
2
- class Application
3
- class QueryRunner
4
- def initialize(query_name:, application:, module_name:, args:)
5
- @query_name = query_name
6
- @application = application
7
- @module_name = module_name
8
- @args = args
9
- end
1
+ class HecksApplication
10
2
 
11
- def call()
12
- fetch.new(repository: repository).call(@args)
13
- end
3
+ # Call queries by name
4
+ class QueryRunner
5
+ def initialize(query_name:, application:, module_name:, args:)
6
+ @query_name = query_name
7
+ @application = application
8
+ @module_name = module_name
9
+ @args = args
10
+ end
11
+
12
+ def call()
13
+ fetch.new(repository: repository).call(@args)
14
+ end
14
15
 
15
- private
16
+ private
16
17
 
17
- def fetch
18
- Queries.const_get(@query_name.to_s.camelcase)
19
- end
18
+ def fetch
19
+ Queries.const_get(@query_name.to_s.camelcase)
20
+ end
20
21
 
21
- def repository
22
- @application.database[@module_name]
23
- end
22
+ def repository
23
+ @application.database[@module_name]
24
24
  end
25
25
  end
26
26
  end
@@ -0,0 +1,32 @@
1
+ class HecksApplication
2
+ # Looks for the presence of required fields.
3
+ class Validator
4
+ attr_reader :errors
5
+
6
+ def initialize(command:)
7
+ @args = command.args
8
+ @head_spec = command.domain_module.head
9
+ @errors = {}
10
+ end
11
+
12
+ def call
13
+ validate
14
+ return self
15
+ end
16
+
17
+ private
18
+
19
+ attr_reader :args, :head_spec
20
+
21
+ def validate
22
+ (missing_attributes).each do |missing_attribute|
23
+ errors[missing_attribute] = []
24
+ errors[missing_attribute] << "missing"
25
+ end
26
+ end
27
+
28
+ def missing_attributes
29
+ head_spec.attribute_hash.keys - args.keys
30
+ end
31
+ end
32
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: hecks-application
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.16.rc
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Chris Young
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-03-15 00:00:00.000000000 Z
11
+ date: 2017-12-01 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: hecks-domain
@@ -16,31 +16,47 @@ dependencies:
16
16
  requirements:
17
17
  - - '='
18
18
  - !ruby/object:Gem::Version
19
- version: 0.1.16.rc
19
+ version: 0.2.0
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - '='
25
25
  - !ruby/object:Gem::Version
26
- version: 0.1.16.rc
26
+ version: 0.2.0
27
+ - !ruby/object:Gem::Dependency
28
+ name: hecks-memory-database
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - '='
32
+ - !ruby/object:Gem::Version
33
+ version: 0.2.0
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - '='
39
+ - !ruby/object:Gem::Version
40
+ version: 0.2.0
27
41
  description: Hecks Application
28
42
  email: chris@example.com
29
43
  executables: []
30
44
  extensions: []
31
45
  extra_rdoc_files: []
32
46
  files:
33
- - lib/Version
47
+ - lib/command_runner.rb
34
48
  - lib/commands/commands.rb
35
49
  - lib/commands/create.rb
36
50
  - lib/commands/crud_handler.rb
37
51
  - lib/commands/delete.rb
38
- - lib/commands/runner.rb
39
52
  - lib/commands/update.rb
53
+ - lib/events.rb
40
54
  - lib/hecks-application.rb
55
+ - lib/logger.rb
41
56
  - lib/queries/find_by_id.rb
42
57
  - lib/queries/queries.rb
43
58
  - lib/queries/query_runner.rb
59
+ - lib/validator.rb
44
60
  homepage: https://github.com/chrisyoung/hecks-application
45
61
  licenses:
46
62
  - MIT
@@ -56,14 +72,13 @@ required_ruby_version: !ruby/object:Gem::Requirement
56
72
  version: '0'
57
73
  required_rubygems_version: !ruby/object:Gem::Requirement
58
74
  requirements:
59
- - - ">"
75
+ - - ">="
60
76
  - !ruby/object:Gem::Version
61
- version: 1.3.1
77
+ version: '0'
62
78
  requirements: []
63
79
  rubyforge_project:
64
80
  rubygems_version: 2.6.10
65
81
  signing_key:
66
82
  specification_version: 4
67
- summary: Hecks::Application understands things and acts as an interface to Domains
68
- built with Hecks::Domain
83
+ summary: HecksApplication acts as an interface to Domains built with HecksDomain
69
84
  test_files: []
@@ -1 +0,0 @@
1
- 0.1.16.rc
@@ -1,46 +0,0 @@
1
- module Hecks
2
- class Application
3
- class Runner
4
- attr_reader :module_name, :command
5
-
6
- def initialize(command_name:, module_name:, args:, application:)
7
- @command_name = command_name
8
- @module_name = module_name
9
- @args = args
10
- @application = application
11
- @domain_spec = application.domain_spec
12
- end
13
-
14
- def call()
15
- fetch_command
16
- run_command
17
- broadcast
18
- command
19
- end
20
-
21
- private
22
-
23
- attr_reader :command_name, :args, :application, :domain_spec
24
-
25
- def broadcast
26
- application.events_port.send(command: command, module_name: module_name)
27
- end
28
-
29
- def fetch_command
30
- @command = Commands.const_get(command_name.to_s.camelcase).new(
31
- repository: application.database[module_name],
32
- args: args,
33
- domain_module: fetch_module
34
- )
35
- end
36
-
37
- def fetch_module
38
- domain_spec.domain_modules[module_name.to_s.camelize.to_sym]
39
- end
40
-
41
- def run_command
42
- @command = command.call
43
- end
44
- end
45
- end
46
- end