kamerling 0.0.1 → 0.0.2

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 (40) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +4 -30
  3. data/Gemfile +1 -0
  4. data/Gemfile.lock +48 -16
  5. data/config/reek.yml +0 -4
  6. data/kamerling.gemspec +4 -3
  7. data/lib/kamerling.rb +2 -2
  8. data/lib/kamerling/addr.rb +4 -0
  9. data/lib/kamerling/client.rb +13 -1
  10. data/lib/kamerling/core_extensions/main.rb +2 -2
  11. data/lib/kamerling/handler.rb +13 -8
  12. data/lib/kamerling/logging.rb +22 -10
  13. data/lib/kamerling/message.rb +4 -4
  14. data/lib/kamerling/migrations/1_basic_schema.rb +3 -3
  15. data/lib/kamerling/net_dispatcher.rb +3 -1
  16. data/lib/kamerling/project.rb +2 -1
  17. data/lib/kamerling/registration.rb +11 -1
  18. data/lib/kamerling/repo.rb +1 -1
  19. data/lib/kamerling/result.rb +12 -1
  20. data/lib/kamerling/server_runner.rb +13 -15
  21. data/lib/kamerling/task.rb +8 -1
  22. data/lib/kamerling/task_dispatcher.rb +2 -2
  23. data/lib/kamerling/uuid_entity.rb +15 -0
  24. data/spec/kamerling/addr_spec.rb +6 -0
  25. data/spec/kamerling/handler_spec.rb +19 -8
  26. data/spec/kamerling/logging_spec.rb +9 -2
  27. data/spec/kamerling/message_spec.rb +2 -2
  28. data/spec/kamerling/net_dispatcher_spec.rb +2 -2
  29. data/spec/kamerling/receiver_spec.rb +6 -5
  30. data/spec/kamerling/registrar_spec.rb +9 -5
  31. data/spec/kamerling/repo_spec.rb +3 -3
  32. data/spec/kamerling/server/tcp_spec.rb +1 -1
  33. data/spec/kamerling/server/udp_spec.rb +1 -1
  34. data/spec/kamerling/server_runner_spec.rb +4 -4
  35. data/spec/kamerling/task_dispatcher_spec.rb +3 -3
  36. data/spec/kamerling/uuid_entity_spec.rb +35 -0
  37. data/spec/spec_helper.rb +9 -7
  38. metadata +24 -9
  39. data/lib/kamerling/uuid_object.rb +0 -79
  40. data/spec/kamerling/uuid_object_spec.rb +0 -101
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: e5fc62bb2935ad87b89aab902c23a18f7ca22ec6
4
- data.tar.gz: 130ab735ffaca0ea074199318838895de984db52
3
+ metadata.gz: 9be4e3ac2863218c3d390f4afb2e80f8da0c93be
4
+ data.tar.gz: 98c18518041d91d383daa9c79c5bd46999de4b75
5
5
  SHA512:
6
- metadata.gz: 95ce8867168f59361bbe8d3f6b711f65b8a2de44fe3aa8bb9d0d61dcdfc509c30a166d0a07881733b00c34bdfd9365de49f9c443dfead6fb057bcd994e1157f5
7
- data.tar.gz: 37b7debbd247514aa960526b2a28fda463d9eaf0992037d40484326a24b5674278e63fce7d5e8b2ed4ac0d3d029a41d70b838a9e207d93377284e09b03848a95
6
+ metadata.gz: e1b0aeb3ea6a079fd8999f326e6800edcc9f6b56ad1ab0ed997fbf71223e571ae44a7e8c02dc0f5d7d11c65e4dc98b0eae55be57e532bfd90a8d9e61030a56b6
7
+ data.tar.gz: ffe10141b36930b5bf9b4b904312ca96e62e652b51b35f1fceab122fabd7a77258cd9a137936ce6af9c48fefc5968784f189c619cb3685c53091fea66fabcde0
data/.rubocop.yml CHANGED
@@ -1,27 +1,9 @@
1
1
  AccessModifierIndentation:
2
2
  Enabled: false
3
3
 
4
- AlignArray:
5
- Enabled: false
6
-
7
- AlignHash:
8
- Enabled: false
9
-
10
- AlignParameters:
11
- Enabled: false
12
-
13
4
  AndOr:
14
5
  Enabled: false
15
6
 
16
- CaseEquality:
17
- Enabled: false
18
-
19
- ConstantName:
20
- Enabled: false
21
-
22
- CyclomaticComplexity:
23
- Enabled: false
24
-
25
7
  Documentation:
26
8
  Enabled: false
27
9
 
@@ -29,22 +11,14 @@ EndAlignment:
29
11
  Enabled: false
30
12
 
31
13
  HandleExceptions:
32
- Enabled: false
14
+ Exclude:
15
+ - lib/kamerling/server/sock.rb
33
16
 
34
17
  IndentationWidth:
35
18
  Enabled: false
36
19
 
37
20
  MethodDefParentheses:
38
- Enabled: false
39
-
40
- MethodName:
41
- Enabled: false
42
-
43
- SignalException:
44
- Enabled: false
45
-
46
- SpaceAroundOperators:
47
- Enabled: false
21
+ EnforcedStyle: require_no_parentheses
48
22
 
49
23
  TrailingComma:
50
- Enabled: false
24
+ EnforcedStyleForMultiline: comma
data/Gemfile CHANGED
@@ -1,2 +1,3 @@
1
1
  source 'https://rubygems.org'
2
2
  gemspec
3
+ gem 'virtus', github: 'solnic/virtus'
data/Gemfile.lock CHANGED
@@ -1,34 +1,62 @@
1
+ GIT
2
+ remote: git://github.com/solnic/virtus.git
3
+ revision: c31940a63d1a4a2ac30032a0c01a9a217b5f5f82
4
+ specs:
5
+ virtus (1.0.2)
6
+ axiom-types (~> 0.1)
7
+ coercible (~> 1.0)
8
+ descendants_tracker (~> 0.0.3)
9
+ equalizer (~> 0.0.9)
10
+
1
11
  PATH
2
12
  remote: .
3
13
  specs:
4
- kamerling (0.0.1)
14
+ kamerling (0.0.2)
5
15
  after_do (~> 0.3.0)
6
16
  sequel (~> 4.4)
7
17
  sinatra (~> 1.4)
8
18
  slim (~> 2.0)
9
19
  sqlite3 (~> 1.3)
20
+ virtus (~> 1.0)
10
21
 
11
22
  GEM
12
23
  remote: https://rubygems.org/
13
24
  specs:
14
25
  after_do (0.3.0)
15
26
  ast (1.1.0)
27
+ atomic (1.1.16)
28
+ axiom-types (0.1.0)
29
+ descendants_tracker (~> 0.0.3)
30
+ ice_nine (~> 0.11.0)
31
+ thread_safe (~> 0.1.3)
16
32
  bogus (0.1.4)
17
33
  dependor (>= 0.0.4)
34
+ celluloid (0.15.2)
35
+ timers (~> 1.1.0)
36
+ celluloid-io (0.15.0)
37
+ celluloid (>= 0.15.0)
38
+ nio4r (>= 0.5.0)
39
+ coercible (1.0.0)
40
+ descendants_tracker (~> 0.0.1)
18
41
  dependor (1.0.1)
42
+ descendants_tracker (0.0.3)
43
+ equalizer (0.0.9)
19
44
  ffi (1.9.3)
45
+ ice_nine (0.11.0)
20
46
  json (1.8.1)
21
- listen (1.0.3)
47
+ listen (2.7.1)
48
+ celluloid (>= 0.15.2)
49
+ celluloid-io (>= 0.15.0)
22
50
  rb-fsevent (>= 0.9.3)
23
51
  rb-inotify (>= 0.9)
24
- rb-kqueue (>= 0.2)
25
52
  mini_portile (0.5.2)
26
- minitest (5.3.0)
53
+ minitest (5.3.1)
27
54
  minitest-focus (1.1.0)
28
55
  minitest (>= 4, < 6)
56
+ nio4r (1.0.0)
29
57
  nokogiri (1.6.1)
30
58
  mini_portile (~> 0.5.0)
31
- parser (2.1.5)
59
+ parser (2.1.7)
32
60
  ast (~> 1.1)
33
61
  slop (~> 3.4, >= 3.4.5)
34
62
  powerpack (0.0.9)
@@ -42,26 +70,26 @@ GEM
42
70
  rb-fsevent (0.9.4)
43
71
  rb-inotify (0.9.3)
44
72
  ffi (>= 0.5.0)
45
- rb-kqueue (0.2.2)
46
- ffi (>= 0.5.0)
47
73
  reek (1.3.6)
48
74
  ruby2ruby (~> 2.0.7)
49
75
  ruby_parser (~> 3.2)
50
76
  sexp_processor
51
- rerun (0.8.2)
52
- listen (~> 1.0.3)
53
- rubocop (0.18.1)
77
+ rerun (0.9.0)
78
+ listen (~> 2.7)
79
+ rubocop (0.19.1)
54
80
  json (>= 1.7.7, < 2)
55
- parser (~> 2.1.3)
81
+ parser (~> 2.1.7)
56
82
  powerpack (~> 0.0.6)
57
83
  rainbow (>= 1.99.1, < 3.0)
84
+ ruby-progressbar (~> 1.4)
85
+ ruby-progressbar (1.4.2)
58
86
  ruby2ruby (2.0.7)
59
87
  ruby_parser (~> 3.1)
60
88
  sexp_processor (~> 4.0)
61
89
  ruby_parser (3.4.1)
62
90
  sexp_processor (~> 4.1)
63
- sequel (4.7.0)
64
- sexp_processor (4.4.1)
91
+ sequel (4.8.0)
92
+ sexp_processor (4.4.2)
65
93
  sinatra (1.4.4)
66
94
  rack (~> 1.4)
67
95
  rack-protection (~> 1.4)
@@ -69,10 +97,13 @@ GEM
69
97
  slim (2.0.2)
70
98
  temple (~> 0.6.6)
71
99
  tilt (>= 1.3.3, < 2.1)
72
- slop (3.4.7)
100
+ slop (3.5.0)
73
101
  sqlite3 (1.3.9)
74
102
  temple (0.6.7)
103
+ thread_safe (0.1.3)
104
+ atomic
75
105
  tilt (1.4.1)
106
+ timers (1.1.0)
76
107
 
77
108
  PLATFORMS
78
109
  ruby
@@ -86,5 +117,6 @@ DEPENDENCIES
86
117
  rack-test (~> 0.6.2)
87
118
  rake (~> 10.1)
88
119
  reek (~> 1.3)
89
- rerun (~> 0.8.2)
90
- rubocop (~> 0.18.0)
120
+ rerun (~> 0.9.0)
121
+ rubocop (~> 0.19.0)
122
+ virtus!
data/config/reek.yml CHANGED
@@ -9,10 +9,6 @@ IrresponsibleModule:
9
9
  NestedIterators:
10
10
  max_allowed_nesting: 2
11
11
 
12
- UncommunicativeMethodName:
13
- exclude:
14
- - Kamerling#self.UUIDObject
15
-
16
12
  UnusedParameters:
17
13
  exclude:
18
14
  - Kamerling::Server::HTTP#initialize
data/kamerling.gemspec CHANGED
@@ -6,7 +6,7 @@ Gem::Specification.new do |gem|
6
6
  gem.license = 'AGPL-3.0'
7
7
  gem.name = 'kamerling'
8
8
  gem.summary = 'Kamerling: a computation network server'
9
- gem.version = '0.0.1'
9
+ gem.version = '0.0.2'
10
10
 
11
11
  gem.files = `git ls-files -z`.split "\0"
12
12
  gem.executables = gem.files.grep(%r{^bin/}).map { |path| File.basename path }
@@ -17,6 +17,7 @@ Gem::Specification.new do |gem|
17
17
  gem.add_dependency 'sinatra', '~> 1.4'
18
18
  gem.add_dependency 'slim', '~> 2.0'
19
19
  gem.add_dependency 'sqlite3', '~> 1.3'
20
+ gem.add_dependency 'virtus', '~> 1.0'
20
21
 
21
22
  gem.add_development_dependency 'bogus', '~> 0.1.3'
22
23
  gem.add_development_dependency 'minitest', '~> 5.0'
@@ -25,6 +26,6 @@ Gem::Specification.new do |gem|
25
26
  gem.add_development_dependency 'rack-test', '~> 0.6.2'
26
27
  gem.add_development_dependency 'rake', '~> 10.1'
27
28
  gem.add_development_dependency 'reek', '~> 1.3'
28
- gem.add_development_dependency 'rerun', '~> 0.8.2'
29
- gem.add_development_dependency 'rubocop', '~> 0.18.0'
29
+ gem.add_development_dependency 'rerun', '~> 0.9.0'
30
+ gem.add_development_dependency 'rubocop', '~> 0.19.0'
30
31
  end
data/lib/kamerling.rb CHANGED
@@ -20,10 +20,10 @@ require_relative 'kamerling/server/udp'
20
20
  require_relative 'kamerling/server_runner'
21
21
  require_relative 'kamerling/task_dispatcher'
22
22
  require_relative 'kamerling/uuid'
23
- require_relative 'kamerling/uuid_object'
23
+ require_relative 'kamerling/uuid_entity'
24
24
  require_relative 'kamerling/client'
25
25
  require_relative 'kamerling/project'
26
26
  require_relative 'kamerling/registration'
27
- require_relative 'kamerling/result'
28
27
  require_relative 'kamerling/task'
28
+ require_relative 'kamerling/result'
29
29
  require_relative 'kamerling/logging'
@@ -11,6 +11,10 @@ module Kamerling
11
11
  [host, port]
12
12
  end
13
13
 
14
+ def to_h
15
+ super.merge prot: prot.to_s
16
+ end
17
+
14
18
  def to_s
15
19
  "#{host}:#{port} (#{prot})"
16
20
  end
@@ -1,2 +1,14 @@
1
- module Kamerling class Client < UUIDObject :addr, busy: false
1
+ module Kamerling class Client < UUIDEntity
2
+ attribute :addr, Addr
3
+ attribute :busy, Boolean, default: false
4
+
5
+ def self.from_h hash
6
+ super.tap do |client|
7
+ client.addr = Addr[hash[:host], hash[:port], hash[:prot]]
8
+ end
9
+ end
10
+
11
+ def to_h
12
+ super.reject { |key, _| key == :addr }.merge addr.to_h
13
+ end
2
14
  end end
@@ -3,8 +3,8 @@ module Kamerling module CoreExtensions module Main
3
3
 
4
4
  def req param
5
5
  method = caller.first[/`(.*)'$/, 1]
6
- callsite = Class === self ? "#{name}.#{method}" : "#{self.class}##{method}"
7
- raise "#{callsite}: param #{param} is required"
6
+ callsite = is_a?(Class) ? "#{name}.#{method}" : "#{self.class}##{method}"
7
+ fail "#{callsite}: param #{param} is required"
8
8
  end
9
9
 
10
10
  def warn_off
@@ -6,19 +6,24 @@ module Kamerling class Handler
6
6
  end
7
7
 
8
8
  def handle input, addr
9
- message = Message.new input
9
+ process Message.new(input), addr
10
+ rescue Message::UnknownType => exception
11
+ raise UnknownInput, exception.message
12
+ end
13
+
14
+ attr_reader :receiver, :registrar
15
+ private :receiver, :registrar
16
+
17
+ private
18
+
19
+ def process message, addr
10
20
  case message.type
11
21
  when :RGST
12
22
  registrar.register addr: addr, client_uuid: message.client_uuid,
13
- project_uuid: message.project_uuid
23
+ project_uuid: message.project_uuid
14
24
  when :RSLT
15
25
  receiver.receive addr: addr, client_uuid: message.client_uuid,
16
- data: message.payload, task_uuid: message.task_uuid
26
+ data: message.payload, task_uuid: message.task_uuid
17
27
  end
18
- rescue Message::UnknownType => exception
19
- raise UnknownInput, exception.message
20
28
  end
21
-
22
- attr_reader :receiver, :registrar
23
- private :receiver, :registrar
24
29
  end end
@@ -4,17 +4,29 @@ require 'logger'
4
4
  module Kamerling module Logging
5
5
  module_function
6
6
 
7
- def log_to logger: Logger.new($stdout)
8
- Server::Sock.extend AfterDo
9
- Server::Sock.before :start do |*, server|
10
- logger.info "start #{server.addr}"
11
- end
12
- Server::Sock.before :handle do |input, client_addr|
13
- logger.info "connect #{client_addr}"
14
- logger.debug "received #{client_addr} #{input}"
7
+ def log_to logger = Logger.new($stdout)
8
+ log_dispatcher_to logger
9
+ log_server_to logger
10
+ end
11
+
12
+ class << self
13
+ private
14
+
15
+ def log_dispatcher_to logger
16
+ NetDispatcher.singleton_class.extend AfterDo
17
+ NetDispatcher.singleton_class.before :dispatch do |addr, bytes|
18
+ logger.debug "sent #{addr} #{bytes}"
19
+ end
15
20
  end
16
- Server::Sock.after :stop do |*, server|
17
- logger.info "stop #{server.addr}"
21
+
22
+ def log_server_to logger
23
+ Server::Sock.extend AfterDo
24
+ Server::Sock.before(:start) { |srv| logger.info "start #{srv.addr}" }
25
+ Server::Sock.after(:stop) { |srv| logger.info "stop #{srv.addr}" }
26
+ Server::Sock.before :handle do |input, client_addr|
27
+ logger.info "connect #{client_addr}"
28
+ logger.debug "received #{client_addr} #{input}"
29
+ end
18
30
  end
19
31
  end
20
32
  end end
@@ -1,9 +1,8 @@
1
1
  module Kamerling class Message
2
- KnownTypes = %w[DATA PING RGST RSLT]
3
2
  UnknownType = Class.new RuntimeError
4
3
 
5
- def self.[](client: req(:client), payload: req(:payload),
6
- project: req(:project), task: req(:task), type: req(:type))
4
+ def self.[] client: req(:client), payload: req(:payload),
5
+ project: req(:project), task: req(:task), type: req(:type)
7
6
  new "#{type}\0\0\0\0\0\0\0\0\0\0\0\0" + UUID.bin(client.uuid) +
8
7
  UUID.bin(project.uuid) + UUID.bin(task.uuid) + payload
9
8
  end
@@ -11,7 +10,8 @@ module Kamerling class Message
11
10
  def initialize raw
12
11
  @raw = raw
13
12
  type = raw[0..3]
14
- raise UnknownType, type unless KnownTypes.include? type or type.empty?
13
+ known_types = %w(DATA PING RGST RSLT)
14
+ fail UnknownType, type unless known_types.include? type or type.empty?
15
15
  end
16
16
 
17
17
  def == other
@@ -19,9 +19,9 @@ Sequel.migration do
19
19
  integer :port, null: false
20
20
  string :prot, null: false
21
21
  foreign_key :client_uuid, :clients, index: true, null: false,
22
- type: :uuid
22
+ type: :uuid
23
23
  foreign_key :project_uuid, :projects, index: true, null: false,
24
- type: :uuid
24
+ type: :uuid
25
25
  end
26
26
 
27
27
  create_table :results do
@@ -39,7 +39,7 @@ Sequel.migration do
39
39
  boolean :done, null: false
40
40
  bytea :data, null: false
41
41
  foreign_key :project_uuid, :projects, index: true, null: false,
42
- type: :uuid
42
+ type: :uuid
43
43
  end
44
44
  end
45
45
  end
@@ -1,4 +1,6 @@
1
- module Kamerling class NetDispatcher
1
+ module Kamerling module NetDispatcher
2
+ module_function
3
+
2
4
  def dispatch addr, bytes
3
5
  case addr.prot
4
6
  when :TCP then TCPSocket.open(*addr) { |socket| socket << bytes }
@@ -1,2 +1,3 @@
1
- module Kamerling class Project < UUIDObject :name
1
+ module Kamerling class Project < UUIDEntity
2
+ attribute :name, String
2
3
  end end
@@ -1,2 +1,12 @@
1
- module Kamerling class Registration < UUIDObject :addr, :client, :project
1
+ module Kamerling class Registration < UUIDEntity
2
+ attribute :addr, Addr
3
+ attribute :client, Client
4
+ attribute :project, Project
5
+
6
+ def to_h
7
+ super
8
+ .reject { |key, _| key == :addr }.merge(addr.to_h)
9
+ .reject { |key, _| key == :client }.merge(client_uuid: client.uuid)
10
+ .reject { |key, _| key == :project }.merge project_uuid: project.uuid
11
+ end
2
12
  end end
@@ -14,7 +14,7 @@ module Kamerling class Repo
14
14
 
15
15
  def [] uuid
16
16
  hash = warn_off { source[uuid: uuid] }
17
- raise NotFound, "#{klass} with UUID #{uuid}" unless hash
17
+ fail NotFound, "#{klass} with UUID #{uuid}" unless hash
18
18
  klass.from_h hash
19
19
  end
20
20
 
@@ -1,2 +1,13 @@
1
- module Kamerling class Result < UUIDObject :addr, :client, :data, :task
1
+ module Kamerling class Result < UUIDEntity
2
+ attribute :addr, Addr
3
+ attribute :client, Client
4
+ attribute :data, String
5
+ attribute :task, Task
6
+
7
+ def to_h
8
+ super
9
+ .reject { |key, _| key == :addr }.merge(addr.to_h)
10
+ .reject { |key, _| key == :client }.merge(client_uuid: client.uuid)
11
+ .reject { |key, _| key == :task }.merge task_uuid: task.uuid
12
+ end
2
13
  end end
@@ -1,8 +1,6 @@
1
1
  require 'optparse'
2
2
 
3
3
  module Kamerling class ServerRunner
4
- Settings = Struct.new(*%i[db host http tcp udp])
5
-
6
4
  def initialize args, classes: def_classes, orm: Sequel, repos: Repos
7
5
  @args = args
8
6
  repos.db = orm.connect settings.db
@@ -26,24 +24,24 @@ module Kamerling class ServerRunner
26
24
 
27
25
  private
28
26
 
27
+ Settings = Struct.new(*%i(db host http tcp udp))
28
+
29
29
  def def_classes
30
30
  { http: Server::HTTP, tcp: Server::TCP, udp: Server::UDP }
31
31
  end
32
32
 
33
+ def defaults
34
+ Settings.new 'sqlite::memory:', '127.0.0.1'
35
+ end
36
+
33
37
  def settings
34
- @settings ||= Settings.new.tap do |sets|
35
- sets.db = 'sqlite::memory:'
36
- sets.host = '127.0.0.1'
37
- OptionParser.new do |opts|
38
- opts.on("--db #{sets.db}", String, 'database') do |db|
39
- sets.db = db
40
- end
41
- opts.on("--host #{sets.host}", String, 'server host') do |host|
42
- sets.host = host
43
- end
44
- opts.on('--http 0', Integer, 'HTTP port') { |http| sets.http = http }
45
- opts.on('--tcp 0', Integer, 'TCP port') { |tcp| sets.tcp = tcp }
46
- opts.on('--udp 0', Integer, 'UDP port') { |udp| sets.udp = udp }
38
+ @settings ||= defaults.tap do |set|
39
+ OptionParser.new do |opt|
40
+ opt.on("--db #{set.db}", String, 'database') { |db| set.db = db }
41
+ opt.on("--host #{set.host}", String, 'host') { |host| set.host = host }
42
+ opt.on('--http 0', Integer, 'HTTP port') { |http| set.http = http }
43
+ opt.on('--tcp 0', Integer, 'TCP port') { |tcp| set.tcp = tcp }
44
+ opt.on('--udp 0', Integer, 'UDP port') { |udp| set.udp = udp }
47
45
  end.parse! args
48
46
  end
49
47
  end
@@ -1,2 +1,9 @@
1
- module Kamerling class Task < UUIDObject :data, :project, done: false
1
+ module Kamerling class Task < UUIDEntity
2
+ attribute :data, String
3
+ attribute :done, Boolean, default: false
4
+ attribute :project, Project
5
+
6
+ def to_h
7
+ super.reject { |key, _| key == :project }.merge project_uuid: project.uuid
8
+ end
2
9
  end end
@@ -1,5 +1,5 @@
1
1
  module Kamerling class TaskDispatcher
2
- def initialize net_dispatcher: NetDispatcher.new, repos: Repos
2
+ def initialize net_dispatcher: NetDispatcher, repos: Repos
3
3
  @net_dispatcher = net_dispatcher
4
4
  @repos = repos
5
5
  end
@@ -21,7 +21,7 @@ module Kamerling class TaskDispatcher
21
21
  def dispatch_task client: req(:client), project: req(:project),
22
22
  task: req(:task)
23
23
  message = Message[client: client, payload: task.data, project: project,
24
- task: task, type: :DATA]
24
+ task: task, type: :DATA]
25
25
  net_dispatcher.dispatch client.addr, message.to_s
26
26
  client.busy = true
27
27
  repos << client
@@ -0,0 +1,15 @@
1
+ require 'virtus'
2
+
3
+ module Kamerling class UUIDEntity
4
+ include Equalizer.new :uuid
5
+
6
+ include Virtus.model
7
+
8
+ attribute :uuid, String, default: -> * { UUID.new }
9
+
10
+ class << self
11
+ alias_method :from_h, :new
12
+ end
13
+
14
+ alias_method :to_h, :attributes
15
+ end end
@@ -19,6 +19,12 @@ module Kamerling describe Addr do
19
19
  end
20
20
  end
21
21
 
22
+ describe '#to_h' do
23
+ it 'returns a Hash with Integer and String values' do
24
+ addr.to_h.must_equal host: 'localhost', port: 1981, prot: 'TCP'
25
+ end
26
+ end
27
+
22
28
  describe '#to_s' do
23
29
  it 'returns the Addr in ‘host:port (protocol)’ notation' do
24
30
  addr.to_s.must_equal 'localhost:1981 (TCP)'
@@ -7,19 +7,30 @@ module Kamerling describe Handler do
7
7
 
8
8
  it 'handles RGST inputs' do
9
9
  input = 'RGST' + "\0" * 12 + '16B client UUID16B project UUID'
10
+ client_uuid = UUID['16B client UUID']
11
+ project_uuid = UUID['16B project UUID']
10
12
  handler.handle input, addr
11
- registrar.must_have_received :register, [{ addr: addr,
12
- client_uuid: UUID['16B client UUID'],
13
- project_uuid: UUID['16B project UUID'] }]
13
+ args = {
14
+ addr: addr,
15
+ client_uuid: client_uuid,
16
+ project_uuid: project_uuid,
17
+ }
18
+ registrar.must_have_received :register, [args]
14
19
  end
15
20
 
16
21
  it 'handles RSLT inputs' do
17
- input = 'RSLT' + "\0" * 12
18
- input << '16B client UUID16B project UUID16B task UUIDdata'
22
+ input = 'RSLT' + "\0" * 12 +
23
+ '16B client UUID16B project UUID16B task UUIDdata'
24
+ client_uuid = UUID['16B client UUID']
25
+ task_uuid = UUID['16B task UUID']
19
26
  handler.handle input, addr
20
- receiver.must_have_received :receive, [{ addr: addr,
21
- client_uuid: UUID['16B client UUID'], data: 'data',
22
- task_uuid: UUID['16B task UUID'] }]
27
+ args = {
28
+ addr: addr,
29
+ client_uuid: client_uuid,
30
+ data: 'data',
31
+ task_uuid: task_uuid,
32
+ }
33
+ receiver.must_have_received :receive, [args]
23
34
  end
24
35
 
25
36
  it 'raises on unknown inputs' do
@@ -8,7 +8,7 @@ module Kamerling describe Logging do
8
8
  let(:udp_server) { Server::UDP.new addr: Addr['localhost', 1979, :UDP] }
9
9
 
10
10
  before do
11
- Logging.log_to logger: logger
11
+ Logging.log_to logger
12
12
  tcp_server.start
13
13
  udp_server.start
14
14
  end
@@ -18,7 +18,7 @@ module Kamerling describe Logging do
18
18
  udp_server.stop
19
19
  end
20
20
 
21
- describe '.new' do
21
+ describe '.log_to' do
22
22
  it 'logs TCP server starts' do
23
23
  logged.must_include 'start localhost:1981 (TCP)'
24
24
  end
@@ -69,5 +69,12 @@ module Kamerling describe Logging do
69
69
  run_all_threads
70
70
  logged.must_include "received #{udp_addr} PING"
71
71
  end
72
+
73
+ it 'logs packet dispatches' do
74
+ server = UDPSocket.new.tap { |s| s.bind '127.0.0.1', 0 }
75
+ addr = Addr[server.addr[3], server.addr[1], :UDP]
76
+ NetDispatcher.dispatch addr, 'PING'
77
+ logged.must_include "sent #{addr} PING"
78
+ end
72
79
  end
73
80
  end end
@@ -12,7 +12,7 @@ module Kamerling describe Message do
12
12
  project = fake :project, uuid: UUID.new
13
13
  task = fake :task, uuid: UUID.new
14
14
  message = Message[client: client, payload: 'pay', project: project,
15
- task: task, type: :DATA]
15
+ task: task, type: :DATA]
16
16
  message.client_uuid.must_equal client.uuid
17
17
  message.project_uuid.must_equal project.uuid
18
18
  message.task_uuid.must_equal task.uuid
@@ -57,7 +57,7 @@ module Kamerling describe Message do
57
57
 
58
58
  describe '#to_s' do
59
59
  it 'returns the raw bytes' do
60
- mess.to_s.must_equal "#{mess.type}\0\0\0\0\0\0\0\0\0\0\0\0" +
60
+ mess.to_s.must_equal "#{mess.type}\0\0\0\0\0\0\0\0\0\0\0\0" \
61
61
  '16B client UUID16B project UUID16B task UUIDsome payload'
62
62
  end
63
63
  end
@@ -6,7 +6,7 @@ module Kamerling describe NetDispatcher do
6
6
  server = TCPServer.open 0
7
7
  thread = Thread.new { server.accept.read }
8
8
  addr = Addr[server.addr[3], server.addr[1], :TCP]
9
- NetDispatcher.new.dispatch addr, 'foo'
9
+ NetDispatcher.dispatch addr, 'foo'
10
10
  thread.value.must_equal 'foo'
11
11
  end
12
12
 
@@ -14,7 +14,7 @@ module Kamerling describe NetDispatcher do
14
14
  server = UDPSocket.new.tap { |s| s.bind '127.0.0.1', 0 }
15
15
  thread = Thread.new { server.recvfrom(2**16).first }
16
16
  addr = Addr[server.addr[3], server.addr[1], :UDP]
17
- NetDispatcher.new.dispatch addr, 'foo'
17
+ NetDispatcher.dispatch addr, 'foo'
18
18
  thread.value.must_equal 'foo'
19
19
  end
20
20
  end
@@ -10,13 +10,14 @@ module Kamerling describe Receiver do
10
10
  stub(repos).[](Client) { fake :repo, :[] => client }
11
11
  stub(repos).[](Task) { fake :repo, :[] => task }
12
12
  Receiver.new.receive addr: addr, client_uuid: client.uuid, data: 'data',
13
- repos: repos, task_uuid: task.uuid
13
+ repos: repos, task_uuid: task.uuid
14
+ result = Result.new addr: addr, client: client, data: 'data', task: task,
15
+ uuid: anything
14
16
  client.must_have_received :busy=, [false]
15
17
  task.must_have_received :done=, [true]
16
- repos.must_have_received :<<, [client]
17
- repos.must_have_received :<<, [task]
18
- repos.must_have_received :<<, [Result.new(addr: addr, client: client,
19
- data: 'data', task: task, uuid: anything)]
18
+ repos.must_have_received :<<, [client]
19
+ repos.must_have_received :<<, [task]
20
+ repos.must_have_received :<<, [result]
20
21
  end
21
22
  end
22
23
  end end
@@ -5,12 +5,16 @@ module Kamerling describe Registrar do
5
5
  fakes :addr, :client, :project, :repo
6
6
 
7
7
  it 'registers that the given client can do the given project' do
8
- repos = { Client => { client.uuid => client },
9
- Project => { project.uuid => project }, Registration => repo }
8
+ repos = {
9
+ Client => { client.uuid => client },
10
+ Project => { project.uuid => project },
11
+ Registration => repo,
12
+ }
10
13
  Registrar.new.register addr: addr, client_uuid: client.uuid,
11
- project_uuid: project.uuid, repos: repos
12
- repo.must_have_received :<<, [Registration.new(addr: addr,
13
- client: client, project: project, uuid: anything)]
14
+ project_uuid: project.uuid, repos: repos
15
+ registration = Registration.new addr: addr, client: client,
16
+ project: project, uuid: anything
17
+ repo.must_have_received :<<, [registration]
14
18
  end
15
19
  end
16
20
  end end
@@ -1,7 +1,7 @@
1
1
  require_relative '../spec_helper'
2
2
 
3
3
  module Kamerling describe Repo do
4
- Tune = Kamerling.UUIDObject :genre
4
+ Tune = Class.new(UUIDEntity) { attribute :genre, Symbol }
5
5
 
6
6
  describe '#<<' do
7
7
  it 'passes the Hash version of an object to the source' do
@@ -15,7 +15,7 @@ module Kamerling describe Repo do
15
15
  dataset = fake Sequel::Dataset
16
16
  source = fake Sequel::Dataset
17
17
  tune = Tune.new genre: :chap_hop
18
- stub(source).<<(tune.to_h) { raise Sequel::UniqueConstraintViolation }
18
+ stub(source).<<(tune.to_h) { fail Sequel::UniqueConstraintViolation }
19
19
  stub(source).where(uuid: tune.uuid) { dataset }
20
20
  Repo.new(Tune, source) << tune
21
21
  dataset.must_have_received :update, [tune.to_h]
@@ -39,7 +39,7 @@ module Kamerling describe Repo do
39
39
  it 'returns all objects' do
40
40
  tune = Tune.new genre: :chap_hop, uuid: UUID.new
41
41
  source = fake Sequel::Dataset,
42
- all: [{ genre: :chap_hop, uuid: tune.uuid }]
42
+ all: [{ genre: :chap_hop, uuid: tune.uuid }]
43
43
  Repo.new(Tune, source).all.must_equal [tune]
44
44
  end
45
45
  end
@@ -30,7 +30,7 @@ module Kamerling describe Server::TCP do
30
30
  it 'doesn’t blow up on unknown inputs' do
31
31
  server = Server::TCP.new addr: addr, handler: handler = fake(:handler)
32
32
  server.start
33
- stub(handler).handle('foo', any(Addr)) { raise Handler::UnknownInput }
33
+ stub(handler).handle('foo', any(Addr)) { fail Handler::UnknownInput }
34
34
  TCPSocket.open(*server.addr) { |socket| socket << 'foo' }
35
35
  server.stop
36
36
  end
@@ -22,7 +22,7 @@ module Kamerling describe Server::UDP do
22
22
  it 'doesn’t blow up on unknown inputs' do
23
23
  server = Server::UDP.new addr: addr, handler: handler = fake(:handler)
24
24
  server.start
25
- stub(handler).handle('foo', any(Addr)) { raise Handler::UnknownInput }
25
+ stub(handler).handle('foo', any(Addr)) { fail Handler::UnknownInput }
26
26
  UDPSocket.new.send 'foo', 0, *server.addr
27
27
  run_all_threads
28
28
  server.stop
@@ -20,7 +20,7 @@ module Kamerling describe ServerRunner do
20
20
 
21
21
  describe '.new' do
22
22
  it 'hooks to the given database' do
23
- args = %w[--host 0.0.0.0 --db sqlite::memory:]
23
+ args = %w(--host 0.0.0.0 --db sqlite::memory:)
24
24
  db = fake { Sequel::SQLite::Database }
25
25
  orm = fake :sequel, as: :class
26
26
  stub(orm).connect('sqlite::memory:') { db }
@@ -32,7 +32,7 @@ module Kamerling describe ServerRunner do
32
32
 
33
33
  describe '#join' do
34
34
  it 'joins all the created servers' do
35
- args = %w[--host 0.0.0.0 --http 1234]
35
+ args = %w(--host 0.0.0.0 --http 1234)
36
36
  ServerRunner.new(args, classes: classes).join
37
37
  http.must_have_received :join, []
38
38
  tcp.wont_have_received :join, []
@@ -42,7 +42,7 @@ module Kamerling describe ServerRunner do
42
42
 
43
43
  describe '#start' do
44
44
  it 'starts the servers based on the given command-line parameters' do
45
- args = %w[--host 0.0.0.0 --http 1234 --tcp 3456 --udp 5678]
45
+ args = %w(--host 0.0.0.0 --http 1234 --tcp 3456 --udp 5678)
46
46
  ServerRunner.new(args, classes: classes).start
47
47
  http.must_have_received :start, []
48
48
  tcp.must_have_received :start, []
@@ -50,7 +50,7 @@ module Kamerling describe ServerRunner do
50
50
  end
51
51
 
52
52
  it 'starts only the servers for which the port was given' do
53
- args = %w[--host 0.0.0.0 --http 1234]
53
+ args = %w(--host 0.0.0.0 --http 1234)
54
54
  ServerRunner.new(args, classes: classes).start
55
55
  http.must_have_received :start, []
56
56
  tcp.wont_have_received :start, []
@@ -10,12 +10,12 @@ module Kamerling describe TaskDispatcher do
10
10
  repos = fake :repos, as: :class, projects: [project]
11
11
  stub(repos).next_task_for(project) { task }
12
12
  stub(repos).free_clients_for(project) { [client] }
13
- net_dispatcher = fake :net_dispatcher
13
+ net_dispatcher = fake :net_dispatcher, as: :class
14
14
 
15
15
  TaskDispatcher.new(net_dispatcher: net_dispatcher, repos: repos).dispatch
16
16
 
17
- net_dispatcher.must_have_received :dispatch, [addr,
18
- "DATA#{"\0" * 12}16B client UUID16B project UUID16B task UUIDdata"]
17
+ header = "DATA#{"\0" * 12}16B client UUID16B project UUID16B task "
18
+ net_dispatcher.must_have_received :dispatch, [addr, header + 'UUIDdata']
19
19
  client.must_have_received :busy=, [true]
20
20
  repos.must_have_received :<<, [client]
21
21
  end
@@ -0,0 +1,35 @@
1
+ require_relative '../spec_helper'
2
+
3
+ module Kamerling describe UUIDEntity do
4
+ describe '.from_h' do
5
+ it 'deserialises the object from a Hash' do
6
+ Trivial = Class.new(UUIDEntity) { attribute :question, Symbol }
7
+ Trivial.from_h(question: :answer).question.must_equal :answer
8
+ end
9
+ end
10
+
11
+ describe '.new' do
12
+ it 'creates a class with an UUID property defaulting to a random UUID' do
13
+ AttrLess = Class.new UUIDEntity
14
+ AttrLess.new.uuid.must_match(/\A\h{8}-\h{4}-\h{4}-\h{4}-\h{12}\z/)
15
+ AttrLess.new.uuid.wont_equal AttrLess.new.uuid
16
+ end
17
+ end
18
+
19
+ describe '#==' do
20
+ it 'reports UUID-based euqality' do
21
+ Actor = Class.new(UUIDEntity) { attribute :name, Symbol }
22
+ Actor.new(name: :laurel).wont_equal Actor.new name: :laurel
23
+ uuid = UUID.new
24
+ Actor.new(name: :laurel, uuid: uuid)
25
+ .must_equal Actor.new name: :hardy, uuid: uuid
26
+ end
27
+ end
28
+
29
+ describe '#to_h' do
30
+ it 'serialises the object to a Hash' do
31
+ Hashble = Class.new(UUIDEntity) { attribute :param, Symbol }
32
+ Hashble.new(param: :val).to_h.must_equal param: :val, uuid: any(String)
33
+ end
34
+ end
35
+ end end
data/spec/spec_helper.rb CHANGED
@@ -9,14 +9,16 @@ require 'kamerling'
9
9
 
10
10
  Bogus.configure { |config| config.search_modules << Kamerling }
11
11
 
12
- module MiniTest::Spec::DSL
13
- def fakes *args
14
- args.map { |arg| fake arg }
15
- end
16
- end
12
+ module Minitest
13
+ class Spec
14
+ include Rack::Test::Methods
17
15
 
18
- class MiniTest::Spec
19
- include Rack::Test::Methods
16
+ module DSL
17
+ def fakes *args
18
+ args.map { |arg| fake arg }
19
+ end
20
+ end
21
+ end
20
22
  end
21
23
 
22
24
  Thread.abort_on_exception = true
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: kamerling
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Piotr Szotkowski
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-02-26 00:00:00.000000000 Z
11
+ date: 2014-03-24 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: after_do
@@ -80,6 +80,20 @@ dependencies:
80
80
  - - "~>"
81
81
  - !ruby/object:Gem::Version
82
82
  version: '1.3'
83
+ - !ruby/object:Gem::Dependency
84
+ name: virtus
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: '1.0'
90
+ type: :runtime
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - "~>"
95
+ - !ruby/object:Gem::Version
96
+ version: '1.0'
83
97
  - !ruby/object:Gem::Dependency
84
98
  name: bogus
85
99
  requirement: !ruby/object:Gem::Requirement
@@ -184,28 +198,28 @@ dependencies:
184
198
  requirements:
185
199
  - - "~>"
186
200
  - !ruby/object:Gem::Version
187
- version: 0.8.2
201
+ version: 0.9.0
188
202
  type: :development
189
203
  prerelease: false
190
204
  version_requirements: !ruby/object:Gem::Requirement
191
205
  requirements:
192
206
  - - "~>"
193
207
  - !ruby/object:Gem::Version
194
- version: 0.8.2
208
+ version: 0.9.0
195
209
  - !ruby/object:Gem::Dependency
196
210
  name: rubocop
197
211
  requirement: !ruby/object:Gem::Requirement
198
212
  requirements:
199
213
  - - "~>"
200
214
  - !ruby/object:Gem::Version
201
- version: 0.18.0
215
+ version: 0.19.0
202
216
  type: :development
203
217
  prerelease: false
204
218
  version_requirements: !ruby/object:Gem::Requirement
205
219
  requirements:
206
220
  - - "~>"
207
221
  - !ruby/object:Gem::Version
208
- version: 0.18.0
222
+ version: 0.19.0
209
223
  description: A network server for distributing computations across different clients
210
224
  speaking TCP or UDP.
211
225
  email: p.szotkowski@tele.pw.edu.pl
@@ -250,7 +264,7 @@ files:
250
264
  - lib/kamerling/task.rb
251
265
  - lib/kamerling/task_dispatcher.rb
252
266
  - lib/kamerling/uuid.rb
253
- - lib/kamerling/uuid_object.rb
267
+ - lib/kamerling/uuid_entity.rb
254
268
  - lib/kamerling/views/clients.slim
255
269
  - lib/kamerling/views/layout.slim
256
270
  - lib/kamerling/views/project.slim
@@ -274,7 +288,7 @@ files:
274
288
  - spec/kamerling/server_runner_spec.rb
275
289
  - spec/kamerling/task_dispatcher_spec.rb
276
290
  - spec/kamerling/task_spec.rb
277
- - spec/kamerling/uuid_object_spec.rb
291
+ - spec/kamerling/uuid_entity_spec.rb
278
292
  - spec/kamerling/uuid_spec.rb
279
293
  - spec/spec_helper.rb
280
294
  homepage: https://github.com/chastell/kamerling
@@ -320,6 +334,7 @@ test_files:
320
334
  - spec/kamerling/server_runner_spec.rb
321
335
  - spec/kamerling/task_dispatcher_spec.rb
322
336
  - spec/kamerling/task_spec.rb
323
- - spec/kamerling/uuid_object_spec.rb
337
+ - spec/kamerling/uuid_entity_spec.rb
324
338
  - spec/kamerling/uuid_spec.rb
325
339
  - spec/spec_helper.rb
340
+ has_rdoc:
@@ -1,79 +0,0 @@
1
- module Kamerling
2
- def self.UUIDObject *params
3
- class_definition_from attrs_from params
4
- end
5
-
6
- private
7
-
8
- def self.attrs_from params
9
- { uuid: -> { UUID.new } }.tap do |attrs|
10
- attrs.merge! params.pop if params.last.is_a? Hash
11
- attrs.merge! raises_from params
12
- end
13
- end
14
-
15
- def self.class_definition_from attrs
16
- Class.new do
17
- define_singleton_method(:attrs) { attrs }
18
-
19
- def self.from_h hash, repos: Repos
20
- args = hash.reduce({}) do |result, (key, _)|
21
- result.merge from_h_mapping hash, key, repos
22
- end
23
- new args
24
- end
25
-
26
- def initialize args = {}
27
- @values = Hash[self.class.attrs.map do |attr, default|
28
- value = args.fetch attr do
29
- default.respond_to?(:call) ? default.call : default
30
- end
31
- [attr, value]
32
- end]
33
- end
34
-
35
- def == other
36
- uuid == other.uuid
37
- end
38
-
39
- attrs.each do |attr, _|
40
- define_method(attr) { @values[attr] }
41
- define_method("#{attr}=") { |val| @values[attr] = val }
42
- end
43
-
44
- def to_h
45
- self.class.attrs.reduce({}) do |hash, (attr, _)|
46
- hash.merge to_h_mapping attr
47
- end
48
- end
49
-
50
- private
51
-
52
- def self.from_h_mapping hash, key, repos
53
- case key
54
- when :host, :port, :prot
55
- { addr: Addr[hash[:host], hash[:port], hash[:prot].to_sym] }
56
- when :client_uuid then { client: repos[Client][hash[key]] }
57
- when :project_uuid then { project: repos[Project][hash[key]] }
58
- when :task_uuid then { task: repos[Task][hash[key]] }
59
- else { key => hash[key] }
60
- end
61
- end
62
-
63
- def to_h_mapping attr
64
- case value = @values[attr]
65
- when Addr
66
- { host: value.host, port: value.port, prot: value.prot.to_s }
67
- when Client then { client_uuid: client.uuid }
68
- when Project then { project_uuid: project.uuid }
69
- when Task then { task_uuid: task.uuid }
70
- else { attr => value }
71
- end
72
- end
73
- end
74
- end
75
-
76
- def self.raises_from params
77
- Hash[params.map { |param| [param, -> { raise "#{param} required" }] }]
78
- end
79
- end
@@ -1,101 +0,0 @@
1
- require_relative '../spec_helper'
2
-
3
- module Kamerling describe '.UUIDObject' do
4
- describe '.from_h' do
5
- it 'deserialises the object from a Hash' do
6
- Trivial = Kamerling.UUIDObject :question
7
- Trivial.from_h(question: :answer).question.must_equal :answer
8
- end
9
-
10
- it 'deserialises addr' do
11
- Netable = Kamerling.UUIDObject :addr
12
- Netable.from_h(host: '127.0.0.1', port: 1981, prot: :TCP).addr
13
- .must_equal Addr['127.0.0.1', 1981, :TCP]
14
- end
15
-
16
- it 'deserialises {client,project,task}_uuid' do
17
- client = fake :client, uuid: UUID.new
18
- project = fake :project, uuid: UUID.new
19
- task = fake :task, uuid: UUID.new
20
- Complete = Kamerling.UUIDObject :client, :project, :task
21
- repos = {
22
- Client => { client.uuid => client },
23
- Project => { project.uuid => project },
24
- Task => { task.uuid => task },
25
- }
26
- hash = { client_uuid: client.uuid, project_uuid: project.uuid,
27
- task_uuid: task.uuid, uuid: UUID.new }
28
- complete = Complete.from_h hash, repos: repos
29
- complete.client.must_equal client
30
- complete.project.must_equal project
31
- complete.task.must_equal task
32
- end
33
- end
34
-
35
- describe '.new' do
36
- it 'creates a class with an UUID property defaulting to a random UUID' do
37
- AttrLess = Kamerling.UUIDObject
38
- AttrLess.new.uuid.must_match(/\A\h{8}-\h{4}-\h{4}-\h{4}-\h{12}\z/)
39
- AttrLess.new.uuid.wont_equal AttrLess.new.uuid
40
- end
41
-
42
- it 'allows setting custom properties and raises when they lack defaults' do
43
- FooFul = Kamerling.UUIDObject :foo
44
- FooFul.new(foo: 'bar').foo.must_equal 'bar'
45
- -> { FooFul.new }.must_raise RuntimeError
46
- end
47
-
48
- it 'allows setting properties’ default procs' do
49
- ProcFul = Kamerling.UUIDObject rand: -> { rand }
50
- ProcFul.new.rand.wont_equal ProcFul.new.rand
51
- end
52
-
53
- it 'allows setting properties’ default values' do
54
- ValFul = Kamerling.UUIDObject bar: :baz
55
- ValFul.new.bar.must_equal :baz
56
- end
57
- end
58
-
59
- describe '#==' do
60
- it 'reports UUID-based euqality' do
61
- Actor = Kamerling.UUIDObject :name
62
- Actor.new(name: :laurel).wont_equal Actor.new name: :laurel
63
- uuid = UUID.new
64
- Actor.new(name: :laurel, uuid: uuid)
65
- .must_equal Actor.new name: :hardy, uuid: uuid
66
- end
67
- end
68
-
69
- describe '#to_h' do
70
- it 'serialises the object to a Hash' do
71
- Hashble = Kamerling.UUIDObject :param
72
- Hashble.new(param: :val).to_h.must_equal param: :val, uuid: anything
73
- end
74
-
75
- it 'serialises addr' do
76
- Addrble = Kamerling.UUIDObject :addr
77
- addrble = Addrble.new addr: Addr['127.0.0.1', 1981, :TCP]
78
- addrble.to_h.must_equal host: '127.0.0.1', port: 1981, prot: 'TCP',
79
- uuid: anything
80
- end
81
-
82
- it 'serialises client' do
83
- Clintable = Kamerling.UUIDObject :client
84
- clintable = Clintable.new client: client = Client.new(addr: fake(:addr))
85
- clintable.to_h.must_equal client_uuid: client.uuid, uuid: anything
86
- end
87
-
88
- it 'serialises project' do
89
- Projable = Kamerling.UUIDObject :project
90
- projable = Projable.new project: project = Project.new(name: 'name')
91
- projable.to_h.must_equal project_uuid: project.uuid, uuid: anything
92
- end
93
-
94
- it 'serialises task' do
95
- project = fake :project
96
- Tskble = Kamerling.UUIDObject :task
97
- tskble = Tskble.new task: task = Task.new(data: 'data', project: project)
98
- tskble.to_h.must_equal task_uuid: task.uuid, uuid: anything
99
- end
100
- end
101
- end end