kamerling 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
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