[DRE-commits] [ruby-monkey-lib] 01/02: Imported Upstream version 0.5.4
Richard Winters
devrik-guest at moszumanska.debian.org
Sat May 2 20:01:56 UTC 2015
This is an automated email from the git hooks/post-receive script.
devrik-guest pushed a commit to branch master
in repository ruby-monkey-lib.
commit ede7575f3366702dd03ce66d659d72676a725f60
Author: Richard B Winters <rik at mmogp.com>
Date: Fri May 1 12:17:41 2015 -0400
Imported Upstream version 0.5.4
---
LICENSE | 27 +++
README.rdoc | 47 ++++
Rakefile | 126 ++++++++++
lib/monkey-lib.rb | 15 ++
lib/monkey.rb | 56 +++++
lib/monkey/autoloader.rb | 45 ++++
lib/monkey/backend.rb | 140 +++++++++++
lib/monkey/backend/active_support.rb | 30 +++
lib/monkey/backend/backports.rb | 11 +
lib/monkey/backend/common/extract_options.rb | 12 +
lib/monkey/backend/common/parent.rb | 12 +
lib/monkey/backend/common/singleton_class.rb | 14 ++
lib/monkey/backend/common/tap.rb | 13 ++
lib/monkey/backend/extlib.rb | 14 ++
lib/monkey/backend/facets.rb | 18 ++
lib/monkey/engine.rb | 139 +++++++++++
lib/monkey/ext.rb | 111 +++++++++
lib/monkey/ext/array.rb | 19 ++
lib/monkey/ext/enumerable.rb | 20 ++
lib/monkey/ext/file.rb | 12 +
lib/monkey/ext/module.rb | 28 +++
lib/monkey/ext/object.rb | 50 ++++
lib/monkey/ext/pathname.rb | 25 ++
lib/monkey/ext/string.rb | 179 +++++++++++++++
lib/monkey/ext/symbol.rb | 11 +
lib/monkey/hash_fix.rb | 2 +
lib/monkey/matcher.rb | 11 +
lib/monkey/version.rb | 35 +++
metadata.yml | 146 ++++++++++++
spec/monkey/backend_spec.rb | 7 +
spec/monkey/engine_spec.rb | 55 +++++
spec/monkey/ext/array_spec.rb | 37 +++
spec/monkey/ext/enumerable_spec.rb | 28 +++
spec/monkey/ext/module_spec.rb | 32 +++
spec/monkey/ext/object_spec.rb | 53 +++++
spec/monkey/ext/pathname_spec.rb | 0
spec/monkey/ext/string_spec.rb | 332 +++++++++++++++++++++++++++
spec/monkey/ext/symbol_spec.rb | 20 ++
spec/monkey/ext_spec.rb | 50 ++++
spec/monkey/matcher_spec.rb | 17 ++
spec/monkey_spec.rb | 25 ++
spec/spec_helper.rb | 26 +++
42 files changed, 2050 insertions(+)
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..dd8b891
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,27 @@
+copyright (c) 2009 Konstantin Haase. All rights reserved.
+
+Developed by: Konstantin Haase
+ http://github.com/rkh/monkey-lib
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to
+deal with the Software without restriction, including without limitation the
+rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+sell copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimers.
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimers in the
+ documentation and/or other materials provided with the distribution.
+ 3. Neither the name of Konstantin Haase, nor the names of other contributors
+ may be used to endorse or promote products derived from this Software without
+ specific prior written permission.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+WITH THE SOFTWARE.
diff --git a/README.rdoc b/README.rdoc
new file mode 100644
index 0000000..cd1f97d
--- /dev/null
+++ b/README.rdoc
@@ -0,0 +1,47 @@
+Makes ruby extension libraries pluggable (thus not forcing such a library
+on the users of your library - like BigBand - but still giving you some
+fancy features).
+
+TODO: Describe what it actually does. Feel free to have a look at the specs/code, should
+be pretty easy to understand.
+
+Version number will soon be synchronized with BigBand.
+
+== Backends
+Those libraries are supported as backends out of the box:
+* ActiveSupport (tested with 2.3.2 to 3.0.beta)
+* Backports (tested with 1.11.1 to 1.15.0, >= 1.13.1 required for Rubinius)
+* Extlib (tested with 0.9.13 and 0.9.14)
+* Facets (tested with 2.8.0 to 2.8.2)
+
+== Ruby versions
+MonkeyLib has been tested and is known to work with the following Ruby implementations:
+
+* Ruby (MRI) 1.8.6, 1.8.7, 1.9.1, 1.9.2-preview1, also tested with trunk on regular basis
+* Ruby Enterprise Edition 2009.10, 2010.01
+* Rubinius 1.0.0-rc2 to 1.0.0-rc4, also tested with master branch on regular basis
+* JRuby 1.3.1, 1.4.0
+* MagLev 22780 to 23191 (Backports backend recommended, but all expectations pass on all backends)
+* IronRuby 0.9.3, 1.0-rc2 (only Extlib and Backports)
+
+Currently it does *not* run on MacRuby, but I'm working on it.
+
+== Running the specs
+
+Run specs with all backends:
+ rake spec
+
+Run specs with active_support:
+ rake spec:active_support
+
+Run specs with backports and using mspec instead of rspec (so it might work on incomplete ruby implementations):
+ SPEC_RUNNER=mspec rake spec:backports
+
+Sometimes there are issues with running rake from the ruby implementation (maybe rake is not fully supported, or the backend detection messes
+with your ruby). You can use one ruby implementation to run the specs on another one. For instance, I use rvm to manage my rubies:
+
+ rvm install macruby-0.5
+ rvm use macruby-0.5
+ gem install mspec backports
+ rvm use default
+ RUBY=$rvm_path/rubies/macruby-0.5/bin/ruby SPEC_RUNNER=mspec rake spec:backports
diff --git a/Rakefile b/Rakefile
new file mode 100644
index 0000000..6a3eb39
--- /dev/null
+++ b/Rakefile
@@ -0,0 +1,126 @@
+require "rake/clean"
+
+task :default => :spec
+
+backends = Dir.glob('lib/monkey/backend/*.rb').map { |f| File.basename f, ".rb" }
+modes = [:autodetect, :explicit]
+
+CLEAN.include "**/*.rbc"
+CLOBBER.include "monkey-lib*.gem"
+
+setup_rspec = proc do
+ require "spec/rake/spectask"
+ SPEC_RUNNER = "mspec"
+ def define_spec_task(name, ruby_cmd, pattern)
+ Spec::Rake::SpecTask.new name do |t|
+ t.spec_opts += %w[-b -c --format progress --loadby mtime --reverse]
+ t.ruby_cmd = ruby_cmd
+ t.pattern = pattern
+ end
+ end
+end
+
+setup_mspec = proc do
+ require "mspec"
+ SPEC_RUNNER = "mspec"
+ def define_spec_task(name, ruby_cmd, pattern)
+ task(name) { sh "#{ruby_cmd} -S mspec-run #{pattern}" }
+ end
+end
+
+case ENV['SPEC_RUNNER']
+when "rspec" then setup_rspec.call
+when "mspec" then setup_mspec.call
+when nil
+ # yes, this code is trying to be smart, but let me have some fun, please?
+ raise @spec_load_error unless [setup_rspec, setup_mspec].any? { |b| b.call || true rescue (@spec_load_error ||= $!) && false }
+else
+ puts "sorry, currently no #{ENV['SPEC_RUNNER']} support"
+ exit 1
+end
+
+def backend_available?(backend = nil)
+ require backend unless backend.nil?
+ true
+rescue LoadError
+ false
+end
+
+def spec_task(name, backend = nil, mode = nil)
+ desc "runs specs #{"with backend #{backend} " if backend}#{"(#{mode} mode)" if mode}"
+ if backend_available? backend
+ define_spec_task(name, "BACKEND=#{backend.to_s.inspect} BACKEND_SETUP=#{mode.to_s.inspect} #{ENV['RUBY'] || RUBY}", "spec/**/*_spec.rb")
+ else
+ task(name) do
+ puts "", "could not load #{backend.inspect}, skipping specs.", ""
+ end
+ end
+end
+
+task :environment do
+ $LOAD_PATH.unshift "lib"
+ require "monkey-lib"
+end
+
+desc "run all specs"
+task :spec => "spec:all"
+namespace :spec do
+
+ desc "runs specs without explicitly setting a backend"
+ spec_task :autodetect
+
+ backends.each do |backend|
+ task :all => backend
+
+ desc "runs specs with backend #{backend}"
+ task backend => "#{backend}:all"
+
+ namespace backend do
+ modes.each do |mode|
+ task :all => mode
+ spec_task mode, backend, mode
+ end
+ end
+
+ end
+end
+
+namespace :backend do
+
+ desc "lists all available backends"
+ task(:list) { puts backends }
+
+ desc "lists expectations a backend has to meet"
+ task :expectations => :environment do
+ Monkey::Ext.expectations.each do |core_class, methods|
+ print "#{core_class}:".ljust(10)
+ puts methods.map { |n| "##{n}" }.join(", ")
+ end
+ end
+
+ desc "checks whether specs for expectations are present"
+ task :spec_check =>:environment do
+ Monkey::Ext.expectations.each do |core_class, methods|
+ path = "spec/monkey/ext/#{core_class.name.to_const_path}_spec.rb"
+ list = path.file_exists? ? %x[spec -d -fs #{path} -e "Monkey::Ext::#{core_class.name} backend expectations"] : ""
+ methods.each { |m| puts "missing specs for #{core_class.name}##{m}" unless list =~ /- imports #{m} from backend/ }
+ end
+ end
+
+end
+
+############
+# aliases
+
+namespace(:b) do
+ task :e => "backend:expectations"
+ task :l => "backend:list"
+ task :s => "backend:spec_check"
+end
+
+namespace(:s) do
+ task :as => "spec:active_support:explicit"
+ task :bp => "spec:backports:explicit"
+ task :ex => "spec:extlib:explicit"
+ task :fc => "spec:facets:explicit"
+end
diff --git a/lib/monkey-lib.rb b/lib/monkey-lib.rb
new file mode 100644
index 0000000..b6f629a
--- /dev/null
+++ b/lib/monkey-lib.rb
@@ -0,0 +1,15 @@
+require "monkey"
+
+unless defined? Monkey
+ warn "installing both the monkey and the monkey-lib gem results in conflicts, add a Gemfile, use gemsets or remove monkey gem"
+ $LOADED_FEATURES.delete_if { |l| l =~ /monkey\.rb$/ }
+ if defined? require_relative
+ require_relative "monkey"
+ else
+ $LOAD_PATH.unshift File.expand_path('..', __FILE__)
+ require 'monkey'
+ end
+ fail "Please remove monkey gem (not monkey-lib gem) from your $LOAD_PATH" unless defined? Monkey
+end
+
+MonkeyLib = Monkey
diff --git a/lib/monkey.rb b/lib/monkey.rb
new file mode 100644
index 0000000..581a6f3
--- /dev/null
+++ b/lib/monkey.rb
@@ -0,0 +1,56 @@
+module Monkey
+ def self.backend=(backend)
+ Backend.setup! backend
+ backend
+ end
+
+ def self.backend
+ Backend.backend
+ end
+
+ def self.invisible(*from)
+ yield
+ rescue Exception => error
+ unless show_invisibles?
+ from << caller.first[/^[^:]*/] if from.empty?
+ from << __FILE__
+ delete_from_backtrace(error) { |l| from.any? { |f| l.include? f } }
+ end
+ raise error
+ end
+
+ def self.show_invisibles?
+ !!@show_invisibles
+ end
+
+ def self.show_invisibles!(show = true)
+ return @show_invisibles = show unless block_given?
+ # actually, that is not thread-safe. but that's no issue, as
+ # it is quite unlikely and does not cause any harm.
+ show_invisibles_was, @show_invisibles = @show_invisibles, show
+ result = yield
+ @show_invisibles = show_invisibles_was
+ result
+ end
+
+ def self.hide_invisibles!(&block)
+ show_invisibles!(false, &block)
+ end
+
+ def self.delete_from_backtrace(error, &block)
+ if error.respond_to? :awesome_backtrace
+ # HACK: we rely on the internal data structure, btw
+ locations = error.instance_variable_get :@locations
+ return unless locations
+ locations.reject! { |l| yield l.position }
+ error.instance_variable_set :@backtrace, nil
+ else
+ error.backtrace.reject!(&block)
+ end
+ end
+
+ Dir[File.dirname(__FILE__) + "/monkey/*.rb"].sort.each do |path|
+ filename = File.basename(path, '.rb')
+ require "monkey/#{filename}"
+ end
+end
\ No newline at end of file
diff --git a/lib/monkey/autoloader.rb b/lib/monkey/autoloader.rb
new file mode 100644
index 0000000..727416b
--- /dev/null
+++ b/lib/monkey/autoloader.rb
@@ -0,0 +1,45 @@
+require "monkey-lib"
+
+Module.class_eval do
+ alias const_missing_without_detection const_missing
+
+ def const_missing(const_name)
+ if respond_to? :parent and parent.autoloader? and not is_a? Monkey::Autoloader
+ extend Monkey::Autoloader
+ const_missing const_name
+ else
+ Monkey.invisible(__FILE__) { const_missing_without_detection const_name }
+ end
+ end
+
+ def autoloader?
+ is_a? Monkey::Autoloader or (respond_to? :parent and parent != self and parent.autoloader?)
+ end
+end
+
+module Monkey
+ module Autoloader
+ def const_missing(const_name)
+ const_name = const_name.to_s
+ file = File.join(self.name.to_const_path, const_name.to_const_path)
+ begin
+ require file
+ if const_defined? const_name
+ const = const_get const_name
+ const.extend Monkey::Autoloader
+ const
+ else
+ warn "expected #{file} to define #{name}::#{const_name}"
+ raise LoadError
+ end
+ rescue LoadError => error
+ begin
+ return parent.const_get(const_name) if respond_to? :parent and parent != self
+ rescue NameError
+ end
+ warn "tried to load #{file}: #{error.message}"
+ super
+ end
+ end
+ end
+end
\ No newline at end of file
diff --git a/lib/monkey/backend.rb b/lib/monkey/backend.rb
new file mode 100644
index 0000000..b3d0829
--- /dev/null
+++ b/lib/monkey/backend.rb
@@ -0,0 +1,140 @@
+module Monkey
+ module Backend
+
+ @available_backends = []
+
+ class << self
+ attr_reader :available_backends, :backend
+ end
+
+ module AbstractBackend
+ attr_accessor :backend_name, :backend_path
+
+ def available?
+ return true if Object.const_defined? backend_name
+ $LOADED_FEATURES.any? do |f|
+ f =~ /^(.*lib\/)?#{backend_path}|#{backend_path}(-[^\/]+)?\/lib/
+ end
+ end
+
+ def setup_complete
+ require backend_path
+ setup
+ end
+
+ def load_libs(*data)
+ load_with_prefix backend_path, data
+ end
+
+ alias load_lib load_libs
+
+ def load_with_prefix(prefix, libs = nil)
+ case libs
+ when String, Symbol then require File.join(prefix.to_s, libs.to_s)
+ when Array then libs.each { |lib| load_with_prefix prefix, lib }
+ when Hash then libs.each { |k, v| load_with_prefix File.join(prefix.to_s, k.to_s), v }
+ else raise ArgumentError, "cannot handle #{libs.inspect}"
+ end
+ end
+
+ def missing(*libs)
+ load_with_prefix "monkey/backend/common", libs
+ end
+
+ def expects_module(name)
+ name.split("::").inject(Object) do |parent, name|
+ if name.empty?
+ parent
+ else
+ parent.class_eval "module #{name}; self; end"
+ end
+ end
+ end
+
+ def version(default = "0")
+ return version(nil) || default unless default.nil?
+ return @version if @version
+ return unless defined? Gem
+ Gem.send :attr_accessor, :loaded_specs
+ return unless Gem.loaded_specs.respond_to? :[]
+ @version = Gem.loaded_specs[gem_name].version.to_s if Gem.loaded_specs.include? gem_name
+ end
+
+ def version!
+ version(nil) or raise RuntimeError, "unable to determine backend version"
+ end
+
+ def version?
+ !!version(false)
+ end
+
+ def gem_name
+ @gem_name ||= name[/[^:]*$/].downcase
+ end
+
+ end
+
+ def self.new(backend_name, backend_path = nil, &block)
+ mod = eval "module #{backend_name}; self; end"
+ mod.extend AbstractBackend
+ backend_path ||= backend_name.to_s.downcase
+ mod.backend_name, mod.backend_path = backend_name.to_s, backend_path.to_s
+ available_backends << mod
+ if block
+ eigenclass = class << mod; self; end
+ eigenclass.class_eval(&block)
+ end
+ mod
+ end
+
+ def self.preferred_backend
+ available_backends.detect { |b| b.available? } || @backend
+ end
+
+ def self.setup?
+ !!@setup
+ end
+
+ def self.setup!(backend)
+ if backend
+ @setup = true
+ @backend = detect_backend(backend)
+ @backend.setup
+ @backend
+ else
+ available_backends.each do |backend|
+ begin
+ return setup!(backend)
+ rescue LoadError => error
+ @load_error ||= error
+ @backend = nil
+ end
+ end
+ raise @load_error
+ end
+ end
+
+ class << self
+ alias backend= setup!
+ end
+
+ def self.setup
+ setup! preferred_backend unless setup?
+ end
+
+ def self.detect_backend(backend_or_name)
+ return backend_or_name if backend_or_name.respond_to? :setup
+ detected = available_backends.detect do |backend|
+ [backend.backend_name.to_s, backend.backend_path.to_s, backend.name.to_s].include? backend_or_name.to_s
+ end
+ raise ArgumentError, "cannot detect backend #{backend_or_name.inspect}" unless detected
+ detected
+ end
+
+ require "monkey/backend/backports"
+ require "monkey/backend/active_support"
+ require "monkey/backend/facets"
+ require "monkey/backend/extlib"
+
+ end
+end
diff --git a/lib/monkey/backend/active_support.rb b/lib/monkey/backend/active_support.rb
new file mode 100644
index 0000000..9f4f1ee
--- /dev/null
+++ b/lib/monkey/backend/active_support.rb
@@ -0,0 +1,30 @@
+Monkey::Backend.new :ActiveSupport, :active_support do
+ def setup
+ load_lib :version
+ expects_module "::ActiveSupport::CoreExtensions::String::Inflections" if version < "3"
+ load_libs :core_ext => %w[array/extract_options string/inflections module/introspection]
+ if version < "3"
+ begin
+ load_libs "core_ext/object/singleton_class"
+ rescue LoadError
+ load_libs "core_ext/object/metaclass"
+ ::Object.send(:alias_method, :singleton_class, :metaclass)
+ end
+ load_libs "core_ext/object/misc"
+ ::Array.send :include, ::ActiveSupport::CoreExtensions::Array::ExtractOptions
+ ::Module.send :include, ::ActiveSupport::CoreExtensions::Module
+ ::String.send :include, ::ActiveSupport::CoreExtensions::String::Inflections
+ else
+ load_libs "core_ext/kernel/singleton_class"
+ end
+ ::String.send(:alias_method, :to_const_string, :camelcase)
+ ::String.send(:alias_method, :to_const_path, :underscore)
+ end
+
+ def version(default = "0")
+ load_lib :version
+ @version ||= ActiveSupport::VERSION::STRING or super
+ rescue NameError
+ super
+ end
+end
\ No newline at end of file
diff --git a/lib/monkey/backend/backports.rb b/lib/monkey/backend/backports.rb
new file mode 100644
index 0000000..a0063a4
--- /dev/null
+++ b/lib/monkey/backend/backports.rb
@@ -0,0 +1,11 @@
+Monkey::Backend.new :Backports do
+ def setup
+ load_libs "tools", "1.8.7/kernel", :rails => [:array, :string]
+ missing :parent, :singleton_class
+ ::String.class_eval do
+ alias camelcase camelize
+ alias to_const_string camelize
+ alias to_const_path underscore
+ end
+ end
+end
diff --git a/lib/monkey/backend/common/extract_options.rb b/lib/monkey/backend/common/extract_options.rb
new file mode 100644
index 0000000..fcce80b
--- /dev/null
+++ b/lib/monkey/backend/common/extract_options.rb
@@ -0,0 +1,12 @@
+module Monkey
+ module Backend
+ module Common
+ module ExtractOptions
+ ::Array.send :include, self
+ def extract_options!
+ last.is_a?(::Hash) ? pop : {}
+ end
+ end
+ end
+ end
+end
diff --git a/lib/monkey/backend/common/parent.rb b/lib/monkey/backend/common/parent.rb
new file mode 100644
index 0000000..b7dca91
--- /dev/null
+++ b/lib/monkey/backend/common/parent.rb
@@ -0,0 +1,12 @@
+module Monkey
+ module Backend
+ module Common
+ module Parent
+ ::Module.send :include, self
+ def parent
+ name && name =~ /^(.+)::[^:]+$/ ? $1.constantize : Object
+ end
+ end
+ end
+ end
+end
\ No newline at end of file
diff --git a/lib/monkey/backend/common/singleton_class.rb b/lib/monkey/backend/common/singleton_class.rb
new file mode 100644
index 0000000..a117b8f
--- /dev/null
+++ b/lib/monkey/backend/common/singleton_class.rb
@@ -0,0 +1,14 @@
+module Monkey
+ module Backend
+ module Common
+ module SingletonClass
+ ::Object.send :include, self
+ def singleton_class
+ class << self
+ self
+ end
+ end
+ end
+ end
+ end
+end
\ No newline at end of file
diff --git a/lib/monkey/backend/common/tap.rb b/lib/monkey/backend/common/tap.rb
new file mode 100644
index 0000000..aba12a3
--- /dev/null
+++ b/lib/monkey/backend/common/tap.rb
@@ -0,0 +1,13 @@
+module Monkey
+ module Backend
+ module Common
+ module Tap
+ ::Object.send :include, self
+ def tap
+ yield self
+ self
+ end
+ end
+ end
+ end
+end
\ No newline at end of file
diff --git a/lib/monkey/backend/extlib.rb b/lib/monkey/backend/extlib.rb
new file mode 100644
index 0000000..ef06fea
--- /dev/null
+++ b/lib/monkey/backend/extlib.rb
@@ -0,0 +1,14 @@
+Monkey::Backend.new :Extlib do
+ def setup
+ load_libs :object, :string, :inflection
+ missing :parent, :extract_options, :tap
+ ::Object.class_eval { alias singleton_class meta_class }
+ ::String.class_eval do
+ alias camelcase to_const_string
+ alias underscore to_const_path
+ def constantize
+ Extlib::Inflection.constantize(self)
+ end
+ end
+ end
+end
diff --git a/lib/monkey/backend/facets.rb b/lib/monkey/backend/facets.rb
new file mode 100644
index 0000000..1ca6b4d
--- /dev/null
+++ b/lib/monkey/backend/facets.rb
@@ -0,0 +1,18 @@
+Monkey::Backend.new :Facets do
+ def setup
+ load_libs :kernel => [:meta_class, :constant], :string => [:camelcase, :snakecase]
+ # Actually, facets has Kernel#tap, but it behaves different if the block takes no argument.
+ missing :tap, :extract_options, :parent
+ ::String.class_eval do
+ def constantize
+ constant to_const_string
+ end
+ alias to_const_string upper_camelcase
+ alias to_const_path snakecase
+ alias underscore snakecase
+ end
+ ::Object.class_eval do
+ alias singleton_class meta_class unless respond_to? :singleton_class
+ end
+ end
+end
\ No newline at end of file
diff --git a/lib/monkey/engine.rb b/lib/monkey/engine.rb
new file mode 100644
index 0000000..f2ba0bb
--- /dev/null
+++ b/lib/monkey/engine.rb
@@ -0,0 +1,139 @@
+module Monkey
+
+ # Makes sure we always have RUBY_ENGINE, RUBY_ENGINE_VERSION and RUBY_DESCRIPTION
+ # TODO: Check IronRuby version detection.
+ module Engine
+
+ def jruby?; RUBY_ENGINE == "jruby"; end
+ def mri?; RUBY_ENGINE == "ruby"; end
+ def rbx?; RUBY_ENGINE == "rbx"; end
+ def ironruby?; RUBY_ENGINE == "ironruby"; end
+ def macruby?; RUBY_ENGINE == "macruby"; end
+ def maglev?; RUBY_ENGINE == "maglev"; end
+
+ alias rubinius? rbx?
+
+ def ree?
+ !!(RUBY_DESCRIPTION =~ /Ruby Enterprise Edition/) || RUBY_ENGINE == "ree"
+ end
+
+ module_function :jruby?
+ module_function :mri?
+ module_function :rbx?
+ module_function :rubinius?
+ module_function :ironruby?
+ module_function :macruby?
+ module_function :maglev?
+ module_function :ree?
+
+ def ruby_core?
+ maglev? or rubinius?
+ end
+
+ module_function :ruby_core?
+
+ include Rubinius if defined? Rubinius
+
+ unless defined? RUBY_ENGINE
+ if defined? JRUBY_VERSION then ::RUBY_ENGINE = "jruby"
+ elsif defined? Rubinius then ::RUBY_ENGINE = "rbx"
+ elsif defined? NSObject then ::RUBY_ENINGE = "macruby"
+ elsif defined? Maglev then ::RUBY_ENINGE = "maglev"
+ else ::RUBY_ENGINE = "ruby"
+ end
+ end
+
+ unless RUBY_ENGINE.frozen?
+ RUBY_ENGINE.replace "rbx" if RUBY_ENGINE == "rubinius"
+ RUBY_ENGINE.downcase!
+ RUBY_ENGINE.freeze
+ end
+
+ unless defined? RUBY_ENGINE_VERSION
+ begin
+ # ruby, jruby, macruby, some rubinius versions
+ ::RUBY_ENGINE_VERSION = const_get("#{RUBY_ENGINE.upcase}_VERSION")
+ rescue NameError
+ # maglev, some rubinius versions
+ ::RUBY_ENGINE_VERSION = const_get("VERSION")
+ end
+ end
+
+ unless defined? RUBY_DESCRIPTION
+ ::RUBY_DESCRIPTION = "#{RUBY_ENGINE} #{RUBY_ENGINE_VERSION} "
+ unless RUBY_ENGINE == "ruby"
+ ::RUBY_DESCRIPTION << "(ruby #{RUBY_VERSION}"
+ ::RUBY_DESCRIPTION << " patchlevel #{RUBY_PATCHLEVEL}" if defined? RUBY_PATCHLEVEL
+ ::RUBY_DESCRIPTION << ") "
+ end
+ if defined? RUBY_RELEASE_DATE
+ ::RUBY_DESCRIPTION << "("
+ ::RUBY_DESCRIPTION << BUILDREV[0..8] << " " if defined? BUILDREV
+ ::RUBY_DESCRIPTION << RUBY_RELEASE_DATE << ") "
+ end
+ ::RUBY_DESCRIPTION << "[#{RUBY_PLATFORM}]"
+ end
+
+ if ree?
+ ::REAL_RUBY_ENGINE_VERSION = ::REE_VERSION = RUBY_DESCRIPTION[/[^ ]+$/]
+ ::REAL_RUBY_ENGINE = "ree"
+ else
+ ::REAL_RUBY_ENGINE, ::REAL_RUBY_ENGINE_VERSION = ::RUBY_ENGINE, ::RUBY_ENGINE_VERSION
+ end
+
+ def ruby_engine(engine = RUBY_ENGINE, pretty = true)
+ return engine unless pretty
+ case engine
+ when "ruby" then ree? ? "Ruby Enterprise Edition" : "Ruby"
+ when "ree" then "Ruby Enterprise Edition"
+ when "rbx" then "Rubinius"
+ when "maglev" then "MagLev"
+ else engine.capitalize.gsub("ruby", "Ruby")
+ end
+ end
+
+ module_function :ruby_engine
+
+ def self.set_engine(engine, engine_version = nil)
+ Object.send :remove_const, "RUBY_ENGINE"
+ Object.const_set "RUBY_ENGINE", engine
+ if engine_version
+ Object.send :remove_const, "RUBY_ENGINE_VERSION"
+ Object.const_set "RUBY_ENGINE_VERSION", engine_version
+ end
+ end
+
+ def with_ruby_engine(engine, engine_version)
+ engine_was, engine_version_was = ::RUBY_ENGINE, ::RUBY_ENGINE_VERSION
+ unless defined? ::OLD_RUBY_ENGINE
+ Object.const_set("OLD_RUBY_ENGINE", ::RUBY_ENGINE)
+ Object.const_set("OLD_RUBY_ENGINE_VERSION", ::RUBY_ENGINE_VERSION)
+ end
+ Monkey::Engine.set_engine engine, engine_version
+ if block_given?
+ result = yield
+ Monkey::Engine.set_engine engine_was, engine_version_was
+ result
+ else
+ [engine_was, engine_version_was]
+ end
+ end
+
+ module_function :with_ruby_engine
+
+ def use_real_ruby_engine(&block)
+ with_ruby_engine(::REAL_RUBY_ENGINE, ::REAL_RUBY_ENGINE_VERSION, &block)
+ end
+
+ module_function :use_real_ruby_engine
+
+ def use_original_ruby_engine(&block)
+ if defined? ::OLD_RUBY_ENGINE then with_ruby_engine(::OLD_RUBY_ENGINE, ::OLD_RUBY_ENGINE_VERSION, &block)
+ else with_ruby_engine(::RUBY_ENGINE, ::RUBY_ENGINE_VERSION, &block)
+ end
+ end
+
+ module_function :use_original_ruby_engine
+
+ end
+end
\ No newline at end of file
diff --git a/lib/monkey/ext.rb b/lib/monkey/ext.rb
new file mode 100644
index 0000000..cd66990
--- /dev/null
+++ b/lib/monkey/ext.rb
@@ -0,0 +1,111 @@
+require "pathname"
+require "monkey/engine"
+
+module Monkey
+ module Ext
+
+ module ExtDSL
+
+ module ClassDsl
+ include ExtDSL
+ def core_class(klass = nil)
+ klass ? @core_class = klass : @core_class
+ end
+ end
+
+ def core_class(klass = nil)
+ if klass
+ @core_class = klass
+ klass.send :include, self
+ self::ExtClassMethods.extend ClassDsl
+ self::ExtClassMethods.core_class @core_class
+ @core_class.class_eval <<-EOS
+ def method_missing(meth, *args, &blk)
+ return super if Monkey::Backend.setup?
+ Monkey::Backend.setup
+ __send__(meth, *args, &blk)
+ end
+ EOS
+ propagate_include
+ end
+ @core_class
+ end
+
+ if Monkey::Engine.jruby? and JRUBY_VERSION < '1.6.0'
+ def each_module(&block)
+ list = []
+ ObjectSpace.each_object(Class) { |c| list << c }
+ list.each(&block)
+ end
+ else
+ def each_module(&block)
+ ObjectSpace.each_object(Module, &block)
+ end
+ end
+
+ def propagate_include
+ return if core_class.is_a? Class
+ each_module do |mod|
+ next unless mod < core_class and not mod < self
+ mod.send(:include, core_class)
+ end
+ end
+
+ def included(klass)
+ klass.extend self::ExtClassMethods
+ super
+ end
+
+ def rename_core_method(old_name, new_name)
+ core_class.send :undef_method, alias_core_method(old_name, new_name)
+ end
+
+ def alias_core_method(old_name, new_name)
+ new_name = new_name % old_name if new_name.is_a? String
+ core_class.send :alias_method, new_name, old_name
+ old_name
+ end
+
+ def feature(name, mode = :instance, &block)
+ case mode
+ when :instance then block.call
+ when :class then class_methods(&block)
+ when :shared
+ feature(name, :instance, &block)
+ feature(name, :class, &block)
+ else raise ArgumentError, "unkown mode #{mode.inspect}"
+ end
+ end
+
+ def class_methods(&block)
+ self::ExtClassMethods.class_eval(&block)
+ end
+
+ def expects(*list)
+ list.each do |name|
+ Monkey::Ext.expectations[core_class] << name.to_s
+ end
+ end
+
+ end
+
+ def self.expectations
+ @expectations ||= Hash.new { |h,k| h[k] = [] }
+ end
+
+ Dir[::File.dirname(__FILE__) + "/ext/*.rb"].sort.each do |path|
+ filename = ::File.basename(path, '.rb')
+ class_name = filename.capitalize
+ extension = eval <<-EOS
+ module ::Monkey::Ext::#{class_name} # <- for MacRuby!?
+ module ExtClassMethods; end # <- for 1.9
+ self
+ end
+ EOS
+ extension.extend ExtDSL
+ extension.core_class ::Object.const_get(class_name)
+ require "monkey/ext/#{filename}"
+ end
+
+ end
+end
\ No newline at end of file
diff --git a/lib/monkey/ext/array.rb b/lib/monkey/ext/array.rb
new file mode 100644
index 0000000..e893c1a
--- /dev/null
+++ b/lib/monkey/ext/array.rb
@@ -0,0 +1,19 @@
+require 'set'
+
+module Monkey
+ module Ext
+ module Array
+ # Defined by backend.
+ expects :extract_options!
+
+ def select!(&block)
+ return :to_enum if block.nil? and respond_to? :to_enum
+ replace select(&block)
+ end
+
+ def +@
+ Set.new self
+ end
+ end
+ end
+end
\ No newline at end of file
diff --git a/lib/monkey/ext/enumerable.rb b/lib/monkey/ext/enumerable.rb
new file mode 100644
index 0000000..e84c4be
--- /dev/null
+++ b/lib/monkey/ext/enumerable.rb
@@ -0,0 +1,20 @@
+module Monkey
+ module Ext
+ module Enumerable
+ def construct(obj)
+ enum_for :construct, obj unless block_given? or !respond_to? :enum_for
+ inject(obj) { |a,v| a.tap { yield(a, v) } }
+ end
+
+ def construct_hash(default = {})
+ enum_for :construct_hash unless block_given? or !respond_to? :enum_for
+ construct(default.to_hash.dup) do |h,v|
+ result = yield(v)
+ result = [result, nil] unless result.is_a? Enumerable
+ result = [result] unless result.respond_to? :to_ary
+ h.merge! Hash[*result]
+ end
+ end
+ end
+ end
+end
diff --git a/lib/monkey/ext/file.rb b/lib/monkey/ext/file.rb
new file mode 100644
index 0000000..dd860e2
--- /dev/null
+++ b/lib/monkey/ext/file.rb
@@ -0,0 +1,12 @@
+module Monkey
+ module Ext
+ module File
+ module ExtClassMethods
+ def write(path, content = '', mode = 'w')
+ File.open(path, mode) { |f| f.write content }
+ content
+ end
+ end
+ end
+ end
+end
\ No newline at end of file
diff --git a/lib/monkey/ext/module.rb b/lib/monkey/ext/module.rb
new file mode 100644
index 0000000..cc921bf
--- /dev/null
+++ b/lib/monkey/ext/module.rb
@@ -0,0 +1,28 @@
+module Monkey
+ module Ext
+ module Module
+ # Defined by backend.
+ expects :parent
+
+ def nested_method_missing(mod, name, *args, &block)
+ Monkey.invisible __FILE__ do
+ if respond_to? :parent and parent != self
+ parent.send(:nested_method_missing, mod, name, *args, &block)
+ else
+ mod.send(:method_missing_without_nesting, name, *args)
+ end
+ end
+ end
+
+ def method_missing(name, *args, &block)
+ if respond_to? :parent and parent.respond_to? :nested_method_missing
+ parent.nested_method_missing(self, name, *args, &block)
+ else
+ method_missing_without_nesting(name, *args, &block)
+ end
+ end
+
+ end
+ end
+end
+
diff --git a/lib/monkey/ext/object.rb b/lib/monkey/ext/object.rb
new file mode 100644
index 0000000..49f15f2
--- /dev/null
+++ b/lib/monkey/ext/object.rb
@@ -0,0 +1,50 @@
+module Monkey
+ module Ext
+ module Object
+
+ # Defined by backend.
+ expects :singleton_class, :tap
+
+ # Behaves like instance_eval or yield depending on whether a block takes an argument or not.
+ #
+ # class Foo
+ # define_method(:foo) { 42 }
+ # end
+ #
+ # Foo.new.instance_yield { foo } # => 42
+ # Foo.new.instance_yield { |c| c.foo } # => 42
+ #
+ # Also, you can pass a proc directly:
+ #
+ # block = proc { }
+ # instance_yield(block)
+ def instance_yield(block = nil, &alternate_block)
+ raise ArgumentError, "too many blocks given" if block && alternate_block
+ block ||= alternate_block
+ raise LocalJumpError, "no block given (yield)" unless block
+ block.arity > 0 ? yield(self) : instance_eval(&block)
+ end
+
+ def singleton_class_eval(&block)
+ singleton_class.class_eval(&block)
+ end
+
+ def define_singleton_method(name, &block)
+ singleton_class_eval { define_method(name, &block) }
+ end
+
+ def metaclass
+ warn "DEPRECATION WARNING: #metaclass will be removed, use #singleton_class (#{caller})"
+ singleton_class
+ end
+
+ def metaclass_eval(&block)
+ warn "DEPRECATION WARNING: #metaclass_eval will be removed, use #singleton_class_eval (#{caller})"
+ singleton_class_eval(&block)
+ end
+
+ alias_core_method :method_missing, :method_missing_without_nesting
+
+ end
+ end
+end
\ No newline at end of file
diff --git a/lib/monkey/ext/pathname.rb b/lib/monkey/ext/pathname.rb
new file mode 100644
index 0000000..d2662fd
--- /dev/null
+++ b/lib/monkey/ext/pathname.rb
@@ -0,0 +1,25 @@
+require "pathname"
+
+module Monkey
+ module Ext
+ module Pathname
+ ##
+ # @return [Pathname, NilClass] Path with correct casing.
+ def cased_path
+ return unless exist?
+ return Dir.chdir(self) { Pathname(Dir.pwd) } if ::File.directory? path
+ files = Dir.chdir(dirname) { Dir.entries('.').select { |f| f.downcase == basename.to_s.downcase } }
+ dirname.cased_path.join(files.size == 1 ? files.first : basename)
+ end
+
+ def chdir(&block)
+ Dir.chdir(self.to_s, &block)
+ end
+
+ def open(mode = "r", &block)
+ File.open(self, mode, &block)
+ end
+
+ end
+ end
+end
diff --git a/lib/monkey/ext/string.rb b/lib/monkey/ext/string.rb
new file mode 100644
index 0000000..93526b4
--- /dev/null
+++ b/lib/monkey/ext/string.rb
@@ -0,0 +1,179 @@
+require "pathname"
+
+module Monkey
+ module Ext
+ module String
+ # Defined by backend.
+ expects :constantize, :to_const_string, :to_const_path, :underscore, :camelcase
+
+ feature :version do
+ def to_version
+ dup.to_version!
+ end
+
+ def to_version!
+ extend Monkey::Version
+ self
+ end
+ end
+
+ feature :pathname do
+ def atime
+ Pathname(self).atime
+ end
+
+ def absolute_path?
+ Pathname(self).absolute?
+ end
+
+ def basename
+ Pathname(self).basename.to_s
+ end
+
+ def blockdev?
+ Pathname(self).blockdev?
+ end
+
+ def chardev?
+ Pathname(self).chardev?
+ end
+
+ def cleanpath
+ Pathname(self).cleanpath.to_s
+ end
+
+ def ctime
+ Pathname(self).ctime
+ end
+
+ def directory_children
+ Pathname(self).children
+ end
+
+ def directory?
+ Pathname(self).directory?
+ end
+
+ def dirname
+ Pathname(self).dirname.to_s
+ end
+
+ def cased_path
+ Pathname(self).cased_path.to_s
+ end
+
+ def chdir(&block)
+ Pathname(self).chdir(&block)
+ end
+
+ def expand_path
+ Pathname(self).expand_path.to_s
+ end
+
+ def extname
+ Pathname(self).extname.to_s
+ end
+
+ def file?
+ Pathname(self).file?
+ end
+
+ def file_exist?
+ Pathname(self).exist?
+ end
+
+ alias file_exists? file_exist?
+
+ def file_grpowned?
+ Pathname(self).grpowned?
+ end
+
+ def file_owned?
+ Pathname(self).owned?
+ end
+
+ def file_size?
+ Pathname(self).size?
+ end
+
+ def file_sticky?
+ Pathname(self).sticky?
+ end
+
+ def file_executable?
+ Pathname(self).executable?
+ end
+
+ def file_executable_real?
+ Pathname(self).executable_real?
+ end
+
+ def file_join(other)
+ Pathname(self).join(other.to_s).to_s
+ end
+
+ alias / file_join
+
+ def file_open(mode = 'r', &block)
+ Pathname(self).open(mode = 'r', &block)
+ end
+
+ def file_readable?
+ Pathname(self).readable?
+ end
+
+ def file_readable_real?
+ Pathname(self).readable_real?
+ end
+
+ def file_relative?
+ Pathname(self).relative?
+ end
+
+ def file_writable?
+ Pathname(self).writable?
+ end
+
+ def file_writable_real?
+ Pathname(self).writable_real?
+ end
+
+ def file_zero?
+ Pathname(self).zero?
+ end
+
+ def ftype
+ Pathname(self).ftype.to_s
+ end
+
+ def mountpoint?
+ Pathname(self).mountpoint?
+ end
+
+ def mtime
+ Pathname(self).mtime
+ end
+
+ def pipe?
+ Pathname(self).pipe?
+ end
+
+ def realpath
+ Pathname(self).realpath.to_s
+ end
+
+ def root?
+ Pathname(self).root?
+ end
+
+ def socket?
+ Pathname(self).socket?
+ end
+
+ def symlink?
+ Pathname(self).symlink?
+ end
+ end
+ end
+ end
+end
\ No newline at end of file
diff --git a/lib/monkey/ext/symbol.rb b/lib/monkey/ext/symbol.rb
new file mode 100644
index 0000000..9851e0f
--- /dev/null
+++ b/lib/monkey/ext/symbol.rb
@@ -0,0 +1,11 @@
+module Monkey
+ module Ext
+ module Symbol
+ def ~@
+ Monkey::Matcher.new do |obj|
+ obj.respond_to?(self)
+ end
+ end
+ end
+ end
+end
\ No newline at end of file
diff --git a/lib/monkey/hash_fix.rb b/lib/monkey/hash_fix.rb
new file mode 100644
index 0000000..4dbb5fa
--- /dev/null
+++ b/lib/monkey/hash_fix.rb
@@ -0,0 +1,2 @@
+require 'monkey/engine'
+Hash.class_eval { def hash; to_a.hash end } if Monkey::Engine.mri? and RUBY_VERSION < '1.8.7'
diff --git a/lib/monkey/matcher.rb b/lib/monkey/matcher.rb
new file mode 100644
index 0000000..44cd851
--- /dev/null
+++ b/lib/monkey/matcher.rb
@@ -0,0 +1,11 @@
+module Monkey
+ class Matcher
+ def initialize(&block)
+ @block = block
+ end
+
+ def ===(other)
+ @block.call(other)
+ end
+ end
+end
diff --git a/lib/monkey/version.rb b/lib/monkey/version.rb
new file mode 100644
index 0000000..cbe9095
--- /dev/null
+++ b/lib/monkey/version.rb
@@ -0,0 +1,35 @@
+module Monkey
+ module Version
+ def self.new(value = "")
+ super.to_version!
+ end
+
+ def to_version
+ self.dup
+ end
+
+ def to_version!
+ self
+ end
+
+ def major; fields[0]; end
+ def minor; fields[1]; end
+ def tiny; fields[2]; end
+
+ def <=>(other)
+ return super unless other.respond_to? :to_version
+ mine, others = fields.dup, other.to_version.fields
+ loop do
+ a, b = mine.unshift, others.unshift
+ return 0 if a.nil? and b.nil?
+ return 1 if b.nil? or (a.is_a? Integer and b.is_a? String)
+ return -1 if a.nil? or (b.is_a? Integer and a.is_a? String)
+ return comp unless (comp = (a <=> b)) == 0
+ end
+ end
+
+ def fields
+ split(".").map { |f| f =~ /^\d+$/ ? f.to_i : f }
+ end
+ end
+end
\ No newline at end of file
diff --git a/metadata.yml b/metadata.yml
new file mode 100644
index 0000000..9db7f4a
--- /dev/null
+++ b/metadata.yml
@@ -0,0 +1,146 @@
+--- !ruby/object:Gem::Specification
+name: monkey-lib
+version: !ruby/object:Gem::Version
+ hash: 3
+ prerelease: false
+ segments:
+ - 0
+ - 5
+ - 4
+ version: 0.5.4
+platform: ruby
+authors:
+- Konstantin Haase
+autorequire:
+bindir: bin
+cert_chain: []
+
+date: 2010-09-20 00:00:00 +02:00
+default_executable:
+dependencies:
+- !ruby/object:Gem::Dependency
+ name: backports
+ prerelease: false
+ requirement: &id001 !ruby/object:Gem::Requirement
+ none: false
+ requirements:
+ - - ">="
+ - !ruby/object:Gem::Version
+ hash: 3
+ segments:
+ - 0
+ version: "0"
+ type: :runtime
+ version_requirements: *id001
+description: Making ruby extension frameworks pluggable.
+email: konstantin.mailinglists at googlemail.com
+executables: []
+
+extensions: []
+
+extra_rdoc_files:
+- README.rdoc
+- LICENSE
+- lib/monkey/autoloader.rb
+- lib/monkey/backend/active_support.rb
+- lib/monkey/backend/backports.rb
+- lib/monkey/backend/common/extract_options.rb
+- lib/monkey/backend/common/parent.rb
+- lib/monkey/backend/common/singleton_class.rb
+- lib/monkey/backend/common/tap.rb
+- lib/monkey/backend/extlib.rb
+- lib/monkey/backend/facets.rb
+- lib/monkey/backend.rb
+- lib/monkey/engine.rb
+- lib/monkey/ext/array.rb
+- lib/monkey/ext/enumerable.rb
+- lib/monkey/ext/file.rb
+- lib/monkey/ext/module.rb
+- lib/monkey/ext/object.rb
+- lib/monkey/ext/pathname.rb
+- lib/monkey/ext/string.rb
+- lib/monkey/ext/symbol.rb
+- lib/monkey/ext.rb
+- lib/monkey/hash_fix.rb
+- lib/monkey/matcher.rb
+- lib/monkey/version.rb
+- lib/monkey-lib.rb
+- lib/monkey.rb
+files:
+- LICENSE
+- Rakefile
+- README.rdoc
+- lib/monkey/autoloader.rb
+- lib/monkey/backend/active_support.rb
+- lib/monkey/backend/backports.rb
+- lib/monkey/backend/common/extract_options.rb
+- lib/monkey/backend/common/parent.rb
+- lib/monkey/backend/common/singleton_class.rb
+- lib/monkey/backend/common/tap.rb
+- lib/monkey/backend/extlib.rb
+- lib/monkey/backend/facets.rb
+- lib/monkey/backend.rb
+- lib/monkey/engine.rb
+- lib/monkey/ext/array.rb
+- lib/monkey/ext/enumerable.rb
+- lib/monkey/ext/file.rb
+- lib/monkey/ext/module.rb
+- lib/monkey/ext/object.rb
+- lib/monkey/ext/pathname.rb
+- lib/monkey/ext/string.rb
+- lib/monkey/ext/symbol.rb
+- lib/monkey/ext.rb
+- lib/monkey/hash_fix.rb
+- lib/monkey/matcher.rb
+- lib/monkey/version.rb
+- lib/monkey-lib.rb
+- lib/monkey.rb
+- spec/monkey/backend_spec.rb
+- spec/monkey/engine_spec.rb
+- spec/monkey/ext/array_spec.rb
+- spec/monkey/ext/enumerable_spec.rb
+- spec/monkey/ext/module_spec.rb
+- spec/monkey/ext/object_spec.rb
+- spec/monkey/ext/pathname_spec.rb
+- spec/monkey/ext/string_spec.rb
+- spec/monkey/ext/symbol_spec.rb
+- spec/monkey/ext_spec.rb
+- spec/monkey/matcher_spec.rb
+- spec/monkey_spec.rb
+- spec/spec_helper.rb
+has_rdoc: true
+homepage: http://github.com/rkh/monkey-lib
+licenses: []
+
+post_install_message:
+rdoc_options: []
+
+require_paths:
+- lib
+required_ruby_version: !ruby/object:Gem::Requirement
+ none: false
+ requirements:
+ - - ">="
+ - !ruby/object:Gem::Version
+ hash: 3
+ segments:
+ - 0
+ version: "0"
+required_rubygems_version: !ruby/object:Gem::Requirement
+ none: false
+ requirements:
+ - - ">="
+ - !ruby/object:Gem::Version
+ hash: 3
+ segments:
+ - 0
+ version: "0"
+requirements: []
+
+rubyforge_project:
+rubygems_version: 1.3.7
+signing_key:
+specification_version: 3
+summary: Making ruby extension frameworks pluggable.
+test_files: []
+
diff --git a/spec/monkey/backend_spec.rb b/spec/monkey/backend_spec.rb
new file mode 100644
index 0000000..13ccfce
--- /dev/null
+++ b/spec/monkey/backend_spec.rb
@@ -0,0 +1,7 @@
+require __FILE__.sub(%r{monkey/.*$}, "spec_helper")
+
+describe Monkey::Backend do
+ it "should preffer backports unless any backend already has been loaded" do
+ Monkey::Backend.available_backends.first.should == Monkey::Backend::Backports
+ end
+end
diff --git a/spec/monkey/engine_spec.rb b/spec/monkey/engine_spec.rb
new file mode 100644
index 0000000..27ca78a
--- /dev/null
+++ b/spec/monkey/engine_spec.rb
@@ -0,0 +1,55 @@
+require __FILE__.sub(%r{monkey/.*$}, "spec_helper")
+
+describe Monkey::Engine do
+
+ it "defines RUBY_VERSION" do
+ defined?(RUBY_VERSION).should == "constant"
+ end
+
+ it "defines RUBY_ENGINE_VERSION" do
+ defined?(RUBY_ENGINE_VERSION).should == "constant"
+ end
+
+ it "defines RUBY_DESCRIPTION" do
+ defined?(RUBY_DESCRIPTION).should == "constant"
+ end
+
+ it "defines REAL_RUBY_VERSION" do
+ defined?(RUBY_VERSION).should == "constant"
+ end
+
+ it "defines REAL_RUBY_ENGINE_VERSION" do
+ defined?(RUBY_ENGINE_VERSION).should == "constant"
+ end
+
+ describe "with_ruby_engine" do
+
+ it "sets RUBY_ENGINE and RUBY_ENGINE_VERSION" do
+ Monkey::Engine.with_ruby_engine("jruby", "1.4.0") do
+ RUBY_ENGINE.should == "jruby"
+ RUBY_ENGINE_VERSION.should == "1.4.0"
+ Monkey::Engine.should be_jruby
+ end
+ Monkey::Engine.with_ruby_engine("ruby", "1.8.7") do
+ RUBY_ENGINE.should == "ruby"
+ RUBY_ENGINE_VERSION.should == "1.8.7"
+ Monkey::Engine.should be_mri
+ end
+ end
+
+ it "restores old RUBY_ENGINE if block given" do
+ old = RUBY_ENGINE
+ Monkey::Engine.with_ruby_engine("foobar", "1.0") { }
+ RUBY_ENGINE.should_not == "foobar"
+ RUBY_ENGINE.should == old
+ end
+
+ it "restores old RUBY_ENGINE_VERSION if block given" do
+ old = RUBY_ENGINE_VERSION
+ Monkey::Engine.with_ruby_engine("foobar", "1.0") { }
+ RUBY_ENGINE_VERSION.should == old
+ end
+
+ end
+
+end
\ No newline at end of file
diff --git a/spec/monkey/ext/array_spec.rb b/spec/monkey/ext/array_spec.rb
new file mode 100644
index 0000000..8cd81ee
--- /dev/null
+++ b/spec/monkey/ext/array_spec.rb
@@ -0,0 +1,37 @@
+require __FILE__.sub(%r{monkey/.*$}, "spec_helper")
+
+describe Monkey::Ext::Array do
+ describe "backend expectations" do
+ # expects :extract_options!
+ it "imports extract_options! from backend" do
+ [:foo, {:x => 10}].extract_options!.should == {:x => 10}
+ [:foo].extract_options!.should == {}
+ [{:x => 10}, :foo].extract_options!.should == {}
+ ary1 = [:foo, {:x => 10}]
+ ary1.extract_options!
+ ary1.should == [:foo]
+ ary2 = [{:x => 10}, :foo]
+ ary2.extract_options!
+ ary2.should == [{:x => 10}, :foo]
+ end
+ end
+
+ describe "select!" do
+ it "results in the same arrays as Array#select" do
+ ([1, 2, 3, 4, 5, 6].select! { |e| e > 3 }).should == ([1, 2, 3, 4, 5, 6].select { |e| e > 3 })
+ ([1, 2, 3, 4, 5, 6].select! { |e| e < 0 }).should == ([1, 2, 3, 4, 5, 6].select { |e| e < 0 })
+ end
+
+ it "modifies the current array, rather than returning a new one" do
+ x = [1, 2, 3, 4, 5, 6]
+ x.select! { |e| e > 3 }
+ x.should == [4, 5, 6]
+ end
+ end
+
+ describe '+@' do
+ it 'returns a set' do
+ (+[1,2]).should be_a(Set)
+ end
+ end
+end
\ No newline at end of file
diff --git a/spec/monkey/ext/enumerable_spec.rb b/spec/monkey/ext/enumerable_spec.rb
new file mode 100644
index 0000000..addbc76
--- /dev/null
+++ b/spec/monkey/ext/enumerable_spec.rb
@@ -0,0 +1,28 @@
+require __FILE__.sub(%r{monkey/.*$}, "spec_helper")
+
+describe Monkey::Ext::Enumerable do
+ describe :construct do
+ it "always returns the initial object" do
+ obj = Object.new
+ (1..100).construct(obj) { "not obj" }.should == obj
+ end
+
+ it "allows modifying that object" do
+ ("a".."c").construct("result: ") { |a,v| a << v }.should == "result: abc"
+ end
+ end
+
+ describe :construct_hash do
+ it "constructs a hash from given hashes" do
+ ("a".."b").construct_hash { |v| { v => v } }.should == { "a" => "a", "b" => "b" }
+ end
+
+ it "constructs a hash from given arrays" do
+ ("a".."b").construct_hash { |v| [v, v] }.should == { "a" => "a", "b" => "b" }
+ end
+
+ it "takes an initial hash" do
+ ["a"].construct_hash("b" => "b") { |v| [v, v] }.should == { "a" => "a", "b" => "b" }
+ end
+ end
+end
\ No newline at end of file
diff --git a/spec/monkey/ext/module_spec.rb b/spec/monkey/ext/module_spec.rb
new file mode 100644
index 0000000..489670d
--- /dev/null
+++ b/spec/monkey/ext/module_spec.rb
@@ -0,0 +1,32 @@
+require __FILE__.sub(%r{monkey/.*$}, "spec_helper")
+
+describe Monkey::Ext::Module do
+ describe "backend expectations" do
+ # expects :parent
+ it "imports parent from backend" do
+ Monkey::Ext::Module.parent.should == Monkey::Ext
+ Monkey::Ext.parent.should == Monkey
+ Monkey.parent.should == Object
+ Object.parent.should == Object
+ Object.send :remove_const, :ExtFoo if Object.const_defined? :ExtFoo
+ ExtFoo = Monkey::Ext::Module
+ ExtFoo.parent.should == Monkey::Ext
+ end
+ end
+
+ describe "nested_method_missing" do
+
+ before do
+ [:Foo, :Bar, :Blah].inject(Object) do |parent, name|
+ parent.send :remove_const, name if parent.const_defined? name
+ parent.const_set name, Module.new
+ end
+ end
+
+ it "should call nested_method_missing on parent" do
+ Foo.should_receive(:nested_method_missing).once.with(Foo::Bar, :foo)
+ Foo::Bar.foo
+ end
+
+ end
+end
diff --git a/spec/monkey/ext/object_spec.rb b/spec/monkey/ext/object_spec.rb
new file mode 100644
index 0000000..0e21691
--- /dev/null
+++ b/spec/monkey/ext/object_spec.rb
@@ -0,0 +1,53 @@
+require __FILE__.sub(%r{monkey/.*$}, "spec_helper")
+
+describe Monkey::Ext::Object do
+
+ before do
+ @obj = Object.new
+ end
+
+ describe "backend expectations" do
+
+ # expects :tap
+ it "imports tap from backend" do
+ @obj.tap { |o| o.should == @obj }
+ 42.tap { 23 }.should == 42
+ end
+
+ # expects :singleton_class
+ it "imports singleton_class from backend" do
+ @obj.singleton_class.should == (class << @obj; self; end)
+ end
+
+ end
+
+ describe :instance_yield do
+
+ before do
+ @obj.stub! :foo
+ end
+
+ it "calls a block if block takes at least one argument" do
+ foo = nil
+ @obj.should_not_receive :foo
+ @obj.send :instance_yield do |x|
+ foo
+ end
+ end
+
+ it "passes object as first argument to blog" do
+ @obj.send :instance_yield do |x|
+ x.should == @obj
+ end
+ end
+
+ it "passes the block to instance_eval if block doesn't take arguments" do
+ @obj.should_receive :foo
+ @obj.send :instance_yield do
+ foo
+ end
+ end
+
+ end
+
+end
\ No newline at end of file
diff --git a/spec/monkey/ext/pathname_spec.rb b/spec/monkey/ext/pathname_spec.rb
new file mode 100644
index 0000000..e69de29
diff --git a/spec/monkey/ext/string_spec.rb b/spec/monkey/ext/string_spec.rb
new file mode 100644
index 0000000..623cf7f
--- /dev/null
+++ b/spec/monkey/ext/string_spec.rb
@@ -0,0 +1,332 @@
+require __FILE__.sub(%r{monkey/.*$}, "spec_helper")
+
+describe Monkey::Ext::String do
+
+ describe "backend expectations" do
+
+ # expects :constantize :underscore, :camelcase
+ it "imports constantize from backend" do
+ "Object".constantize.should == Object
+ "Monkey::Ext".constantize.should == Monkey::Ext
+ end
+
+ # expects :to_const_string
+ it "imports to_const_string from backend" do
+ "object".to_const_string.should == "Object"
+ "monkey/ext".to_const_string.should == "Monkey::Ext"
+ end
+
+ # expects :to_const_path
+ it "imports to_const_path from backend" do
+ "Object".to_const_path.should == "object"
+ "Monkey::Ext".to_const_path.should == "monkey/ext"
+ end
+
+ # expects :underscore
+ it "imports underscore from backend" do
+ "FooBar".underscore.should == "foo_bar"
+ end
+
+ # expects :camelcase
+ it "imports camelcase from backend" do
+ ["FooBar", "fooBar"].should include("foo_bar".camelcase)
+ end
+
+ end
+
+ describe "like Pathname" do
+
+ before do
+ @strings = ["/usr/bin/ruby", ".", "..", ENV["HOME"]]
+ end
+
+ it "imports Pathname's cleanpath to String" do
+ @strings.each do |s|
+ s.cleanpath.should == Pathname(s).cleanpath.to_s
+ end
+ end
+
+ it "imports Pathname's realpath to String" do
+ @strings.each do |s|
+ begin
+ s.realpath.should == Pathname(s).realpath.to_s
+ rescue Errno::ENOENT
+ end
+ end
+ end
+
+ it "imports Pathname's mountpoint? to String" do
+ @strings.each do |s|
+ s.mountpoint?.should == Pathname(s).mountpoint?
+ end
+ end
+
+ it "imports Pathname's root? to String" do
+ @strings.each do |s|
+ s.root?.should == Pathname(s).root?
+ end
+ end
+
+ it "imports Pathname's absolute_path? to String" do
+ @strings.each do |s|
+ s.absolute_path?.should == Pathname(s).absolute?
+ end
+ end
+
+ it "imports Pathname's file_relative? to String" do
+ @strings.each do |s|
+ s.file_relative?.should == Pathname(s).relative?
+ end
+ end
+
+ it "imports Pathname's file_join to String" do
+ @strings.each do |s|
+ s.file_join("foo").should == Pathname(s).join("foo").to_s
+ s.file_join(:foo).should == Pathname(s).join("foo").to_s
+ end
+ end
+
+ it "imports Pathname's atime to String" do
+ @strings.each do |s|
+ s.atime.should == Pathname(s).atime
+ end
+ end
+
+ it "imports Pathname's ctime to String" do
+ @strings.each do |s|
+ s.ctime.should == Pathname(s).ctime
+ end
+ end
+
+ it "imports Pathname's mtime to String" do
+ @strings.each do |s|
+ s.mtime.should == Pathname(s).mtime
+ end
+ end
+
+ it "imports Pathname's ftype to String" do
+ @strings.each do |s|
+ s.ftype.should == Pathname(s).ftype.to_s
+ end
+ end
+
+ it "imports Pathname's basename to String" do
+ @strings.each do |s|
+ s.basename.should == Pathname(s).basename.to_s
+ end
+ end
+
+ it "imports Pathname's dirname to String" do
+ @strings.each do |s|
+ s.dirname.should == Pathname(s).dirname.to_s
+ end
+ end
+
+ it "imports Pathname's extname to String" do
+ @strings.each do |s|
+ s.extname.should == Pathname(s).extname.to_s
+ end
+ end
+
+ it "imports Pathname's expand_path to String" do
+ @strings.each do |s|
+ s.expand_path.should == Pathname(s).expand_path.to_s
+ end
+ end
+
+ it "imports Pathname's blockdev? to String" do
+ @strings.each do |s|
+ s.blockdev?.should == Pathname(s).blockdev?
+ end
+ end
+
+ it "imports Pathname's chardev? to String" do
+ @strings.each do |s|
+ s.chardev?.should == Pathname(s).chardev?
+ end
+ end
+
+ it "imports Pathname's file_executable? to String" do
+ @strings.each do |s|
+ s.file_executable?.should == Pathname(s).executable?
+ end
+ end
+
+ it "imports Pathname's file_executable_real? to String" do
+ @strings.each do |s|
+ s.file_executable_real?.should == Pathname(s).executable_real?
+ end
+ end
+
+ it "imports Pathname's atime to String" do
+ @strings.each do |s|
+ s.atime.should == Pathname(s).atime
+ end
+ end
+
+ it "imports Pathname's ctime to String" do
+ @strings.each do |s|
+ s.ctime.should == Pathname(s).ctime
+ end
+ end
+
+ it "imports Pathname's mtime to String" do
+ @strings.each do |s|
+ s.mtime.should == Pathname(s).mtime
+ end
+ end
+
+ it "imports Pathname's ftype to String" do
+ @strings.each do |s|
+ s.ftype.should == Pathname(s).ftype.to_s
+ end
+ end
+
+ it "imports Pathname's basename to String" do
+ @strings.each do |s|
+ s.basename.should == Pathname(s).basename.to_s
+ end
+ end
+
+ it "imports Pathname's dirname to String" do
+ @strings.each do |s|
+ s.dirname.should == Pathname(s).dirname.to_s
+ end
+ end
+
+ it "imports Pathname's extname to String" do
+ @strings.each do |s|
+ s.extname.should == Pathname(s).extname.to_s
+ end
+ end
+
+ it "imports Pathname's expand_path to String" do
+ @strings.each do |s|
+ s.expand_path.should == Pathname(s).expand_path.to_s
+ end
+ end
+
+ it "imports Pathname's blockdev? to String" do
+ @strings.each do |s|
+ s.blockdev?.should == Pathname(s).blockdev?
+ end
+ end
+
+ it "imports Pathname's chardev? to String" do
+ @strings.each do |s|
+ s.chardev?.should == Pathname(s).chardev?
+ end
+ end
+
+ it "imports Pathname's file_executable? to String" do
+ @strings.each do |s|
+ s.file_executable?.should == Pathname(s).executable?
+ end
+ end
+
+ it "imports Pathname's file_executable_real? to String" do
+ @strings.each do |s|
+ s.file_executable_real?.should == Pathname(s).executable_real?
+ end
+ end
+
+ it "imports Pathname's directory? to String" do
+ @strings.each do |s|
+ s.directory?.should == Pathname(s).directory?
+ end
+ end
+
+ it "imports Pathname's file? to String" do
+ @strings.each do |s|
+ s.file?.should == Pathname(s).file?
+ end
+ end
+
+ it "imports Pathname's pipe? to String" do
+ @strings.each do |s|
+ s.pipe?.should == Pathname(s).pipe?
+ end
+ end
+
+ it "imports Pathname's socket? to String" do
+ @strings.each do |s|
+ s.socket?.should == Pathname(s).socket?
+ end
+ end
+
+ it "imports Pathname's file_owned? to String" do
+ @strings.each do |s|
+ s.file_owned?.should == Pathname(s).owned?
+ end
+ end
+
+ it "imports Pathname's file_readable? to String" do
+ @strings.each do |s|
+ s.file_readable?.should == Pathname(s).readable?
+ end
+ end
+
+ it "imports Pathname's file_readable_real? to String" do
+ @strings.each do |s|
+ s.file_readable_real?.should == Pathname(s).readable_real?
+ end
+ end
+
+ it "imports Pathname's symlink? to String" do
+ @strings.each do |s|
+ s.symlink?.should == Pathname(s).symlink?
+ end
+ end
+
+ it "imports Pathname's file_writable? to String" do
+ @strings.each do |s|
+ s.file_writable?.should == Pathname(s).writable?
+ end
+ end
+
+ it "imports Pathname's file_writable_real? to String" do
+ @strings.each do |s|
+ s.file_writable_real?.should == Pathname(s).writable_real?
+ end
+ end
+
+ it "imports Pathname's file_zero? to String" do
+ @strings.each do |s|
+ s.file_zero?.should == Pathname(s).zero?
+ end
+ end
+
+ it "imports Pathname's file_exist? to String" do
+ @strings.each do |s|
+ s.file_exist?.should == Pathname(s).exist?
+ s.file_exists?.should == Pathname(s).exist?
+ end
+ end
+
+ it "imports Pathname's file_grpowned? to String" do
+ @strings.each do |s|
+ s.file_grpowned?.should == Pathname(s).grpowned?
+ end
+ end
+
+ it "imports Pathname's file_size? to String" do
+ @strings.each do |s|
+ s.file_size?.should == Pathname(s).size?
+ end
+ end
+
+ it "imports Pathname's file_sticky? to String" do
+ @strings.each do |s|
+ s.file_sticky?.should == Pathname(s).sticky?
+ end
+ end
+
+ it "imports Pathname's directory_children to String" do
+ @strings.each do |s|
+ s.directory_children.should == Pathname(s).children if s.directory?
+ end
+ end
+
+ end
+
+end
\ No newline at end of file
diff --git a/spec/monkey/ext/symbol_spec.rb b/spec/monkey/ext/symbol_spec.rb
new file mode 100644
index 0000000..1cf2755
--- /dev/null
+++ b/spec/monkey/ext/symbol_spec.rb
@@ -0,0 +1,20 @@
+require __FILE__.sub(%r{monkey/.*$}, "spec_helper")
+
+describe Monkey::Ext::Symbol do
+ describe '~@' do
+ it 'should match objects responding to a method' do
+ matcher = ~:foo
+ o = Object.new
+ (matcher === o).should be_false
+ o.stub! :foo
+ (matcher === o).should be_true
+ end
+
+ it 'should work for case statements' do
+ case 'foo'
+ when ~:to_s then nil
+ else fail 'did not match'
+ end
+ end
+ end
+end
diff --git a/spec/monkey/ext_spec.rb b/spec/monkey/ext_spec.rb
new file mode 100644
index 0000000..f15e99d
--- /dev/null
+++ b/spec/monkey/ext_spec.rb
@@ -0,0 +1,50 @@
+require __FILE__.sub(%r{monkey/.*$}, "spec_helper")
+
+describe Monkey::Ext do
+ describe Monkey::Ext::ExtDSL do
+
+ before do
+ @core_class = Class.new
+ @extension = Module.new
+ @extension::ExtClassMethods = Module.new
+ @extension.extend Monkey::Ext::ExtDSL
+ @extension.core_class @core_class
+ end
+
+ it "extends the core class" do
+ @core_class.ancestors.should include(@extension)
+ end
+
+ it "adds methods to the core class instances" do
+ instance = @core_class.new
+ @extension.class_eval do
+ def foo
+ 42
+ end
+ end
+ instance.foo.should == 42
+ end
+
+ it "adds methods to the core class" do
+ @extension.class_methods do
+ def foo
+ 42
+ end
+ end
+ @core_class.foo.should == 42
+ end
+
+ it "is able to rename core instance methods" do
+ instance = @core_class.new
+ @core_class.class_eval do
+ def foo
+ 42
+ end
+ end
+ @extension.rename_core_method :foo, :bar
+ instance.should_not respond_to(:foo)
+ instance.bar.should == 42
+ end
+
+ end
+end
diff --git a/spec/monkey/matcher_spec.rb b/spec/monkey/matcher_spec.rb
new file mode 100644
index 0000000..3319620
--- /dev/null
+++ b/spec/monkey/matcher_spec.rb
@@ -0,0 +1,17 @@
+require __FILE__.sub(%r{monkey/.*$}, "spec_helper")
+
+describe Monkey::Matcher do
+ it 'should consider block for #===' do
+ matcher = Monkey::Matcher.new { |x| x > 6 }
+ (matcher === 5).should be_false
+ (matcher === 8).should be_true
+ end
+
+ it 'should work with switch' do
+ matcher = Monkey::Matcher.new { |x| /foo/ === x }
+ case 'foobar'
+ when matcher then nil
+ else fail 'did not match'
+ end
+ end
+end
\ No newline at end of file
diff --git a/spec/monkey_spec.rb b/spec/monkey_spec.rb
new file mode 100644
index 0000000..5c416ef
--- /dev/null
+++ b/spec/monkey_spec.rb
@@ -0,0 +1,25 @@
+require __FILE__.sub(%r{monkey_spec\.rb$}, "spec_helper")
+
+describe Monkey do
+ describe :invisible do
+ it "removes lines from a backtrace" do
+ Monkey.hide_invisibles! do
+ begin
+ Monkey.invisible(__FILE__) { raise }
+ rescue
+ $!.backtrace.each do |line|
+ line.should_not include(__FILE__)
+ end
+ end
+ end
+ end
+ end
+
+ if BACKEND
+ describe "backend" do
+ it "uses backend #{ENV['BACKEND']}" do
+ Monkey.backend.should == Monkey::Backend.detect_backend(BACKEND)
+ end
+ end
+ end
+end
\ No newline at end of file
diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb
new file mode 100644
index 0000000..7f3c013
--- /dev/null
+++ b/spec/spec_helper.rb
@@ -0,0 +1,26 @@
+$LOAD_PATH.unshift File.expand_path(__FILE__.sub("spec/spec_helper.rb", "lib"))
+require "monkey-lib"
+
+# I hate that code, but rbx for some reason ignores RUBYOPT.
+begin
+ require "rubygems"
+rescue LoadError
+end
+
+BACKEND, BACKEND_SETUP = ENV['BACKEND'], ENV['BACKEND_SETUP']
+if BACKEND and not BACKEND.empty?
+ case BACKEND_SETUP
+ when "autodetect"
+ require BACKEND
+ Monkey::Backend.setup
+ when "explicit"
+ Monkey.backend = BACKEND
+ else
+ puts "Please set BACKEND_SETUP."
+ exit 1
+ end
+ version = "version " << Monkey.backend.version << ", " if Monkey.backend.version?
+ puts "Using #{BACKEND} (#{version}#{BACKEND_SETUP} setup mode)"
+end
+
+Monkey.show_invisibles!
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-ruby-extras/ruby-monkey-lib.git
More information about the Pkg-ruby-extras-commits
mailing list