pluggaloid 1.3.1 → 1.4.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.circleci/config.yml +40 -0
- data/README.md +2 -0
- data/lib/pluggaloid.rb +3 -0
- data/lib/pluggaloid/collection.rb +55 -0
- data/lib/pluggaloid/error.rb +2 -0
- data/lib/pluggaloid/event.rb +63 -9
- data/lib/pluggaloid/plugin.rb +40 -3
- data/lib/pluggaloid/subscriber.rb +2 -2
- data/lib/pluggaloid/version.rb +1 -1
- data/test/collect_test.rb +135 -0
- metadata +6 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 076d2f155418730ea29519ce8d7281343146dab271b2db4458fbf2c6db600ef9
|
4
|
+
data.tar.gz: 42e8f0dcb752dcc4535a4d7c797f99f3864c738d06cb4f55a99ec15dadb92212
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 2b6ad3377a18ea67c24c063a1c844f098401844cb46bda2df9db4db51ca3d8e225344d4703ba90ce622b9f1dbf99245ae6fb33c4dd4cf8cf77385dac6e0be222
|
7
|
+
data.tar.gz: 5e45e8b7eb9dbfd2335502ddd225cea420dfd980593ebdb1fc830840274a3d2442da05c5ca06a774a74202a0465428276b1f7a7eb8d7ad468a7af59e9765b100
|
@@ -0,0 +1,40 @@
|
|
1
|
+
version: '2.1'
|
2
|
+
|
3
|
+
executors:
|
4
|
+
ruby:
|
5
|
+
parameters:
|
6
|
+
tag:
|
7
|
+
type: string
|
8
|
+
docker:
|
9
|
+
- image: circleci/ruby:<< parameters.tag >>
|
10
|
+
|
11
|
+
jobs:
|
12
|
+
build:
|
13
|
+
parameters:
|
14
|
+
ruby-version:
|
15
|
+
type: string
|
16
|
+
executor:
|
17
|
+
name: ruby
|
18
|
+
tag: << parameters.ruby-version >>
|
19
|
+
steps:
|
20
|
+
- checkout
|
21
|
+
- run:
|
22
|
+
name: Which bundler?
|
23
|
+
command: bundle -v
|
24
|
+
- run:
|
25
|
+
command: bundle install --path vendor/bundle
|
26
|
+
- run:
|
27
|
+
name: test
|
28
|
+
command: bundle exec rake test
|
29
|
+
workflows:
|
30
|
+
build:
|
31
|
+
jobs:
|
32
|
+
- build:
|
33
|
+
name: 'ruby-2.5'
|
34
|
+
ruby-version: '2.5.7'
|
35
|
+
- build:
|
36
|
+
name: 'ruby-2.6'
|
37
|
+
ruby-version: '2.6.5'
|
38
|
+
- build:
|
39
|
+
name: 'ruby-2.7'
|
40
|
+
ruby-version: '2.7.0'
|
data/README.md
CHANGED
data/lib/pluggaloid.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
require "pluggaloid/version"
|
2
|
+
require 'pluggaloid/collection'
|
2
3
|
require "pluggaloid/plugin"
|
3
4
|
require 'pluggaloid/stream'
|
4
5
|
require 'pluggaloid/event'
|
@@ -16,7 +17,9 @@ module Pluggaloid
|
|
16
17
|
VM = Struct.new(*%i<Delayer Plugin Event Listener Filter HandlerTag Subscriber>, keyword_init: true)
|
17
18
|
|
18
19
|
class PrototypeStream; end
|
20
|
+
class PrototypeCollect; end
|
19
21
|
STREAM = PrototypeStream.new.freeze
|
22
|
+
COLLECT = PrototypeCollect.new.freeze
|
20
23
|
|
21
24
|
def self.new(delayer)
|
22
25
|
vm = VM.new(Delayer: delayer,
|
@@ -0,0 +1,55 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Pluggaloid
|
4
|
+
class Collection
|
5
|
+
attr_reader :values
|
6
|
+
|
7
|
+
def initialize(event, *args)
|
8
|
+
@event = event
|
9
|
+
args[event.collect_index] = nil
|
10
|
+
@args = args.freeze
|
11
|
+
@spec = argument_hash(args)
|
12
|
+
@values = [].freeze
|
13
|
+
end
|
14
|
+
|
15
|
+
def add(*v)
|
16
|
+
rewind do |privitive|
|
17
|
+
privitive + v
|
18
|
+
end
|
19
|
+
end
|
20
|
+
alias_method :<<, :add
|
21
|
+
|
22
|
+
def delete(*v)
|
23
|
+
rewind do |privitive|
|
24
|
+
privitive - v
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def rewind(&block)
|
29
|
+
new_values = block.(@values.dup)
|
30
|
+
added, deleted = new_values - @values, @values - new_values
|
31
|
+
@values = new_values.freeze
|
32
|
+
unless added.empty?
|
33
|
+
args = @args.dup
|
34
|
+
args[@event.collect_index] = added
|
35
|
+
@event.collection_add_event.call(*args)
|
36
|
+
end
|
37
|
+
unless deleted.empty?
|
38
|
+
args = @args.dup
|
39
|
+
args[@event.collect_index] = deleted
|
40
|
+
@event.collection_delete_event.call(*args)
|
41
|
+
end
|
42
|
+
self
|
43
|
+
end
|
44
|
+
|
45
|
+
def argument_hash_same?(specs)
|
46
|
+
@spec == argument_hash(specs)
|
47
|
+
end
|
48
|
+
|
49
|
+
private
|
50
|
+
|
51
|
+
def argument_hash(specs)
|
52
|
+
@event.argument_hash(specs, @event.collect_index)
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
data/lib/pluggaloid/error.rb
CHANGED
data/lib/pluggaloid/event.rb
CHANGED
@@ -21,6 +21,24 @@ class Pluggaloid::Event
|
|
21
21
|
@subscribers = {}
|
22
22
|
end
|
23
23
|
|
24
|
+
def prototype
|
25
|
+
@options[:prototype]
|
26
|
+
end
|
27
|
+
|
28
|
+
# イベント _event_name_ を宣言する
|
29
|
+
# ==== Args
|
30
|
+
# [new_options] イベントの定義
|
31
|
+
def defevent(new_options)
|
32
|
+
@options.merge!(new_options)
|
33
|
+
if collect_index
|
34
|
+
new_proto = self.prototype.dup
|
35
|
+
new_proto[self.collect_index] = Pluggaloid::STREAM
|
36
|
+
collection_add_event.defevent(prototype: new_proto)
|
37
|
+
collection_delete_event.defevent(prototype: new_proto)
|
38
|
+
end
|
39
|
+
self
|
40
|
+
end
|
41
|
+
|
24
42
|
def vm
|
25
43
|
self.class.vm end
|
26
44
|
|
@@ -83,7 +101,7 @@ class Pluggaloid::Event
|
|
83
101
|
end
|
84
102
|
|
85
103
|
def subscribe?(*args)
|
86
|
-
!@listeners.empty? || @subscribers.key?(argument_hash(args))
|
104
|
+
!@listeners.empty? || @subscribers.key?(argument_hash(args, stream_index))
|
87
105
|
end
|
88
106
|
|
89
107
|
def delete_listener(listener)
|
@@ -132,25 +150,61 @@ class Pluggaloid::Event
|
|
132
150
|
self
|
133
151
|
end
|
134
152
|
|
135
|
-
def argument_hash(args)
|
153
|
+
def argument_hash(args, exclude_index)
|
136
154
|
args.each_with_index.map do |item, i|
|
137
|
-
if i !=
|
155
|
+
if i != exclude_index
|
138
156
|
item.hash
|
139
157
|
end
|
140
158
|
end.compact.freeze
|
141
159
|
end
|
142
160
|
|
143
|
-
def
|
144
|
-
unless defined?(@
|
145
|
-
@
|
161
|
+
def stream_index
|
162
|
+
unless defined?(@stream_index)
|
163
|
+
@stream_index = self.prototype&.index(Pluggaloid::STREAM)
|
146
164
|
end
|
147
|
-
@
|
165
|
+
@stream_index
|
166
|
+
end
|
167
|
+
|
168
|
+
def collect_index
|
169
|
+
unless defined?(@collect_index)
|
170
|
+
@collect_index = self.prototype&.index(Pluggaloid::COLLECT)
|
171
|
+
end
|
172
|
+
@collect_index
|
173
|
+
end
|
174
|
+
|
175
|
+
# defeventで定義されたprototype引数に _Pluggaloid::COLLECT_ を含むイベントに対して使える。
|
176
|
+
# フィルタの _Pluggaloid::COLLECT_ 引数に空の配列を渡して実行したあと、その配列を返す。
|
177
|
+
# ==== Args
|
178
|
+
# [*args] Pluggaloid::COLLECT 以外の引数のリスト
|
179
|
+
# ==== Return
|
180
|
+
# [Array] フィルタ実行結果
|
181
|
+
def collect(*args)
|
182
|
+
specified_index = args.index(Pluggaloid::COLLECT)
|
183
|
+
specified_index&.yield_self(&args.method(:delete_at))
|
184
|
+
insert_index = collect_index || specified_index
|
185
|
+
if insert_index
|
186
|
+
Enumerator.new do |yielder|
|
187
|
+
cargs = args.dup
|
188
|
+
cargs.insert(insert_index, yielder)
|
189
|
+
filtering(*cargs)
|
190
|
+
end
|
191
|
+
else
|
192
|
+
raise Pluggaloid::UndefinedCollectionIndexError, 'To call collect(), it must define prototype arguments include `Pluggaloid::COLLECT\'.'
|
193
|
+
end
|
194
|
+
end
|
195
|
+
|
196
|
+
def collection_add_event
|
197
|
+
self.class['%{name}__add' % {name: name}]
|
198
|
+
end
|
199
|
+
|
200
|
+
def collection_delete_event
|
201
|
+
self.class['%{name}__delete' % {name: name}]
|
148
202
|
end
|
149
203
|
|
150
204
|
private
|
151
205
|
def call_all_listeners(args)
|
152
|
-
if
|
153
|
-
@subscribers[argument_hash(args)]&.each do |subscriber|
|
206
|
+
if stream_index
|
207
|
+
@subscribers[argument_hash(args, stream_index)]&.each do |subscriber|
|
154
208
|
subscriber.call(*args)
|
155
209
|
end
|
156
210
|
end
|
data/lib/pluggaloid/plugin.rb
CHANGED
@@ -64,6 +64,17 @@ module Pluggaloid
|
|
64
64
|
def filtering(event_name, *args)
|
65
65
|
vm.Event[event_name].filtering(*args) end
|
66
66
|
|
67
|
+
# フィルタ _event_name_ を実行し、defeventでPluggaloid::COLLECTと
|
68
|
+
# 宣言されている引数の結果を列挙するEnumeratorを返す
|
69
|
+
# ==== Args
|
70
|
+
# [event_name] イベント名(String | Symbol)
|
71
|
+
# [*specs] Pluggaloid::COLLECT以外の引数
|
72
|
+
# ==== Return
|
73
|
+
# [Enumerator]
|
74
|
+
def collect(event_name, *specs)
|
75
|
+
vm.Event[event_name].collect(*specs)
|
76
|
+
end
|
77
|
+
|
67
78
|
# 互換性のため
|
68
79
|
def uninstall(plugin_name)
|
69
80
|
self[plugin_name].uninstall end
|
@@ -116,7 +127,7 @@ module Pluggaloid
|
|
116
127
|
|
117
128
|
# イベントフィルタを新しく登録する
|
118
129
|
# ==== Args
|
119
|
-
# [
|
130
|
+
# [event_name] イベント名(String | Symbol)
|
120
131
|
# [name:] 名前(String | nil)
|
121
132
|
# [slug:] フィルタスラッグ(Symbol | nil)
|
122
133
|
# [tags:] Pluggaloid::HandlerTag|Array フィルタのタグ
|
@@ -148,6 +159,32 @@ module Pluggaloid
|
|
148
159
|
vm.Event[event_name].subscribe?(*specs)
|
149
160
|
end
|
150
161
|
|
162
|
+
def collect(event_name, *specs)
|
163
|
+
self.class.collect(event_name, *specs)
|
164
|
+
end
|
165
|
+
|
166
|
+
# 追加・削除がフィルタに反映されるコレクションオブジェクトを作成する。
|
167
|
+
# 同時に _event_name_ にフィルタが定義され、フィルタが呼ばれると
|
168
|
+
# その時点のコレクションオブジェクトの内容を全て列挙する。
|
169
|
+
# フィルタと対になるコレクションオブジェクトは、 _&block_ の引数として渡される。
|
170
|
+
# ==== Args
|
171
|
+
# [event_name] イベント名(String | Symbol)
|
172
|
+
# [*specs] Pluggaloid::COLLECT以外の引数
|
173
|
+
# [&block] コレクションオブジェクトを受け取って一度だけ実行されるblock
|
174
|
+
# ==== Return
|
175
|
+
# _&block_ の戻り値
|
176
|
+
def collection(event_name, *specs, &block)
|
177
|
+
event = vm.Event[event_name]
|
178
|
+
mutation = Pluggaloid::Collection.new(event, *specs)
|
179
|
+
add_event_filter(event_name) do |*args|
|
180
|
+
if mutation.argument_hash_same?(args)
|
181
|
+
mutation.values.each(&args[event.collect_index].method(:<<))
|
182
|
+
end
|
183
|
+
args
|
184
|
+
end
|
185
|
+
block.call(mutation)
|
186
|
+
end
|
187
|
+
|
151
188
|
# このプラグインのHandlerTagを作る。
|
152
189
|
# ブロックが渡された場合は、ブロックの中を実行し、ブロックの中で定義された
|
153
190
|
# Handler全てにTagを付与する。
|
@@ -198,7 +235,6 @@ module Pluggaloid
|
|
198
235
|
end
|
199
236
|
end
|
200
237
|
|
201
|
-
|
202
238
|
# イベントを削除する。
|
203
239
|
# 引数は、Pluggaloid::ListenerかPluggaloid::Filterのみ(on_*やfilter_*の戻り値)。
|
204
240
|
# 互換性のため、二つ引数がある場合は第一引数は無視され、第二引数が使われる。
|
@@ -239,7 +275,8 @@ module Pluggaloid
|
|
239
275
|
# [event_name] イベント名
|
240
276
|
# [options] イベントの定義
|
241
277
|
def defevent(event_name, options={})
|
242
|
-
vm.Event[event_name].
|
278
|
+
vm.Event[event_name].defevent({ plugin: self, **options })
|
279
|
+
end
|
243
280
|
|
244
281
|
# DSLメソッドを新しく追加する。
|
245
282
|
# 追加されたメソッドは呼ぶと &callback が呼ばれ、その戻り値が返される。引数も順番通り全て &callbackに渡される
|
@@ -14,7 +14,7 @@ class Pluggaloid::Subscriber < Pluggaloid::Handler
|
|
14
14
|
def initialize(event, *specs, **kwrest, &callback)
|
15
15
|
super(event, **kwrest)
|
16
16
|
@callback = callback
|
17
|
-
@accepted_hash = @event.argument_hash(specs)
|
17
|
+
@accepted_hash = @event.argument_hash(specs, @event.stream_index)
|
18
18
|
event.add_listener(self)
|
19
19
|
end
|
20
20
|
|
@@ -22,7 +22,7 @@ class Pluggaloid::Subscriber < Pluggaloid::Handler
|
|
22
22
|
# ==== Args
|
23
23
|
# [stream] イベントの引数
|
24
24
|
def call(*args)
|
25
|
-
@callback.call(args[@event.
|
25
|
+
@callback.call(args[@event.stream_index])
|
26
26
|
end
|
27
27
|
|
28
28
|
# このリスナを削除する
|
data/lib/pluggaloid/version.rb
CHANGED
@@ -0,0 +1,135 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'bundler/setup'
|
4
|
+
require 'minitest/autorun'
|
5
|
+
|
6
|
+
require 'pluggaloid'
|
7
|
+
require_relative 'helper'
|
8
|
+
|
9
|
+
describe(Pluggaloid::Plugin) do
|
10
|
+
include PluggaloidTestHelper
|
11
|
+
|
12
|
+
before do
|
13
|
+
Delayer.default = Delayer.generate_class(priority: %i<high normal low>, default: :normal)
|
14
|
+
Pluggaloid::Plugin.clear!
|
15
|
+
end
|
16
|
+
|
17
|
+
it 'collect' do
|
18
|
+
Pluggaloid::Plugin.create(:event) do
|
19
|
+
defevent :list, prototype: [Integer, Pluggaloid::COLLECT]
|
20
|
+
|
21
|
+
filter_list do |i, yielder|
|
22
|
+
i.times(&yielder.method(:<<))
|
23
|
+
[i, yielder]
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
assert_equal([0, 1, 2], Pluggaloid::Event[:list].collect(3).to_a)
|
28
|
+
end
|
29
|
+
|
30
|
+
it 'fail when collect with undefined' do
|
31
|
+
Pluggaloid::Plugin.create(:event) do
|
32
|
+
filter_list do |i, yielder|
|
33
|
+
i.times(&yielder.method(:<<))
|
34
|
+
[i, yielder]
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
assert_raises(Pluggaloid::UndefinedCollectionIndexError) do
|
39
|
+
Pluggaloid::Event[:list].collect(3)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
it 'success caller arguments include Pluggaloid::COLLECT when collect with undefined' do
|
44
|
+
Pluggaloid::Plugin.create(:event) do
|
45
|
+
filter_list do |i, yielder|
|
46
|
+
i.times(&yielder.method(:<<))
|
47
|
+
[i, yielder]
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
assert_equal([0, 1, 2], Pluggaloid::Event[:list].collect(3, Pluggaloid::COLLECT).to_a)
|
52
|
+
end
|
53
|
+
|
54
|
+
it 'success different caller argument specific and prototype definition' do
|
55
|
+
Pluggaloid::Plugin.create(:event) do
|
56
|
+
defevent :list, prototype: [Integer, Pluggaloid::COLLECT]
|
57
|
+
|
58
|
+
filter_list do |i, yielder|
|
59
|
+
i.times(&yielder.method(:<<))
|
60
|
+
[i, yielder]
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
assert_equal([0, 1, 2], Pluggaloid::Event[:list].collect(Pluggaloid::COLLECT, 3).to_a)
|
65
|
+
end
|
66
|
+
|
67
|
+
describe 'collection' do
|
68
|
+
it 'add' do
|
69
|
+
Pluggaloid::Plugin.create(:event) do
|
70
|
+
defevent :list, prototype: [Integer, Pluggaloid::COLLECT]
|
71
|
+
defevent :insert, prototype: [Pluggaloid::STREAM]
|
72
|
+
|
73
|
+
collection(:list, 3) do |collector|
|
74
|
+
subscribe(:insert).each do |i|
|
75
|
+
collector.add(i * 3)
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
eval_all_events do
|
80
|
+
Pluggaloid::Event[:insert].call([2, 5])
|
81
|
+
end
|
82
|
+
assert_equal([6, 15], Pluggaloid::Event[:list].collect(3).to_a)
|
83
|
+
end
|
84
|
+
|
85
|
+
it 'delete' do
|
86
|
+
Pluggaloid::Plugin.create(:event) do
|
87
|
+
defevent :list, prototype: [Integer, Pluggaloid::COLLECT]
|
88
|
+
defevent :destroy, prototype: [Pluggaloid::STREAM]
|
89
|
+
|
90
|
+
collection(:list, 3) do |collector|
|
91
|
+
collector << 1 << 2 << 3
|
92
|
+
subscribe(:destroy).each do |i|
|
93
|
+
collector.delete(i)
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
97
|
+
eval_all_events do
|
98
|
+
Pluggaloid::Event[:destroy].call([2, 4])
|
99
|
+
end
|
100
|
+
assert_equal([1, 3], Pluggaloid::Event[:list].collect(3).to_a)
|
101
|
+
end
|
102
|
+
|
103
|
+
it 'rewind' do
|
104
|
+
added = []
|
105
|
+
deleted = []
|
106
|
+
Pluggaloid::Plugin.create(:event) do
|
107
|
+
defevent :list, prototype: [Integer, Pluggaloid::COLLECT]
|
108
|
+
|
109
|
+
collection(:list, 3) do |collector|
|
110
|
+
collector << 1 << 2 << 3
|
111
|
+
on_rewind do |e|
|
112
|
+
collector.rewind do |lst|
|
113
|
+
e
|
114
|
+
end
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
subscribe(:list__add, 3) do |elm|
|
119
|
+
added += elm
|
120
|
+
end
|
121
|
+
|
122
|
+
subscribe(:list__delete, 3) do |elm|
|
123
|
+
deleted += elm
|
124
|
+
end
|
125
|
+
end
|
126
|
+
eval_all_events do
|
127
|
+
Pluggaloid::Event[:rewind].call([2, 3, 4])
|
128
|
+
end
|
129
|
+
assert_equal([2, 3, 4], Pluggaloid::Event[:list].collect(3).to_a)
|
130
|
+
assert_equal([1, 2, 3, 4], added)
|
131
|
+
assert_equal([1], deleted)
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
135
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: pluggaloid
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.4.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Toshiaki Asai
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-01
|
11
|
+
date: 2020-02-01 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: delayer
|
@@ -99,12 +99,14 @@ executables: []
|
|
99
99
|
extensions: []
|
100
100
|
extra_rdoc_files: []
|
101
101
|
files:
|
102
|
+
- ".circleci/config.yml"
|
102
103
|
- ".gitignore"
|
103
104
|
- Gemfile
|
104
105
|
- LICENSE.txt
|
105
106
|
- README.md
|
106
107
|
- Rakefile
|
107
108
|
- lib/pluggaloid.rb
|
109
|
+
- lib/pluggaloid/collection.rb
|
108
110
|
- lib/pluggaloid/error.rb
|
109
111
|
- lib/pluggaloid/event.rb
|
110
112
|
- lib/pluggaloid/filter.rb
|
@@ -117,6 +119,7 @@ files:
|
|
117
119
|
- lib/pluggaloid/subscriber.rb
|
118
120
|
- lib/pluggaloid/version.rb
|
119
121
|
- pluggaloid.gemspec
|
122
|
+
- test/collect_test.rb
|
120
123
|
- test/handler_tag_test.rb
|
121
124
|
- test/helper.rb
|
122
125
|
- test/multi_vm_test.rb
|
@@ -146,6 +149,7 @@ signing_key:
|
|
146
149
|
specification_version: 4
|
147
150
|
summary: Extensible plugin system
|
148
151
|
test_files:
|
152
|
+
- test/collect_test.rb
|
149
153
|
- test/handler_tag_test.rb
|
150
154
|
- test/helper.rb
|
151
155
|
- test/multi_vm_test.rb
|