ruby_ext 0.4.25 → 0.5.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (50) hide show
  1. data/Rakefile +2 -0
  2. data/lib/rake_ext/project.rb +19 -19
  3. data/lib/rake_ext.rb +18 -18
  4. data/lib/rspec_ext/xhtml.rb +6 -6
  5. data/lib/rspec_ext.rb +40 -25
  6. data/lib/ruby_ext/core/array.rb +7 -7
  7. data/lib/ruby_ext/core/basic_object.rb +1 -1
  8. data/lib/ruby_ext/core/deep_clone.rb +2 -2
  9. data/lib/ruby_ext/core/enumerable.rb +1 -1
  10. data/lib/ruby_ext/core/hash.rb +4 -4
  11. data/lib/ruby_ext/core/module.rb +20 -30
  12. data/lib/ruby_ext/core/multiple_inheritance.rb +24 -24
  13. data/lib/ruby_ext/core/must.rb +39 -39
  14. data/lib/ruby_ext/core/object.rb +15 -3
  15. data/lib/ruby_ext/core/open_object.rb +22 -20
  16. data/lib/ruby_ext/core/string.rb +19 -19
  17. data/lib/ruby_ext/core/symbol.rb +1 -13
  18. data/lib/ruby_ext/core.rb +4 -8
  19. data/lib/ruby_ext/more/callbacks.rb +172 -0
  20. data/lib/ruby_ext/more/declarative_cache.rb +20 -22
  21. data/lib/ruby_ext/more/miscellaneous.rb +1 -46
  22. data/lib/ruby_ext/more/{observable2.rb → observable.rb} +8 -8
  23. data/lib/ruby_ext/more/open_constructor.rb +10 -10
  24. data/lib/ruby_ext/more/tuple.rb +1 -1
  25. data/lib/ruby_ext/more.rb +5 -3
  26. data/lib/ruby_ext.rb +0 -3
  27. data/lib/yaml_fix.rb +2 -2
  28. data/readme.md +51 -50
  29. data/spec/core/deep_clone_spec.rb +8 -8
  30. data/spec/core/module_spec.rb +29 -36
  31. data/spec/core/multiple_inheritance_spec.rb +32 -32
  32. data/spec/core/must_spec.rb +6 -6
  33. data/spec/core/object_spec.rb +15 -0
  34. data/spec/core/open_object_spec.rb +6 -6
  35. data/spec/more/callbacks_spec.rb +155 -0
  36. data/spec/more/declarative_cache_spec.rb +33 -33
  37. data/spec/more/{observable2_spec.rb → observable_spec.rb} +7 -7
  38. data/spec/more/open_constructor_spec.rb +5 -5
  39. metadata +7 -15
  40. data/lib/ruby_ext/core/class.rb +0 -0
  41. data/lib/ruby_ext/core/file.rb +0 -23
  42. data/lib/ruby_ext/core/kernel.rb +0 -69
  43. data/lib/ruby_ext/core/miscellaneous.rb +0 -14
  44. data/lib/ruby_ext/more/synchronize.rb +0 -26
  45. data/spec/core/kernel_spec/TheNamespace/ClassA.rb +0 -7
  46. data/spec/core/kernel_spec/another_class.rb +0 -5
  47. data/spec/core/kernel_spec/the_namespace/class_b.rb +0 -11
  48. data/spec/core/kernel_spec.rb +0 -51
  49. data/spec/more/miscellaneous_spec.rb +0 -14
  50. data/spec/more/synchronize_spec.rb +0 -79
data/Rakefile CHANGED
@@ -8,6 +8,8 @@ project(
8
8
  gem: true,
9
9
  summary: "Ruby Extensions",
10
10
 
11
+ version: '0.5.1',
12
+
11
13
  author: "Alexey Petrushin",
12
14
  homepage: "http://github.com/alexeypetrushin/ruby_ext"
13
15
  )
@@ -4,24 +4,24 @@ require 'psych'
4
4
  YAML::ENGINE.yamler = 'syck'
5
5
 
6
6
 
7
- #
7
+ #
8
8
  # Helper for releasing gem, add following code to Your Rakefile:
9
- #
9
+ #
10
10
  # project(
11
11
  # name: "fake_gem",
12
12
  # gem: true,
13
13
  # summary: "Makes any directory looks like Ruby Gem",
14
- #
14
+ #
15
15
  # bin: 'bin',
16
16
  # executables: ['fake_gem'],
17
17
  # dirs: %w(bin),
18
- #
18
+ #
19
19
  # author: "Alexey Petrushin",
20
20
  # homepage: "http://github.com/alexeypetrushin/fake_gem"
21
21
  # )
22
- #
22
+ #
23
23
  # use "rake gem" to release gem
24
- #
24
+ #
25
25
 
26
26
  require 'rubygems/specification'
27
27
 
@@ -35,7 +35,7 @@ class GemHelper
35
35
  end
36
36
  return '0.0.1'
37
37
  end
38
-
38
+
39
39
  def parse_project_gemfile
40
40
  required_gems, required_fake_gems = [], []
41
41
  gem_file = "#{project_dir}/lib/#{project[:name]}/gems.rb"
@@ -54,7 +54,7 @@ class GemHelper
54
54
 
55
55
  return required_gems, required_fake_gems
56
56
  end
57
-
57
+
58
58
  def gemspec
59
59
  Gem::Specification.new do |s|
60
60
  gems, fake_gems = parse_project_gemfile
@@ -73,15 +73,15 @@ class GemHelper
73
73
  s.has_rdoc = options.delete(:has_rdoc) == nil ? false : true
74
74
  s.require_path = options.delete(:lib) || "lib"
75
75
  s.files = options.delete(:files) || (
76
- %w{Rakefile readme.md} +
77
- Dir.glob("{lib,spec}/**/*") +
76
+ %w{Rakefile readme.md} +
77
+ Dir.glob("{lib,spec}/**/*") +
78
78
  ((options[:dirs] && Array(options.delete(:dirs)).collect{|d| Dir["#{d}/**/*"]}) || [])
79
79
  )
80
80
  s.bindir = options.delete(:bin) if options.include? :bin
81
81
 
82
82
  s.version = options.delete(:version) || GemHelper.next_version(name)
83
83
 
84
- options.each{|k, v| s.send "#{k}=", v}
84
+ options.each{|k, v| s.send "#{k}=", v}
85
85
  end
86
86
  end
87
87
  end
@@ -99,7 +99,7 @@ namespace :gem do
99
99
  %x(gem build #{gemspec_file})
100
100
 
101
101
  puts ' pushing'
102
- gem_file = Dir.glob("#{gemspec.name}*.gem").first
102
+ gem_file = Dir.glob("#{gemspec.name}*.gem").first
103
103
  %x"gem push #{gem_file}"
104
104
 
105
105
  puts ' cleaning'
@@ -107,26 +107,26 @@ namespace :gem do
107
107
 
108
108
  puts " #{gemspec.name} #{gemspec.version} successfully released"
109
109
  end
110
-
110
+
111
111
  desc "Install gem required by project"
112
112
  task :install do
113
- gems, fake_gems = parse_project_gemfile
113
+ gems, fake_gems = GemHelper.parse_project_gemfile
114
114
  gems.each do |name, version|
115
115
  puts "Installing gem #{name} #{version}"
116
116
  %x(gem install #{name}#{" -v #{version}" if version}) # --ignore-dependencies)
117
117
  end
118
- end
119
-
118
+ end
119
+
120
120
  desc "List all gems required by project"
121
121
  task :list do
122
122
  puts "Gems required for #{project[:official_name]}:"
123
- gems, fake_gems = parse_project_gemfile
123
+ gems, fake_gems = GemHelper.parse_project_gemfile
124
124
  puts(gems + fake_gems)
125
125
  end
126
-
126
+
127
127
  desc "Install all gem required by project (including fake gems)"
128
128
  task :install_all do
129
- gems, fake_gems = parse_project_gemfile
129
+ gems, fake_gems = GemHelper.parse_project_gemfile
130
130
  (gems + fake_gems).each do |name, version|
131
131
  puts "Installing gem #{name} #{version}"
132
132
  %x(gem install #{name} #{"-v #{version}" if version})
data/lib/rake_ext.rb CHANGED
@@ -1,23 +1,23 @@
1
1
  require 'rake'
2
2
  require 'fileutils'
3
3
 
4
- #
4
+ #
5
5
  # Code Coverage
6
- #
6
+ #
7
7
  # begin
8
8
  # require 'class_loader/tasks'
9
- #
9
+ #
10
10
  # desc "Clean code coverage temporary files"
11
11
  # task clean: 'class_loader:clean' do
12
12
  # require 'fileutils'
13
13
  # FileUtils.rm_r '../*/coverage' if File.exist? '../*/coverage'
14
- # end
14
+ # end
15
15
  # rescue LoadError
16
16
  # end
17
17
 
18
- #
18
+ #
19
19
  # Spec
20
- #
20
+ #
21
21
  begin
22
22
  require 'rspec/core/rake_task'
23
23
  task default: :spec
@@ -25,8 +25,8 @@ begin
25
25
  RSpec::Core::RakeTask.new('spec') do |t|
26
26
  t.pattern = "spec/**/[^_]*_spec.rb"
27
27
  end
28
-
29
- namespace :spec do
28
+
29
+ namespace :spec do
30
30
  desc "Run RSpec code exapmples in isolated mode (every spec file in another Ruby process)"
31
31
  task :isolated do
32
32
  Dir.glob("spec/[^_]**/[^_]*_spec.rb").each do |spec_file|
@@ -40,17 +40,17 @@ rescue LoadError
40
40
  end
41
41
  end
42
42
 
43
- #
43
+ #
44
44
  # before, after and remove task
45
- #
45
+ #
46
46
  def before task_name, &block
47
47
  $_task_counter ||= {}
48
48
  counter = ($_task_counter[task_name] ||= 0)
49
49
  before_task_name = "#{task_name}_before_#{counter}"
50
-
50
+
51
51
  task before_task_name, &block
52
52
  task task_name => before_task_name
53
-
53
+
54
54
  $_task_counter[task_name] += 1
55
55
  end
56
56
 
@@ -64,25 +64,25 @@ end
64
64
  alias :delete_task :remove_task
65
65
 
66
66
 
67
- #
67
+ #
68
68
  # project
69
- #
69
+ #
70
70
  $_project_dir = (
71
- caller.find{|line| line =~ /\/Rakefile\:/} ||
71
+ caller.find{|line| line =~ /\/Rakefile\:/} ||
72
72
  raise("You can include the 'rake_ext' only in Rakefile!")
73
73
  ).sub(/\/Rakefile\:.*/, '')
74
74
  def project_dir
75
75
  $_project_dir
76
76
  end
77
77
 
78
- def project options = nil
78
+ def project options = nil
79
79
  if options
80
80
  $_project = {}
81
81
  options.each{|k, v| $_project[k.to_sym] = v}
82
-
82
+
83
83
  $_project[:name] || raise("project name not defined")
84
84
  $_project[:official_name] ||= $_project[:name]
85
-
85
+
86
86
  require 'rake_ext/project'
87
87
  end
88
88
  $_project || raise("project not defined!")
@@ -1,9 +1,9 @@
1
- #
1
+ #
2
2
  # FuzzyHash, to_fuzzy_hash, to_html
3
- #
3
+ #
4
4
  begin
5
5
  require 'nokogiri'
6
-
6
+
7
7
  class RSpec::FuzzyHash < Hash
8
8
  def == o
9
9
  return true if super
@@ -18,7 +18,7 @@ begin
18
18
  false
19
19
  end
20
20
  end
21
-
21
+
22
22
  ::Nokogiri::XML::Node.class_eval do
23
23
  def to_fuzzy_hash
24
24
  h = RSpec::FuzzyHash.new
@@ -27,9 +27,9 @@ begin
27
27
  h
28
28
  end
29
29
  end
30
-
30
+
31
31
  class String
32
- def to_xhtml css = nil
32
+ def to_xhtml css = nil
33
33
  require 'nokogiri'
34
34
 
35
35
  node = Nokogiri::HTML(self)
data/lib/rspec_ext.rb CHANGED
@@ -1,6 +1,6 @@
1
- #
1
+ #
2
2
  # Code Coverage
3
- #
3
+ #
4
4
  # require 'simplecov'
5
5
  # SimpleCov.start do
6
6
  # add_filter "/spec/"
@@ -9,13 +9,13 @@
9
9
  # SimpleCov.result.format!
10
10
  # Kernel.exec 'open ./coverage/index.html'
11
11
  # end
12
- #
12
+ #
13
13
  # CLASS_LOADER_GENERATE_TMP_FILES = true
14
14
 
15
15
 
16
- #
16
+ #
17
17
  # RSpec
18
- #
18
+ #
19
19
  require 'rspec'
20
20
  require 'fileutils'
21
21
 
@@ -44,7 +44,7 @@ rspec do
44
44
  before(:all){paths.each{|path| $LOAD_PATH << path}}
45
45
  after(:all){paths.each{|path| $LOAD_PATH.delete path}}
46
46
  end
47
-
47
+
48
48
  def with_load_path *paths, &b
49
49
  begin
50
50
  paths.each{|path| $LOAD_PATH << path}
@@ -53,73 +53,88 @@ rspec do
53
53
  paths.each{|path| $LOAD_PATH.delete path}
54
54
  end
55
55
  end
56
-
56
+
57
57
  def self.with_tmp_spec_dir *args
58
58
  options = args.last.is_a?(Hash) ? args.pop : {}
59
59
  dir = args.first || self.spec_dir
60
-
60
+
61
61
  options[:before] ||= :all
62
62
  tmp_dir = "/tmp/#{dir.split('/').last}"
63
-
63
+
64
64
  before options do
65
65
  FileUtils.rm_r tmp_dir if File.exist? tmp_dir
66
66
  FileUtils.cp_r dir, tmp_dir
67
67
  @spec_dir = tmp_dir
68
68
  end
69
-
70
- after options do
69
+
70
+ after options do
71
71
  FileUtils.rm_r tmp_dir if File.exist? tmp_dir
72
72
  @spec_dir = nil
73
- end
74
-
73
+ end
74
+
75
75
  tmp_dir
76
76
  end
77
-
77
+
78
78
  def self.with_spec_dir dir
79
79
  before(:all){@spec_dir = dir}
80
80
  after(:all){@spec_dir = nil}
81
81
  end
82
-
82
+
83
83
  # def self.with_spec_dir
84
-
84
+
85
85
  # def self.spec_dir dir = nil
86
86
  # @spec_dir ||= calculate_spec_dir_for_current_caller
87
87
  # end
88
-
88
+
89
89
  def self.spec_dir
90
90
  self.calculate_default_spec_dir || raise(":spec_dir not defined!")
91
91
  end
92
-
92
+
93
93
  def spec_dir
94
94
  @spec_dir || self.class.spec_dir
95
95
  end
96
-
96
+
97
97
  def self.calculate_default_spec_dir
98
98
  spec_file_name = caller.find{|line| line =~ /_spec\.rb\:/}
99
- return nil unless spec_file_name
99
+ return nil unless spec_file_name
100
100
  spec_dir = spec_file_name.sub(/\.rb\:.*/, '')
101
101
  raise "spec dir not exist (#{spec_dir})!" unless File.exist? spec_dir
102
102
  spec_dir
103
103
  end
104
-
104
+
105
105
  def remove_constants *args
106
106
  args = args.first if args.size == 1 and args.first.is_a?(Array)
107
- args.each{|c| Object.send :remove_const, c if Object.const_defined? c}
107
+ args.each{|c| Object.send :remove_const, c if Object.const_defined? c}
108
108
  end
109
-
109
+
110
110
  # def spec_tmp_dir
111
111
  # $spec_tmp_dir || raise("you should call :with_tmp_spec_dir to be able to use :spec_tmp_dir!")
112
112
  # end
113
113
  end
114
114
 
115
115
 
116
- #
116
+ #
117
117
  # dirname, parent_dirname
118
- #
118
+ #
119
119
  class String
120
120
  unless method_defined? :dirname
121
121
  def dirname
122
122
  File.expand_path(File.dirname(self))
123
123
  end
124
124
  end
125
+ end
126
+
127
+
128
+ #
129
+ # instance_stub
130
+ #
131
+ class Class
132
+ def instance_stub! &block
133
+ new_method = method(:new)
134
+ stub!(:new).and_return do |*args|
135
+ instance = new_method.call(*args)
136
+ block.call instance
137
+ instance
138
+ end
139
+ end
125
140
  end
@@ -1,4 +1,4 @@
1
- class Array
1
+ class Array
2
2
  def sfilter *filters
3
3
  filters = filters.first if filters.size == 1 and filters.first.is_a?(Array)
4
4
  filters.collect!{|o| o.is_a?(Regexp) ? o : /#{Regexp.escape o}/}
@@ -6,19 +6,19 @@ class Array
6
6
  !filters.any?{|re| line =~ re}
7
7
  end
8
8
  end
9
-
9
+
10
10
  def self.wrap value
11
11
  Array(value)
12
- end
13
-
12
+ end
13
+
14
14
  alias_method :blank?, :empty?
15
-
15
+
16
16
  alias_method :filter, :select
17
-
17
+
18
18
  def extract_options
19
19
  last.is_a?(Hash) ? last : {}
20
20
  end
21
-
21
+
22
22
  def extract_options!
23
23
  last.is_a?(Hash) ? pop : {}
24
24
  end
@@ -1,6 +1,6 @@
1
1
  class BasicObject
2
2
  protected :==, :equal?, :!, :!=
3
-
3
+
4
4
  protected
5
5
  def raise *args
6
6
  ::Object.send :raise, *args
@@ -27,10 +27,10 @@ OpenObject.class_eval do
27
27
  end
28
28
  end
29
29
 
30
- Struct.class_eval do
30
+ Struct.class_eval do
31
31
  def deep_clone
32
32
  clone = super
33
- clone.clear
33
+ clone.clear
34
34
  each_pair{|k, v| clone[k.deep_clone] = v.deep_clone}
35
35
  clone
36
36
  end
@@ -10,7 +10,7 @@ module Enumerable
10
10
  self
11
11
  end
12
12
  end
13
-
13
+
14
14
  def every
15
15
  EveryProxy.new(self)
16
16
  end
@@ -1,7 +1,7 @@
1
1
  class Hash
2
2
  def subset *keys, &block
3
3
  keys = keys.first if keys.first.is_a? Array
4
- h = {}
4
+ h = {}
5
5
  if keys
6
6
  self.each do |k, v|
7
7
  h[k] = v if keys.include? k
@@ -13,12 +13,12 @@ class Hash
13
13
  end
14
14
  h
15
15
  end
16
-
16
+
17
17
  def validate_options! *valid_options
18
18
  unknown_options = keys - valid_options
19
19
  raise "unknown options :#{unknown_options.join(': ')}!" unless unknown_options.empty?
20
20
  end
21
-
21
+
22
22
  alias_method :blank?, :empty?
23
- alias_method :to_h, :to_hash
23
+ alias_method :to_h, :to_hash
24
24
  end
@@ -10,19 +10,11 @@ Module.class_eval do
10
10
  @alias ||= self.name.split('::').last
11
11
  end
12
12
  end
13
-
13
+
14
14
  def is?(base)
15
15
  ancestors.include?(base)
16
16
  end
17
-
18
- def wrap_method( sym, prefix = "old_", &blk )
19
- old_method = "#{prefix}_#{sym}".to_sym
20
- alias_method old_method, sym
21
- define_method(sym) do |*args|
22
- instance_exec(old_method, *args, &blk)
23
- end
24
- end
25
-
17
+
26
18
  def namespace
27
19
  if @module_namespace_defined
28
20
  @module_namespace
@@ -31,7 +23,7 @@ Module.class_eval do
31
23
  @module_namespace = Module.namespace_for name
32
24
  end
33
25
  end
34
-
26
+
35
27
  def each_namespace &block
36
28
  current = namespace
37
29
  while current do
@@ -39,7 +31,7 @@ Module.class_eval do
39
31
  current = current.namespace
40
32
  end
41
33
  end
42
-
34
+
43
35
  def each_ancestor include_standard = false, &block
44
36
  if include_standard
45
37
  ancestors.each{|a| block.call a unless a == self}
@@ -50,7 +42,7 @@ Module.class_eval do
50
42
  end
51
43
  end
52
44
  end
53
-
45
+
54
46
  def self_ancestors_and_namespaces &b
55
47
  b.call self
56
48
  each_ancestor &b
@@ -58,7 +50,7 @@ Module.class_eval do
58
50
  end
59
51
 
60
52
  # TODO cache it?
61
- def self.namespace_for class_name
53
+ def self.namespace_for class_name
62
54
  list = class_name.split("::")
63
55
  if list.size > 1
64
56
  list.pop
@@ -67,21 +59,20 @@ Module.class_eval do
67
59
  return nil
68
60
  end
69
61
  end
70
-
62
+
71
63
  def inheritable_accessor attribute_name, default_value
72
64
  raise "Can be used only for Class and Module" unless self.class.is? Module
73
- # raise "Default value can't be nil!" unless default_value
74
-
65
+
75
66
  iv_name = "@#{attribute_name}"
76
67
  iv_defined = "@#{attribute_name}_defined"
77
-
68
+
78
69
  define_method attribute_name do
79
70
  unless instance_variable_get(iv_defined)
80
71
  iv = nil
81
72
  ancestors[1..-1].each do |a|
82
73
  if a.respond_to?(attribute_name) and (value = a.send(attribute_name))
83
74
  iv = value.deep_clone
84
- break
75
+ break
85
76
  end
86
77
  end
87
78
  iv ||= default_value.deep_clone
@@ -90,17 +81,16 @@ Module.class_eval do
90
81
  iv
91
82
  else
92
83
  instance_variable_get iv_name
93
- end
84
+ end
94
85
  end
95
-
86
+
96
87
  define_method "#{attribute_name}=" do |value|
97
- # raise "Value can't be nil!" unless value
98
88
  instance_variable_set iv_name, value
99
89
  instance_variable_set iv_defined, true
100
90
  end
101
91
  end
102
-
103
- raise "Internal error, it shouldn't be loaded twice!" if defined? ESCAPE_METHOD_SYMBOLS # some tricky error when runing spec with rake
92
+
93
+ raise "Internal error, it shouldn't be loaded twice!" if defined? ESCAPE_METHOD_SYMBOLS # some tricky error when runing spec with rake
104
94
  ESCAPE_METHOD_SYMBOLS = [
105
95
  ['==', 'assign'],
106
96
  ['>', 'gt'],
@@ -117,24 +107,24 @@ Module.class_eval do
117
107
  ['**', 'pw'],
118
108
  ['=~', 'sim'],
119
109
  ['[]', 'sb'],
120
- ]
121
-
110
+ ]
111
+
122
112
  def escape_method method
123
113
  m = method.to_s.clone
124
114
  ESCAPE_METHOD_SYMBOLS.each{|from, to| m.gsub! from, to}
125
115
  raise "Invalid method name '#{method}'!" unless m =~ /^[_a-zA-Z0-9]+$/
126
116
  m.to_sym
127
117
  end
128
-
118
+
129
119
  def attr_required *attrs
130
120
  attrs.each do |attr|
131
121
  define_method(attr){instance_variable_get(:"@#{attr}") || raise("attribute :#{attr} not defined!")}
132
122
  end
133
123
  end
134
-
124
+
135
125
  public :include, :define_method
136
-
137
-
126
+
127
+
138
128
  # copied from rails
139
129
  def delegate(*methods)
140
130
  options = methods.pop