multiset 0.3.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.
@@ -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