Hello community,

here is the log from the commit of package rubygem-nio4r for openSUSE:Factory 
checked in at 2018-02-12 10:13:33
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/rubygem-nio4r (Old)
 and      /work/SRC/openSUSE:Factory/.rubygem-nio4r.new (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "rubygem-nio4r"

Mon Feb 12 10:13:33 2018 rev:4 rq:574047 version:2.2.0

Changes:
--------
--- /work/SRC/openSUSE:Factory/rubygem-nio4r/rubygem-nio4r.changes      
2017-06-02 10:33:50.735553748 +0200
+++ /work/SRC/openSUSE:Factory/.rubygem-nio4r.new/rubygem-nio4r.changes 
2018-02-12 10:13:35.513014684 +0100
@@ -1,0 +2,44 @@
+Tue Jan  9 07:37:26 UTC 2018 - co...@suse.com
+
+- updated to version 2.2.0
+ see installed CHANGES.md
+
+  ## 2.2.0 (2017-12-27)
+  
+  * [#151](https://github.com/socketry/nio4r/pull/151)
+    `NIO::Selector`: Support for enumerating and configuring backend
+    ([@tarcieri])
+  
+  * [#153](https://github.com/socketry/nio4r/pull/153)
+    Fix builds on Windows
+    ([@unak])
+  
+  * [#157](https://github.com/socketry/nio4r/pull/157)
+    Windows / MinGW test failure - fix spec_helper.rb
+    ([@MSP-Greg])
+  
+  * [#162](https://github.com/socketry/nio4r/pull/162)
+    Don't build the C extension on Windows
+    ([@larskanis])
+  
+  * [#164](https://github.com/socketry/nio4r/pull/164)
+    Fix NIO::ByteBuffer leak
+    ([@HoneyryderChuck])
+  
+  * [#170](https://github.com/socketry/nio4r/pull/170)
+    Avoid CancelledKeyExceptions on JRuby
+    ([@HoneyryderChuck])
+  
+  * [#177](https://github.com/socketry/nio4r/pull/177)
+    Fix `NIO::ByteBuffer` string conversions on JRuby
+    ([@tarcieri])
+  
+  * [#179](https://github.com/socketry/nio4r/pull/179)
+    Fix argument error when running on ruby 2.5.0
+    ([@tompng])
+  
+  * [#180](https://github.com/socketry/nio4r/pull/180)
+    ext/nio4r/extconf.rb: check for port_event_t in port.h (fixes #178)
+    ([@tarcieri])
+
+-------------------------------------------------------------------

Old:
----
  nio4r-2.1.0.gem

New:
----
  nio4r-2.2.0.gem

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ rubygem-nio4r.spec ++++++
--- /var/tmp/diff_new_pack.qLKd60/_old  2018-02-12 10:13:36.720971153 +0100
+++ /var/tmp/diff_new_pack.qLKd60/_new  2018-02-12 10:13:36.724971009 +0100
@@ -1,7 +1,7 @@
 #
 # spec file for package rubygem-nio4r
 #
-# Copyright (c) 2017 SUSE LINUX GmbH, Nuernberg, Germany.
+# Copyright (c) 2018 SUSE LINUX GmbH, Nuernberg, Germany.
 #
 # All modifications and additions to the file contributed by third parties
 # remain the property of their copyright owners, unless otherwise agreed
@@ -24,7 +24,7 @@
 #
 
 Name:           rubygem-nio4r
-Version:        2.1.0
+Version:        2.2.0
 Release:        0
 %define mod_name nio4r
 %define mod_full_name %{mod_name}-%{version}
@@ -33,7 +33,7 @@
 BuildRequires:  %{rubygem gem2rpm}
 BuildRequires:  ruby-macros >= 5
 Url:            https://github.com/socketry/nio4r
-Source:         http://rubygems.org/gems/%{mod_full_name}.gem
+Source:         https://rubygems.org/gems/%{mod_full_name}.gem
 Source1:        rubygem-nio4r-rpmlintrc
 Source2:        gem2rpm.yml
 Summary:        New IO for Ruby

++++++ nio4r-2.1.0.gem -> nio4r-2.2.0.gem ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/.rubocop.yml new/.rubocop.yml
--- old/.rubocop.yml    2017-05-28 22:58:36.000000000 +0200
+++ new/.rubocop.yml    2017-12-27 17:33:22.000000000 +0100
@@ -1,4 +1,5 @@
 AllCops:
+  TargetRubyVersion: 2.2
   DisplayCopNames: true
 
 #
@@ -18,6 +19,9 @@
 Metrics/AbcSize:
   Max: 35
 
+Metrics/BlockLength:
+  Max: 128
+
 Metrics/ClassLength:
   Max: 128
 
@@ -35,11 +39,21 @@
   Max: 15
 
 #
+# Performance
+#
+
+Performance/RegexpMatch:
+  Enabled: false
+
+#
 # Style
 #
 
-Style/StringLiterals:
-  EnforcedStyle: double_quotes
+Style/FormatStringToken:
+  Enabled: false
+
+Style/FrozenStringLiteralComment:
+  Enabled: true
 
 Style/GlobalVars:
   Enabled: false
@@ -50,5 +64,11 @@
 Style/RescueModifier:
   Enabled: false
 
+Style/SafeNavigation:
+  Enabled: false
+
+Style/StringLiterals:
+  EnforcedStyle: double_quotes
+
 Style/TrivialAccessors:
   Enabled: false
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/.ruby-version new/.ruby-version
--- old/.ruby-version   2017-05-28 22:58:36.000000000 +0200
+++ new/.ruby-version   1970-01-01 01:00:00.000000000 +0100
@@ -1 +0,0 @@
-2.4.0
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/.travis.yml new/.travis.yml
--- old/.travis.yml     2017-05-28 22:58:36.000000000 +0200
+++ new/.travis.yml     2017-12-27 17:33:22.000000000 +0100
@@ -3,7 +3,7 @@
 cache: bundler
 
 before_install:
-  - gem update --system 2.6.10
+  - gem update --system
   - gem --version
 
 bundler_args: --without development
@@ -13,10 +13,11 @@
     - master
 
 rvm:
-  - jruby-9.1.10.0 # latest stable
+  - jruby-9.1.15.0 # latest stable
   - 2.2.7
   - 2.3.4
   - 2.4.1
+  - 2.5.0
   - ruby-head
 
 env:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/CHANGES.md new/CHANGES.md
--- old/CHANGES.md      2017-05-28 22:58:36.000000000 +0200
+++ new/CHANGES.md      2017-12-27 17:33:22.000000000 +0100
@@ -1,3 +1,41 @@
+## 2.2.0 (2017-12-27)
+
+* [#151](https://github.com/socketry/nio4r/pull/151)
+  `NIO::Selector`: Support for enumerating and configuring backend
+  ([@tarcieri])
+
+* [#153](https://github.com/socketry/nio4r/pull/153)
+  Fix builds on Windows
+  ([@unak])
+
+* [#157](https://github.com/socketry/nio4r/pull/157)
+  Windows / MinGW test failure - fix spec_helper.rb
+  ([@MSP-Greg])
+
+* [#162](https://github.com/socketry/nio4r/pull/162)
+  Don't build the C extension on Windows
+  ([@larskanis])
+
+* [#164](https://github.com/socketry/nio4r/pull/164)
+  Fix NIO::ByteBuffer leak
+  ([@HoneyryderChuck])
+
+* [#170](https://github.com/socketry/nio4r/pull/170)
+  Avoid CancelledKeyExceptions on JRuby
+  ([@HoneyryderChuck])
+
+* [#177](https://github.com/socketry/nio4r/pull/177)
+  Fix `NIO::ByteBuffer` string conversions on JRuby
+  ([@tarcieri])
+
+* [#179](https://github.com/socketry/nio4r/pull/179)
+  Fix argument error when running on ruby 2.5.0
+  ([@tompng])
+
+* [#180](https://github.com/socketry/nio4r/pull/180)
+  ext/nio4r/extconf.rb: check for port_event_t in port.h (fixes #178)
+  ([@tarcieri])
+
 ## 2.1.0 (2017-05-28)
 
 * [#130](https://github.com/socketry/nio4r/pull/130)
@@ -163,3 +201,8 @@
 [@johnnyt]: https://github.com/johnnyt
 [@UpeksheJay]: https://github.com/UpeksheJay
 [@junaruga]: https://github.com/junaruga
+[@unak]: https://github.com/unak
+[@MSP-Greg]: https://github.com/MSP-Greg
+[@larskanis]: https://github.com/larskanis
+[@HoneyryderChuck]: https://github.com/HoneyryderChuck
+[@tompng]: https://github.com/tompng
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Gemfile new/Gemfile
--- old/Gemfile 2017-05-28 22:58:36.000000000 +0200
+++ new/Gemfile 2017-12-27 17:33:22.000000000 +0100
@@ -14,7 +14,7 @@
 group :development, :test do
   gem "coveralls",         require: false
   gem "rake-compiler",     require: false
-  gem "rspec", "~> 3",     require: false
+  gem "rspec", "~> 3.7",   require: false
   gem "rspec-retry",       require: false
-  gem "rubocop", "0.46.0", require: false
+  gem "rubocop", "0.52.1", require: false
 end
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Guardfile new/Guardfile
--- old/Guardfile       2017-05-28 22:58:36.000000000 +0200
+++ new/Guardfile       2017-12-27 17:33:22.000000000 +0100
@@ -1,6 +1,6 @@
 # frozen_string_literal: true
 
-directories %w(lib spec)
+directories %w[lib spec]
 clearing :on
 
 guard :rspec, cmd: "bundle exec rspec" do
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/README.md new/README.md
--- old/README.md       2017-05-28 22:58:36.000000000 +0200
+++ new/README.md       2017-12-27 17:33:22.000000000 +0100
@@ -1,9 +1,11 @@
 # ![nio4r](https://raw.github.com/socketry/nio4r/master/logo.png)
 
 [![Gem 
Version](https://badge.fury.io/rb/nio4r.svg)](http://rubygems.org/gems/nio4r)
-[![Build 
Status](https://secure.travis-ci.org/socketry/nio4r.svg?branch=master)](http://travis-ci.org/socketry/nio4r)
+[![Travis CI 
Status](https://secure.travis-ci.org/socketry/nio4r.svg?branch=master)](http://travis-ci.org/socketry/nio4r)
+[![Appveyor 
Status](https://ci.appveyor.com/api/projects/status/1ru8x81v91vaewax/branch/master?svg=true)](https://ci.appveyor.com/project/tarcieri/nio4r/branch/master)
 [![Code 
Climate](https://codeclimate.com/github/socketry/nio4r.svg)](https://codeclimate.com/github/socketry/nio4r)
 [![Coverage 
Status](https://coveralls.io/repos/socketry/nio4r/badge.svg?branch=master)](https://coveralls.io/r/socketry/nio4r)
+[![Yard 
Docs](https://img.shields.io/badge/yard-docs-blue.svg)](http://www.rubydoc.info/gems/nio4r/2.2.0)
 [![MIT 
licensed](https://img.shields.io/badge/license-MIT-blue.svg)](https://github.com/socketry/nio4r/blob/master/LICENSE.txt)
 
 _NOTE: This is the 2.x **stable** branch of nio4r.  For the 1.x **legacy** 
branch,
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Rakefile new/Rakefile
--- old/Rakefile        2017-05-28 22:58:36.000000000 +0200
+++ new/Rakefile        2017-12-27 17:33:22.000000000 +0100
@@ -5,6 +5,6 @@
 
 Dir[File.expand_path("../tasks/**/*.rake", __FILE__)].each { |task| load task }
 
-task default: %w(compile spec rubocop)
+task default: %w[compile spec rubocop]
 
 CLEAN.include "**/*.o", "**/*.so", "**/*.bundle", "**/*.jar", "pkg", "tmp"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/appveyor.yml new/appveyor.yml
--- old/appveyor.yml    1970-01-01 01:00:00.000000000 +0100
+++ new/appveyor.yml    2017-12-27 17:33:22.000000000 +0100
@@ -0,0 +1,27 @@
+branches:
+  only:
+    - master
+
+environment:
+  PATH: 
C:\Ruby%RUBY_VERSION%\DevKit\mingw\bin;C:\Ruby%RUBY_VERSION%\bin;C:\Ruby%RUBY_VERSION%\DevKit\bin;%PATH%
+  matrix:
+  - RUBY_VERSION: "24-x64"
+  - RUBY_VERSION: "23-x64"
+  - RUBY_VERSION: "23"
+  - RUBY_VERSION: "22"
+
+install:
+  - SET RAKEOPT=-rdevkit
+  - ruby -v
+  - gem -v
+  - bundle -v
+  - bundle install
+
+build: off
+
+before_build:
+  - gem update --system
+
+test_script:
+  - echo %PATH%
+  - bundle exec rake spec
Binary files old/checksums.yaml.gz and new/checksums.yaml.gz differ
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ext/nio4r/bytebuffer.c new/ext/nio4r/bytebuffer.c
--- old/ext/nio4r/bytebuffer.c  2017-05-28 22:58:36.000000000 +0200
+++ new/ext/nio4r/bytebuffer.c  2017-12-27 17:33:22.000000000 +0100
@@ -75,6 +75,7 @@
 static VALUE NIO_ByteBuffer_allocate(VALUE klass)
 {
     struct NIO_ByteBuffer *bytebuffer = (struct NIO_ByteBuffer 
*)xmalloc(sizeof(struct NIO_ByteBuffer));
+    bytebuffer->buffer = NULL;
     return Data_Wrap_Struct(klass, NIO_ByteBuffer_gc_mark, 
NIO_ByteBuffer_free, bytebuffer);
 }
 
@@ -84,6 +85,8 @@
 
 static void NIO_ByteBuffer_free(struct NIO_ByteBuffer *buffer)
 {
+    if(buffer->buffer)
+      xfree(buffer->buffer);
     xfree(buffer);
 }
 
@@ -124,10 +127,11 @@
 
 static VALUE NIO_ByteBuffer_set_position(VALUE self, VALUE new_position)
 {
+    int pos;
     struct NIO_ByteBuffer *buffer;
     Data_Get_Struct(self, struct NIO_ByteBuffer, buffer);
 
-    int pos = NUM2INT(new_position);
+    pos = NUM2INT(new_position);
 
     if(pos < 0) {
         rb_raise(rb_eArgError, "negative position given");
@@ -156,10 +160,11 @@
 
 static VALUE NIO_ByteBuffer_set_limit(VALUE self, VALUE new_limit)
 {
+    int lim;
     struct NIO_ByteBuffer *buffer;
     Data_Get_Struct(self, struct NIO_ByteBuffer, buffer);
 
-    int lim = NUM2INT(new_limit);
+    lim = NUM2INT(new_limit);
 
     if(lim < 0) {
         rb_raise(rb_eArgError, "negative limit given");
@@ -237,10 +242,11 @@
 
 static VALUE NIO_ByteBuffer_fetch(VALUE self, VALUE index)
 {
+    int i;
     struct NIO_ByteBuffer *buffer;
     Data_Get_Struct(self, struct NIO_ByteBuffer, buffer);
 
-    int i = NUM2INT(index);
+    i = NUM2INT(index);
 
     if(i < 0) {
         rb_raise(rb_eArgError, "negative index given");
@@ -255,10 +261,12 @@
 
 static VALUE NIO_ByteBuffer_put(VALUE self, VALUE string)
 {
+    long length;
     struct NIO_ByteBuffer *buffer;
     Data_Get_Struct(self, struct NIO_ByteBuffer, buffer);
 
-    long length = RSTRING_LEN(string);
+    StringValue(string);
+    length = RSTRING_LEN(string);
 
     if(length > buffer->limit - buffer->position) {
         rb_raise(cNIO_ByteBuffer_OverflowError, "buffer is full");
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ext/nio4r/extconf.rb new/ext/nio4r/extconf.rb
--- old/ext/nio4r/extconf.rb    2017-05-28 22:58:36.000000000 +0200
+++ new/ext/nio4r/extconf.rb    2017-12-27 17:33:22.000000000 +0100
@@ -1,35 +1,26 @@
 # frozen_string_literal: true
 
-require "mkmf"
-
-have_header("unistd.h")
-
-$defs << "-DEV_USE_SELECT" if have_header("sys/select.h")
+require "rubygems"
 
-$defs << "-DEV_USE_POLL" if have_header("poll.h")
-
-$defs << "-DEV_USE_EPOLL" if have_header("sys/epoll.h")
-
-if have_header("sys/event.h") && have_header("sys/queue.h")
-  $defs << "-DEV_USE_KQUEUE"
+# Write a dummy Makefile on Windows because we use the pure Ruby 
implementation there
+if Gem.win_platform?
+  File.write("Makefile", "all install::\n")
+  File.write("nio4r_ext.so", "")
+  exit
 end
 
-$defs << "-DEV_USE_PORT" if have_header("port.h")
+require "mkmf"
 
+have_header("unistd.h")
+
+$defs << "-DEV_USE_SELECT"       if have_header("sys/select.h")
+$defs << "-DEV_USE_POLL"         if have_type("port_event_t", "poll.h")
+$defs << "-DEV_USE_EPOLL"        if have_header("sys/epoll.h")
+$defs << "-DEV_USE_KQUEUE"       if have_header("sys/event.h") && 
have_header("sys/queue.h")
+$defs << "-DEV_USE_PORT"         if have_type("port_event_t", "port.h")
 $defs << "-DHAVE_SYS_RESOURCE_H" if have_header("sys/resource.h")
 
-CONFIG["optflags"] << " -fno-strict-aliasing"
+CONFIG["optflags"] << " -fno-strict-aliasing" unless RUBY_PLATFORM =~ /mswin/
 
 dir_config "nio4r_ext"
 create_makefile "nio4r_ext"
-
-# win32 needs to link in "just the right order" for some reason or
-# ioctlsocket will be mapped to an [inverted] ruby specific version.
-if RUBY_PLATFORM =~ /mingw|win32/
-  makefile_contents = File.read "Makefile"
-
-  makefile_contents.gsub! "DLDFLAGS = ", "DLDFLAGS = -export-all "
-
-  makefile_contents.gsub! "LIBS = $(LIBRUBYARG_SHARED)", "LIBS = -lws2_32 
$(LIBRUBYARG_SHARED)"
-  File.open("Makefile", "w") { |f| f.write makefile_contents }
-end
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ext/nio4r/monitor.c new/ext/nio4r/monitor.c
--- old/ext/nio4r/monitor.c     2017-05-28 22:58:36.000000000 +0200
+++ new/ext/nio4r/monitor.c     2017-12-27 17:33:22.000000000 +0100
@@ -92,7 +92,7 @@
         monitor->interests = EV_READ | EV_WRITE;
     } else {
         rb_raise(rb_eArgError, "invalid event type %s (must be :r, :w, or 
:rw)",
-            RSTRING_PTR(rb_funcall(interests, rb_intern("inspect"), 0, 0)));
+            RSTRING_PTR(rb_funcall(interests, rb_intern("inspect"), 0)));
     }
 
     GetOpenFile(rb_convert_type(io, T_FILE, "IO", "to_io"), fptr);
@@ -258,7 +258,7 @@
         return EV_READ | EV_WRITE;
     } else {
         rb_raise(rb_eArgError, "invalid interest type %s (must be :r, :w, or 
:rw)",
-            RSTRING_PTR(rb_funcall(interests, rb_intern("inspect"), 0, 0)));
+            RSTRING_PTR(rb_funcall(interests, rb_intern("inspect"), 0)));
     }
 }
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ext/nio4r/nio4r_ext.c new/ext/nio4r/nio4r_ext.c
--- old/ext/nio4r/nio4r_ext.c   2017-05-28 22:58:36.000000000 +0200
+++ new/ext/nio4r/nio4r_ext.c   2017-12-27 17:33:22.000000000 +0100
@@ -12,6 +12,8 @@
 
 void Init_nio4r_ext()
 {
+    ev_set_allocator(xrealloc);
+
     Init_NIO_Selector();
     Init_NIO_Monitor();
     Init_NIO_ByteBuffer();
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ext/nio4r/org/nio4r/ByteBuffer.java 
new/ext/nio4r/org/nio4r/ByteBuffer.java
--- old/ext/nio4r/org/nio4r/ByteBuffer.java     2017-05-28 22:58:36.000000000 
+0200
+++ new/ext/nio4r/org/nio4r/ByteBuffer.java     2017-12-27 17:33:22.000000000 
+0100
@@ -163,10 +163,8 @@
 
     @JRubyMethod(name = "<<")
     public IRubyObject put(ThreadContext context, IRubyObject str) {
-        String string = str.asJavaString();
-
         try {
-            this.byteBuffer.put(string.getBytes());
+            this.byteBuffer.put(str.convertToString().getByteList().bytes());
         } catch(BufferOverflowException e) {
             throw ByteBuffer.newOverflowError(context, "buffer is full");
         }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ext/nio4r/org/nio4r/Monitor.java 
new/ext/nio4r/org/nio4r/Monitor.java
--- old/ext/nio4r/org/nio4r/Monitor.java        2017-05-28 22:58:36.000000000 
+0200
+++ new/ext/nio4r/org/nio4r/Monitor.java        2017-12-27 17:33:22.000000000 
+0100
@@ -102,12 +102,16 @@
 
     @JRubyMethod
     public IRubyObject readiness(ThreadContext context) {
+        if(!key.isValid())
+          return this.interests; 
         return Nio4r.interestOpsToSymbol(context.getRuntime(), key.readyOps());
     }
 
     @JRubyMethod(name = "readable?")
     public IRubyObject isReadable(ThreadContext context) {
         Ruby runtime  = context.getRuntime();
+        if (!this.key.isValid())
+          return runtime.getTrue();
         int  readyOps = this.key.readyOps();
 
         if((readyOps & SelectionKey.OP_READ) != 0 || (readyOps & 
SelectionKey.OP_ACCEPT) != 0) {
@@ -120,6 +124,8 @@
     @JRubyMethod(name = {"writable?", "writeable?"})
     public IRubyObject writable(ThreadContext context) {
         Ruby runtime  = context.getRuntime();
+        if (!this.key.isValid())
+          return runtime.getTrue();
         int  readyOps = this.key.readyOps();
 
         if((readyOps & SelectionKey.OP_WRITE) != 0 || (readyOps & 
SelectionKey.OP_CONNECT) != 0) {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ext/nio4r/org/nio4r/Selector.java 
new/ext/nio4r/org/nio4r/Selector.java
--- old/ext/nio4r/org/nio4r/Selector.java       2017-05-28 22:58:36.000000000 
+0200
+++ new/ext/nio4r/org/nio4r/Selector.java       2017-12-27 17:33:22.000000000 
+0100
@@ -7,6 +7,7 @@
 import java.nio.channels.Channel;
 import java.nio.channels.SelectableChannel;
 import java.nio.channels.SelectionKey;
+import java.nio.channels.CancelledKeyException;
 
 import org.jruby.Ruby;
 import org.jruby.RubyArray;
@@ -30,8 +31,23 @@
         super(ruby, rubyClass);
     }
 
+    @JRubyMethod(meta = true)
+    public static IRubyObject backends(ThreadContext context, IRubyObject 
self) {
+        return context.runtime.newArray(context.runtime.newSymbol("java"));
+    }
+
     @JRubyMethod
     public IRubyObject initialize(ThreadContext context) {
+        initialize(context, context.runtime.newSymbol("java"));
+        return context.nil;
+    }
+
+    @JRubyMethod
+    public IRubyObject initialize(ThreadContext context, IRubyObject backend) {
+        if(backend != context.runtime.newSymbol("java")) {
+            throw context.runtime.newArgumentError(":java is the only 
supported backend");
+        }
+
         this.cancelledKeys = new HashMap<SelectableChannel,SelectionKey>();
         this.wakeupFired = false;
 
@@ -193,6 +209,7 @@
         while(selectedKeys.hasNext()) {
             SelectionKey key = (SelectionKey)selectedKeys.next();
             processKey(key);
+
             selectedKeys.remove();
 
             if(block.isGiven()) {
@@ -254,7 +271,7 @@
     // Remove connect interest from connected sockets
     // See: 
http://stackoverflow.com/questions/204186/java-nio-select-returns-without-selected-keys-why
     private void processKey(SelectionKey key) {
-        if((key.readyOps() & SelectionKey.OP_CONNECT) != 0) {
+        if(key.isValid() && (key.readyOps() & SelectionKey.OP_CONNECT) != 0) {
             int interestOps = key.interestOps();
 
             interestOps &= ~SelectionKey.OP_CONNECT;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ext/nio4r/selector.c new/ext/nio4r/selector.c
--- old/ext/nio4r/selector.c    2017-05-28 22:58:36.000000000 +0200
+++ new/ext/nio4r/selector.c    2017-12-27 17:33:22.000000000 +0100
@@ -27,8 +27,11 @@
 static void NIO_Selector_shutdown(struct NIO_Selector *selector);
 static void NIO_Selector_free(struct NIO_Selector *loop);
 
-/* Methods */
-static VALUE NIO_Selector_initialize(VALUE self);
+/* Class methods */
+static VALUE NIO_Selector_supported_backends(VALUE klass);
+
+/* Instance methods */
+static VALUE NIO_Selector_initialize(int argc, VALUE *argv, VALUE self);
 static VALUE NIO_Selector_backend(VALUE self);
 static VALUE NIO_Selector_register(VALUE self, VALUE selectable, VALUE 
interest);
 static VALUE NIO_Selector_deregister(VALUE self, VALUE io);
@@ -65,7 +68,8 @@
     cNIO_Selector = rb_define_class_under(mNIO, "Selector", rb_cObject);
     rb_define_alloc_func(cNIO_Selector, NIO_Selector_allocate);
 
-    rb_define_method(cNIO_Selector, "initialize", NIO_Selector_initialize, 0);
+    rb_define_singleton_method(cNIO_Selector, "backends", 
NIO_Selector_supported_backends, 0);
+    rb_define_method(cNIO_Selector, "initialize", NIO_Selector_initialize, -1);
     rb_define_method(cNIO_Selector, "backend", NIO_Selector_backend, 0);
     rb_define_method(cNIO_Selector, "register", NIO_Selector_register, 2);
     rb_define_method(cNIO_Selector, "deregister", NIO_Selector_deregister, 1);
@@ -102,7 +106,9 @@
     }
 
     selector = (struct NIO_Selector *)xmalloc(sizeof(struct NIO_Selector));
-    selector->ev_loop = ev_loop_new(0);
+
+    /* Defer initializing the loop to #initialize */
+    selector->ev_loop = 0;
 
     ev_init(&selector->timer, NIO_Selector_timeout_callback);
 
@@ -112,8 +118,6 @@
     ev_io_init(&selector->wakeup, NIO_Selector_wakeup_callback, 
selector->wakeup_reader, EV_READ);
     selector->wakeup.data = (void *)selector;
 
-    ev_io_start(selector->ev_loop, &selector->wakeup);
-
     selector->closed = selector->selecting = selector->wakeup_fired = 
selector->ready_count = 0;
     selector->ready_array = Qnil;
 
@@ -154,12 +158,83 @@
     xfree(selector);
 }
 
+/* Return an array of symbols for supported backends */
+static VALUE NIO_Selector_supported_backends(VALUE klass) {
+    unsigned int backends = ev_supported_backends();
+    VALUE result = rb_ary_new();
+
+    if(backends & EVBACKEND_EPOLL) {
+        rb_ary_push(result, ID2SYM(rb_intern("epoll")));
+    }
+
+    if(backends & EVBACKEND_POLL) {
+        rb_ary_push(result, ID2SYM(rb_intern("poll")));
+    }
+
+    if(backends & EVBACKEND_KQUEUE) {
+        rb_ary_push(result, ID2SYM(rb_intern("kqueue")));
+    }
+
+    if(backends & EVBACKEND_SELECT) {
+        rb_ary_push(result, ID2SYM(rb_intern("select")));
+    }
+
+    if(backends & EVBACKEND_PORT) {
+        rb_ary_push(result, ID2SYM(rb_intern("port")));
+    }
+
+    return result;
+}
+
 /* Create a new selector. This is more or less the pure Ruby version
    translated into an MRI cext */
-static VALUE NIO_Selector_initialize(VALUE self)
+static VALUE NIO_Selector_initialize(int argc, VALUE *argv, VALUE self)
 {
+    ID backend_id;
+    VALUE backend;
     VALUE lock;
 
+    struct NIO_Selector *selector;
+    unsigned int flags = 0;
+
+    Data_Get_Struct(self, struct NIO_Selector, selector);
+
+    rb_scan_args(argc, argv, "01", &backend);
+
+    if(backend != Qnil) {
+        if(!rb_ary_includes(NIO_Selector_supported_backends(CLASS_OF(self)), 
backend)) {
+            rb_raise(rb_eArgError, "unsupported backend: %s",
+                RSTRING_PTR(rb_funcall(backend, rb_intern("inspect"), 0)));
+        }
+
+        backend_id = SYM2ID(backend);
+
+        if(backend_id == rb_intern("epoll")) {
+            flags = EVBACKEND_EPOLL;
+        } else if(backend_id == rb_intern("poll")) {
+            flags = EVBACKEND_POLL;
+        } else if(backend_id == rb_intern("kqueue")) {
+            flags = EVBACKEND_KQUEUE;
+        } else if(backend_id == rb_intern("select")) {
+            flags = EVBACKEND_SELECT;
+        } else if(backend_id == rb_intern("port")) {
+            flags = EVBACKEND_PORT;
+        } else {
+            rb_raise(rb_eArgError, "unsupported backend: %s",
+                RSTRING_PTR(rb_funcall(backend, rb_intern("inspect"), 0)));
+        }
+    }
+
+    /* Ensure the selector loop has not yet been initialized */
+    assert(!selector->ev_loop);
+
+    selector->ev_loop = ev_loop_new(flags);
+    if(!selector->ev_loop) {
+        rb_raise(rb_eIOError, "error initializing event loop");
+    }
+
+    ev_io_start(selector->ev_loop, &selector->wakeup);
+
     rb_ivar_set(self, rb_intern("selectables"), rb_hash_new());
     rb_ivar_set(self, rb_intern("lock_holder"), Qnil);
 
@@ -204,7 +279,7 @@
 
     if(lock_holder != current_thread) {
         lock = rb_ivar_get(self, rb_intern("lock"));
-        rb_funcall(lock, rb_intern("lock"), 0, 0);
+        rb_funcall(lock, rb_intern("lock"), 0);
         rb_ivar_set(self, rb_intern("lock_holder"), current_thread);
 
         /* We've acquired the lock, so ensure we unlock it */
@@ -223,7 +298,7 @@
     rb_ivar_set(self, rb_intern("lock_holder"), Qnil);
 
     lock = rb_ivar_get(self, rb_intern("lock"));
-    rb_funcall(lock, rb_intern("unlock"), 0, 0);
+    rb_funcall(lock, rb_intern("unlock"), 0);
 
     return Qnil;
 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/lib/nio/bytebuffer.rb new/lib/nio/bytebuffer.rb
--- old/lib/nio/bytebuffer.rb   2017-05-28 22:58:36.000000000 +0200
+++ new/lib/nio/bytebuffer.rb   2017-12-27 17:33:22.000000000 +0100
@@ -48,10 +48,8 @@
       raise ArgumentError, "negative position given" if new_position < 0
       raise ArgumentError, "specified position exceeds capacity" if 
new_position > @capacity
 
+      @mark = nil if @mark && @mark > new_position
       @position = new_position
-      @mark = nil if @mark && @mark > @position
-
-      new_position
     end
 
     # Set the limit to the given value. New limit must be less than capacity.
@@ -65,11 +63,9 @@
       raise ArgumentError, "negative limit given" if new_limit < 0
       raise ArgumentError, "specified limit exceeds capacity" if new_limit > 
@capacity
 
+      @position = new_limit if @position > new_limit
+      @mark = nil if @mark && @mark > new_limit
       @limit = new_limit
-      @position = new_limit if @position > @limit
-      @mark = nil if @mark && @mark > @limit
-
-      new_limit
     end
 
     # Number of bytes remaining in the buffer before the limit
@@ -115,15 +111,22 @@
 
     # Add a String to the buffer
     #
+    # @param str [#to_str] data to add to the buffer
+    #
+    # @raise [TypeError] given a non-string type
     # @raise [NIO::ByteBuffer::OverflowError] buffer is full
     #
     # @return [self]
-    def <<(str)
+    def put(str)
+      raise TypeError, "expected String, got #{str.class}" unless 
str.respond_to?(:to_str)
+      str = str.to_str
+
       raise OverflowError, "buffer is full" if str.length > @limit - @position
       @buffer[@position...str.length] = str
       @position += str.length
       self
     end
+    alias << put
 
     # Perform a non-blocking read from the given IO object into the buffer
     # Reads as much data as is immediately available and returns
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/lib/nio/monitor.rb new/lib/nio/monitor.rb
--- old/lib/nio/monitor.rb      2017-05-28 22:58:36.000000000 +0200
+++ new/lib/nio/monitor.rb      2017-12-27 17:33:22.000000000 +0100
@@ -31,7 +31,7 @@
     # @return [Symbol] new interests
     def interests=(interests)
       raise EOFError, "monitor is closed" if closed?
-      raise ArgumentError, "bad interests: #{interests}" unless [:r, :w, 
:rw].include?(interests)
+      raise ArgumentError, "bad interests: #{interests}" unless %i[r w 
rw].include?(interests)
 
       @interests = interests
     end
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/lib/nio/selector.rb new/lib/nio/selector.rb
--- old/lib/nio/selector.rb     2017-05-28 22:58:36.000000000 +0200
+++ new/lib/nio/selector.rb     2017-12-27 17:33:22.000000000 +0100
@@ -5,8 +5,17 @@
 module NIO
   # Selectors monitor IO objects for events of interest
   class Selector
+    # Return supported backends as symbols
+    #
+    # See `#backend` method definition for all possible backends
+    def self.backends
+      [:ruby]
+    end
+
     # Create a new NIO::Selector
-    def initialize
+    def initialize(backend = :ruby)
+      raise ArgumentError, "unsupported backend: #{backend}" unless backend == 
:ruby
+
       @selectables = {}
       @lock = Mutex.new
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/lib/nio/version.rb new/lib/nio/version.rb
--- old/lib/nio/version.rb      2017-05-28 22:58:36.000000000 +0200
+++ new/lib/nio/version.rb      2017-12-27 17:33:22.000000000 +0100
@@ -1,5 +1,5 @@
 # frozen_string_literal: true
 
 module NIO
-  VERSION = "2.1.0"
+  VERSION = "2.2.0".freeze
 end
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/lib/nio.rb new/lib/nio.rb
--- old/lib/nio.rb      2017-05-28 22:58:36.000000000 +0200
+++ new/lib/nio.rb      2017-12-27 17:33:22.000000000 +0100
@@ -1,6 +1,5 @@
 # frozen_string_literal: true
 
-require "thread"
 require "socket"
 require "nio/version"
 
@@ -19,7 +18,7 @@
   require "nio/monitor"
   require "nio/selector"
   require "nio/bytebuffer"
-  NIO::ENGINE = "ruby"
+  NIO::ENGINE = "ruby".freeze
 else
   require "nio4r_ext"
 
@@ -27,8 +26,8 @@
     require "java"
     require "jruby"
     org.nio4r.Nio4r.new.load(JRuby.runtime, false)
-    NIO::ENGINE = "java"
+    NIO::ENGINE = "java".freeze
   else
-    NIO::ENGINE = "libev"
+    NIO::ENGINE = "libev".freeze
   end
 end
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/metadata new/metadata
--- old/metadata        2017-05-28 22:58:36.000000000 +0200
+++ new/metadata        2017-12-27 17:33:22.000000000 +0100
@@ -1,17 +1,17 @@
 --- !ruby/object:Gem::Specification
 name: nio4r
 version: !ruby/object:Gem::Version
-  version: 2.1.0
+  version: 2.2.0
 platform: ruby
 authors:
 - Tony Arcieri
 autorequire: 
 bindir: bin
 cert_chain: []
-date: 2017-05-28 00:00:00.000000000 Z
+date: 2017-12-27 00:00:00.000000000 Z
 dependencies:
 - !ruby/object:Gem::Dependency
-  name: rake
+  name: bundler
   requirement: !ruby/object:Gem::Requirement
     requirements:
     - - ">="
@@ -25,7 +25,7 @@
       - !ruby/object:Gem::Version
         version: '0'
 - !ruby/object:Gem::Dependency
-  name: bundler
+  name: rake
   requirement: !ruby/object:Gem::Requirement
     requirements:
     - - ">="
@@ -50,7 +50,6 @@
 - ".gitignore"
 - ".rspec"
 - ".rubocop.yml"
-- ".ruby-version"
 - ".travis.yml"
 - CHANGES.md
 - Gemfile
@@ -58,6 +57,7 @@
 - LICENSE.txt
 - README.md
 - Rakefile
+- appveyor.yml
 - examples/echo_server.rb
 - ext/libev/Changes
 - ext/libev/LICENSE
@@ -125,7 +125,7 @@
       version: '0'
 requirements: []
 rubyforge_project: 
-rubygems_version: 2.6.11
+rubygems_version: 2.7.3
 signing_key: 
 specification_version: 4
 summary: New IO for Ruby
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/nio4r.gemspec new/nio4r.gemspec
--- old/nio4r.gemspec   2017-05-28 22:58:36.000000000 +0200
+++ new/nio4r.gemspec   2017-12-27 17:33:22.000000000 +0100
@@ -29,6 +29,6 @@
     spec.extensions = ["ext/nio4r/extconf.rb"]
   end
 
-  spec.add_development_dependency "rake"
   spec.add_development_dependency "bundler"
+  spec.add_development_dependency "rake"
 end
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/spec/nio/acceptables_spec.rb 
new/spec/nio/acceptables_spec.rb
--- old/spec/nio/acceptables_spec.rb    2017-05-28 22:58:36.000000000 +0200
+++ new/spec/nio/acceptables_spec.rb    2017-12-27 17:33:22.000000000 +0100
@@ -20,13 +20,13 @@
     let(:port) { next_available_tcp_port }
 
     let :acceptable_subject do
-      server = TCPServer.new("localhost", port)
-      TCPSocket.open("localhost", port)
+      server = TCPServer.new("127.0.0.1", port)
+      TCPSocket.open("127.0.0.1", port)
       server
     end
 
     let :unacceptable_subject do
-      TCPServer.new("localhost", port + 1)
+      TCPServer.new("127.0.0.1", port + 1)
     end
 
     it_behaves_like "an NIO acceptable"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/spec/nio/bytebuffer_spec.rb 
new/spec/nio/bytebuffer_spec.rb
--- old/spec/nio/bytebuffer_spec.rb     2017-05-28 22:58:36.000000000 +0200
+++ new/spec/nio/bytebuffer_spec.rb     2017-12-27 17:33:22.000000000 +0100
@@ -2,6 +2,7 @@
 
 require "spec_helper"
 
+# rubocop:disable Metrics/BlockLength
 RSpec.describe NIO::ByteBuffer do
   let(:capacity)       { 256 }
   let(:example_string) { "Testing 1 2 3..." }
@@ -179,6 +180,11 @@
       expect(bytebuffer.limit).to eq capacity
     end
 
+    it "raises TypeError if given a non-String type" do
+      expect { bytebuffer << 42 }.to raise_error(TypeError)
+      expect { bytebuffer << nil }.to raise_error(TypeError)
+    end
+
     it "raises NIO::ByteBuffer::OverflowError if the buffer is full" do
       bytebuffer << "X" * (capacity - 1)
       expect { bytebuffer << "X" }.not_to raise_error
@@ -281,7 +287,7 @@
   end
 
   context "I/O" do
-    let(:addr)   { "localhost" }
+    let(:addr)   { "127.0.0.1" }
     let(:port)   { next_available_tcp_port }
     let(:server) { TCPServer.new(addr, port) }
     let(:client) { TCPSocket.new(addr, port) }
@@ -347,3 +353,4 @@
     end
   end
 end
+# rubocop:enable Metrics/BlockLength
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/spec/nio/monitor_spec.rb new/spec/nio/monitor_spec.rb
--- old/spec/nio/monitor_spec.rb        2017-05-28 22:58:36.000000000 +0200
+++ new/spec/nio/monitor_spec.rb        2017-12-27 17:33:22.000000000 +0100
@@ -4,7 +4,7 @@
 require "socket"
 
 RSpec.describe NIO::Monitor do
-  let(:addr) { "localhost" }
+  let(:addr) { "127.0.0.1" }
   let(:port) { next_available_tcp_port }
 
   let(:reader) { TCPServer.new(addr, port) }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/spec/nio/selectables/pipe_spec.rb 
new/spec/nio/selectables/pipe_spec.rb
--- old/spec/nio/selectables/pipe_spec.rb       2017-05-28 22:58:36.000000000 
+0200
+++ new/spec/nio/selectables/pipe_spec.rb       2017-12-27 17:33:22.000000000 
+0100
@@ -27,12 +27,17 @@
     #      will throw EAGAIN if there is too little space to write the string
     # TODO: Use FFI to lookup the platform-specific size of PIPE_BUF
     str = "JUNK IN THE TUBES" * 10_000
+    cntr = 0
     begin
       pipe.write_nonblock str
-      _, writers = select [], [pipe], [], 0
+      cntr += 1
+      t = select [], [pipe], [], 0
     rescue Errno::EPIPE
       break
-    end while writers && writers.include?(pipe)
+    rescue IO::EWOULDBLOCKWaitWritable
+      skip "windows - can't test due to 'select' not showing correct status"
+      break
+    end while t && t[1].include?(pipe) && cntr < 20
 
     pipe
   end
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/spec/nio/selectables/ssl_socket_spec.rb 
new/spec/nio/selectables/ssl_socket_spec.rb
--- old/spec/nio/selectables/ssl_socket_spec.rb 2017-05-28 22:58:36.000000000 
+0200
+++ new/spec/nio/selectables/ssl_socket_spec.rb 2017-12-27 17:33:22.000000000 
+0100
@@ -4,23 +4,23 @@
 require "openssl"
 
 RSpec.describe OpenSSL::SSL::SSLSocket do
-  let(:addr) { "localhost" }
+  let(:addr) { "127.0.0.1" }
   let(:port) { next_available_tcp_port }
 
   let(:ssl_key) { OpenSSL::PKey::RSA.new(1024) }
 
   let(:ssl_cert) do
-    name = OpenSSL::X509::Name.new([%w(CN localhost)])
+    name = OpenSSL::X509::Name.new([%w[CN 127.0.0.1]])
     OpenSSL::X509::Certificate.new.tap do |cert|
       cert.version = 2
       cert.serial = 1
       cert.issuer = name
       cert.subject = name
       cert.not_before = Time.now
-      cert.not_after = Time.now + (365 * 24 * 60 * 60)
+      cert.not_after = Time.now + (7 * 24 * 60 * 60)
       cert.public_key = ssl_key.public_key
 
-      cert.sign(ssl_key, OpenSSL::Digest::SHA1.new)
+      cert.sign(ssl_key, OpenSSL::Digest::SHA256.new)
     end
   end
 
@@ -111,14 +111,15 @@
     ssl_peer.accept
     thread.join
 
+    cntr = 0
     begin
-      _, writers = select [], [ssl_client], [], 0
       count = ssl_client.write_nonblock "X" * 1024
       expect(count).not_to eq(0)
+      cntr += 1
+      t = select [], [ssl_client], [], 0
     rescue IO::WaitReadable, IO::WaitWritable
       pending "SSL will report writable but not accept writes"
-      raise if writers.include? ssl_client
-    end while writers && writers.include?(ssl_client)
+    end while t && t[1].include?(ssl_client) && cntr < 30
 
     # I think the kernel might manage to drain its buffer a bit even after
     # the socket first goes unwritable. Attempt to sleep past this and then
@@ -141,8 +142,6 @@
   end
 
   let :pair do
-    pending "figure out why newly created sockets are selecting readable 
immediately"
-
     server = TCPServer.new(addr, port)
     client = TCPSocket.new(addr, port)
     peer = server.accept
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/spec/nio/selectables/tcp_socket_spec.rb 
new/spec/nio/selectables/tcp_socket_spec.rb
--- old/spec/nio/selectables/tcp_socket_spec.rb 2017-05-28 22:58:36.000000000 
+0200
+++ new/spec/nio/selectables/tcp_socket_spec.rb 2017-12-27 17:33:22.000000000 
+0100
@@ -19,9 +19,7 @@
     sock = TCPSocket.new(addr, port)
 
     # Sanity check to make sure we actually produced an unreadable socket
-    if select([sock], [], [], 0)
-      pending "Failed to produce an unreadable socket"
-    end
+    pending "Failed to produce an unreadable socket" if select([sock], [], [], 
0)
 
     sock
   end
@@ -57,9 +55,7 @@
     end
 
     # Sanity check to make sure we actually produced an unwritable socket
-    if select([], [sock], [], 0)
-      pending "Failed to produce an unwritable socket"
-    end
+    pending "Failed to produce an unwritable socket" if select([], [sock], [], 
0)
 
     sock
   end
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/spec/nio/selectables/udp_socket_spec.rb 
new/spec/nio/selectables/udp_socket_spec.rb
--- old/spec/nio/selectables/udp_socket_spec.rb 2017-05-28 22:58:36.000000000 
+0200
+++ new/spec/nio/selectables/udp_socket_spec.rb 2017-12-27 17:33:22.000000000 
+0100
@@ -2,27 +2,37 @@
 
 require "spec_helper"
 
-RSpec.describe UDPSocket do
+RSpec.describe UDPSocket, if: !defined?(JRUBY_VERSION) do
   let(:udp_port) { 23_456 }
 
   let :readable_subject do
     sock = UDPSocket.new
-    sock.bind("localhost", udp_port)
+    sock.bind("127.0.0.1", udp_port)
 
     peer = UDPSocket.new
-    peer.send("hi there", 0, "localhost", udp_port)
+    peer.send("hi there", 0, "127.0.0.1", udp_port)
 
     sock
   end
 
   let :unreadable_subject do
     sock = UDPSocket.new
-    sock.bind("localhost", udp_port + 1)
+    sock.bind("127.0.0.1", udp_port + 1)
     sock
   end
 
   let :writable_subject do
-    pending "come up with a writable UDPSocket example"
+    peer = UDPSocket.new
+    peer.connect "127.0.0.1", udp_port
+    cntr = 0
+    begin
+      peer.send("X" * 1024, 0)
+      cntr += 1
+      t = select [], [peer], [], 0
+    rescue Errno::ECONNREFUSED => ex
+      skip "Couln't make writable UDPSocket subject: #{ex.class}: #{ex}"
+    end while t && t[1].include?(peer) && cntr < 5
+    peer
   end
 
   let :unwritable_subject do
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/spec/nio/selector_spec.rb 
new/spec/nio/selector_spec.rb
--- old/spec/nio/selector_spec.rb       2017-05-28 22:58:36.000000000 +0200
+++ new/spec/nio/selector_spec.rb       2017-12-27 17:33:22.000000000 +0100
@@ -8,11 +8,35 @@
 # the tests
 TIMEOUT_PRECISION = 0.1
 
+# rubocop:disable Metrics/BlockLength
 RSpec.describe NIO::Selector do
   let(:pair)   { IO.pipe }
   let(:reader) { pair.first }
   let(:writer) { pair.last }
 
+  context ".backends" do
+    it "knows all supported backends" do
+      expect(described_class.backends).to be_a Array
+      expect(described_class.backends.first).to be_a Symbol
+    end
+  end
+
+  context "#initialize" do
+    it "allows explicitly specifying a backend" do
+      backend = described_class.backends.first
+      selector = described_class.new(backend)
+      expect(selector.backend).to eq backend
+    end
+
+    it "raises ArgumentError if given an invalid backend" do
+      expect { described_class.new(:derp) }.to raise_error ArgumentError
+    end
+
+    it "raises TypeError if given a non-Symbol parameter" do
+      expect { described_class.new(42).to raise_error TypeError }
+    end
+  end
+
   context "backend" do
     it "knows its backend" do
       expect(subject.backend).to be_a Symbol
@@ -191,3 +215,4 @@
     expect(subject).to be_closed
   end
 end
+# rubocop:enable Metrics/BlockLength
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/spec/spec_helper.rb new/spec/spec_helper.rb
--- old/spec/spec_helper.rb     2017-05-28 22:58:36.000000000 +0200
+++ new/spec/spec_helper.rb     2017-12-27 17:33:22.000000000 +0100
@@ -20,8 +20,8 @@
     $current_tcp_port += 1
 
     begin
-      sock = Timeout.timeout(1) { TCPSocket.new("localhost", 
$current_tcp_port) }
-    rescue Errno::ECONNREFUSED
+      sock = Timeout.timeout(0.5) { TCPSocket.new("127.0.0.1", 
$current_tcp_port) }
+    rescue Errno::ECONNREFUSED, Timeout::Error
       break $current_tcp_port
     end
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/spec/support/selectable_examples.rb 
new/spec/support/selectable_examples.rb
--- old/spec/support/selectable_examples.rb     2017-05-28 22:58:36.000000000 
+0200
+++ new/spec/support/selectable_examples.rb     2017-12-27 17:33:22.000000000 
+0100
@@ -34,9 +34,6 @@
   let(:peer)     { pair.last }
 
   it "selects readable when the other end closes" do
-    # hax: this test is broken for OpenSSL sockets
-    skip "broken for SSL ;_;" if peer.is_a? OpenSSL::SSL::SSLSocket
-
     monitor = selector.register(stream, :r)
     expect(selector.select(0)).to be_nil
 
@@ -57,4 +54,12 @@
       expect(m.readiness).to eq(:rw)
     end
   end
+  it "keeps readiness after the selectable has been closed" do
+    selector.register(readable_subject, :rw)
+    selector.select(0) do |m|
+      expect(m.readiness).to eq(:rw)
+      readable_subject.close
+      expect(m.readiness).to eq(:rw)
+    end
+  end
 end


Reply via email to