mailgun 0.7 → 0.8
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +0 -4
- data/CONTRIBUTORS.md +23 -0
- data/README.md +31 -16
- data/lib/mailgun.rb +4 -1
- data/lib/mailgun/base.rb +4 -4
- data/lib/mailgun/bounce.rb +24 -3
- data/lib/mailgun/message.rb +1 -1
- data/lib/multimap/.gitignore +4 -0
- data/lib/multimap/LICENSE +20 -0
- data/lib/multimap/README.rdoc +16 -0
- data/lib/multimap/Rakefile +34 -0
- data/lib/multimap/benchmarks/bm_nested_multimap_construction.rb +60 -0
- data/lib/multimap/benchmarks/bm_nested_multimap_lookup.rb +33 -0
- data/lib/multimap/ext/extconf.rb +6 -0
- data/lib/multimap/ext/nested_multimap_ext.c +24 -0
- data/lib/multimap/extras/graphing.rb +83 -0
- data/lib/multimap/lib/multimap.rb +569 -0
- data/lib/multimap/lib/multiset.rb +185 -0
- data/lib/multimap/lib/nested_multimap.rb +158 -0
- data/lib/multimap/spec/enumerable_examples.rb +50 -0
- data/lib/multimap/spec/hash_examples.rb +264 -0
- data/lib/multimap/spec/multimap_spec.rb +45 -0
- data/lib/multimap/spec/multiset_spec.rb +184 -0
- data/lib/multimap/spec/nested_multimap_spec.rb +202 -0
- data/lib/multimap/spec/set_examples.rb +301 -0
- data/lib/multimap/spec/spec_helper.rb +67 -0
- data/mailgun.gemspec +4 -4
- data/spec/base_spec.rb +2 -2
- data/spec/bounce_spec.rb +12 -0
- metadata +43 -23
@@ -0,0 +1,45 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Multimap, "with inital values {'a' => [100], 'b' => [200, 300]}" do
|
4
|
+
it_should_behave_like "Enumerable Multimap with inital values {'a' => [100], 'b' => [200, 300]}"
|
5
|
+
it_should_behave_like "Hash Multimap with inital values {'a' => [100], 'b' => [200, 300]}"
|
6
|
+
|
7
|
+
before do
|
8
|
+
@map = Multimap["a" => 100, "b" => [200, 300]]
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
describe Multimap, "with inital values {'a' => [100], 'b' => [200, 300]}" do
|
13
|
+
it_should_behave_like "Enumerable Multimap with inital values {'a' => [100], 'b' => [200, 300]}"
|
14
|
+
it_should_behave_like "Hash Multimap with inital values {'a' => [100], 'b' => [200, 300]}"
|
15
|
+
|
16
|
+
before do
|
17
|
+
@map = Multimap["a", 100, "b", [200, 300]]
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
describe Multimap, "with", Set do
|
22
|
+
it_should_behave_like "Enumerable Multimap with inital values {'a' => [100], 'b' => [200, 300]}"
|
23
|
+
it_should_behave_like "Hash Multimap with inital values {'a' => [100], 'b' => [200, 300]}"
|
24
|
+
|
25
|
+
before do
|
26
|
+
@container = Set
|
27
|
+
@map = Multimap.new(@container.new)
|
28
|
+
@map["a"] = 100
|
29
|
+
@map["b"] = 200
|
30
|
+
@map["b"] = 300
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
describe Multimap, "with", MiniArray do
|
35
|
+
it_should_behave_like "Enumerable Multimap with inital values {'a' => [100], 'b' => [200, 300]}"
|
36
|
+
it_should_behave_like "Hash Multimap with inital values {'a' => [100], 'b' => [200, 300]}"
|
37
|
+
|
38
|
+
before do
|
39
|
+
@container = MiniArray
|
40
|
+
@map = Multimap.new(@container.new)
|
41
|
+
@map["a"] = 100
|
42
|
+
@map["b"] = 200
|
43
|
+
@map["b"] = 300
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,184 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Multiset do
|
4
|
+
it_should_behave_like "Set"
|
5
|
+
|
6
|
+
it "should return the multiplicity of the element" do
|
7
|
+
set = Multiset.new([:a, :a, :b, :b, :b, :c])
|
8
|
+
set.multiplicity(:a).should eql(2)
|
9
|
+
set.multiplicity(:b).should eql(3)
|
10
|
+
set.multiplicity(:c).should eql(1)
|
11
|
+
end
|
12
|
+
|
13
|
+
it "should return the cardinality of the set" do
|
14
|
+
set = Multiset.new([:a, :a, :b, :b, :b, :c])
|
15
|
+
set.cardinality.should eql(6)
|
16
|
+
end
|
17
|
+
|
18
|
+
it "should be eql" do
|
19
|
+
s1 = Multiset.new([:a, :b])
|
20
|
+
s2 = Multiset.new([:b, :a])
|
21
|
+
s1.should eql(s2)
|
22
|
+
|
23
|
+
s1 = Multiset.new([:a, :a])
|
24
|
+
s2 = Multiset.new([:a])
|
25
|
+
s1.should_not eql(s2)
|
26
|
+
end
|
27
|
+
|
28
|
+
it "should replace the contents of the set" do
|
29
|
+
set = Multiset[:a, :b, :b, :c]
|
30
|
+
ret = set.replace(Multiset[:a, :a, :b, :b, :b, :c])
|
31
|
+
|
32
|
+
set.should equal(ret)
|
33
|
+
set.should eql(Multiset[:a, :a, :b, :b, :b, :c])
|
34
|
+
|
35
|
+
set = Multiset[:a, :b, :b, :c]
|
36
|
+
ret = set.replace([:a, :a, :b, :b, :b, :c])
|
37
|
+
|
38
|
+
set.should equal(ret)
|
39
|
+
set.should eql(Multiset[:a, :a, :b, :b, :b, :c])
|
40
|
+
end
|
41
|
+
|
42
|
+
it "should return true if the set is a superset of the given set" do
|
43
|
+
set = Multiset[1, 2, 2, 3]
|
44
|
+
|
45
|
+
set.superset?(Multiset[]).should be_true
|
46
|
+
set.superset?(Multiset[1, 2]).should be_true
|
47
|
+
set.superset?(Multiset[1, 2, 3]).should be_true
|
48
|
+
set.superset?(Multiset[1, 2, 2, 3]).should be_true
|
49
|
+
set.superset?(Multiset[1, 2, 2, 2]).should be_false
|
50
|
+
set.superset?(Multiset[1, 2, 3, 4]).should be_false
|
51
|
+
set.superset?(Multiset[1, 4]).should be_false
|
52
|
+
end
|
53
|
+
|
54
|
+
it "should return true if the set is a proper superset of the given set" do
|
55
|
+
set = Multiset[1, 2, 2, 3, 3]
|
56
|
+
|
57
|
+
set.proper_superset?(Multiset[]).should be_true
|
58
|
+
set.proper_superset?(Multiset[1, 2]).should be_true
|
59
|
+
set.proper_superset?(Multiset[1, 2, 3]).should be_true
|
60
|
+
set.proper_superset?(Multiset[1, 2, 2, 3, 3]).should be_false
|
61
|
+
set.proper_superset?(Multiset[1, 2, 2, 2]).should be_false
|
62
|
+
set.proper_superset?(Multiset[1, 2, 3, 4]).should be_false
|
63
|
+
set.proper_superset?(Multiset[1, 4]).should be_false
|
64
|
+
end
|
65
|
+
|
66
|
+
it "should return true if the set is a subset of the given set" do
|
67
|
+
set = Multiset[1, 2, 2, 3]
|
68
|
+
|
69
|
+
set.subset?(Multiset[1, 2, 2, 3, 4]).should be_true
|
70
|
+
set.subset?(Multiset[1, 2, 2, 3, 3]).should be_true
|
71
|
+
set.subset?(Multiset[1, 2, 2, 3]).should be_true
|
72
|
+
set.subset?(Multiset[1, 2, 3]).should be_false
|
73
|
+
set.subset?(Multiset[1, 2, 2]).should be_false
|
74
|
+
set.subset?(Multiset[1, 2, 3]).should be_false
|
75
|
+
set.subset?(Multiset[]).should be_false
|
76
|
+
end
|
77
|
+
|
78
|
+
it "should return true if the set is a proper subset of the given set" do
|
79
|
+
set = Multiset[1, 2, 2, 3, 3]
|
80
|
+
|
81
|
+
set.proper_subset?(Multiset[1, 2, 2, 3, 3, 4]).should be_true
|
82
|
+
set.proper_subset?(Multiset[1, 2, 2, 3, 3]).should be_false
|
83
|
+
set.proper_subset?(Multiset[1, 2, 3]).should be_false
|
84
|
+
set.proper_subset?(Multiset[1, 2, 2]).should be_false
|
85
|
+
set.proper_subset?(Multiset[1, 2, 3]).should be_false
|
86
|
+
set.proper_subset?(Multiset[]).should be_false
|
87
|
+
end
|
88
|
+
|
89
|
+
it "should delete the objects from the set and return self" do
|
90
|
+
set = Multiset[1, 2, 2, 3]
|
91
|
+
|
92
|
+
ret = set.delete(4)
|
93
|
+
set.should equal(ret)
|
94
|
+
set.should eql(Multiset[1, 2, 2, 3])
|
95
|
+
|
96
|
+
ret = set.delete(2)
|
97
|
+
set.should eql(ret)
|
98
|
+
set.should eql(Multiset[1, 3])
|
99
|
+
end
|
100
|
+
|
101
|
+
it "should delete the number objects from the set and return self" do
|
102
|
+
set = Multiset[1, 2, 2, 3]
|
103
|
+
|
104
|
+
ret = set.delete(2, 1)
|
105
|
+
set.should eql(ret)
|
106
|
+
set.should eql(Multiset[1, 2, 3])
|
107
|
+
end
|
108
|
+
|
109
|
+
it "should merge the elements of the given enumerable object to the set and return self" do
|
110
|
+
set = Multiset[1, 2, 3]
|
111
|
+
ret = set.merge([2, 4, 5])
|
112
|
+
set.should equal(ret)
|
113
|
+
set.should eql(Multiset[1, 2, 2, 3, 4, 5])
|
114
|
+
|
115
|
+
set = Multiset[1, 2, 3]
|
116
|
+
ret = set.merge(Multiset[2, 4, 5])
|
117
|
+
set.should equal(ret)
|
118
|
+
set.should eql(Multiset[1, 2, 2, 3, 4, 5])
|
119
|
+
end
|
120
|
+
|
121
|
+
it "should delete every element that appears in the given enumerable object and return self" do
|
122
|
+
set = Multiset[1, 2, 2, 3]
|
123
|
+
ret = set.subtract([2, 4, 6])
|
124
|
+
set.should equal(ret)
|
125
|
+
set.should eql(Multiset[1, 2, 3])
|
126
|
+
end
|
127
|
+
|
128
|
+
it "should return a new set containing elements common to the set and the given enumerable object" do
|
129
|
+
set = Multiset[1, 2, 2, 3, 4]
|
130
|
+
|
131
|
+
ret = set & [2, 2, 4, 5]
|
132
|
+
set.should_not equal(ret)
|
133
|
+
ret.should eql(Multiset[2, 2, 4])
|
134
|
+
|
135
|
+
set = Multiset[1, 2, 3]
|
136
|
+
|
137
|
+
ret = set & [1, 2, 2, 2]
|
138
|
+
set.should_not equal(ret)
|
139
|
+
ret.should eql(Multiset[1, 2])
|
140
|
+
end
|
141
|
+
|
142
|
+
it "should return a new set containing elements exclusive between the set and the given enumerable object" do
|
143
|
+
set = Multiset[1, 2, 3, 4, 5]
|
144
|
+
ret = set ^ [2, 4, 5, 5]
|
145
|
+
set.should_not equal(ret)
|
146
|
+
ret.should eql(Multiset[1, 3, 5])
|
147
|
+
|
148
|
+
set = Multiset[1, 2, 4, 5, 5]
|
149
|
+
ret = set ^ [2, 3, 4, 5]
|
150
|
+
set.should_not equal(ret)
|
151
|
+
ret.should eql(Multiset[1, 3, 5])
|
152
|
+
end
|
153
|
+
|
154
|
+
it "should marshal set" do
|
155
|
+
set = Multiset[1, 2, 3, 4, 5]
|
156
|
+
data = Marshal.dump(set)
|
157
|
+
Marshal.load(data).should eql(set)
|
158
|
+
end
|
159
|
+
|
160
|
+
it "should dump yaml" do
|
161
|
+
require 'yaml'
|
162
|
+
|
163
|
+
set = Multiset[1, 2, 3, 4, 5]
|
164
|
+
data = YAML.dump(set)
|
165
|
+
YAML.load(data).should eql(set)
|
166
|
+
end
|
167
|
+
end
|
168
|
+
|
169
|
+
describe Multiset, "with inital values" do
|
170
|
+
it_should_behave_like "Set with inital values [1, 2]"
|
171
|
+
|
172
|
+
before do
|
173
|
+
@set = Multiset.new([1, 2])
|
174
|
+
end
|
175
|
+
|
176
|
+
it "should return the multiplicity of the element" do
|
177
|
+
@set.multiplicity(1).should eql(1)
|
178
|
+
@set.multiplicity(2).should eql(1)
|
179
|
+
end
|
180
|
+
|
181
|
+
it "should return the cardinality of the set" do
|
182
|
+
@set.cardinality.should eql(2)
|
183
|
+
end
|
184
|
+
end
|
@@ -0,0 +1,202 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe NestedMultimap, "with inital values" do
|
4
|
+
it_should_behave_like "Enumerable Multimap with inital values {'a' => [100], 'b' => [200, 300]}"
|
5
|
+
it_should_behave_like "Hash Multimap with inital values {'a' => [100], 'b' => [200, 300]}"
|
6
|
+
|
7
|
+
before do
|
8
|
+
@map = NestedMultimap["a" => [100], "b" => [200, 300]]
|
9
|
+
end
|
10
|
+
|
11
|
+
it "should set value at nested key" do
|
12
|
+
@map["foo", "bar", "baz"] = 100
|
13
|
+
@map["foo", "bar", "baz"].should eql([100])
|
14
|
+
end
|
15
|
+
|
16
|
+
it "should allow nil keys to be set" do
|
17
|
+
@map["b", nil] = 400
|
18
|
+
@map["b", "c"] = 500
|
19
|
+
|
20
|
+
@map["a"].should eql([100])
|
21
|
+
@map["b"].should eql([200, 300])
|
22
|
+
@map["b", nil].should eql([200, 300, 400])
|
23
|
+
@map["b", "c"].should eql([200, 300, 500])
|
24
|
+
end
|
25
|
+
|
26
|
+
it "should treat missing keys as append to all" do
|
27
|
+
@map[] = 400
|
28
|
+
@map["a"].should eql([100, 400])
|
29
|
+
@map["b"].should eql([200, 300, 400])
|
30
|
+
@map["c"].should eql([400])
|
31
|
+
@map[nil].should eql([400])
|
32
|
+
end
|
33
|
+
|
34
|
+
it "should append the value to default containers" do
|
35
|
+
@map << 400
|
36
|
+
@map["a"].should eql([100, 400])
|
37
|
+
@map["b"].should eql([200, 300, 400])
|
38
|
+
@map["c"].should eql([400])
|
39
|
+
@map[nil].should eql([400])
|
40
|
+
end
|
41
|
+
|
42
|
+
it "should append the value to all containers" do
|
43
|
+
@map << 500
|
44
|
+
@map["a"].should eql([100, 500])
|
45
|
+
@map["b"].should eql([200, 300, 500])
|
46
|
+
@map[nil].should eql([500])
|
47
|
+
end
|
48
|
+
|
49
|
+
it "default values should be copied to new containers" do
|
50
|
+
@map << 300
|
51
|
+
@map["x"] = 100
|
52
|
+
@map["x"].should eql([300, 100])
|
53
|
+
end
|
54
|
+
|
55
|
+
it "should list all containers" do
|
56
|
+
@map.containers.should sorted_eql([[100], [200, 300]])
|
57
|
+
end
|
58
|
+
|
59
|
+
it "should list all values" do
|
60
|
+
@map.values.should sorted_eql([100, 200, 300])
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
describe NestedMultimap, "with nested values" do
|
65
|
+
before do
|
66
|
+
@map = NestedMultimap.new
|
67
|
+
@map["a"] = 100
|
68
|
+
@map["b"] = 200
|
69
|
+
@map["b", "c"] = 300
|
70
|
+
@map["c", "e"] = 400
|
71
|
+
@map["c"] = 500
|
72
|
+
end
|
73
|
+
|
74
|
+
it "should retrieve container of values for key" do
|
75
|
+
@map["a"].should eql([100])
|
76
|
+
@map["b"].should eql([200])
|
77
|
+
@map["c"].should eql([500])
|
78
|
+
@map["a", "b"].should eql([100])
|
79
|
+
@map["b", "c"].should eql([200, 300])
|
80
|
+
@map["c", "e"].should eql([400, 500])
|
81
|
+
end
|
82
|
+
|
83
|
+
it "should append the value to default containers" do
|
84
|
+
@map << 600
|
85
|
+
@map["a"].should eql([100, 600])
|
86
|
+
@map["b"].should eql([200, 600])
|
87
|
+
@map["c"].should eql([500, 600])
|
88
|
+
@map["a", "b"].should eql([100, 600])
|
89
|
+
@map["b", "c"].should eql([200, 300, 600])
|
90
|
+
@map["c", "e"].should eql([400, 500, 600])
|
91
|
+
@map[nil].should eql([600])
|
92
|
+
end
|
93
|
+
|
94
|
+
it "should duplicate the containers" do
|
95
|
+
map2 = @map.dup
|
96
|
+
map2.should_not equal(@map)
|
97
|
+
map2.should eql(@map)
|
98
|
+
|
99
|
+
map2["a"].should eql([100])
|
100
|
+
map2["b"].should eql([200])
|
101
|
+
map2["c"].should eql([500])
|
102
|
+
map2["a", "b"].should eql([100])
|
103
|
+
map2["b", "c"].should eql([200, 300])
|
104
|
+
map2["c", "e"].should eql([400, 500])
|
105
|
+
|
106
|
+
map2["a"].should_not equal(@map["a"])
|
107
|
+
map2["b"].should_not equal(@map["b"])
|
108
|
+
map2["c"].should_not equal(@map["c"])
|
109
|
+
map2["a", "b"].should_not equal(@map["a", "b"])
|
110
|
+
map2["b", "c"].should_not equal(@map["b", "c"])
|
111
|
+
map2["c", "e"].should_not equal(@map["c", "e"])
|
112
|
+
|
113
|
+
map2.default.should_not equal(@map.default)
|
114
|
+
map2.default.should eql(@map.default)
|
115
|
+
end
|
116
|
+
|
117
|
+
it "should iterate over each key/value pair and yield an array" do
|
118
|
+
a = []
|
119
|
+
@map.each { |pair| a << pair }
|
120
|
+
a.should sorted_eql([
|
121
|
+
["a", 100],
|
122
|
+
[["b", "c"], 200],
|
123
|
+
[["b", "c"], 300],
|
124
|
+
[["c", "e"], 400],
|
125
|
+
[["c", "e"], 500]
|
126
|
+
])
|
127
|
+
end
|
128
|
+
|
129
|
+
it "should iterate over each key/container" do
|
130
|
+
a = []
|
131
|
+
@map.each_association { |key, container| a << [key, container] }
|
132
|
+
a.should sorted_eql([
|
133
|
+
["a", [100]],
|
134
|
+
[["b", "c"], [200, 300]],
|
135
|
+
[["c", "e"], [400, 500]]
|
136
|
+
])
|
137
|
+
end
|
138
|
+
|
139
|
+
it "should iterate over each container plus the default" do
|
140
|
+
a = []
|
141
|
+
@map.each_container_with_default { |container| a << container }
|
142
|
+
a.should sorted_eql([
|
143
|
+
[100],
|
144
|
+
[200, 300],
|
145
|
+
[200],
|
146
|
+
[400, 500],
|
147
|
+
[500],
|
148
|
+
[]
|
149
|
+
])
|
150
|
+
end
|
151
|
+
|
152
|
+
it "should iterate over each key" do
|
153
|
+
a = []
|
154
|
+
@map.each_key { |key| a << key }
|
155
|
+
a.should sorted_eql(["a", ["b", "c"], ["b", "c"], ["c", "e"], ["c", "e"]])
|
156
|
+
end
|
157
|
+
|
158
|
+
it "should iterate over each key/value pair and yield the pair" do
|
159
|
+
h = {}
|
160
|
+
@map.each_pair { |key, value| (h[key] ||= []) << value }
|
161
|
+
h.should eql({
|
162
|
+
"a" => [100],
|
163
|
+
["c", "e"] => [400, 500],
|
164
|
+
["b", "c"] => [200, 300]
|
165
|
+
})
|
166
|
+
end
|
167
|
+
|
168
|
+
it "should iterate over each value" do
|
169
|
+
a = []
|
170
|
+
@map.each_value { |value| a << value }
|
171
|
+
a.should sorted_eql([100, 200, 300, 400, 500])
|
172
|
+
end
|
173
|
+
|
174
|
+
it "should list all containers" do
|
175
|
+
@map.containers.should sorted_eql([[100], [200, 300], [400, 500]])
|
176
|
+
end
|
177
|
+
|
178
|
+
it "should list all containers plus the default" do
|
179
|
+
@map.containers_with_default.should sorted_eql([[100], [200, 300], [200], [400, 500], [500], []])
|
180
|
+
end
|
181
|
+
|
182
|
+
it "should return array of keys" do
|
183
|
+
@map.keys.should eql(["a", ["b", "c"], ["b", "c"], ["c", "e"], ["c", "e"]])
|
184
|
+
end
|
185
|
+
|
186
|
+
it "should list all values" do
|
187
|
+
@map.values.should sorted_eql([100, 200, 300, 400, 500])
|
188
|
+
end
|
189
|
+
end
|
190
|
+
|
191
|
+
describe NestedMultimap, "with", Set do
|
192
|
+
it_should_behave_like "Enumerable Multimap with inital values {'a' => [100], 'b' => [200, 300]}"
|
193
|
+
it_should_behave_like "Hash Multimap with inital values {'a' => [100], 'b' => [200, 300]}"
|
194
|
+
|
195
|
+
before do
|
196
|
+
@container = Set
|
197
|
+
@map = NestedMultimap.new(@container.new)
|
198
|
+
@map["a"] = 100
|
199
|
+
@map["b"] = 200
|
200
|
+
@map["b"] = 300
|
201
|
+
end
|
202
|
+
end
|
@@ -0,0 +1,301 @@
|
|
1
|
+
shared_examples_for Set do
|
2
|
+
it "should create a new set containing the given objects" do
|
3
|
+
Multiset[]
|
4
|
+
Multiset[nil]
|
5
|
+
Multiset[1, 2, 3]
|
6
|
+
|
7
|
+
Multiset[].size.should eql(0)
|
8
|
+
Multiset[nil].size.should eql(1)
|
9
|
+
Multiset[[]].size.should eql(1)
|
10
|
+
Multiset[[nil]].size.should eql(1)
|
11
|
+
|
12
|
+
set = Multiset[2, 4, 6, 4]
|
13
|
+
Multiset.new([2, 4, 6]).should_not eql(set)
|
14
|
+
|
15
|
+
set = Multiset[2, 4, 6, 4]
|
16
|
+
Multiset.new([2, 4, 6, 4]).should eql(set)
|
17
|
+
end
|
18
|
+
|
19
|
+
it "should create a new set containing the elements of the given enumerable object" do
|
20
|
+
Multiset.new()
|
21
|
+
Multiset.new(nil)
|
22
|
+
Multiset.new([])
|
23
|
+
Multiset.new([1, 2])
|
24
|
+
Multiset.new('a'..'c')
|
25
|
+
|
26
|
+
lambda { Multiset.new(false) }.should raise_error
|
27
|
+
lambda { Multiset.new(1) }.should raise_error
|
28
|
+
lambda { Multiset.new(1, 2) }.should raise_error
|
29
|
+
|
30
|
+
Multiset.new().size.should eql(0)
|
31
|
+
Multiset.new(nil).size.should eql(0)
|
32
|
+
Multiset.new([]).size.should eql(0)
|
33
|
+
Multiset.new([nil]).size.should eql(1)
|
34
|
+
|
35
|
+
ary = [2, 4, 6, 4]
|
36
|
+
set = Multiset.new(ary)
|
37
|
+
ary.clear
|
38
|
+
set.should_not be_empty
|
39
|
+
set.size.should eql(4)
|
40
|
+
|
41
|
+
ary = [1, 2, 3]
|
42
|
+
|
43
|
+
s = Multiset.new(ary) { |o| o * 2 }
|
44
|
+
[2, 4, 6].should eql(s.sort)
|
45
|
+
end
|
46
|
+
|
47
|
+
it "should duplicate set" do
|
48
|
+
set1 = Multiset[1, 2]
|
49
|
+
set2 = set1.dup
|
50
|
+
|
51
|
+
set1.should_not equal(set2)
|
52
|
+
|
53
|
+
set1.should eql(set2)
|
54
|
+
|
55
|
+
set1.add(3)
|
56
|
+
|
57
|
+
set1.should_not eql(set2)
|
58
|
+
end
|
59
|
+
|
60
|
+
it "should return the number of elements" do
|
61
|
+
Multiset[].size.should eql(0)
|
62
|
+
Multiset[1, 2].size.should eql(2)
|
63
|
+
Multiset[1, 2, 1].size.should eql(3)
|
64
|
+
end
|
65
|
+
|
66
|
+
it "should return true if the set contains no elements" do
|
67
|
+
Multiset[].should be_empty
|
68
|
+
Multiset[1, 2].should_not be_empty
|
69
|
+
end
|
70
|
+
|
71
|
+
it "should remove all elements and returns self" do
|
72
|
+
set = Multiset[1, 2]
|
73
|
+
ret = set.clear
|
74
|
+
|
75
|
+
set.should equal(ret)
|
76
|
+
set.should be_empty
|
77
|
+
end
|
78
|
+
|
79
|
+
it "should replaces the contents of the set with the contents of the given enumerable object and returns self" do
|
80
|
+
set = Multiset[1, 2]
|
81
|
+
ret = set.replace('a'..'c')
|
82
|
+
|
83
|
+
set.should equal(ret)
|
84
|
+
set.should eql(Multiset['a', 'b', 'c'])
|
85
|
+
end
|
86
|
+
|
87
|
+
it "should convert the set to an array" do
|
88
|
+
set = Multiset[1, 2, 3, 2]
|
89
|
+
ary = set.to_a
|
90
|
+
|
91
|
+
ary.sort.should eql([1, 2, 2, 3])
|
92
|
+
end
|
93
|
+
|
94
|
+
it "should return true if the set contains the given object" do
|
95
|
+
set = Multiset[1, 2, 3]
|
96
|
+
|
97
|
+
set.include?(1).should be_true
|
98
|
+
set.include?(2).should be_true
|
99
|
+
set.include?(3).should be_true
|
100
|
+
set.include?(0).should be_false
|
101
|
+
set.include?(nil).should be_false
|
102
|
+
|
103
|
+
set = Multiset["1", nil, "2", nil, "0", "1", false]
|
104
|
+
set.include?(nil).should be_true
|
105
|
+
set.include?(false).should be_true
|
106
|
+
set.include?("1").should be_true
|
107
|
+
set.include?(0).should be_false
|
108
|
+
set.include?(true).should be_false
|
109
|
+
end
|
110
|
+
|
111
|
+
it "should return true if the set is a superset of the given set" do
|
112
|
+
set = Multiset[1, 2, 3]
|
113
|
+
|
114
|
+
lambda { set.superset?() }.should raise_error
|
115
|
+
lambda { set.superset?(2) }.should raise_error
|
116
|
+
lambda { set.superset?([2]) }.should raise_error
|
117
|
+
|
118
|
+
set.superset?(Multiset[]).should be_true
|
119
|
+
set.superset?(Multiset[1, 2]).should be_true
|
120
|
+
set.superset?(Multiset[1, 2, 3]).should be_true
|
121
|
+
set.superset?(Multiset[1, 2, 3, 4]).should be_false
|
122
|
+
set.superset?(Multiset[1, 4]).should be_false
|
123
|
+
|
124
|
+
Multiset[].superset?(Multiset[]).should be_true
|
125
|
+
end
|
126
|
+
|
127
|
+
it "should return true if the set is a proper superset of the given set" do
|
128
|
+
set = Multiset[1, 2, 3]
|
129
|
+
|
130
|
+
lambda { set.proper_superset?() }.should raise_error
|
131
|
+
lambda { set.proper_superset?(2) }.should raise_error
|
132
|
+
lambda { set.proper_superset?([2]) }.should raise_error
|
133
|
+
|
134
|
+
set.proper_superset?(Multiset[]).should be_true
|
135
|
+
set.proper_superset?(Multiset[1, 2]).should be_true
|
136
|
+
set.proper_superset?(Multiset[1, 2, 3]).should be_false
|
137
|
+
set.proper_superset?(Multiset[1, 2, 3, 4]).should be_false
|
138
|
+
set.proper_superset?(Multiset[1, 4]).should be_false
|
139
|
+
|
140
|
+
Multiset[].proper_superset?(Multiset[]).should be_false
|
141
|
+
end
|
142
|
+
|
143
|
+
it "should return true if the set is a subset of the given set" do
|
144
|
+
set = Multiset[1, 2, 3]
|
145
|
+
|
146
|
+
lambda { set.subset?() }.should raise_error
|
147
|
+
lambda { set.subset?(2) }.should raise_error
|
148
|
+
lambda { set.subset?([2]) }.should raise_error
|
149
|
+
|
150
|
+
set.subset?(Multiset[1, 2, 3, 4]).should be_true
|
151
|
+
set.subset?(Multiset[1, 2, 3]).should be_true
|
152
|
+
set.subset?(Multiset[1, 2]).should be_false
|
153
|
+
set.subset?(Multiset[]).should be_false
|
154
|
+
|
155
|
+
Multiset[].subset?(Multiset[1]).should be_true
|
156
|
+
Multiset[].subset?(Multiset[]).should be_true
|
157
|
+
end
|
158
|
+
|
159
|
+
it "should return true if the set is a proper subset of the given set" do
|
160
|
+
set = Multiset[1, 2, 3]
|
161
|
+
|
162
|
+
lambda { set.proper_subset?() }.should raise_error
|
163
|
+
lambda { set.proper_subset?(2) }.should raise_error
|
164
|
+
lambda { set.proper_subset?([2]) }.should raise_error
|
165
|
+
|
166
|
+
set.proper_subset?(Multiset[1, 2, 3, 4]).should be_true
|
167
|
+
set.proper_subset?(Multiset[1, 2, 3]).should be_false
|
168
|
+
set.proper_subset?(Multiset[1, 2]).should be_false
|
169
|
+
set.proper_subset?(Multiset[]).should be_false
|
170
|
+
|
171
|
+
Multiset[].proper_subset?(Multiset[]).should be_false
|
172
|
+
end
|
173
|
+
|
174
|
+
it "should add the given object to the set and return self" do
|
175
|
+
set = Multiset[1, 2, 3]
|
176
|
+
|
177
|
+
ret = set.add(2)
|
178
|
+
set.should equal(ret)
|
179
|
+
set.should eql(Multiset[1, 2, 2, 3])
|
180
|
+
|
181
|
+
ret = set.add(4)
|
182
|
+
set.should equal(ret)
|
183
|
+
set.should eql(Multiset[1, 2, 2, 3, 4])
|
184
|
+
end
|
185
|
+
|
186
|
+
it "should delete the given object from the set and return self" do
|
187
|
+
set = Multiset[1, 2, 3]
|
188
|
+
|
189
|
+
ret = set.delete(4)
|
190
|
+
set.should equal(ret)
|
191
|
+
set.should eql(Multiset[1, 2, 3])
|
192
|
+
|
193
|
+
ret = set.delete(2)
|
194
|
+
set.should eql(ret)
|
195
|
+
set.should eql(Multiset[1, 3])
|
196
|
+
end
|
197
|
+
|
198
|
+
it "should delete every element of the set for which block evaluates to true, and return self" do
|
199
|
+
set = Multiset.new(1..10)
|
200
|
+
ret = set.delete_if { |i| i > 10 }
|
201
|
+
set.should equal(ret)
|
202
|
+
set.should eql(Multiset.new(1..10))
|
203
|
+
|
204
|
+
set = Multiset.new(1..10)
|
205
|
+
ret = set.delete_if { |i| i % 3 == 0 }
|
206
|
+
set.should equal(ret)
|
207
|
+
set.should eql(Multiset[1, 2, 4, 5, 7, 8, 10])
|
208
|
+
end
|
209
|
+
|
210
|
+
it "should deletes every element of the set for which block evaluates to true but return nil if no changes were made" do
|
211
|
+
set = Multiset.new(1..10)
|
212
|
+
|
213
|
+
ret = set.reject! { |i| i > 10 }
|
214
|
+
ret.should be_nil
|
215
|
+
set.should eql(Multiset.new(1..10))
|
216
|
+
|
217
|
+
ret = set.reject! { |i| i % 3 == 0 }
|
218
|
+
set.should equal(ret)
|
219
|
+
set.should eql(Multiset[1, 2, 4, 5, 7, 8, 10])
|
220
|
+
end
|
221
|
+
|
222
|
+
it "should merge the elements of the given enumerable object to the set and return self" do
|
223
|
+
set = Multiset[1, 2, 3]
|
224
|
+
|
225
|
+
ret = set.merge([2, 4, 6])
|
226
|
+
set.should equal(ret)
|
227
|
+
set.should eql(Multiset[1, 2, 2, 3, 4, 6])
|
228
|
+
end
|
229
|
+
|
230
|
+
it "should delete every element that appears in the given enumerable object and return self" do
|
231
|
+
set = Multiset[1, 2, 3]
|
232
|
+
|
233
|
+
ret = set.subtract([2, 4, 6])
|
234
|
+
set.should equal(ret)
|
235
|
+
set.should eql(Multiset[1, 3])
|
236
|
+
end
|
237
|
+
|
238
|
+
it "should return a new set built by merging the set and the elements of the given enumerable object" do
|
239
|
+
set = Multiset[1, 2, 3]
|
240
|
+
|
241
|
+
ret = set + [2, 4, 6]
|
242
|
+
set.should_not equal(ret)
|
243
|
+
ret.should eql(Multiset[1, 2, 2, 3, 4, 6])
|
244
|
+
end
|
245
|
+
|
246
|
+
it "should return a new set built by duplicating the set, removing every element that appears in the given enumerable object" do
|
247
|
+
set = Multiset[1, 2, 3]
|
248
|
+
|
249
|
+
ret = set - [2, 4, 6]
|
250
|
+
set.should_not equal(ret)
|
251
|
+
ret.should eql(Multiset[1, 3])
|
252
|
+
end
|
253
|
+
|
254
|
+
it "should return a new set containing elements common to the set and the given enumerable object" do
|
255
|
+
set = Multiset[1, 2, 3, 4]
|
256
|
+
|
257
|
+
ret = set & [2, 4, 6]
|
258
|
+
set.should_not equal(ret)
|
259
|
+
ret.should eql(Multiset[2, 4])
|
260
|
+
end
|
261
|
+
|
262
|
+
it "should return a new set containing elements exclusive between the set and the given enumerable object" do
|
263
|
+
set = Multiset[1, 2, 3, 4]
|
264
|
+
ret = set ^ [2, 4, 5]
|
265
|
+
set.should_not equal(ret)
|
266
|
+
ret.should eql(Multiset[1, 3, 5])
|
267
|
+
end
|
268
|
+
end
|
269
|
+
|
270
|
+
shared_examples_for Set, "with inital values [1, 2]" do
|
271
|
+
it "should add element to set" do
|
272
|
+
@set.add("foo")
|
273
|
+
|
274
|
+
@set.include?(1).should be_true
|
275
|
+
@set.include?(2).should be_true
|
276
|
+
@set.include?("foo").should be_true
|
277
|
+
end
|
278
|
+
|
279
|
+
it "should merge elements into the set" do
|
280
|
+
@set.merge([2, 6])
|
281
|
+
|
282
|
+
@set.include?(1).should be_true
|
283
|
+
@set.include?(2).should be_true
|
284
|
+
@set.include?(2).should be_true
|
285
|
+
@set.include?(6).should be_true
|
286
|
+
end
|
287
|
+
|
288
|
+
it "should iterate over all the values in the set" do
|
289
|
+
a = []
|
290
|
+
@set.each { |o| a << o }
|
291
|
+
a.should eql([1, 2])
|
292
|
+
end
|
293
|
+
|
294
|
+
it "should convert to an array" do
|
295
|
+
@set.to_a.should eql([1, 2])
|
296
|
+
end
|
297
|
+
|
298
|
+
it "should convert to a set" do
|
299
|
+
@set.to_set.to_a.should eql([1, 2])
|
300
|
+
end
|
301
|
+
end
|