kamerling 0.0.2 → 0.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.rubocop.yml +4 -13
- data/Gemfile +0 -1
- data/Gemfile.lock +64 -64
- data/README.md +18 -1
- data/Rakefile +5 -3
- data/bin/kamerling +1 -1
- data/config/reek.yml +20 -3
- data/kamerling.gemspec +16 -13
- data/lib/kamerling.rb +2 -28
- data/lib/kamerling/addr.rb +17 -3
- data/lib/kamerling/client.rb +10 -11
- data/lib/kamerling/core_extensions/main.rb +14 -14
- data/lib/kamerling/dispatch.rb +13 -0
- data/lib/kamerling/handler.rb +16 -25
- data/lib/kamerling/http_api.rb +50 -34
- data/lib/kamerling/logging.rb +36 -16
- data/lib/kamerling/mapper.rb +33 -0
- data/lib/kamerling/message.rb +50 -37
- data/lib/kamerling/migrations/2_results_received_at.rb +7 -0
- data/lib/kamerling/migrations/3_dispatches.rb +17 -0
- data/lib/kamerling/migrations/4_registrations_registered_at.rb +7 -0
- data/lib/kamerling/migrations/5_clients_type.rb +7 -0
- data/lib/kamerling/net_dispatcher.rb +12 -7
- data/lib/kamerling/project.rb +7 -3
- data/lib/kamerling/receiver.rb +38 -10
- data/lib/kamerling/registrar.rb +45 -8
- data/lib/kamerling/registration.rb +9 -10
- data/lib/kamerling/repo.rb +33 -26
- data/lib/kamerling/repos.rb +52 -45
- data/lib/kamerling/result.rb +10 -11
- data/lib/kamerling/server/http.rb +28 -21
- data/lib/kamerling/server/sock.rb +32 -24
- data/lib/kamerling/server/tcp.rb +23 -15
- data/lib/kamerling/server/udp.rb +24 -16
- data/lib/kamerling/server_runner.rb +30 -41
- data/lib/kamerling/settings.rb +28 -0
- data/lib/kamerling/task.rb +7 -7
- data/lib/kamerling/task_dispatcher.rb +31 -22
- data/lib/kamerling/uuid.rb +13 -11
- data/lib/kamerling/uuid_entity.rb +23 -9
- data/lib/kamerling/value.rb +13 -0
- data/lib/kamerling/views/clients.slim +3 -1
- data/lib/kamerling/views/project.slim +8 -4
- data/lib/kamerling/views/projects.slim +7 -1
- data/spec/kamerling/addr_spec.rb +32 -22
- data/spec/kamerling/client_spec.rb +9 -5
- data/spec/kamerling/core_extensions/main_spec.rb +18 -13
- data/spec/kamerling/dispatch_spec.rb +16 -0
- data/spec/kamerling/handler_spec.rb +24 -34
- data/spec/kamerling/http_api_spec.rb +94 -73
- data/spec/kamerling/logging_spec.rb +93 -62
- data/spec/kamerling/mapper_spec.rb +151 -0
- data/spec/kamerling/message_spec.rb +73 -49
- data/spec/kamerling/net_dispatcher_spec.rb +22 -16
- data/spec/kamerling/receiver_spec.rb +29 -19
- data/spec/kamerling/registrar_spec.rb +43 -15
- data/spec/kamerling/registration_spec.rb +17 -0
- data/spec/kamerling/repo_spec.rb +63 -47
- data/spec/kamerling/repos_spec.rb +121 -109
- data/spec/kamerling/result_spec.rb +16 -0
- data/spec/kamerling/server/http_spec.rb +19 -14
- data/spec/kamerling/server/tcp_spec.rb +41 -35
- data/spec/kamerling/server/udp_spec.rb +40 -34
- data/spec/kamerling/server_runner_spec.rb +62 -53
- data/spec/kamerling/settings_spec.rb +36 -0
- data/spec/kamerling/task_dispatcher_spec.rb +38 -15
- data/spec/kamerling/task_spec.rb +9 -5
- data/spec/kamerling/uuid_entity_spec.rb +53 -25
- data/spec/kamerling/uuid_spec.rb +19 -16
- data/spec/kamerling/value_spec.rb +21 -0
- data/spec/spec_helper.rb +3 -6
- metadata +54 -8
- data/lib/kamerling/core_extensions.rb +0 -1
    
        data/lib/kamerling/server/tcp.rb
    CHANGED
    
    | @@ -1,19 +1,27 @@ | |
| 1 | 
            -
             | 
| 2 | 
            -
             | 
| 1 | 
            +
            require 'socket'
         | 
| 2 | 
            +
            require_relative '../addr'
         | 
| 3 | 
            +
            require_relative 'sock'
         | 
| 3 4 |  | 
| 4 | 
            -
             | 
| 5 | 
            -
             | 
| 6 | 
            -
                 | 
| 7 | 
            -
             | 
| 8 | 
            -
              ensure
         | 
| 9 | 
            -
                socket.close
         | 
| 10 | 
            -
              end
         | 
| 5 | 
            +
            module Kamerling
         | 
| 6 | 
            +
              module Server
         | 
| 7 | 
            +
                class TCP < Sock
         | 
| 8 | 
            +
                  private
         | 
| 11 9 |  | 
| 12 | 
            -
             | 
| 13 | 
            -
             | 
| 14 | 
            -
             | 
| 10 | 
            +
                  def handle_connection(socket)
         | 
| 11 | 
            +
                    client_addr = Addr[*socket.remote_address.ip_unpack, :TCP]
         | 
| 12 | 
            +
                    input       = socket.read
         | 
| 13 | 
            +
                    handle input, client_addr
         | 
| 14 | 
            +
                  ensure
         | 
| 15 | 
            +
                    socket.close
         | 
| 16 | 
            +
                  end
         | 
| 17 | 
            +
             | 
| 18 | 
            +
                  def run_loop
         | 
| 19 | 
            +
                    Socket.tcp_server_loop(*addr) { |socket| handle_connection socket }
         | 
| 20 | 
            +
                  end
         | 
| 15 21 |  | 
| 16 | 
            -
             | 
| 17 | 
            -
             | 
| 22 | 
            +
                  def wait_till_started
         | 
| 23 | 
            +
                    loop { break if addr.connectable? }
         | 
| 24 | 
            +
                  end
         | 
| 25 | 
            +
                end
         | 
| 18 26 | 
             
              end
         | 
| 19 | 
            -
            end | 
| 27 | 
            +
            end
         | 
    
        data/lib/kamerling/server/udp.rb
    CHANGED
    
    | @@ -1,20 +1,28 @@ | |
| 1 | 
            -
             | 
| 2 | 
            -
             | 
| 1 | 
            +
            require 'socket'
         | 
| 2 | 
            +
            require_relative '../addr'
         | 
| 3 | 
            +
            require_relative 'sock'
         | 
| 3 4 |  | 
| 4 | 
            -
             | 
| 5 | 
            -
             | 
| 6 | 
            -
                 | 
| 7 | 
            -
             | 
| 8 | 
            -
              end
         | 
| 5 | 
            +
            module Kamerling
         | 
| 6 | 
            +
              module Server
         | 
| 7 | 
            +
                class UDP < Sock
         | 
| 8 | 
            +
                  private
         | 
| 9 9 |  | 
| 10 | 
            -
             | 
| 11 | 
            -
             | 
| 12 | 
            -
             | 
| 13 | 
            -
             | 
| 14 | 
            -
             | 
| 15 | 
            -
             | 
| 10 | 
            +
                  def handle_connection(socket)
         | 
| 11 | 
            +
                    input, conn = socket.recvfrom 2**16
         | 
| 12 | 
            +
                    client_addr = Addr[conn[3], conn[1], :UDP]
         | 
| 13 | 
            +
                    handle input, client_addr
         | 
| 14 | 
            +
                  end
         | 
| 15 | 
            +
             | 
| 16 | 
            +
                  def run_loop
         | 
| 17 | 
            +
                    socket = UDPSocket.new.tap { |server| server.bind(*addr) }
         | 
| 18 | 
            +
                    loop { handle_connection socket if IO.select [socket] }
         | 
| 19 | 
            +
                  ensure
         | 
| 20 | 
            +
                    socket.close if socket
         | 
| 21 | 
            +
                  end
         | 
| 16 22 |  | 
| 17 | 
            -
             | 
| 18 | 
            -
             | 
| 23 | 
            +
                  def wait_till_started
         | 
| 24 | 
            +
                    200.times { thread.run }
         | 
| 25 | 
            +
                  end
         | 
| 26 | 
            +
                end
         | 
| 19 27 | 
             
              end
         | 
| 20 | 
            -
            end | 
| 28 | 
            +
            end
         | 
| @@ -1,48 +1,37 @@ | |
| 1 | 
            -
            require ' | 
| 2 | 
            -
             | 
| 3 | 
            -
             | 
| 4 | 
            -
             | 
| 5 | 
            -
             | 
| 6 | 
            -
             | 
| 7 | 
            -
             | 
| 8 | 
            -
             | 
| 9 | 
            -
             | 
| 10 | 
            -
             | 
| 11 | 
            -
             | 
| 12 | 
            -
             | 
| 13 | 
            -
             | 
| 14 | 
            -
             | 
| 15 | 
            -
             | 
| 16 | 
            -
             | 
| 17 | 
            -
             | 
| 18 | 
            -
                servers.each(&:start)
         | 
| 19 | 
            -
                self
         | 
| 20 | 
            -
              end
         | 
| 21 | 
            -
             | 
| 22 | 
            -
              attr_reader :args, :servers
         | 
| 23 | 
            -
              private     :args, :servers
         | 
| 1 | 
            +
            require 'sequel'
         | 
| 2 | 
            +
            require_relative 'addr'
         | 
| 3 | 
            +
            require_relative 'repos'
         | 
| 4 | 
            +
            require_relative 'server/http'
         | 
| 5 | 
            +
            require_relative 'server/tcp'
         | 
| 6 | 
            +
            require_relative 'server/udp'
         | 
| 7 | 
            +
            require_relative 'settings'
         | 
| 8 | 
            +
             | 
| 9 | 
            +
            module Kamerling
         | 
| 10 | 
            +
              class ServerRunner
         | 
| 11 | 
            +
                def initialize(args, classes: def_classes, orm: Sequel, repos: Repos)
         | 
| 12 | 
            +
                  settings = Settings.new(args)
         | 
| 13 | 
            +
                  repos.db = orm.connect(settings.db)
         | 
| 14 | 
            +
                  @servers = settings.server_addrs.map do |type, addr|
         | 
| 15 | 
            +
                    classes[type].new(addr: addr)
         | 
| 16 | 
            +
                  end
         | 
| 17 | 
            +
                end
         | 
| 24 18 |  | 
| 25 | 
            -
             | 
| 19 | 
            +
                def join
         | 
| 20 | 
            +
                  servers.each(&:join)
         | 
| 21 | 
            +
                end
         | 
| 26 22 |  | 
| 27 | 
            -
             | 
| 23 | 
            +
                def start
         | 
| 24 | 
            +
                  servers.each(&:start)
         | 
| 25 | 
            +
                  self
         | 
| 26 | 
            +
                end
         | 
| 28 27 |  | 
| 29 | 
            -
             | 
| 30 | 
            -
                 | 
| 31 | 
            -
              end
         | 
| 28 | 
            +
                attr_reader :servers
         | 
| 29 | 
            +
                private     :servers
         | 
| 32 30 |  | 
| 33 | 
            -
             | 
| 34 | 
            -
                Settings.new 'sqlite::memory:', '127.0.0.1'
         | 
| 35 | 
            -
              end
         | 
| 31 | 
            +
                private
         | 
| 36 32 |  | 
| 37 | 
            -
             | 
| 38 | 
            -
             | 
| 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  }
         | 
| 45 | 
            -
                  end.parse! args
         | 
| 33 | 
            +
                def def_classes
         | 
| 34 | 
            +
                  { http: Server::HTTP, tcp: Server::TCP, udp: Server::UDP }
         | 
| 46 35 | 
             
                end
         | 
| 47 36 | 
             
              end
         | 
| 48 | 
            -
            end | 
| 37 | 
            +
            end
         | 
| @@ -0,0 +1,28 @@ | |
| 1 | 
            +
            require 'optparse'
         | 
| 2 | 
            +
            require_relative 'addr'
         | 
| 3 | 
            +
            require_relative 'value'
         | 
| 4 | 
            +
             | 
| 5 | 
            +
            module Kamerling
         | 
| 6 | 
            +
              class Settings < Value
         | 
| 7 | 
            +
                vals db: String, host: String, http: Integer, tcp: Integer, udp: Integer
         | 
| 8 | 
            +
             | 
| 9 | 
            +
                def initialize(args)
         | 
| 10 | 
            +
                  super db: 'sqlite::memory:', host: '127.0.0.1'
         | 
| 11 | 
            +
                  OptionParser.new do |opt|
         | 
| 12 | 
            +
                    opt.on("--db #{db}", String, 'database') { |db|   self.db   = db   }
         | 
| 13 | 
            +
                    opt.on("--host #{host}", String, 'host') { |host| self.host = host }
         | 
| 14 | 
            +
                    opt.on('--http 0', Integer, 'HTTP port') { |http| self.http = http }
         | 
| 15 | 
            +
                    opt.on('--tcp 0',  Integer, 'TCP port')  { |tcp|  self.tcp  = tcp  }
         | 
| 16 | 
            +
                    opt.on('--udp 0',  Integer, 'UDP port')  { |udp|  self.udp  = udp  }
         | 
| 17 | 
            +
                  end.parse! args
         | 
| 18 | 
            +
                end
         | 
| 19 | 
            +
             | 
| 20 | 
            +
                def server_addrs
         | 
| 21 | 
            +
                  {
         | 
| 22 | 
            +
                    http: Addr[host, http, :TCP],
         | 
| 23 | 
            +
                    tcp:  Addr[host, tcp,  :TCP],
         | 
| 24 | 
            +
                    udp:  Addr[host, udp,  :UDP],
         | 
| 25 | 
            +
                  }.select { |_, addr| addr.port }
         | 
| 26 | 
            +
                end
         | 
| 27 | 
            +
              end
         | 
| 28 | 
            +
            end
         | 
    
        data/lib/kamerling/task.rb
    CHANGED
    
    | @@ -1,9 +1,9 @@ | |
| 1 | 
            -
             | 
| 2 | 
            -
             | 
| 3 | 
            -
              attribute :done,    Boolean, default: false
         | 
| 4 | 
            -
              attribute :project, Project
         | 
| 1 | 
            +
            require_relative 'project'
         | 
| 2 | 
            +
            require_relative 'uuid_entity'
         | 
| 5 3 |  | 
| 6 | 
            -
             | 
| 7 | 
            -
             | 
| 4 | 
            +
            module Kamerling
         | 
| 5 | 
            +
              class Task < UUIDEntity
         | 
| 6 | 
            +
                attrs data: String, done: Boolean, project: Project
         | 
| 7 | 
            +
                defaults done: false
         | 
| 8 8 | 
             
              end
         | 
| 9 | 
            -
            end | 
| 9 | 
            +
            end
         | 
| @@ -1,29 +1,38 @@ | |
| 1 | 
            -
             | 
| 2 | 
            -
             | 
| 3 | 
            -
             | 
| 4 | 
            -
             | 
| 5 | 
            -
             | 
| 1 | 
            +
            require_relative 'dispatch'
         | 
| 2 | 
            +
            require_relative 'message'
         | 
| 3 | 
            +
            require_relative 'net_dispatcher'
         | 
| 4 | 
            +
            require_relative 'repos'
         | 
| 5 | 
            +
             | 
| 6 | 
            +
            module Kamerling
         | 
| 7 | 
            +
              class TaskDispatcher
         | 
| 8 | 
            +
                def initialize(net_dispatcher: NetDispatcher, repos: Repos)
         | 
| 9 | 
            +
                  @net_dispatcher = net_dispatcher
         | 
| 10 | 
            +
                  @repos          = repos
         | 
| 11 | 
            +
                end
         | 
| 6 12 |  | 
| 7 | 
            -
             | 
| 8 | 
            -
             | 
| 9 | 
            -
             | 
| 10 | 
            -
             | 
| 11 | 
            -
             | 
| 13 | 
            +
                def dispatch_all
         | 
| 14 | 
            +
                  repos.projects.each do |project|
         | 
| 15 | 
            +
                    repos.free_clients_for(project).each do |client|
         | 
| 16 | 
            +
                      task = repos.next_task_for(project)
         | 
| 17 | 
            +
                      dispatch_task client: client, project: project, task: task if task
         | 
| 18 | 
            +
                    end
         | 
| 12 19 | 
             
                  end
         | 
| 13 20 | 
             
                end
         | 
| 14 | 
            -
              end
         | 
| 15 21 |  | 
| 16 | 
            -
             | 
| 17 | 
            -
             | 
| 22 | 
            +
                attr_reader :net_dispatcher, :repos
         | 
| 23 | 
            +
                private     :net_dispatcher, :repos
         | 
| 18 24 |  | 
| 19 | 
            -
             | 
| 25 | 
            +
                private
         | 
| 20 26 |  | 
| 21 | 
            -
             | 
| 22 | 
            -
             | 
| 23 | 
            -
             | 
| 24 | 
            -
             | 
| 25 | 
            -
             | 
| 26 | 
            -
             | 
| 27 | 
            -
             | 
| 27 | 
            +
                def dispatch_task(client:, project:, task:)
         | 
| 28 | 
            +
                  message = Message.build(client: client, payload: task.data,
         | 
| 29 | 
            +
                                          project: project, task: task, type: :DATA)
         | 
| 30 | 
            +
                  dispatch = Dispatch.new(addr: client.addr, client: client,
         | 
| 31 | 
            +
                                          project: project, task: task)
         | 
| 32 | 
            +
                  net_dispatcher.dispatch client.addr, message
         | 
| 33 | 
            +
                  client.busy = true
         | 
| 34 | 
            +
                  repos << client
         | 
| 35 | 
            +
                  repos << dispatch
         | 
| 36 | 
            +
                end
         | 
| 28 37 | 
             
              end
         | 
| 29 | 
            -
            end | 
| 38 | 
            +
            end
         | 
    
        data/lib/kamerling/uuid.rb
    CHANGED
    
    | @@ -1,17 +1,19 @@ | |
| 1 1 | 
             
            require 'securerandom'
         | 
| 2 2 |  | 
| 3 | 
            -
            module Kamerling | 
| 4 | 
            -
               | 
| 3 | 
            +
            module Kamerling
         | 
| 4 | 
            +
              module UUID
         | 
| 5 | 
            +
                module_function
         | 
| 5 6 |  | 
| 6 | 
            -
             | 
| 7 | 
            -
             | 
| 8 | 
            -
             | 
| 7 | 
            +
                def [](bin)
         | 
| 8 | 
            +
                  bin.unpack('H8H4H4H4H12').join('-')
         | 
| 9 | 
            +
                end
         | 
| 9 10 |  | 
| 10 | 
            -
             | 
| 11 | 
            -
             | 
| 12 | 
            -
             | 
| 11 | 
            +
                def bin(uuid)
         | 
| 12 | 
            +
                  [uuid.tr('-', '')].pack('H*')
         | 
| 13 | 
            +
                end
         | 
| 13 14 |  | 
| 14 | 
            -
             | 
| 15 | 
            -
             | 
| 15 | 
            +
                def new
         | 
| 16 | 
            +
                  SecureRandom.uuid
         | 
| 17 | 
            +
                end
         | 
| 16 18 | 
             
              end
         | 
| 17 | 
            -
            end | 
| 19 | 
            +
            end
         | 
| @@ -1,15 +1,29 @@ | |
| 1 | 
            +
            require 'equalizer'
         | 
| 1 2 | 
             
            require 'virtus'
         | 
| 3 | 
            +
            require_relative 'uuid'
         | 
| 2 4 |  | 
| 3 | 
            -
            module Kamerling | 
| 4 | 
            -
               | 
| 5 | 
            +
            module Kamerling
         | 
| 6 | 
            +
              class UUIDEntity
         | 
| 7 | 
            +
                include Equalizer.new(:uuid)
         | 
| 5 8 |  | 
| 6 | 
            -
             | 
| 9 | 
            +
                include Virtus.model
         | 
| 7 10 |  | 
| 8 | 
            -
             | 
| 11 | 
            +
                attribute :uuid, String, default: -> (*) { UUID.new }
         | 
| 9 12 |  | 
| 10 | 
            -
             | 
| 11 | 
            -
             | 
| 12 | 
            -
             | 
| 13 | 
            +
                def self.attrs(hash = {})
         | 
| 14 | 
            +
                  hash.each { |name, klass| attribute name, klass }
         | 
| 15 | 
            +
                end
         | 
| 16 | 
            +
             | 
| 17 | 
            +
                def self.defaults(hash = {})
         | 
| 18 | 
            +
                  hash.each do |name, default|
         | 
| 19 | 
            +
                    warn_off { attribute name, attribute_set[name].type, default: default }
         | 
| 20 | 
            +
                  end
         | 
| 21 | 
            +
                end
         | 
| 13 22 |  | 
| 14 | 
            -
             | 
| 15 | 
            -
             | 
| 23 | 
            +
                def to_h
         | 
| 24 | 
            +
                  attributes.map do |key, value|
         | 
| 25 | 
            +
                    value.is_a?(UUIDEntity) ? [key, value.to_h] : [key, value]
         | 
| 26 | 
            +
                  end.to_h
         | 
| 27 | 
            +
                end
         | 
| 28 | 
            +
              end
         | 
| 29 | 
            +
            end
         | 
| @@ -2,5 +2,7 @@ nav | |
| 2 2 | 
             
              ul#clients
         | 
| 3 3 | 
             
                - clients.each do |client|
         | 
| 4 4 | 
             
                  li
         | 
| 5 | 
            -
                    a | 
| 5 | 
            +
                    a(data-addr=client.addr data-busy=client.busy.to_s data-class='client'
         | 
| 6 | 
            +
                      data-type=client.type data-uuid=client.uuid
         | 
| 7 | 
            +
                      href="/clients/#{client.uuid}")
         | 
| 6 8 | 
             
                      = client.busy
         | 
| @@ -2,10 +2,14 @@ nav | |
| 2 2 | 
             
              ul#clients
         | 
| 3 3 | 
             
                - clients.each do |client|
         | 
| 4 4 | 
             
                  li
         | 
| 5 | 
            -
                    a | 
| 6 | 
            -
                      = client. | 
| 5 | 
            +
                    a(data-busy=client.busy.to_s data-class='client' data-type=client.type
         | 
| 6 | 
            +
                      data-uuid=client.uuid href="/clients/#{client.uuid}")
         | 
| 7 | 
            +
                      = client.uuid
         | 
| 8 | 
            +
                    = "busy: #{client.busy.to_s}"
         | 
| 7 9 | 
             
              ul#tasks
         | 
| 8 10 | 
             
                - tasks.each do |task|
         | 
| 9 11 | 
             
                  li
         | 
| 10 | 
            -
                    a data-done=task.done.to_s data-uuid=task.uuid | 
| 11 | 
            -
                      = | 
| 12 | 
            +
                    a(data-class='task' data-done=task.done.to_s data-uuid=task.uuid
         | 
| 13 | 
            +
                      href="/tasks/#{task.uuid}")
         | 
| 14 | 
            +
                      = task.uuid
         | 
| 15 | 
            +
                    = "done: #{task.done.to_s}"
         | 
| @@ -2,8 +2,14 @@ nav | |
| 2 2 | 
             
              ul#projects
         | 
| 3 3 | 
             
                - projects.each do |project|
         | 
| 4 4 | 
             
                  li
         | 
| 5 | 
            -
                    a | 
| 5 | 
            +
                    a(data-class='project' data-uuid=project.uuid
         | 
| 6 | 
            +
                      href="/projects/#{project.uuid}")
         | 
| 6 7 | 
             
                      = project.name
         | 
| 7 8 |  | 
| 8 9 | 
             
            form action='/projects' method='POST'
         | 
| 9 10 | 
             
              input name='name'
         | 
| 11 | 
            +
              input name='uuid' type='hidden' value=Kamerling::UUID.new
         | 
| 12 | 
            +
              input type='submit' value='create'
         | 
| 13 | 
            +
             | 
| 14 | 
            +
            form action='/projects/dispatch' method='POST'
         | 
| 15 | 
            +
              input type='submit' value='dispatch'
         | 
    
        data/spec/kamerling/addr_spec.rb
    CHANGED
    
    | @@ -1,33 +1,43 @@ | |
| 1 | 
            +
            require 'socket'
         | 
| 1 2 | 
             
            require_relative '../spec_helper'
         | 
| 3 | 
            +
            require_relative '../../lib/kamerling/addr'
         | 
| 2 4 |  | 
| 3 | 
            -
            module Kamerling | 
| 4 | 
            -
               | 
| 5 | 
            +
            module Kamerling
         | 
| 6 | 
            +
              describe Addr do
         | 
| 7 | 
            +
                let(:addr) { Addr['localhost', 1981, :TCP] }
         | 
| 5 8 |  | 
| 6 | 
            -
             | 
| 7 | 
            -
             | 
| 8 | 
            -
             | 
| 9 | 
            -
             | 
| 10 | 
            -
             | 
| 11 | 
            -
             | 
| 9 | 
            +
                describe '#connectable?' do
         | 
| 10 | 
            +
                  it 'is a predicate whether the (TCP) address is connectable' do
         | 
| 11 | 
            +
                    server = TCPServer.new(*addr)
         | 
| 12 | 
            +
                    addr.must_be :connectable?
         | 
| 13 | 
            +
                    server.close
         | 
| 14 | 
            +
                    addr.wont_be :connectable?
         | 
| 15 | 
            +
                  end
         | 
| 12 16 | 
             
                end
         | 
| 13 | 
            -
              end
         | 
| 14 17 |  | 
| 15 | 
            -
             | 
| 16 | 
            -
             | 
| 17 | 
            -
             | 
| 18 | 
            -
             | 
| 18 | 
            +
                describe '#to_a' do
         | 
| 19 | 
            +
                  it 'returns host + port for splat use' do
         | 
| 20 | 
            +
                    splat = *addr
         | 
| 21 | 
            +
                    splat.must_equal ['localhost', 1981]
         | 
| 22 | 
            +
                  end
         | 
| 19 23 | 
             
                end
         | 
| 20 | 
            -
              end
         | 
| 21 24 |  | 
| 22 | 
            -
             | 
| 23 | 
            -
             | 
| 24 | 
            -
             | 
| 25 | 
            +
                describe '#to_h' do
         | 
| 26 | 
            +
                  it 'returns a Hash with Integer and String values' do
         | 
| 27 | 
            +
                    addr.to_h.must_equal host: 'localhost', port: 1981, prot: 'TCP'
         | 
| 28 | 
            +
                  end
         | 
| 29 | 
            +
                end
         | 
| 30 | 
            +
             | 
| 31 | 
            +
                describe '#to_s' do
         | 
| 32 | 
            +
                  it 'returns the Addr in URI notation' do
         | 
| 33 | 
            +
                    addr.to_s.must_equal 'tcp://localhost:1981'
         | 
| 34 | 
            +
                  end
         | 
| 25 35 | 
             
                end
         | 
| 26 | 
            -
              end
         | 
| 27 36 |  | 
| 28 | 
            -
             | 
| 29 | 
            -
             | 
| 30 | 
            -
             | 
| 37 | 
            +
                describe '#uri' do
         | 
| 38 | 
            +
                  it 'returns and URI representation of the Addr' do
         | 
| 39 | 
            +
                    addr.uri.must_equal URI.parse('tcp://localhost:1981')
         | 
| 40 | 
            +
                  end
         | 
| 31 41 | 
             
                end
         | 
| 32 42 | 
             
              end
         | 
| 33 | 
            -
            end | 
| 43 | 
            +
            end
         |