ruby_ext 4.0.0 → 4.0.1

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/Rakefile CHANGED
@@ -7,7 +7,6 @@ project \
7
7
  name: "ruby_ext",
8
8
  gem: true,
9
9
  summary: "Ruby Extensions",
10
- version: '4.0.0',
11
10
 
12
11
  author: "Alexey Petrushin",
13
12
  homepage: "http://github.com/alexeypetrushin/ruby_ext"
data/lib/rake_ext.rb CHANGED
@@ -96,7 +96,44 @@ end
96
96
  #
97
97
  # Docs
98
98
  #
99
- desc "Generate documentation"
100
- task :docs do
101
- %x(cd docs && rocco -o site *.rb)
99
+ namespace :docs do
100
+ desc "Generate documentation"
101
+ task :generate do
102
+ %x(cd docs && rocco -o site *.rb)
103
+ end
104
+
105
+ desc "Publish documentation"
106
+ task :publish do
107
+ require 'open3'
108
+ require 'vfs'
109
+
110
+ executor = Class.new do
111
+ def run cmd, expectation = nil
112
+ stdin, stdout, stderr = Open3.popen3 cmd
113
+ stderr = stderr.read
114
+ stdout = stdout.read
115
+
116
+ if expectation and (stdout + stderr) !~ expectation
117
+ puts stdout
118
+ puts stderr
119
+ raise "can't execute '#{cmd}'!"
120
+ end
121
+ stdout
122
+ end
123
+ end.new
124
+
125
+ out = executor.run "git status", /nothing to commit .working directory clean/
126
+
127
+ '.'.to_dir.tmp do |tmp|
128
+ tmp.delete
129
+ "docs/site".to_dir.copy_to tmp['site']
130
+
131
+ executor.run "git checkout gh-pages", /Switched to branch 'gh-pages'/
132
+ tmp['site'].copy_to '.'.to_dir
133
+ executor.run "git add ."
134
+ executor.run "git commit -a -m 'upd docs'", /upd docs/
135
+ executor.run "git push", /gh-pages -> gh-pages/
136
+ executor.run "git checkout master", /Switched to branch 'master'/
137
+ end
138
+ end
102
139
  end
data/lib/rspec_ext.rb CHANGED
@@ -1,142 +1,13 @@
1
- #
2
- # Code Coverage
3
- #
4
- # require 'simplecov'
5
- # SimpleCov.start do
6
- # add_filter "/spec/"
7
- # end
8
- # SimpleCov.at_exit do
9
- # SimpleCov.result.format!
10
- # Kernel.exec 'open ./coverage/index.html'
11
- # end
12
- #
13
- # CLASS_LOADER_GENERATE_TMP_FILES = true
1
+ # Uncomment to enable code coverage tool.
2
+ # require 'rspec_ext/code_coverage'
14
3
 
15
4
  require 'rspec'
16
- require 'fileutils'
17
5
 
18
- RSpec.configure do |c|
19
- c.filter_run focus: true
20
- c.run_all_when_everything_filtered = true
21
- end
6
+ require 'rspec_ext/rspec'
7
+ require 'rspec_ext/misc'
22
8
 
23
- def rspec &block
24
- RSpec::Core::ExampleGroup.class_eval &block if block
25
- return RSpec::Core::ExampleGroup
26
- end
27
-
28
- rspec do
29
- def self.define_matcher *args, &block
30
- RSpec::Matchers.define *args do |expected|
31
- match do |actual|
32
- block.call actual, expected if block
33
- end
34
- end
35
- end
36
- end
37
-
38
- rspec do
39
- def self.before_all &block
40
- before :all, &block
41
- end
42
-
43
- def self.after_all &block
44
- after :all, &block
45
- end
46
-
47
- def self.with_load_path *paths
48
- before_all{paths.each{|path| $LOAD_PATH << path}}
49
- after_all{paths.each{|path| $LOAD_PATH.delete path}}
50
- end
51
-
52
- def with_load_path *paths, &b
53
- begin
54
- paths.each{|path| $LOAD_PATH << path}
55
- b.call
56
- ensure
57
- paths.each{|path| $LOAD_PATH.delete path}
58
- end
59
- end
60
-
61
- def self.with_tmp_spec_dir *args
62
- options = args.last.is_a?(Hash) ? args.pop : {}
63
- dir = args.first || self.spec_dir
64
-
65
- options[:before] ||= :all
66
- tmp_dir = "/tmp/#{dir.split('/').last}"
67
-
68
- before options do
69
- FileUtils.rm_r tmp_dir if File.exist? tmp_dir
70
- FileUtils.cp_r dir, tmp_dir
71
- @spec_dir = tmp_dir
72
- end
73
-
74
- after options do
75
- FileUtils.rm_r tmp_dir if File.exist? tmp_dir
76
- @spec_dir = nil
77
- end
78
-
79
- tmp_dir
80
- end
81
-
82
- def self.with_spec_dir dir
83
- before_all{@spec_dir = dir}
84
- after_all{@spec_dir = nil}
85
- end
86
-
87
- def self.spec_dir
88
- self.calculate_default_spec_dir || raise(":spec_dir not defined!")
89
- end
90
-
91
- def spec_dir
92
- @spec_dir || self.class.spec_dir
93
- end
94
-
95
- def self.calculate_default_spec_dir
96
- spec_file_name = caller.find{|line| line =~ /_spec\.rb\:/}
97
- return nil unless spec_file_name
98
- spec_dir = spec_file_name.sub(/\.rb\:.*/, '')
99
- raise "spec dir not exist (#{spec_dir})!" unless File.exist? spec_dir
100
- spec_dir
101
- end
102
-
103
- def remove_constants *args
104
- args = args.first if args.size == 1 and args.first.is_a?(Array)
105
- args.each{|c| Object.send :remove_const, c if Object.const_defined? c}
106
- end
107
- end
108
-
109
-
110
- class String
111
- unless method_defined? :dirname
112
- def dirname
113
- File.expand_path(File.dirname(self))
114
- end
115
- end
116
-
117
- def to_xhtml css = nil
118
- require 'rspec_ext/nokogiri'
119
-
120
- node = Nokogiri::HTML(self)
121
- unless css
122
- node
123
- else
124
- nodes = node.css(css)
125
- raise "Elements for '#{css}' CSS query not found!" if nodes.size < 1
126
- raise "Found more than one elment for '#{css}' CSS query!" if nodes.size > 1
127
- nodes.first
128
- end
129
- end
130
- end
131
-
132
- # Stubbing every instances of class.
133
- class Class
134
- def instance_stub! &block
135
- new_method = method :new
136
- stub! :new do |*args|
137
- instance = new_method.call *args
138
- block.call instance
139
- instance
140
- end
141
- end
9
+ # FactoryGirl replacement.
10
+ autoload :Factory, 'rspec_ext/factory'
11
+ def factory name = nil
12
+ name ? factory.build(name) : $factory ||= Factory.new
142
13
  end
@@ -0,0 +1,9 @@
1
+ # Code Coverage.
2
+ require 'simplecov'
3
+ SimpleCov.start do
4
+ add_filter "/spec/"
5
+ end
6
+ SimpleCov.at_exit do
7
+ SimpleCov.result.format!
8
+ Kernel.exec 'open ./coverage/index.html'
9
+ end
@@ -0,0 +1,64 @@
1
+ # FactoryGirl replacement (because original FactoryGirl is bloated, and
2
+ # even more - it depends on activesupport, and this makes it too
3
+ # unconvinient to use in non-Rails environments).
4
+
5
+ class Factory
6
+ class Builder
7
+ attr_reader :name, :klass, :parent, :initializer
8
+
9
+ def initialize name, options = {}, &initializer
10
+ @initializer = initializer
11
+ @klass, @parent = options[:class], options[:parent]
12
+ unless klass or parent or initializer
13
+ raise "there are nor class nor initializer nor parent provided for :#{name}!"
14
+ end
15
+ end
16
+
17
+ def build attributes = {}, &block
18
+ if parent
19
+ o = factory.build parent
20
+ initializer.call o if initializer
21
+ elsif klass
22
+ real_class = self.klass.is_a?(String) ? self.klass.constantize : self.klass
23
+ o = real_class.new
24
+ initializer.call o if initializer
25
+ elsif initializer
26
+ o = initializer.call
27
+ end
28
+
29
+ attributes.each{|name, value| o.send :"#{name}=", value}
30
+ block.call o if block
31
+
32
+ o
33
+ end
34
+ end
35
+
36
+ attr_reader :registry, :counters
37
+
38
+ def initialize
39
+ @registry, @counters = {}, Hash.new(0)
40
+ end
41
+
42
+ def define name, options = {}, &initializer
43
+ raise "definition of :#{name} already exist!" if registry.include? name
44
+ registry[name] = Builder.new(name, options, &initializer)
45
+ end
46
+
47
+ def build name, attributes = {}, &block
48
+ builder = registry[name] || raise("no definition for :#{name}!")
49
+ builder.build attributes, &block
50
+ end
51
+ alias_method :[], :build
52
+
53
+ def create name, attributes = {}, &block
54
+ o = build name, attributes, &block
55
+ o.respond_to?(:save!) ? o.save! : o.save
56
+ o
57
+ end
58
+
59
+ def next name = :general
60
+ v = counters[name]
61
+ counters[name] += 1
62
+ v
63
+ end
64
+ end
@@ -0,0 +1,22 @@
1
+ String.class_eval do
2
+ unless method_defined? :dirname
3
+ def dirname
4
+ File.expand_path(File.dirname(self))
5
+ end
6
+ end
7
+
8
+ # Convert string to HTML node.
9
+ def to_xhtml css = nil
10
+ require 'rspec_ext/nokogiri'
11
+
12
+ node = Nokogiri::HTML(self)
13
+ unless css
14
+ node
15
+ else
16
+ nodes = node.css(css)
17
+ raise "Elements for '#{css}' CSS query not found!" if nodes.size < 1
18
+ raise "Found more than one elment for '#{css}' CSS query!" if nodes.size > 1
19
+ nodes.first
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,106 @@
1
+ # Adding filtering specs with focus.
2
+ RSpec.configure do |c|
3
+ c.filter_run focus: true
4
+ c.run_all_when_everything_filtered = true
5
+ end
6
+
7
+ # Shortcut for extending RSpec.
8
+ def rspec &block
9
+ RSpec::Core::ExampleGroup.class_eval &block if block
10
+ return RSpec::Core::ExampleGroup
11
+ end
12
+
13
+ # Shortcut for defining matchers.
14
+ rspec do
15
+ def self.define_matcher *args, &block
16
+ RSpec::Matchers.define *args do |expected|
17
+ match do |actual|
18
+ block.call actual, expected if block
19
+ end
20
+ end
21
+ end
22
+ end
23
+
24
+ rspec do
25
+ def remove_constants *args
26
+ args = args.first if args.size == 1 and args.first.is_a?(Array)
27
+ args.each{|c| Object.send :remove_const, c if Object.const_defined? c}
28
+ end
29
+
30
+ # Before and after all shortcuts.
31
+ def self.before_all &block; before :all, &block end
32
+ def self.after_all &block; after :all, &block end
33
+
34
+ # Helpers for working with $LOAD_PATH.
35
+ def self.with_load_path *paths
36
+ before_all{paths.each{|path| $LOAD_PATH << path}}
37
+ after_all{paths.each{|path| $LOAD_PATH.delete path}}
38
+ end
39
+ def with_load_path *paths, &b
40
+ begin
41
+ paths.each{|path| $LOAD_PATH << path}
42
+ b.call
43
+ ensure
44
+ paths.each{|path| $LOAD_PATH.delete path}
45
+ end
46
+ end
47
+
48
+ # Helpers for working with spec directories and temp directories.
49
+
50
+ def self.with_tmp_spec_dir *args
51
+ options = args.last.is_a?(Hash) ? args.pop : {}
52
+ dir = args.first || self.spec_dir
53
+
54
+ options[:before] ||= :all
55
+ tmp_dir = "/tmp/#{dir.split('/').last}"
56
+
57
+ before options do
58
+ require 'fileutils'
59
+
60
+ FileUtils.rm_r tmp_dir if File.exist? tmp_dir
61
+ FileUtils.cp_r dir, tmp_dir
62
+ @spec_dir = tmp_dir
63
+ end
64
+
65
+ after options do
66
+ FileUtils.rm_r tmp_dir if File.exist? tmp_dir
67
+ @spec_dir = nil
68
+ end
69
+
70
+ tmp_dir
71
+ end
72
+
73
+ def self.with_spec_dir dir
74
+ before_all{@spec_dir = dir}
75
+ after_all{@spec_dir = nil}
76
+ end
77
+
78
+ def self.spec_dir
79
+ self.calculate_default_spec_dir || raise(":spec_dir not defined!")
80
+ end
81
+
82
+ def spec_dir
83
+ @spec_dir || self.class.spec_dir
84
+ end
85
+
86
+ protected
87
+ def self.calculate_default_spec_dir
88
+ spec_file_name = caller.find{|line| line =~ /_spec\.rb\:/}
89
+ return nil unless spec_file_name
90
+ spec_dir = spec_file_name.sub(/\.rb\:.*/, '')
91
+ raise "spec dir not exist (#{spec_dir})!" unless File.exist? spec_dir
92
+ spec_dir
93
+ end
94
+ end
95
+
96
+ # Stubbing every instances of class.
97
+ class Class
98
+ def after_instantiate &block
99
+ new_method = method :new
100
+ stub! :new do |*args|
101
+ instance = new_method.call *args
102
+ block.call instance
103
+ instance
104
+ end
105
+ end
106
+ end
@@ -1,4 +1,6 @@
1
1
  Array.class_eval do
2
+ alias_method :add, :push
3
+
2
4
  def sfilter *filters
3
5
  filters = filters.first if filters.size == 1 and filters.first.is_a?(Array)
4
6
  filters.collect!{|o| o.is_a?(Regexp) ? o : /#{Regexp.escape o}/}
@@ -38,8 +38,6 @@ Hash.class_eval do
38
38
 
39
39
  alias_method :blank?, :empty?
40
40
 
41
- alias_method :to_h, :to_hash
42
-
43
41
  # OpenObject.
44
42
 
45
43
  def to_openobject deep = false
@@ -53,4 +51,25 @@ Hash.class_eval do
53
51
  other == self if other.is_a? OpenObject
54
52
  eql_without_oo other
55
53
  end
54
+
55
+ class << self
56
+ def symbolize obj
57
+ convert_keys obj, :to_sym
58
+ end
59
+
60
+ def stringify obj
61
+ convert_keys obj, :to_s
62
+ end
63
+
64
+ protected
65
+ def convert_keys obj, method
66
+ if obj.is_a? Hash
67
+ {}.tap{|h| obj.each{|k, v| h[k.send(method)] = convert_keys v, method}}
68
+ elsif obj.is_a? Array
69
+ obj.collect{|v| convert_keys v, method}
70
+ else
71
+ obj
72
+ end
73
+ end
74
+ end
56
75
  end
@@ -93,7 +93,6 @@ class OpenObject < Hash
93
93
  h
94
94
  end
95
95
  end
96
- alias_method :to_h, :to_hash
97
96
 
98
97
  def to_json *args
99
98
  to_hash.to_json *args
data/readme.md CHANGED
@@ -1,8 +1,6 @@
1
- Collection of various utility classes and standard library extensions for Ruby language.
2
-
3
1
  ## must - assertion tool, kind of RSpec assertions in runtime code
4
2
 
5
- Expectations are generated dynamically, so it will be also available and have the same form
3
+ Expectations are generated dynamically, so it will be also available and have the same form
6
4
  for any of Your custom methods.
7
5
 
8
6
  It also doesn't pollute core Ruby classes very much, there are only 2 methods `must`, `must_not` added to
@@ -0,0 +1,21 @@
1
+ require "spec_helper"
2
+
3
+ describe 'Hash' do
4
+ it 'should symbolize hashes in arbitrary objects' do
5
+ as_string = {
6
+ 'a' => 'a',
7
+ 'b' => {
8
+ 'a' => [{'a' => 'a'}]
9
+ }
10
+ }
11
+ as_symbol = {
12
+ a: 'a',
13
+ b: {
14
+ a: [{a: 'a'}]
15
+ }
16
+ }
17
+
18
+ Hash.symbolize(as_string).should == as_symbol
19
+ Hash.stringify(as_symbol).should == as_string
20
+ end
21
+ end
@@ -41,8 +41,8 @@ describe 'Assert' do
41
41
  [].must.be_empty.should == []
42
42
  end
43
43
 
44
- it "have", focus: true do
44
+ it "have" do
45
45
  [1, 2, 3].must_not.have_any{|v| v == 4}
46
- -> {[1, 2, 3].must_not.have_any{|v| v == 2}}.should raise_error(/[1, 2, 3] must not have any/)
46
+ -> {[1, 2, 3].must_not.have_any{|v| v == 2}}.should raise_error(/must not have any/m)
47
47
  end
48
48
  end
@@ -0,0 +1,50 @@
1
+ require 'spec_helper'
2
+
3
+ describe "factory" do
4
+ before do
5
+ factory.registry.clear
6
+ factory.counters.clear
7
+ end
8
+ after{remove_constants :User}
9
+
10
+ it "basic" do
11
+ factory.define :user, class: 'OpenObject' do |u|
12
+ u.name = 'an_user'
13
+ end
14
+
15
+ factory.build(:user, password: 'abc'){|u| u.roles = %w(user)}.should ==
16
+ {name: 'an_user', password: 'abc', roles: %w(user)}.to_openobject
17
+ end
18
+
19
+ it "parent" do
20
+ factory.define :user, class: 'OpenObject' do |u|
21
+ u.name = 'an_user'
22
+ end
23
+
24
+ factory.define :manager, parent: :user do |u|
25
+ u.name = 'a_manager'
26
+ end
27
+
28
+ factory.build(:manager, password: 'abc'){|u| u.roles = %w(manager)}.should ==
29
+ {name: 'a_manager', password: 'abc', roles: %w(manager)}.to_openobject
30
+ end
31
+
32
+ it "create" do
33
+ stub = self.stub
34
+ factory.define :user, class: stub
35
+ factory.define :manager, parent: :user
36
+
37
+ stub.should_receive(:new).once.and_return stub
38
+ stub.should_receive(:save!).once
39
+ factory.create :manager
40
+ end
41
+
42
+ it "input validations" do
43
+ -> {factory.define :user}.should raise_error(/provided for :user/)
44
+ end
45
+
46
+ it "counters" do
47
+ factory.next(:id).should == 0
48
+ factory.next(:id).should == 1
49
+ end
50
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ruby_ext
3
3
  version: !ruby/object:Gem::Version
4
- version: 4.0.0
4
+ version: 4.0.1
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2011-11-01 00:00:00.000000000Z
12
+ date: 2011-11-19 00:00:00.000000000Z
13
13
  dependencies: []
14
14
  description:
15
15
  email:
@@ -21,7 +21,11 @@ files:
21
21
  - readme.md
22
22
  - lib/rake_ext/project.rb
23
23
  - lib/rake_ext.rb
24
+ - lib/rspec_ext/code_coverage.rb
25
+ - lib/rspec_ext/factory.rb
26
+ - lib/rspec_ext/misc.rb
24
27
  - lib/rspec_ext/nokogiri.rb
28
+ - lib/rspec_ext/rspec.rb
25
29
  - lib/rspec_ext.rb
26
30
  - lib/ruby_ext/core/array.rb
27
31
  - lib/ruby_ext/core/basic_object.rb
@@ -54,6 +58,7 @@ files:
54
58
  - spec/core/array_spec.rb
55
59
  - spec/core/deep_clone_spec.rb
56
60
  - spec/core/enumerable.rb
61
+ - spec/core/hash_spec.rb
57
62
  - spec/core/module_spec.rb
58
63
  - spec/core/multiple_inheritance_spec.rb
59
64
  - spec/core/object_spec.rb
@@ -63,6 +68,7 @@ files:
63
68
  - spec/more/must_spec.rb
64
69
  - spec/more/observable_spec.rb
65
70
  - spec/more/open_constructor_spec.rb
71
+ - spec/rspec_ext/factory_spec.rb
66
72
  - spec/spec_helper.rb
67
73
  homepage: http://github.com/alexeypetrushin/ruby_ext
68
74
  licenses: []