muack 1.2.0 → 1.5.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.
@@ -4,16 +4,16 @@
4
4
 
5
5
  Provided tasks:
6
6
 
7
- rake clean # Remove ignored files
7
+ rake clean # Trash ignored files
8
8
  rake gem:build # Build gem
9
9
  rake gem:install # Install gem
10
10
  rake gem:release # Release gem
11
11
  rake gem:spec # Generate gemspec
12
- rake test # Run tests in memory
12
+ rake test # Run tests
13
13
 
14
14
  ## REQUIREMENTS:
15
15
 
16
- * Tested with MRI (official CRuby) 1.9.3, 2.0.0, Rubinius and JRuby.
16
+ * Tested with MRI (official CRuby) and JRuby.
17
17
 
18
18
  ## INSTALLATION:
19
19
 
@@ -23,13 +23,13 @@ And in Rakefile:
23
23
 
24
24
  ``` ruby
25
25
  begin
26
- require "#{dir = File.dirname(__FILE__)}/task/gemgem"
26
+ require "#{__dir__}/task/gemgem"
27
27
  rescue LoadError
28
- sh 'git submodule update --init'
28
+ sh 'git submodule update --init --recursive'
29
29
  exec Gem.ruby, '-S', $PROGRAM_NAME, *ARGV
30
30
  end
31
31
 
32
- Gemgem.init(dir) do |s|
32
+ Gemgem.init(__dir__, :submodules => %w[your-dep]) do |s|
33
33
  s.name = 'your-gem'
34
34
  s.version = '0.1.0'
35
35
  end
@@ -37,9 +37,9 @@ end
37
37
 
38
38
  ## LICENSE:
39
39
 
40
- Apache License 2.0
40
+ Apache License 2.0 (Apache-2.0)
41
41
 
42
- Copyright (c) 2011-2013, Lin Jen-Shin (godfat)
42
+ Copyright (c) 2011-2019, Lin Jen-Shin (godfat)
43
43
 
44
44
  Licensed under the Apache License, Version 2.0 (the "License");
45
45
  you may not use this file except in compliance with the License.
@@ -1,7 +1,7 @@
1
1
 
2
2
  module Gemgem
3
3
  class << self
4
- attr_accessor :dir, :spec, :spec_create
4
+ attr_accessor :dir, :spec, :submodules, :spec_create
5
5
  end
6
6
 
7
7
  module_function
@@ -11,12 +11,14 @@ module Gemgem
11
11
  def pkg_dir ; "#{dir}/pkg" ; end
12
12
  def escaped_dir; @escaped_dir ||= Regexp.escape(dir); end
13
13
 
14
- def init dir, &block
14
+ def init dir, options={}, &block
15
15
  self.dir = dir
16
- $LOAD_PATH.unshift("#{dir}/lib")
17
16
  ENV['RUBYLIB'] = "#{dir}/lib:#{ENV['RUBYLIB']}"
18
17
  ENV['PATH'] = "#{dir}/bin:#{ENV['PATH']}"
18
+ self.submodules = options[:submodules] || []
19
19
  self.spec_create = block
20
+
21
+ $LOAD_PATH.unshift("#{dir}/lib", *submodules_libs)
20
22
  end
21
23
 
22
24
  def create
@@ -26,7 +28,7 @@ module Gemgem
26
28
 
27
29
  s.description = description.join
28
30
  s.summary = description.first
29
- s.license = readme['LICENSE'].sub(/.+\n\n/, '').lines.first.strip
31
+ s.license = license
30
32
 
31
33
  s.date = Time.now.strftime('%Y-%m-%d')
32
34
  s.files = gem_files
@@ -79,6 +81,11 @@ module Gemgem
79
81
  end
80
82
 
81
83
  def gem_check
84
+ unless git('status', '--porcelain').empty?
85
+ puts("\e[35mWorking copy is not clean.\e[0m")
86
+ exit(3)
87
+ end
88
+
82
89
  ver = spec.version.to_s
83
90
 
84
91
  if ENV['VERSION'].nil?
@@ -110,6 +117,7 @@ module Gemgem
110
117
  SimpleCov.start do
111
118
  add_filter('test/')
112
119
  add_filter('test.rb')
120
+ submodules_libs.each(&method(:add_filter))
113
121
  end
114
122
  end
115
123
 
@@ -154,11 +162,15 @@ module Gemgem
154
162
  end
155
163
 
156
164
  def strip_home_path path
157
- path.sub(ENV['HOME'], '~')
165
+ path.sub(/\A#{Regexp.escape(ENV['HOME'])}\//, '~/')
158
166
  end
159
167
 
160
168
  def strip_cwd_path path
161
- path.sub(Dir.pwd, '.')
169
+ path.sub(/\A#{Regexp.escape(Dir.pwd)}\//, '')
170
+ end
171
+
172
+ def submodules_libs
173
+ submodules.map{ |path| "#{dir}/#{path}/lib" }
162
174
  end
163
175
 
164
176
  def git *args
@@ -196,6 +208,11 @@ module Gemgem
196
208
  @description ||= (readme['DESCRIPTION']||'').sub(/.+\n\n/, '').lines.to_a
197
209
  end
198
210
 
211
+ def license
212
+ readme['LICENSE'].sub(/.+\n\n/, '').lines.first.
213
+ split(/[()]/).map(&:strip).reject(&:empty?).last
214
+ end
215
+
199
216
  def all_files
200
217
  @all_files ||= fold_files(glob).sort
201
218
  end
@@ -216,7 +233,8 @@ module Gemgem
216
233
 
217
234
  def gem_files
218
235
  @gem_files ||= all_files.reject{ |f|
219
- f =~ ignored_pattern && !git_files.include?(f)
236
+ f =~ submodules_pattern ||
237
+ (f =~ ignored_pattern && !git_files.include?(f))
220
238
  }
221
239
  end
222
240
 
@@ -248,6 +266,15 @@ module Gemgem
248
266
  end
249
267
  end
250
268
 
269
+ def submodules_pattern
270
+ @submodules_pattern ||= if submodules.empty?
271
+ /^$/
272
+ else
273
+ Regexp.new(submodules.map{ |path|
274
+ "^#{Regexp.escape(path)}/" }.join('|'))
275
+ end
276
+ end
277
+
251
278
  def expand_patterns pathes
252
279
  # http://git-scm.com/docs/gitignore
253
280
  pathes.flat_map{ |path|
@@ -57,8 +57,8 @@ describe Muack::AnyInstanceOf do
57
57
  end
58
58
 
59
59
  would 'mock with multiple any_instance_of call' do
60
- any_instance_of(klass){ |inst| mock(inst).f(is_a(Fixnum)){ |i| i+1 } }
61
- any_instance_of(klass){ |inst| mock(inst).f(is_a(Fixnum)){ |i| i+2 } }
60
+ any_instance_of(klass){ |inst| mock(inst).f(is_a(Integer)){ |i| i+1 } }
61
+ any_instance_of(klass){ |inst| mock(inst).f(is_a(Integer)){ |i| i+2 } }
62
62
  obj = klass.new
63
63
  obj.f(2).should.eq 3
64
64
  obj.f(2).should.eq 4
@@ -112,4 +112,18 @@ describe Muack::AnyInstanceOf do
112
112
 
113
113
  obj.f.should.eq 0
114
114
  end
115
+
116
+ # Brought from rspec-mocks and it's currently failing on rspec-mocks
117
+ would 'stub any_instance_of on module extending it self' do
118
+ mod = Module.new {
119
+ extend self
120
+ def hello; :hello; end
121
+ }
122
+
123
+ any_instance_of(mod){ |inst| stub(inst).hello{ :stub } }
124
+
125
+ expect(mod.hello).eq(:stub)
126
+ expect(Muack.verify)
127
+ expect(mod.hello).eq(:hello)
128
+ end
115
129
  end
@@ -2,8 +2,7 @@
2
2
  require 'muack/test'
3
3
 
4
4
  describe 'from README.md' do
5
- readme = File.read(
6
- "#{File.dirname(File.expand_path(__FILE__))}/../README.md")
5
+ readme = File.read("#{__dir__}/../README.md")
7
6
  codes = readme.scan(/``` ruby(.+?)```/m).map(&:first)
8
7
 
9
8
  after{ Muack.reset }
@@ -12,21 +11,20 @@ describe 'from README.md' do
12
11
  include Muack::API
13
12
 
14
13
  def describe desc, &block
15
- @executor.describe(desc, &block)
16
- @executor.execute(@stat)
14
+ @suite.describe(desc, &block)
15
+ Pork::Executor.execute(:stat => @stat, :suite => @suite)
17
16
  end
18
17
 
19
18
  def results; @results ||= []; end
20
19
  def p res ; results << res ; end
21
20
 
22
21
  def verify expects
23
- return if results.empty?
24
22
  results.zip(expects).each do |(res, exp)|
25
23
  next if exp == 'ok'
26
24
  if exp.start_with?('raise')
27
25
  res.should.kind_of? eval(exp.sub('raise', ''))
28
26
  else
29
- res.should.eq eval(exp)
27
+ res.should.eq instance_eval(exp)
30
28
  end
31
29
  end
32
30
  end
@@ -34,10 +32,10 @@ describe 'from README.md' do
34
32
 
35
33
  codes.each.with_index do |code, index|
36
34
  would 'pass from README.md #%02d' % index do
37
- executor, stat = Class.new(self.class){ init }, pork_stat
35
+ suite, stat = Class.new(self.class){ init }, pork_stat
38
36
  context = Module.new do
39
37
  extend Context
40
- @executor, @stat = executor, stat
38
+ @suite, @stat = suite, stat
41
39
  end
42
40
  begin
43
41
  context.instance_eval(code, 'README.md', 0)
@@ -0,0 +1,111 @@
1
+
2
+ require 'muack/test'
3
+
4
+ describe Muack::Mock do
5
+ after do
6
+ Muack.verify.should.eq true
7
+ Muack::EnsureReset.call
8
+ end
9
+
10
+ describe 'passing single hash' do
11
+ would 'hash literal' do
12
+ mock(Obj).say({}, &:itself)
13
+
14
+ expect(Obj.say({})).eq({})
15
+ end
16
+
17
+ would 'hash literal with satisfying check' do
18
+ mock(Obj).say(is_a(Hash), &:itself)
19
+
20
+ expect(Obj.say({})).eq({})
21
+ end
22
+
23
+ would 'hash value' do
24
+ arg = {}
25
+
26
+ mock(Obj).say(arg, &:itself)
27
+
28
+ expect(Obj.say(arg)).eq(arg)
29
+ end
30
+
31
+ would 'non-empty hash' do
32
+ mock(Obj).say(a: 0, &:itself)
33
+
34
+ expect(Obj.say(a: 0)).eq(a: 0)
35
+ end
36
+
37
+ would 'non-empty hash with satisfying check' do
38
+ mock(Obj).say(where(a: 0), &:itself)
39
+
40
+ expect(Obj.say(a: 0)).eq(a: 0)
41
+ end
42
+ end
43
+
44
+ describe 'keyargs mock' do
45
+ copy :tests do
46
+ would 'local block' do
47
+ mock(obj).say.with_any_args.returns{ |a:| a }
48
+
49
+ expect(instance.say(a: 0)).eq(0)
50
+ end
51
+
52
+ would 'instance method' do
53
+ mock(obj).bonjour(a: 0, b: 1)
54
+
55
+ expect(instance.bonjour(a: 0, b: 1)).eq([0, 1])
56
+ end
57
+
58
+ would 'prepended method' do
59
+ mock(obj).prepend_bonjour(a: 0, b: 1)
60
+
61
+ expect(instance.prepend_bonjour(a: 0, b: 1)).eq([0, 1])
62
+ end
63
+ end
64
+
65
+ describe 'with direct mock' do
66
+ def obj
67
+ Obj
68
+ end
69
+
70
+ def instance
71
+ obj
72
+ end
73
+
74
+ paste :tests
75
+
76
+ would 'singleton method' do
77
+ mock(obj).single_bonjour(a: 0, b: 1)
78
+
79
+ expect(instance.single_bonjour(a: 0, b: 1)).eq([0, 1])
80
+ end
81
+ end
82
+
83
+ describe 'with any_instance_of' do
84
+ def obj
85
+ any_instance_of(Cls)
86
+ end
87
+
88
+ def instance
89
+ @instance ||= Cls.new
90
+ end
91
+
92
+ paste :tests
93
+ end
94
+
95
+ would 'peek_args' do
96
+ mock(Obj).say.with_any_args.
97
+ peek_args{ |a:| [{a: a.succ}] }.
98
+ returns{ |a:| a.succ }
99
+
100
+ expect(Obj.say(a: 0)).eq(2)
101
+ end
102
+
103
+ would 'peek_args with instance_exec' do
104
+ mock(Obj).say.with_any_args.
105
+ peek_args(instance_exec: true){ |a:| [{a: object_id}] }.
106
+ returns{ |a:| a }
107
+
108
+ expect(Obj.say(a: 0)).eq(Obj.object_id)
109
+ end
110
+ end
111
+ end
@@ -37,19 +37,19 @@ describe Muack::Modifier do
37
37
 
38
38
  describe 'peek_args' do
39
39
  would 'with lexical scope' do
40
- str = 'ff'
40
+ str = String.new('ff')
41
41
  stub(str).to_i.peek_args{16}
42
42
  str.to_i.should.eq 255
43
43
  end
44
44
 
45
45
  would 'with dynamic scope' do
46
- str = '16'
46
+ str = String.new('16')
47
47
  stub(str).to_i.peek_args(:instance_exec => true){Integer(self)}
48
48
  str.to_i.should.eq 22
49
49
  end
50
50
 
51
51
  would 'modify' do
52
- str = 'ff'
52
+ str = String.new('ff')
53
53
  stub(str).to_i(is_a(Integer)).peek_args{ |radix| radix * 2 }
54
54
  str.to_i(8).should.eq 255
55
55
  end
@@ -82,19 +82,19 @@ describe Muack::Modifier do
82
82
 
83
83
  describe 'peek_return' do
84
84
  would 'with lexical scope' do
85
- str = 'ff'
85
+ str = String.new('ff')
86
86
  stub(str).to_i.peek_return{16}
87
87
  str.to_i.should.eq 16
88
88
  end
89
89
 
90
90
  would 'with dynamic scope' do
91
- str = '16'
91
+ str = String.new('16')
92
92
  stub(str).to_i.peek_return(:instance_exec => true){Integer(self)+1}
93
93
  str.to_i.should.eq 17
94
94
  end
95
95
 
96
96
  would 'modify' do
97
- str = 'ff'
97
+ str = String.new('ff')
98
98
  stub(str).to_i(is_a(Integer)).peek_return{ |result| result * 2 }
99
99
  str.to_i(16).should.eq 510
100
100
  end
@@ -0,0 +1,121 @@
1
+
2
+ require 'muack/test'
3
+
4
+ describe 'mock with prepend' do
5
+ after do
6
+ verify
7
+ end
8
+
9
+ def verify
10
+ expect(Muack.verify).eq true
11
+ end
12
+
13
+ def generate
14
+ klass = Class.new do
15
+ def greet
16
+ 'hi'
17
+ end
18
+ end
19
+
20
+ mod = Module.new do
21
+ def greet
22
+ hello
23
+ end
24
+
25
+ def hello
26
+ 'hello'
27
+ end
28
+ private :hello
29
+ end
30
+
31
+ perform(klass, mod)
32
+ end
33
+
34
+ copy :test do
35
+ would 'mock' do
36
+ obj = generate
37
+
38
+ mock(obj).hello{'mocked'}
39
+
40
+ expect(obj.greet).eq 'mocked'
41
+ verify
42
+ expect(obj.greet).eq 'hello'
43
+ expect(obj).not.respond_to? :hello
44
+ end
45
+
46
+ would 'mock proxy' do
47
+ obj = generate
48
+
49
+ mock(obj).hello
50
+
51
+ expect(obj.greet).eq 'hello'
52
+ verify
53
+ expect(obj.greet).eq 'hello'
54
+ expect(obj).not.respond_to? :hello
55
+ end
56
+ end
57
+
58
+ describe 'prepend on class mock with object' do
59
+ def perform(klass, mod)
60
+ klass.prepend(mod)
61
+ klass.new
62
+ end
63
+
64
+ paste :test
65
+ end
66
+
67
+ describe 'extend on object mock with object' do
68
+ def perform(klass, mod)
69
+ obj = klass.new
70
+ obj.extend(mod)
71
+ obj
72
+ end
73
+
74
+ paste :test
75
+ end
76
+
77
+ describe 'include on singleton_class mock with object' do
78
+ def perform(klass, mod)
79
+ obj = klass.new
80
+ obj.singleton_class.include(mod)
81
+ obj
82
+ end
83
+
84
+ paste :test
85
+ end
86
+
87
+ describe 'prepend on singleton_class mock with object' do
88
+ def perform(klass, mod)
89
+ obj = klass.new
90
+ obj.singleton_class.prepend(mod)
91
+ obj
92
+ end
93
+
94
+ paste :test
95
+ end
96
+
97
+ # Brought from rspec-mocks and it's currently failing on rspec-mocks
98
+ # See https://github.com/rspec/rspec-mocks/pull/1218
99
+ would "handle stubbing prepending methods that were only defined on the prepended module" do
100
+ to_be_prepended = Module.new do
101
+ def value
102
+ "#{super}_prepended".to_sym
103
+ end
104
+
105
+ def value_without_super
106
+ :prepended
107
+ end
108
+ end
109
+
110
+ object = Object.new
111
+ object.singleton_class.send(:prepend, to_be_prepended)
112
+ expect(object.value_without_super).eq :prepended
113
+
114
+ stub(object).value_without_super{ :stubbed }
115
+
116
+ expect(object.value_without_super).eq :stubbed
117
+
118
+ expect(Muack.verify)
119
+ expect(object.value_without_super).eq :prepended
120
+ end
121
+ end