monkey-lib 0.2.1 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/README.rdoc +12 -0
- data/Rakefile +111 -47
- data/lib/monkey.rb +11 -0
- data/lib/monkey/autoloader.rb +2 -0
- data/lib/monkey/backend.rb +97 -32
- data/lib/monkey/backend/active_support.rb +10 -15
- data/lib/monkey/backend/backports.rb +8 -14
- data/lib/monkey/backend/common/parent.rb +4 -6
- data/lib/monkey/backend/common/tap.rb +1 -1
- data/lib/monkey/backend/extlib.rb +10 -18
- data/lib/monkey/backend/facets.rb +11 -18
- data/lib/monkey/ext.rb +20 -12
- data/lib/monkey/ext/module.rb +0 -16
- data/lib/monkey/ext/string.rb +147 -0
- data/spec/monkey/engine_spec.rb +5 -6
- data/spec/monkey/ext/array_spec.rb +18 -0
- data/spec/monkey/ext/module_spec.rb +15 -0
- data/spec/monkey/ext/object_spec.rb +53 -0
- data/spec/monkey/ext/string_spec.rb +331 -0
- data/spec/spec_helper.rb +13 -1
- metadata +10 -23
- data/lib/monkey/string/like_pathname.rb +0 -38
- data/lib/monkey/watcher.rb +0 -139
- data/spec/monkey/hash/sub_hash_spec.rb +0 -15
- data/spec/monkey/object/backports_spec.rb +0 -24
- data/spec/monkey/object/instance_yield_spec.rb +0 -32
- data/spec/monkey/string/like_pathname_spec.rb +0 -272
data/README.rdoc
CHANGED
@@ -0,0 +1,12 @@
|
|
1
|
+
Some description goes here.
|
2
|
+
|
3
|
+
== Running the specs
|
4
|
+
|
5
|
+
Run specs with all backends:
|
6
|
+
rake spec
|
7
|
+
|
8
|
+
Run specs with active_support:
|
9
|
+
rake spec:active_support
|
10
|
+
|
11
|
+
Run specs with backports and using mspec instead of rspec (so it might work on incomplete ruby implementations):
|
12
|
+
SPEC_RUNNER=mspec rake spec:backports
|
data/Rakefile
CHANGED
@@ -1,49 +1,113 @@
|
|
1
|
-
require "spec/rake/spectask"
|
2
1
|
require "rake/clean"
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
s.add_dependency "extlib"
|
22
|
-
end
|
23
|
-
|
24
|
-
Rake::GemPackageTask.new(spec) do |pkg|
|
25
|
-
pkg.gem_spec = spec
|
26
|
-
end
|
27
|
-
|
28
|
-
desc "install the gem locally"
|
29
|
-
task :install => [:package] do
|
30
|
-
sh %{gem install pkg/monkey-lib-#{MONKEY_VERSION}.gem}
|
31
|
-
end
|
32
|
-
|
33
|
-
desc "create a gemspec file"
|
34
|
-
task :make_spec do
|
35
|
-
File.open("monkey-lib.gemspec", "w") do |file|
|
36
|
-
file.puts spec.to_ruby
|
2
|
+
|
3
|
+
task :default => :spec
|
4
|
+
|
5
|
+
backends = Dir.glob('lib/monkey/backend/*.rb').map { |f| File.basename f, ".rb" }
|
6
|
+
modes = [:autodetect, :explicit]
|
7
|
+
|
8
|
+
CLEAN.include "**/*.rbc"
|
9
|
+
CLOBBER.include "monkey-lib*.gem"
|
10
|
+
|
11
|
+
setup_rspec = proc do
|
12
|
+
require "spec/rake/spectask"
|
13
|
+
SPEC_RUNNER = "mspec"
|
14
|
+
def define_spec_task(name, ruby_cmd, pattern)
|
15
|
+
Spec::Rake::SpecTask.new name do |t|
|
16
|
+
t.spec_opts = %w[-c --format progress --loadby mtime --reverse]
|
17
|
+
t.ruby_cmd = ruby_cmd
|
18
|
+
t.pattern = pattern
|
19
|
+
end
|
37
20
|
end
|
38
|
-
end
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
end
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
21
|
+
end
|
22
|
+
|
23
|
+
setup_mspec = proc do
|
24
|
+
require "mspec"
|
25
|
+
SPEC_RUNNER = "mspec"
|
26
|
+
def define_spec_task(name, ruby_cmd, pattern)
|
27
|
+
task(name) { sh "#{ruby_cmd} -S mspec-run #{pattern}" }
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
case ENV['SPEC_RUNNER']
|
32
|
+
when "rspec" then setup_rspec.call
|
33
|
+
when "mspec" then setup_mspec.call
|
34
|
+
when nil
|
35
|
+
# yes, this code is trying to be smart, but let me have some fun, please?
|
36
|
+
raise @spec_load_error unless [setup_rspec, setup_mspec].any? { |b| b.call || true rescue (@spec_load_error ||= $!) && false }
|
37
|
+
else
|
38
|
+
puts "sorry, currently no #{ENV['SPEC_RUNNER']} support"
|
39
|
+
exit 1
|
40
|
+
end
|
41
|
+
|
42
|
+
def spec_task(name, backend = nil, mode = nil)
|
43
|
+
desc "runs specs #{"with backend #{backend} " if backend}#{"(#{mode} mode)" if mode}"
|
44
|
+
define_spec_task(name, "BACKEND=#{backend.to_s.inspect} BACKEND_SETUP=#{mode.to_s.inspect} #{ENV['RUBY'] || RUBY}", "spec/monkey/**/*_spec.rb")
|
45
|
+
end
|
46
|
+
|
47
|
+
task :environment do
|
48
|
+
$LOAD_PATH.unshift "lib"
|
49
|
+
require "monkey"
|
50
|
+
end
|
51
|
+
|
52
|
+
desc "run all specs"
|
53
|
+
task :spec => "spec:all"
|
54
|
+
namespace :spec do
|
55
|
+
|
56
|
+
desc "runs specs without explicitly setting a backend"
|
57
|
+
spec_task :autodetect
|
58
|
+
|
59
|
+
backends.each do |backend|
|
60
|
+
task :all => backend
|
61
|
+
|
62
|
+
desc "runs specs with backend #{backend}"
|
63
|
+
task backend => "#{backend}:all"
|
64
|
+
|
65
|
+
namespace backend do
|
66
|
+
modes.each do |mode|
|
67
|
+
task :all => mode
|
68
|
+
spec_task mode, backend, mode
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
namespace :backend do
|
76
|
+
|
77
|
+
desc "lists all available backends"
|
78
|
+
task(:list) { puts backends }
|
79
|
+
|
80
|
+
desc "lists expectations a backend has to meet"
|
81
|
+
task :expectations => :environment do
|
82
|
+
Monkey::Ext.expectations.each do |core_class, methods|
|
83
|
+
print "#{core_class}:".ljust(10)
|
84
|
+
puts methods.map { |n| "##{n}" }.join(", ")
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
desc "checks whether specs for expectations are present"
|
89
|
+
task :spec_check =>:environment do
|
90
|
+
Monkey::Ext.expectations.each do |core_class, methods|
|
91
|
+
path = "spec/monkey/ext/#{core_class.name.to_const_path}_spec.rb"
|
92
|
+
list = path.file_exists? ? %x[spec -d -fs #{path} -e "Monkey::Ext::#{core_class.name} backend expectations"] : ""
|
93
|
+
methods.each { |m| puts "missing specs for #{core_class.name}##{m}" unless list =~ /- imports #{m} from backend/ }
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
end
|
98
|
+
|
99
|
+
############
|
100
|
+
# aliases
|
101
|
+
|
102
|
+
namespace(:b) do
|
103
|
+
task :e => "backend:expectations"
|
104
|
+
task :l => "backend:list"
|
105
|
+
task :s => "backend:spec_check"
|
106
|
+
end
|
107
|
+
|
108
|
+
namespace(:s) do
|
109
|
+
task :as => "spec:active_support:explicit"
|
110
|
+
task :bp => "spec:backports:explicit"
|
111
|
+
task :ex => "spec:extlib:explicit"
|
112
|
+
task :fc => "spec:facets:explicit"
|
113
|
+
end
|
data/lib/monkey.rb
CHANGED
@@ -1,6 +1,17 @@
|
|
1
1
|
module Monkey
|
2
|
+
|
2
3
|
Dir[File.dirname(__FILE__) + "/monkey/*.rb"].sort.each do |path|
|
3
4
|
filename = File.basename(path, '.rb')
|
4
5
|
require "monkey/#{filename}"
|
5
6
|
end
|
7
|
+
|
8
|
+
def self.backend=(backend)
|
9
|
+
Backend.setup! backend
|
10
|
+
backend
|
11
|
+
end
|
12
|
+
|
13
|
+
def self.backend
|
14
|
+
Backend.backend
|
15
|
+
end
|
16
|
+
|
6
17
|
end
|
data/lib/monkey/autoloader.rb
CHANGED
data/lib/monkey/backend.rb
CHANGED
@@ -1,45 +1,110 @@
|
|
1
|
-
require "set"
|
2
|
-
|
3
1
|
module Monkey
|
4
2
|
module Backend
|
5
|
-
|
6
|
-
autoload :ActiveSupport, "monkey/backend/active_support"
|
7
|
-
autoload :BackendDsl, "monkey/backend/backend_dsl"
|
8
|
-
autoload :Backports, "monkey/backend/backports"
|
9
|
-
autoload :Extlib, "monkey/backend/extlib"
|
10
3
|
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
backend_name ||= expected_name
|
4
|
+
@available_backends = []
|
5
|
+
|
6
|
+
class << self
|
7
|
+
attr_reader :available_backends, :backend
|
16
8
|
end
|
17
|
-
|
18
|
-
|
19
|
-
|
9
|
+
|
10
|
+
module AbstractBackend
|
11
|
+
attr_accessor :backend_name, :backend_path
|
12
|
+
|
13
|
+
def available?
|
14
|
+
Object.const_defined? backend_name or $LOADED_FEATURES.any? { |l| l =~ /^#{backend_path}\// }
|
15
|
+
end
|
16
|
+
|
17
|
+
def setup_complete
|
18
|
+
require backend_path
|
19
|
+
setup
|
20
|
+
end
|
21
|
+
|
22
|
+
def load_libs(*data)
|
23
|
+
load_with_prefix backend_path, data
|
24
|
+
end
|
25
|
+
|
26
|
+
def load_with_prefix(prefix, libs = nil)
|
27
|
+
case libs
|
28
|
+
when String, Symbol then require File.join(prefix.to_s, libs.to_s)
|
29
|
+
when Array then libs.each { |lib| load_with_prefix prefix, lib }
|
30
|
+
when Hash then libs.each { |k, v| load_with_prefix File.join(prefix.to_s, k.to_s), v }
|
31
|
+
else raise ArgumentError, "cannot handle #{libs.inspect}"
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def missing(*libs)
|
36
|
+
load_with_prefix "monkey/backend/common", libs
|
37
|
+
end
|
38
|
+
|
39
|
+
def expects_module(name)
|
40
|
+
name.split("::").inject(Object) do |parent, name|
|
41
|
+
if name.empty?
|
42
|
+
parent
|
43
|
+
else
|
44
|
+
parent.class_eval "module #{name}; self; end"
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
20
49
|
end
|
21
50
|
|
22
|
-
def
|
23
|
-
|
51
|
+
def self.new(backend_name, backend_path = nil, &block)
|
52
|
+
mod = eval "module #{backend_name}; self; end"
|
53
|
+
mod.extend AbstractBackend
|
54
|
+
backend_path ||= backend_name.to_s.downcase
|
55
|
+
mod.backend_name, mod.backend_path = backend_name.to_s, backend_path.to_s
|
56
|
+
available_backends << mod
|
57
|
+
mod.class_eval(&block) if block
|
24
58
|
end
|
25
|
-
|
26
|
-
def
|
27
|
-
|
59
|
+
|
60
|
+
def self.preferred_backend
|
61
|
+
available_backends.detect { |b| b.available? } || @backend
|
28
62
|
end
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
def self.add_hook(klass, name)
|
33
|
-
mod = module_for klass
|
34
|
-
mod.class_eval "def #{name}(*a, &b); Monkey::Backend.call(#{klass.name}, #{name}, *a, &b); end"
|
63
|
+
|
64
|
+
def self.setup?
|
65
|
+
!!@setup
|
35
66
|
end
|
36
|
-
|
37
|
-
def self.
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
67
|
+
|
68
|
+
def self.setup!(backend)
|
69
|
+
if backend
|
70
|
+
@backend = detect_backend(backend)
|
71
|
+
@backend.setup
|
72
|
+
@setup = true
|
73
|
+
@backend
|
74
|
+
else
|
75
|
+
available_backends.each do |backend|
|
76
|
+
begin
|
77
|
+
return setup!(backend)
|
78
|
+
rescue LoadError => error
|
79
|
+
@load_error ||= error
|
80
|
+
@backend = nil
|
81
|
+
end
|
82
|
+
end
|
83
|
+
raise @load_error
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
class << self
|
88
|
+
alias backend= setup!
|
89
|
+
end
|
90
|
+
|
91
|
+
def self.setup
|
92
|
+
setup! preferred_backend unless setup?
|
42
93
|
end
|
43
94
|
|
95
|
+
def self.detect_backend(backend_or_name)
|
96
|
+
return backend_or_name if backend_or_name.respond_to? :setup
|
97
|
+
detected = available_backends.detect do |backend|
|
98
|
+
[backend.backend_name.to_s, backend.backend_path.to_s, backend.name.to_s].include? backend_or_name.to_s
|
99
|
+
end
|
100
|
+
raise ArgumentError, "cannot detect backend #{backend_or_name.inspect}" unless detected
|
101
|
+
detected
|
102
|
+
end
|
103
|
+
|
104
|
+
Dir[File.dirname(__FILE__) + "/backend/*.rb"].sort.each do |path|
|
105
|
+
filename = File.basename(path, '.rb')
|
106
|
+
require "monkey/backend/#{filename}"
|
107
|
+
end
|
108
|
+
|
44
109
|
end
|
45
110
|
end
|
@@ -1,17 +1,12 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
::String.class_eval do
|
11
|
-
alias to_const_string camelcase
|
12
|
-
alias to_const_path underscore
|
13
|
-
end
|
14
|
-
end
|
1
|
+
Monkey::Backend.new :ActiveSupport, :active_support do
|
2
|
+
def self.setup
|
3
|
+
expects_module "::ActiveSupport::CoreExtensions::String::Inflections"
|
4
|
+
load_libs "core_ext/object" => [:metaclass, :misc], :core_ext => %w[array/extract_options string/inflections module/introspection]
|
5
|
+
Array.send :include, ActiveSupport::CoreExtensions::Array::ExtractOptions
|
6
|
+
Module.send :include, ActiveSupport::CoreExtensions::Module
|
7
|
+
::String.class_eval do
|
8
|
+
alias to_const_string camelcase
|
9
|
+
alias to_const_path underscore
|
15
10
|
end
|
16
|
-
end
|
11
|
+
end
|
17
12
|
end
|
@@ -1,17 +1,11 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
require "monkey/backend/common/metaclass"
|
10
|
-
::String.class_eval do
|
11
|
-
alias to_const_string camelcase
|
12
|
-
alias to_const_path underscore
|
13
|
-
end
|
14
|
-
end
|
1
|
+
Monkey::Backend.new :Backports do
|
2
|
+
def self.setup
|
3
|
+
load_libs "tools", "1.8.7/kernel", :rails => [:array, :string]
|
4
|
+
missing :parent, :metaclass
|
5
|
+
::String.class_eval do
|
6
|
+
alias camelcase camelize
|
7
|
+
alias to_const_string camelize
|
8
|
+
alias to_const_path underscore
|
15
9
|
end
|
16
10
|
end
|
17
11
|
end
|
@@ -1,12 +1,10 @@
|
|
1
1
|
module Monkey
|
2
2
|
module Backend
|
3
3
|
module Common
|
4
|
-
module
|
5
|
-
::
|
6
|
-
def
|
7
|
-
|
8
|
-
self
|
9
|
-
end
|
4
|
+
module Parent
|
5
|
+
::Module.send :include, self
|
6
|
+
def parent
|
7
|
+
name =~ /^(.+)::[^:]+$/ ? $1.constantize : Object
|
10
8
|
end
|
11
9
|
end
|
12
10
|
end
|
@@ -1,21 +1,13 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
::Object.class_eval { alias metaclass meta_class }
|
12
|
-
::String.class_eval do
|
13
|
-
alias camelcase to_const_string
|
14
|
-
alias underscore to_const_path
|
15
|
-
def constantize
|
16
|
-
Extlib::Inflection.constantize(self)
|
17
|
-
end
|
18
|
-
end
|
1
|
+
Monkey::Backend.new :Extlib do
|
2
|
+
def self.setup
|
3
|
+
load_libs :object, :string, :inflection
|
4
|
+
missing :parent, :extract_options, :tap
|
5
|
+
::Object.class_eval { alias metaclass meta_class }
|
6
|
+
::String.class_eval do
|
7
|
+
alias camelcase to_const_string
|
8
|
+
alias underscore to_const_path
|
9
|
+
def constantize
|
10
|
+
Extlib::Inflection.constantize(self)
|
19
11
|
end
|
20
12
|
end
|
21
13
|
end
|