ruby_ext 4.0.0 → 4.0.1

Sign up to get free protection for your applications and to get access to all the features.
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: []