mock-thread 0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 281c06e996f0ecee2b850ec80a6a01ad49959d2d
4
+ data.tar.gz: 234cfa97de1a6a42edca8ea87ffbabac9207bbe8
5
+ SHA512:
6
+ metadata.gz: 5d9fb91bfe79f17557b7da312ed1d841ad3359f0b0d051f07b09c4a0a97a3dc805292b357044bcc2b017d78ee685955eab07f7c5ea090f708c01c36182258a55
7
+ data.tar.gz: 99a1ff15e91b629c893aa02f7300655ddb3fffa044e675bb51b6f8f2565077b5d81cf2a6ca5f177b77862a04368c078ec92cb8212a8051039f87742a45cab531
data/COPYING ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2014, Joel VanderWerf, vjoel@users.sourceforge.net
2
+ All rights reserved.
3
+
4
+ Redistribution and use in source and binary forms, with or without
5
+ modification, are permitted provided that the following conditions are met:
6
+
7
+ 1. Redistributions of source code must retain the above copyright notice, this
8
+ list of conditions and the following disclaimer.
9
+ 2. Redistributions in binary form must reproduce the above copyright notice,
10
+ this list of conditions and the following disclaimer in the documentation
11
+ and/or other materials provided with the distribution.
12
+
13
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
14
+ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
15
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
16
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
17
+ ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
18
+ (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
19
+ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
20
+ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
21
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
22
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
@@ -0,0 +1,4 @@
1
+ mock-thread
2
+ ===========
3
+
4
+ Use Fibers to test Thread code
@@ -0,0 +1,65 @@
1
+ require 'rake'
2
+ require 'rake/testtask'
3
+
4
+ PRJ = "mock-thread"
5
+
6
+ def version
7
+ @version ||= begin
8
+ require 'mock-thread/version'
9
+ warn "MockThread::VERSION not a string" unless
10
+ MockThread::VERSION.kind_of? String
11
+ MockThread::VERSION
12
+ end
13
+ end
14
+
15
+ def tag
16
+ @tag ||= "#{PRJ}-#{version}"
17
+ end
18
+
19
+ desc "Run tests"
20
+ Rake::TestTask.new :test do |t|
21
+ t.libs << "lib"
22
+ t.libs << "ext"
23
+ t.test_files = FileList["test/**/*.rb"]
24
+ end
25
+
26
+ desc "Commit, tag, and push repo; build and push gem"
27
+ task :release => "release:is_new_version" do
28
+ require 'tempfile'
29
+
30
+ sh "gem build #{PRJ}.gemspec"
31
+
32
+ file = Tempfile.new "template"
33
+ begin
34
+ file.puts "release #{version}"
35
+ file.close
36
+ sh "git commit --allow-empty -a -v -t #{file.path}"
37
+ ensure
38
+ file.close unless file.closed?
39
+ file.unlink
40
+ end
41
+
42
+ sh "git tag #{tag}"
43
+ sh "git push"
44
+ sh "git push --tags"
45
+
46
+ sh "gem push #{tag}.gem"
47
+ end
48
+
49
+ namespace :release do
50
+ desc "Diff to latest release"
51
+ task :diff do
52
+ latest = `git describe --abbrev=0 --tags --match '#{PRJ}-*'`.chomp
53
+ sh "git diff #{latest}"
54
+ end
55
+
56
+ desc "Log to latest release"
57
+ task :log do
58
+ latest = `git describe --abbrev=0 --tags --match '#{PRJ}-*'`.chomp
59
+ sh "git log #{latest}.."
60
+ end
61
+
62
+ task :is_new_version do
63
+ abort "#{tag} exists; update version!" unless `git tag -l #{tag}`.empty?
64
+ end
65
+ end
@@ -0,0 +1,42 @@
1
+ class MockQueue
2
+ class QueueEmptyError < StandardError; end
3
+
4
+ attr_reader :entries
5
+ attr_reader :yield_on_push
6
+ attr_reader :yield_on_pop
7
+
8
+ def initialize yield_on_push: false, yield_on_pop: false
9
+ @entries = []
10
+ @yield_on_push = yield_on_push
11
+ @yield_on_pop = yield_on_pop
12
+ end
13
+
14
+ def empty?
15
+ entries.empty?
16
+ end
17
+
18
+ def push val
19
+ @entries << val
20
+ if yield_on_push
21
+ Fiber.yield([:push, val]) rescue FiberError
22
+ end
23
+ end
24
+ alias << push
25
+
26
+ def pop
27
+ begin
28
+ while @entries.empty?
29
+ Fiber.yield :block
30
+ end
31
+ rescue FiberError => ex
32
+ raise QueueEmptyError, "queue empty (#{ex.message})"
33
+ end
34
+
35
+ val = @entries.shift
36
+ if yield_on_pop
37
+ Fiber.yield([:pop, val]) rescue FiberError
38
+ end
39
+ val
40
+ end
41
+ end
42
+
@@ -0,0 +1,103 @@
1
+ require 'fiber'
2
+
3
+ require 'mock-thread/mock-queue.rb'
4
+
5
+ class MockThread
6
+ class IsBlocked < RuntimeError; end
7
+ class IsDone < RuntimeError; end
8
+
9
+ def make_queue
10
+ MockQueue.new
11
+ end
12
+
13
+ # Override to update any state before running a step. For example, update
14
+ # part of the system that is not expressed by a mock thread, such as
15
+ # a component that processes what mock threads have sent to a queue.
16
+ def update_before; end
17
+
18
+ # Override to update any state after running a step.
19
+ def update_after; end
20
+
21
+ # Schedule some code for deferred execution. For example:
22
+ #
23
+ # c.will {foo}.will {bar}
24
+ #
25
+ # The #foo and #bar methods of c will be called later.
26
+ #
27
+ def will &block
28
+ (@will_do ||= []) << Fiber.new { instance_eval &block }
29
+ self
30
+ end
31
+
32
+ def step
33
+ loop do
34
+ fiber = @will_do[0] or raise IsDone, "nothing to do"
35
+
36
+ if fiber.alive?
37
+ update_before
38
+ val = fiber.resume
39
+ update_after
40
+ return val
41
+ end
42
+
43
+ @will_do.shift
44
+ end
45
+ end
46
+
47
+ def run limit: 100
48
+ loop do
49
+ fiber = @will_do[0] or raise IsDone, "nothing to do"
50
+
51
+ count = 0
52
+ while fiber.alive?
53
+ update_before
54
+ val = fiber.resume
55
+ update_after
56
+ if fiber.alive? or @will_do.size > 1
57
+ if val == :block
58
+ count += 1
59
+ if count > limit
60
+ raise IsBlocked, "exceeded blocking limit"
61
+ end
62
+ else
63
+ count = 0
64
+ yield val if block_given?
65
+ end
66
+ else
67
+ return val
68
+ end
69
+ end
70
+
71
+ @will_do.shift
72
+ end
73
+ end
74
+
75
+ def run_until_blocked limit: 100, &block
76
+ begin
77
+ run limit: limit, &block
78
+ rescue IsBlocked
79
+ return
80
+ end
81
+ raise IsDone, "run_until_blocked never blocked"
82
+ end
83
+
84
+ def now limit: 100, &block
85
+ fiber = Fiber.new { instance_eval &block }
86
+ val = nil
87
+ count = 0
88
+ update_before
89
+ while fiber.alive?
90
+ val = fiber.resume
91
+ if val == :block
92
+ count += 1
93
+ if count > limit
94
+ raise IsBlocked, "cannot now do that -- exceeded blocking limit"
95
+ end
96
+ else
97
+ count = 0
98
+ end
99
+ update_after
100
+ end
101
+ val
102
+ end
103
+ end
@@ -0,0 +1,3 @@
1
+ module MockThread
2
+ VERSION = "0.1"
3
+ end
@@ -0,0 +1,93 @@
1
+ require 'minitest/autorun'
2
+
3
+ require 'mock-thread/mock-queue.rb'
4
+
5
+ class TestMockQueueWithPushPopYields < Minitest::Test
6
+ def setup
7
+ @q = MockQueue.new yield_on_push: true, yield_on_pop: true
8
+ end
9
+
10
+ def test_push
11
+ f = Fiber.new do |val|
12
+ loop do
13
+ val = @q.push val
14
+ end
15
+ end
16
+
17
+ a = []
18
+ assert_equal a, @q.entries
19
+
20
+ 3.times do |i|
21
+ op, val = f.resume i
22
+ assert_equal :push, op
23
+ assert_equal i, val
24
+ a << i
25
+ assert_equal a, @q.entries
26
+ end
27
+ end
28
+
29
+ def test_pop
30
+ a = []
31
+ f = Fiber.new do
32
+ loop do
33
+ a << @q.pop
34
+ end
35
+ end
36
+
37
+ 3.times do
38
+ op = f.resume
39
+ assert_equal :block, op
40
+ assert_equal [], a
41
+ end
42
+
43
+ @q.entries.concat (0...10).to_a
44
+
45
+ 10.times do |i|
46
+ op, val = f.resume
47
+ assert_equal :pop, op
48
+ assert_equal i, val
49
+ end
50
+
51
+ op = f.resume
52
+ assert_equal :block, op
53
+ assert_equal a, (0...10).to_a
54
+ end
55
+ end
56
+
57
+ class TestMockQueueSimpler < Minitest::Test
58
+ def setup
59
+ @q = MockQueue.new
60
+ end
61
+
62
+ def test_push
63
+ a = []
64
+ assert_equal a, @q.entries
65
+
66
+ 3.times do |i|
67
+ @q.push i
68
+ a << i
69
+ assert_equal a, @q.entries
70
+ end
71
+ end
72
+
73
+ def test_pop
74
+ a = []
75
+ f = Fiber.new do
76
+ loop do
77
+ a << @q.pop
78
+ end
79
+ end
80
+
81
+ 3.times do
82
+ op = f.resume
83
+ assert_equal :block, op
84
+ assert_equal [], a
85
+ end
86
+
87
+ @q.entries.concat (0...10).to_a
88
+
89
+ op = f.resume
90
+ assert_equal :block, op
91
+ assert_equal a, (0...10).to_a
92
+ end
93
+ end
@@ -0,0 +1,93 @@
1
+ require 'minitest/autorun'
2
+
3
+ require 'mock-thread/mock-thread.rb'
4
+
5
+ class TestMockThread < Minitest::Test
6
+ def test_step
7
+ mt = MockThread.new
8
+
9
+ mt.will do
10
+ 3.times do |i|
11
+ Fiber.yield i
12
+ end
13
+ "done"
14
+ end
15
+
16
+ assert_equal 0, mt.step
17
+ assert_equal 1, mt.step
18
+ assert_equal 2, mt.step
19
+ assert_equal "done", mt.step
20
+ assert_raises MockThread::IsDone do
21
+ mt.step
22
+ end
23
+ end
24
+
25
+ def test_run
26
+ mt = MockThread.new
27
+
28
+ mt.will do
29
+ 3.times do |i|
30
+ Fiber.yield i
31
+ end
32
+ "done"
33
+ end
34
+
35
+ a = []
36
+ r = mt.run do |val|
37
+ a << val
38
+ end
39
+
40
+ assert_equal "done", r
41
+ assert_equal [0,1,2], a
42
+ end
43
+
44
+ def test_run_until_blocked
45
+ mt = MockThread.new
46
+
47
+ mt.will do
48
+ 3.times do |i|
49
+ Fiber.yield i
50
+ end
51
+ 11.times do
52
+ Fiber.yield :block
53
+ end
54
+ "done"
55
+ end
56
+
57
+ a = []
58
+ mt.run_until_blocked limit:10 do |val|
59
+ a << val
60
+ end
61
+
62
+ assert_equal [0,1,2], a
63
+
64
+ r = mt.run
65
+ assert_equal "done", r
66
+ end
67
+
68
+ def test_now
69
+ mt = MockThread.new
70
+
71
+ result = mt.now do
72
+ 3.times do
73
+ Fiber.yield :block
74
+ end
75
+ "done"
76
+ end
77
+
78
+ assert_equal "done", result
79
+ end
80
+
81
+ def test_now_limit
82
+ mt = MockThread.new
83
+
84
+ assert_raises MockThread::IsBlocked do
85
+ mt.now limit: 2 do
86
+ 3.times do
87
+ Fiber.yield :block
88
+ end
89
+ "done"
90
+ end
91
+ end
92
+ end
93
+ end
metadata ADDED
@@ -0,0 +1,63 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: mock-thread
3
+ version: !ruby/object:Gem::Version
4
+ version: '0.1'
5
+ platform: ruby
6
+ authors:
7
+ - Joel VanderWerf
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-02-08 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description: Use Fibers to test Thread code.
14
+ email: vjoel@users.sourceforge.net
15
+ executables: []
16
+ extensions: []
17
+ extra_rdoc_files:
18
+ - README.md
19
+ - COPYING
20
+ files:
21
+ - COPYING
22
+ - README.md
23
+ - Rakefile
24
+ - lib/mock-thread/mock-queue.rb
25
+ - lib/mock-thread/mock-thread.rb
26
+ - lib/mock-thread/version.rb
27
+ - test/test-mock-queue.rb
28
+ - test/test-mock-thread.rb
29
+ homepage: https://github.com/vjoel/mock-thread
30
+ licenses:
31
+ - BSD
32
+ metadata: {}
33
+ post_install_message:
34
+ rdoc_options:
35
+ - "--quiet"
36
+ - "--line-numbers"
37
+ - "--inline-source"
38
+ - "--title"
39
+ - MockThread
40
+ - "--main"
41
+ - README.md
42
+ require_paths:
43
+ - lib
44
+ required_ruby_version: !ruby/object:Gem::Requirement
45
+ requirements:
46
+ - - ">="
47
+ - !ruby/object:Gem::Version
48
+ version: '0'
49
+ required_rubygems_version: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - ">="
52
+ - !ruby/object:Gem::Version
53
+ version: '0'
54
+ requirements: []
55
+ rubyforge_project:
56
+ rubygems_version: 2.2.2
57
+ signing_key:
58
+ specification_version: 4
59
+ summary: Use Fibers to test Thread code
60
+ test_files:
61
+ - test/test-mock-thread.rb
62
+ - test/test-mock-queue.rb
63
+ has_rdoc: