Calling map on string now fails, rather than yielding the string.

In Ruby 1.8 `"foo".map` would yield "foo" once, while in Ruby 1.9 it is not
defined as a method.

Various parts of our testing code stub other methods and return strings where
arrays of strings are appropriate; this historically worked because of that
1.8 shim, and no longer does.

The same is true of `String#each`, which fails in the same way.

Signed-off-by: Daniel Pittman <daniel@puppetlabs.com>
`String#to_a` doesn't work in Ruby 1.9

In Ruby 1.8, counterintuitively, `"foo".to_a` would return `["foo"]` - an
array with a single entry, the string.  This went away in Ruby 1.9, likely
as a transition path to a much less confusing set of semantics.

Either way we should stop relying on that behaviour and get with the program.

Signed-off-by: Daniel Pittman <daniel@puppetlabs.com>
Regular expression matching on symbols changed in Ruby 1.9

In Ruby 1.8 a regular expression match on a symbol would never match, while in
Ruby 1.9 it is equivalent t a regular expression match on the equivalent
string.  This is very sensible behaviour, but trips up parts of code that
expect an implicit "... but not symbol" match.

Signed-off-by: Daniel Pittman <daniel@puppetlabs.com>
Whitespace and formatting cleanup on shellquote spec.

The formatting in the spec file was very odd, with extraneous and random
whitespace around arguments, odd line breaks, and so forth.

It also used a whole pile of temporary variables that it didn't need to.

This cleans that up, without making any functional changes to the code.

Signed-off-by: Daniel Pittman <daniel@puppetlabs.com>
Fix the shellquote parser function on Ruby 1.9

The semantics of `String#include?` changed a little in Ruby 1.9, so that you
can't just pass an arbitrary integer and have it check for character
containment.  (...or, perhaps, the semantics of characters vs integers
changed.  Either way, the effect is the same.)

This fixes the code to do the right thing on all platforms; we want to process
the string byte-wise, since that is how sh may well regard it, and we have to
work around some limitations on 1.8.5 semantics of string iterators.

Signed-off-by: Daniel Pittman <daniel@puppetlabs.com>
Protect all existing methods when monkey-patching.

Most, but not all, the method we add to objects while monkey-patching were
correctly protected against overriding a core method.  This adds the right
protections to the handful that were missing them.

Signed-off-by: Daniel Pittman <daniel@puppetlabs.com>
Handle the real semantics of `String#lines`...

The previous monkey-patching of `String#lines` and `IO#lines` led to their
behaving differently in our code than in standard Ruby code.  This is
generally surprising, and led to some subtle misuses of the method.

This corrects that, by adapting all the abusers to real Ruby calling
conventions over the enumerator interface.

Signed-off-by: Daniel Pittman <daniel@puppetlabs.com>
The return type of `methods` changed in 1.9

This test depended on the return type of `methods`, which went from array of
strings to array of symbols in Ruby 1.9.  Given that it really wanted to test
if the instance responded to the message, we can just directly test that.

Signed-off-by: Daniel Pittman <daniel@puppetlabs.com>
A correct implementation of IO#binwrite for Ruby 1.8

When we added the `IO#binwrite` method to our collection of backported
features, the specification was misinterpreted and the offset was treated as
"offset in the string we are writing".

Instead, it is an instruction to seek in the output file before writing, which
meant that our semantics were all wrong - and tests broke - when we ran
against the native binwrite on Ruby 1.9.

The new implementation is correct in behaviour on all tested cases, and has a
more extensive test suite exercising all the various parts of the behaviour
that we need.

Signed-off-by: Daniel Pittman <daniel@puppetlabs.com>
Fix Cisco device canonicalization regular expression on 1.9

The behaviour of the `\b` Regexp match operator, or rather, the classification
of `/` as an end of word character, changed between Ruby 1.8 and 1.9.

Most uses in our code are safe, and this will lead to equally correct
behaviour, but the Cisco device interface canonicalization code used it where
"end of string before newline" was intended.

Moving to the `\Z` match, which imposes the exactly desired condition,
resolves the problem.

Signed-off-by: Daniel Pittman <daniel@puppetlabs.com>
Partially fix UTF-8 and PSON encoding tests for Ruby 1.9

With the introduction of real encoding support in Ruby 1.9, various problems
including incorrectly encoded UTF-8 strings crop up.

By flagging the encoding of the spec file to Ruby, and forcing binary encoding
on strings we compare that contain invalid UTF-8, we can bypass some of those
headaches.

Since PSON is, by design, not compatible with JSON and can do useful things
with arbitrary binary data, this is the most reasonably current choice for how
to handle this troublesome set of data.

Signed-off-by: Daniel Pittman <daniel@puppetlabs.com>
Implement YAML 1.1 binary data encoding in ZAML

The YAML spec has a mechanism to flag arbitrary binary data, as opposed to
sequences of Unicode characters in UTF-8.  This implements full support for
that in the ZAML encoder.

This is used on the basis of a string that doesn't contain valid UTF-8.
Another stinking heuristic, but at least one that results in conformant YAML
being emitted.

Pleasantly, the !binary tagged data is correctly ready by Syck as far back as
Ruby 1.8.5, allowing us to confidently ship this data without too much concern
for compatibility with older libraries.

Additionally, we stop escaping all UTF-8 data as a sequence of bytes.
Theoretically we could go back to escaping it, using real Unicode character
markers, but literal UTF-8 in the output file is just as acceptable.

This should gain better support for the Ruby 1.9 encoding markers, so that
strings could carry their binary or non-binary nature in ... but this gets
things working and passes both Unicode and Binary data tests.

Signed-off-by: Daniel Pittman <daniel@puppetlabs.com>
When shutting down Mongrel, wait synchronously for stop.

The Mongrel tests on Ruby 1.9 were highly unreliable, sometimes failing
because they tried to bind a port that was already in use.

This turns out to be because the default shutdown mode is to asynchronously
stop workers - combined with the fact that our test made a TCP connection to
the service, but never actually completed the request.

That led to one thread that dangled, if the socket didn't close in a timely
fashion, and blocked up the listen port.

Instead, two things: first, wait for all threads to terminate (or 60 seconds
to pass) in the stop method, and second, use a full HTTP request to test, not
just a TCP connection with no content.

Signed-off-by: Daniel Pittman <daniel@puppetlabs.com>
Remove the "fails_on_ruby_1.9.2" tag from tests...

Now we have passing tests on Ruby 1.9, we can make all those tags go away and
enable the full suite.  Now anything that fails should be treated like a real
failure, which is reasonable since this is a real and supported platform.

Signed-off-by: Daniel Pittman <daniel@puppetlabs.com>