mailgun 0.7 → 0.8
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.
- 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
|