multiset 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,66 @@
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE DIRECTLY
3
+ # Instead, edit Jeweler::Tasks in rakefile, and run 'rake gemspec'
4
+ # -*- encoding: utf-8 -*-
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = %q{multiset}
8
+ s.version = "0.3.0"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = ["H.Hiro(Maraigue)"]
12
+ s.date = %q{2011-03-25}
13
+ s.description = %q{Ruby implementation of multiset. Unlike ordinary set(see Ruby documentation for "set" library), multiset can contain two or more same items.}
14
+ s.email = %q{main@hhiro.net}
15
+ s.extra_rdoc_files = [
16
+ "LICENSE.txt",
17
+ "README.rdoc"
18
+ ]
19
+ s.files = [
20
+ ".document",
21
+ ".rspec",
22
+ "Gemfile",
23
+ "LICENSE.txt",
24
+ "README.rdoc",
25
+ "Rakefile",
26
+ "VERSION",
27
+ "lib/multiset.rb",
28
+ "lib/multiset/libmultimap.rb",
29
+ "lib/multiset/libmultiset.rb",
30
+ "multiset.gemspec",
31
+ "spec/multiset_spec.rb",
32
+ "spec/spec_helper.rb"
33
+ ]
34
+ s.homepage = %q{http://github.com/maraigue/multiset}
35
+ s.licenses = ["MIT"]
36
+ s.require_paths = ["lib"]
37
+ s.rubygems_version = %q{1.6.2}
38
+ s.summary = %q{Multiset library for Ruby}
39
+ s.test_files = [
40
+ "spec/multiset_spec.rb",
41
+ "spec/multiset_spec_ported.rb",
42
+ "spec/spec_helper.rb"
43
+ ]
44
+
45
+ if s.respond_to? :specification_version then
46
+ s.specification_version = 3
47
+
48
+ if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
49
+ s.add_development_dependency(%q<rspec>, [">= 2.3.0"])
50
+ s.add_development_dependency(%q<bundler>, [">= 1.0.0"])
51
+ s.add_development_dependency(%q<jeweler>, [">= 1.5.2"])
52
+ s.add_development_dependency(%q<rcov>, [">= 0"])
53
+ else
54
+ s.add_dependency(%q<rspec>, [">= 2.3.0"])
55
+ s.add_dependency(%q<bundler>, [">= 1.0.0"])
56
+ s.add_dependency(%q<jeweler>, [">= 1.5.2"])
57
+ s.add_dependency(%q<rcov>, [">= 0"])
58
+ end
59
+ else
60
+ s.add_dependency(%q<rspec>, [">= 2.3.0"])
61
+ s.add_dependency(%q<bundler>, [">= 1.0.0"])
62
+ s.add_dependency(%q<jeweler>, [">= 1.5.2"])
63
+ s.add_dependency(%q<rcov>, [">= 0"])
64
+ end
65
+ end
66
+
@@ -0,0 +1,12 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
+
3
+ # This version is a direct porting from version 0.202 (not for Rubygems).
4
+ # Unit test code will be added from the next version.
5
+
6
+ require "multiset"
7
+
8
+ describe Multiset do
9
+ end
10
+
11
+ describe Multimap do
12
+ end
@@ -0,0 +1,528 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
+
3
+ require "multiset"
4
+
5
+ # -------------------- specs of Multiset --------------------
6
+ describe Multiset, "to be generated" do
7
+ before do
8
+ Multiset.parse_string? true
9
+ end
10
+
11
+ it "should be correctly parsed from a hash" do
12
+ Multiset.parse({:a => 6, :b => 5}).should == {:a => 6, :b => 5}.to_multiset
13
+ Multiset.parse([:a, 6, :b, 5]).should_not == {:a => 6, :b => 5}.to_multiset
14
+ Multiset.parse([:a, 6, :b, 5]).should == Multiset.new([:a, 6, :b, 5])
15
+ end
16
+
17
+ it "should correctly reject scalar values from being updated (Multiset.parse_string? == true)" do
18
+ Multiset.parse_string? true
19
+
20
+ lambda{ Multiset.parse(83) }.should raise_error(ArgumentError)
21
+ lambda{ Multiset.parse("hoge\npiyo\n") }.should_not raise_error(ArgumentError)
22
+ lambda{ Multiset.parse_force("hoge\npiyo\n") }.should_not raise_error(ArgumentError)
23
+ end
24
+
25
+ it "should correctly reject scalar values from being updated (Multiset.parse_string? == false)" do
26
+ Multiset.parse_string? false
27
+
28
+ lambda{ Multiset.parse(83) }.should raise_error(ArgumentError)
29
+ lambda{ Multiset.parse("hoge\npiyo\n") }.should raise_error(ArgumentError)
30
+ lambda{ Multiset.parse_force("hoge\npiyo\n") }.should_not raise_error(ArgumentError)
31
+ end
32
+ end
33
+
34
+ describe Multiset, "�̐����ɂ‚���" do
35
+ it "Multiset#new��Hash#to_multiset�œ����C���X�^���X�����������" do
36
+ Multiset.new([:a,:a,:b]).should == {:a => 2, :b => 1}.to_multiset
37
+ Multiset[:x,:x,:y,:y].should == {:x => 2, :y => 2, :z => 0}.to_multiset
38
+ end
39
+
40
+ it "���������������" do
41
+ tmp = Multiset.new([:a,:a,:b])
42
+ tmp.should == tmp.dup
43
+
44
+ tmp = Multiset[]
45
+ tmp.should == tmp.dup
46
+ end
47
+
48
+ it "�������u�������" do
49
+ tmp = Multiset[]
50
+ tmp.replace(Multiset[:a,:b,:b]).should == Multiset[:a,:b,:b]
51
+ end
52
+ end
53
+
54
+ describe Multiset, "��2�‚̃C���X�^���X�ɂ‚���" do
55
+ before do
56
+ @ms1 = Multiset.new(%w'a a a a b b b c c d')
57
+ @ms2 = Multiset.new(%w'b c c d d d e e e e')
58
+ end
59
+
60
+ it "��܊֌W��������" do
61
+ tmp1 = Multiset.new(%w'a a a a b b b c c d d')
62
+ tmp2 = Multiset.new(%w'a a a a b b b c c d')
63
+ tmp3 = Multiset.new(%w'a a a b b b c c d')
64
+
65
+ (@ms1 == @ms2).should be_false
66
+ (@ms1 == tmp1).should be_false
67
+ (@ms1 == tmp2).should be_true
68
+ (@ms1 == tmp3).should be_false
69
+
70
+ (@ms1.subset?(@ms2)).should be_false
71
+ (@ms1.subset?(tmp1)).should be_true
72
+ (@ms1.subset?(tmp2)).should be_true
73
+ (@ms1.subset?(tmp3)).should be_false
74
+ (@ms2.subset?(@ms1)).should be_false
75
+ (tmp1.subset?(@ms1)).should be_false
76
+ (tmp2.subset?(@ms1)).should be_true
77
+ (tmp3.subset?(@ms1)).should be_true
78
+
79
+ (@ms1.proper_subset?(@ms2)).should be_false
80
+ (@ms1.proper_subset?(tmp1)).should be_true
81
+ (@ms1.proper_subset?(tmp2)).should be_false
82
+ (@ms1.proper_subset?(tmp3)).should be_false
83
+ (@ms2.proper_subset?(@ms1)).should be_false
84
+ (tmp1.proper_subset?(@ms1)).should be_false
85
+ (tmp2.proper_subset?(@ms1)).should be_false
86
+ (tmp3.proper_subset?(@ms1)).should be_true
87
+
88
+ (@ms1.superset?(@ms2)).should be_false
89
+ (@ms1.superset?(tmp1)).should be_false
90
+ (@ms1.superset?(tmp2)).should be_true
91
+ (@ms1.superset?(tmp3)).should be_true
92
+ (@ms2.superset?(@ms1)).should be_false
93
+ (tmp1.superset?(@ms1)).should be_true
94
+ (tmp2.superset?(@ms1)).should be_true
95
+ (tmp3.superset?(@ms1)).should be_false
96
+
97
+ (@ms1.proper_superset?(@ms2)).should be_false
98
+ (@ms1.proper_superset?(tmp1)).should be_false
99
+ (@ms1.proper_superset?(tmp2)).should be_false
100
+ (@ms1.proper_superset?(tmp3)).should be_true
101
+ (@ms2.proper_superset?(@ms1)).should be_false
102
+ (tmp1.proper_superset?(@ms1)).should be_true
103
+ (tmp2.proper_superset?(@ms1)).should be_false
104
+ (tmp3.proper_superset?(@ms1)).should be_false
105
+ end
106
+
107
+ it "�ϏW����������" do
108
+ (@ms1 & @ms2).should == Multiset.new(%w'b c c d')
109
+ end
110
+
111
+ it "�a�W����������" do
112
+ (@ms1 | @ms2).should == Multiset.new(%w'a a a a b b b c c d d d e e e e')
113
+ end
114
+
115
+ it "�����̌��ʂ�������" do
116
+ (@ms1 + @ms2).should == Multiset.new(%w'a a a a b b b b c c c c d d d d e e e e')
117
+
118
+ tmp = @ms1.dup
119
+ tmp.merge!(@ms2)
120
+ tmp.should == Multiset.new(%w'a a a a b b b b c c c c d d d d e e e e')
121
+ end
122
+
123
+ it "���̌��ʂ�������" do
124
+ (@ms1 - @ms2).should == Multiset.new(%w'a a a a b b')
125
+
126
+ tmp = @ms1.dup
127
+ tmp.subtract!(@ms2)
128
+ tmp.should == Multiset.new(%w'a a a a b b')
129
+ end
130
+
131
+ it "�v�f�̒lj���������" do
132
+ tmp = @ms1.dup
133
+ tmp << "a"
134
+ tmp.should == Multiset.new(%w'a a a a a b b b c c d')
135
+
136
+ tmp = @ms1.dup
137
+ tmp.add("e", 3)
138
+ tmp.should == Multiset.new(%w'a a a a b b b c c d e e e')
139
+
140
+ tmp = @ms1.dup
141
+ tmp.add("a", 3)
142
+ tmp.should == Multiset.new(%w'a a a a a a a b b b c c d')
143
+ end
144
+
145
+ it "�v�f�̍폜��������" do
146
+ tmp = @ms1.dup
147
+ tmp.delete("a")
148
+ tmp.should == Multiset.new(%w'a a a b b b c c d')
149
+
150
+ tmp = @ms1.dup
151
+ tmp.delete("e")
152
+ tmp.should == @ms1
153
+
154
+ tmp = @ms1.dup
155
+ tmp.delete_all("a")
156
+ tmp.should == Multiset.new(%w'b b b c c d')
157
+
158
+ tmp = @ms1.dup
159
+ tmp.delete_all("e")
160
+ tmp.should == @ms1
161
+ end
162
+ end
163
+
164
+ # -------------------- specs of Multimap --------------------
165
+ describe Multimap, "generated by adding items one by one" do
166
+ before do
167
+ Multiset.parse_string? true
168
+
169
+ @empty_multiset = Multiset.new
170
+ @mm = Multimap.new
171
+ end
172
+
173
+ it "should be empty when generated without parameters" do
174
+ @mm[:a].should == empty_multiset
175
+ @mm[:b].should == empty_multiset
176
+ end
177
+
178
+ it "should be correctly updated by adding a scalar value" do
179
+ @mm[:a].add "bar"
180
+ @mm[:a].should == Multiset["bar"]
181
+ end
182
+
183
+ it "should not make unsolicited change" do
184
+ @mm[:a].add "bar"
185
+ @mm[:b].should == empty_multiset
186
+ end
187
+
188
+ it "should be correctly updated by setting an array" do
189
+ @mm[:a] = ["foo", "foo", "bar"]
190
+ @mm[:a].should == Multiset["foo", "foo", "bar"]
191
+ end
192
+
193
+ it "should be correctly updated by setting a hash" do
194
+ @mm[:a] = {"foo" => 3, "bar" => 2}
195
+ @mm[:a].should == Multiset["foo", "foo", "bar", "foo", "bar"]
196
+ end
197
+
198
+ it "should not be updated by setting a scalar (other than 'Enumerable' object)"
199
+ Multiset.parse_string? true
200
+ lambda{ mm[:a] = "foobar" }.should_not raise_error(ArgumentError)
201
+ lambda{ mm[:a] = 56 }.should raise_error(ArgumentError)
202
+ end
203
+
204
+ it "should not be updated by setting a scalar (including strings)"
205
+ Multiset.parse_string? false
206
+ lambda{ mm[:a] = "foobar" }.should raise_error(ArgumentError)
207
+ lambda{ mm[:a] = 56 }.should raise_error(ArgumentError)
208
+ end
209
+ end
210
+
211
+ describe Multimap, "generated from a hash" do
212
+ it "should be correctly generated from hashes (by Hash#to_multimap)"
213
+ # to_multimap / multimap
214
+ mm = {:a => [3, 3], :b => [5, 3]}.to_multimap
215
+ mm[:a].should == Multiset[3, 3]
216
+ mm[:b].should == Multiset[5, 3]
217
+ end
218
+
219
+ it "should be correctly generated from hashes (by Hash#multimap)"
220
+ mm = {:a => [3, 3], :b => [5, 3]}.multimap
221
+ mm[:a].should == Multiset[[3, 3]]
222
+ mm[:b].should == Multiset[[5, 3]]
223
+ end
224
+ end
225
+
226
+ describe Multimap, "to be compared" do
227
+ it "should be correctly compared" do
228
+ mm1 = Multimap.new
229
+ mm1[:a] = ["foo", "foo", "bar", "hoge", "hoge", "moe"]
230
+ mm1[:b] = ["foo", "bar", "hoge", "hoge", "bar"]
231
+ mm2 = Multimap.new
232
+ mm2[:a] = ["foo", "foo", "bar", "hoge", "hoge", "moe"]
233
+ mm2[:b] = ["foo", "bar", "hoge", "hoge", "bar"]
234
+ mm3 = Multimap.new
235
+ mm3[:a] = ["foo", "foo", "bar", "hoge", "hoge", "moe"]
236
+ mm3[:b] = ["foo", "bar", "hoge", "hoge", "bar", "buz"]
237
+
238
+ mm1.should == mm2
239
+ mm1.should_not == mm3
240
+
241
+ mm3.dup.should == mm3
242
+ end
243
+
244
+ it "should be correctly decided whether it is empty or not"
245
+ mm = Multimap.new
246
+
247
+ mm[:a] = []
248
+ mm[:b] = [:a, :b]
249
+ mm.should_not be_empty
250
+
251
+ mm[:a] = []
252
+ mm[:b] = []
253
+ mm.should be_empty
254
+ end
255
+
256
+ it "should be equal to 'dup'ed multimap" do
257
+ @mm = Multimap.new
258
+ @mm[:a] = ["foo", "foo", "bar", "hoge", "hoge", "moe"]
259
+ @mm[:b] = ["foo", "bar", "hoge", "hoge", "bar"]
260
+
261
+ @mm.dup.should == @mm
262
+ end
263
+ end
264
+
265
+ describe Multimap, "to be referred" do
266
+ before do
267
+ @mm = Multimap.new
268
+ @mm[:a] = ["foo", "foo", "bar", "hoge", "hoge", "moe"]
269
+ @mm[:b] = ["foo", "bar", "hoge", "hoge", "bar"]
270
+ end
271
+
272
+ it "should be correctly iterated by 'each_pair'" do
273
+ tmp_a = []
274
+ tmp_b = []
275
+ @mm.each_pair do |key, sval|
276
+ sval.instance_of?(String).should be_true
277
+ case key
278
+ when :a
279
+ tmp_a << sval
280
+ when :b
281
+ tmp_b << sval
282
+ else
283
+ raise
284
+ end
285
+ end
286
+ tmp_a.sort.should == ["foo", "foo", "bar", "hoge", "hoge", "moe"].sort
287
+ tmp_b.sort.should == ["foo", "bar", "hoge", "hoge", "bar"].sort
288
+ end
289
+
290
+ it "should be correctly iterated by 'each_pair_with'" do
291
+ tmp_a = []
292
+ tmp_b = []
293
+ @mm.each_pair_with do |key, val, cnt|
294
+ val.instance_of?(String).should be_true
295
+ cnt.instance_of?(Fixnum).should be_true
296
+ case key
297
+ when :a
298
+ tmp_a << val
299
+ when :b
300
+ tmp_b << val
301
+ else
302
+ raise
303
+ end
304
+ end
305
+ tmp_a.sort.should == ["foo", "foo", "bar", "hoge", "hoge", "moe"].uniq.sort
306
+ tmp_b.sort.should == ["foo", "bar", "hoge", "hoge", "bar"].uniq.sort
307
+ end
308
+
309
+ it "should be correctly iterated by 'each_pair_list'" do
310
+ flag = 0
311
+ @mm.each_pair_list do |key, vals|
312
+ case key
313
+ when :a
314
+ vals.should == Multiset["foo", "foo", "bar", "hoge", "hoge", "moe"]
315
+ flag += 1
316
+ when :b
317
+ vals.should == Multiset["foo", "bar", "hoge", "hoge", "bar"]
318
+ flag += 1
319
+ else
320
+ raise
321
+ end
322
+ end
323
+ flag.should == 2
324
+ end
325
+
326
+ it "should be correctly iterated by 'each_key', ignoring non-existent key" do
327
+ @mm[:c] = []
328
+
329
+ ms = Multiset.new
330
+ mm.each_key{ |key| ms << key }
331
+ ms.should == Multiset[:a, :b]
332
+ end
333
+
334
+ it "should be correctly iterated by 'each_value'"
335
+ ms = Multiset.new
336
+ @mm.each_value{ |sval| ms << sval }
337
+ ms.should == {"foo" => 3, "bar" => 3, "hoge" => 4, "moe" => 1}.to_multiset
338
+ end
339
+ end
340
+
341
+ describe Multimap, "to be updated" do
342
+ before do
343
+ @mm = Multimap.new
344
+ @mm[:a] = ["foo", "foo", "bar", "hoge", "hoge", "moe"]
345
+ @mm[:b] = ["foo", "bar", "hoge", "hoge", "bar"]
346
+ end
347
+
348
+ it "should release items when 'delete'd" do
349
+ @mm.delete(:a).should == Multiset["foo", "foo", "bar", "hoge", "hoge", "moe"]
350
+ @mm[:a].should == Multiset[]
351
+ @mm[:b].should == Multiset["foo", "bar", "hoge", "hoge", "bar"]
352
+ end
353
+
354
+ it "should not release items when 'reject'ed ('reject'ed from only return value)" do
355
+ mm1 = @mm.reject{ |key, sval| sval =~ /o/ }
356
+
357
+ mm1[:a].should == Multiset["bar"]
358
+ mm1[:b].should == Multiset["bar", "bar"]
359
+ mm1.should_not == @mm
360
+ end
361
+
362
+ it "should equal to 'reject!'ed multimap when 'delete_if' is applied" do
363
+ mm1 = @mm.dup
364
+ mm2 = @mm.dup
365
+
366
+ mm1.delete_if{ |key, sval| sval =~ /o/ }
367
+ mm2.reject!{ |key, sval| sval =~ /o/ }
368
+ mm1.should == mm2
369
+
370
+ mm1.delete_if{ |key, sval| sval =~ /x/ }
371
+ mm2.reject!{ |key, sval| sval =~ /x/ }
372
+ mm1.should == mm2
373
+ end
374
+
375
+ it "should return nil when 'reject!' rejects nothing but 'delete_if' not" do
376
+ mm1 = @mm.dup
377
+ mm2 = @mm.dup
378
+
379
+ mm1.delete_if{ |key, sval| sval =~ /o/ }.should == mm1
380
+ mm2.reject!{ |key, sval| sval =~ /o/ }.should == mm2
381
+
382
+ mm1.delete_if{ |key, sval| sval =~ /x/ }.should == mm1
383
+ mm2.reject!{ |key, sval| sval =~ /x/ }.should == nil
384
+ end
385
+
386
+ it "should not release items when 'reject_with' is applied ('reject'ed from only return value)" do
387
+ # reject_with
388
+ mm1 = @mm.reject_with{ |key, val, cnt| cnt >= 2 }
389
+
390
+ mm1[:a].should == Multiset["bar", "moe"]
391
+ mm1[:b].should == Multiset["foo"]
392
+ mm1.should_not == @mm
393
+ end
394
+
395
+ if "should release items when 'delete_with' is applied"
396
+ retval = @mm.delete_with{ |key, val, cnt| cnt >= 2 }
397
+ retval.should == @mm
398
+ @mm[:a].should == Multiset["bar", "moe"]
399
+ @mm[:b].should == Multiset["foo"]
400
+ end
401
+
402
+ if "should release items when 'delete_with' is applied (but not deleted anything)"
403
+ retval = @mm.delete_with{ |key, val, cnt| cnt >= 2 && val.length > 4 }
404
+ retval.should == @mm
405
+ @mm[:a].should == Multiset["foo", "foo", "bar", "hoge", "hoge", "moe"]
406
+ @mm[:b].should == Multiset["foo", "bar", "hoge", "hoge", "bar"]
407
+ end
408
+
409
+ it "Multimap�̗v�f�̓�����������" do
410
+ mm_base = Multimap.new
411
+ mm_base[:a] = ["foo", "foo", "bar", "hoge", "hoge", "moe"]
412
+ mm_base[:b] = ["foo", "bar", "hoge", "hoge", "bar"]
413
+
414
+ # keys, values
415
+ mm = mm_base.dup
416
+ mm[:c] = []
417
+ mm.keys.should satisfy{ |ks| ks == [:a, :b] || ks == [:b, :a] }
418
+ mm.values.should == {"foo" => 3, "bar" => 3, "hoge" => 4, "moe" => 1}.to_multiset
419
+
420
+ # empty?
421
+ mm = mm_base.dup
422
+ mm[:a] = []
423
+ mm.delete :b
424
+ mm[:c] = [:x]
425
+ mm.should_not be_empty
426
+ mm.delete_if{ |key, sval| sval == :x }
427
+ mm.should be_empty
428
+
429
+ # has_key?
430
+ mm = mm_base.dup
431
+ mm[:c] = []
432
+ mm[:d] = [:z]
433
+ mm.should have_key(:a)
434
+ mm.should have_key(:b)
435
+ mm.should_not have_key(:c)
436
+ mm.should be_member(:d)
437
+ mm.should_not be_member(:x)
438
+
439
+ # has_value?
440
+ mm = mm_base.dup
441
+ mm[:c] = []
442
+ mm[:d] = [:z]
443
+ mm.should have_value("foo")
444
+ mm.should have_value(:z)
445
+ mm.should_not have_value("boo")
446
+ mm.should be_value("hoge")
447
+ mm.should_not be_value(:d)
448
+
449
+ # index
450
+ mm = mm_base.dup
451
+ mm.index("moe").should == :a
452
+ [:a, :b].should be_member(mm.index("hoge"))
453
+ mm.index("boo").should == nil
454
+
455
+ # values_at
456
+ mm = mm_base.dup
457
+ mm[:x] = []
458
+
459
+ mm.values_at(:b, :x, :a).should == [
460
+ Multiset["foo", "bar", "hoge", "hoge", "bar"],
461
+ Multiset[],
462
+ Multiset["foo", "foo", "bar", "hoge", "hoge", "moe"],
463
+ ]
464
+
465
+ mm.indexes(:b, :x, :a).map{ |ms|
466
+ ms.empty? ? nil : ms.to_a.sort }.should == [
467
+ ["foo", "bar", "hoge", "hoge", "bar"].sort,
468
+ nil,
469
+ ["foo", "foo", "bar", "hoge", "hoge", "moe"].sort,
470
+ ]
471
+
472
+ # length
473
+ mm = mm_base.dup
474
+ mm.length.should == 11
475
+ mm[:c] = [:y]
476
+ mm.length.should == 12
477
+ end
478
+
479
+ it "Multimap�̕ϊ���������" do
480
+ # invert
481
+ mm_base = Multimap.new
482
+ mm_base[:a] = ["foo", "foo", "bar", "hoge", "hoge", "moe"]
483
+ mm_base[:b] = ["foo", "bar", "hoge", "hoge", "bar"]
484
+
485
+ imm = mm_base.invert
486
+ imm["moe"].should == Multiset[:a]
487
+ imm["foo"].should == Multiset[:a, :a, :b]
488
+ imm["bar"].should == Multiset[:a, :b, :b]
489
+ imm["boo"].should == Multiset[]
490
+
491
+ mm1 = mm_base.dup
492
+ mm2 = Multimap.new
493
+ mm2[:a] = ["foo", "hoge", "hoge"]
494
+ mm2[:c] = ["foo"]
495
+
496
+ mm1.replace(mm2)
497
+ mm1.should == mm2
498
+
499
+ # to_hash
500
+ mm_base.to_hash
501
+ end
502
+
503
+ it "Multimap�ւ̉��Z��������" do
504
+ # merge
505
+ mm_base = Multimap.new
506
+ mm_base[:a] = ["foo", "foo", "bar", "hoge", "hoge", "moe"]
507
+ mm_base[:b] = ["foo", "bar", "hoge", "hoge", "bar"]
508
+
509
+ mm1 = mm_base.dup
510
+
511
+ mm2 = Multimap.new
512
+ mm2[:a] = ["foo", "hoge", "hoge"]
513
+ mm2[:c] = ["foo"]
514
+
515
+ mm1.merge(mm2).should == {
516
+ :a => ["foo", "foo", "bar", "hoge", "hoge", "moe", "foo", "hoge", "hoge"],
517
+ :b => ["foo", "bar", "hoge", "hoge", "bar"],
518
+ :c => ["foo"],
519
+ }.to_multimap
520
+ mm1.should == mm_base
521
+
522
+ mm1.merge!(mm2).should == {
523
+ :a => ["foo", "foo", "bar", "hoge", "hoge", "moe", "foo", "hoge", "hoge"],
524
+ :b => ["foo", "bar", "hoge", "hoge", "bar"],
525
+ :c => ["foo"],
526
+ }.to_multimap
527
+ mm1.should_not == mm_base
528
+ end