diametric 0.1.1 → 0.1.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +8 -8
- data/README.md +627 -179
- data/ext/diametric/DiametricCollection.java +696 -66
- data/ext/diametric/DiametricCommon.java +165 -0
- data/ext/diametric/DiametricDatabase.java +10 -3
- data/ext/diametric/DiametricPeer.java +12 -4
- data/ext/diametric/DiametricService.java +35 -2
- data/ext/diametric/DiametricSet.java +270 -0
- data/ext/diametric/DiametricUtils.java +52 -10
- data/lib/diametric/entity.rb +7 -5
- data/lib/diametric/persistence/common.rb +3 -3
- data/lib/diametric/persistence/peer.rb +3 -12
- data/lib/diametric/persistence/rest.rb +1 -1
- data/lib/diametric/query.rb +26 -14
- data/lib/diametric/version.rb +1 -1
- data/lib/diametric_service.jar +0 -0
- data/spec/developer_query_spec.rb +3 -3
- data/spec/diametric/peer_api_spec.rb +425 -8
- data/spec/diametric/persistence/peer_many2many_spec.rb +10 -9
- data/spec/parent_child_sample.rb +21 -16
- data/spec/peer_integration_spec.rb +43 -9
- data/spec/support/entities.rb +2 -0
- metadata +4 -2
@@ -1,6 +1,5 @@
|
|
1
1
|
package diametric;
|
2
2
|
|
3
|
-
import java.io.FileNotFoundException;
|
4
3
|
import java.io.FileReader;
|
5
4
|
import java.io.IOException;
|
6
5
|
import java.io.Reader;
|
@@ -8,8 +7,10 @@ import java.util.ArrayList;
|
|
8
7
|
import java.util.Collections;
|
9
8
|
import java.util.Date;
|
10
9
|
import java.util.HashMap;
|
10
|
+
import java.util.HashSet;
|
11
11
|
import java.util.List;
|
12
12
|
import java.util.Map;
|
13
|
+
import java.util.Set;
|
13
14
|
import java.util.UUID;
|
14
15
|
|
15
16
|
import org.jruby.Ruby;
|
@@ -30,6 +31,11 @@ import org.jruby.javasupport.util.RuntimeHelpers;
|
|
30
31
|
import org.jruby.runtime.ThreadContext;
|
31
32
|
import org.jruby.runtime.builtin.IRubyObject;
|
32
33
|
|
34
|
+
import clojure.lang.APersistentVector;
|
35
|
+
import clojure.lang.IPersistentSet;
|
36
|
+
import clojure.lang.LazySeq;
|
37
|
+
import clojure.lang.PersistentHashSet;
|
38
|
+
import clojure.lang.PersistentVector;
|
33
39
|
import datomic.Util;
|
34
40
|
|
35
41
|
@JRubyModule(name="Diametric::Persistence::Utils")
|
@@ -71,6 +77,7 @@ public class DiametricUtils {
|
|
71
77
|
}
|
72
78
|
|
73
79
|
static Object convertRubyToJava(ThreadContext context, IRubyObject value) {
|
80
|
+
if (value instanceof RubyNil) return null;
|
74
81
|
if (value instanceof RubyString) {
|
75
82
|
String str = (String)((RubyString)value).toJava(String.class);
|
76
83
|
try {
|
@@ -97,26 +104,39 @@ public class DiametricUtils {
|
|
97
104
|
RubyTime tmvalue = (RubyTime)RuntimeHelpers.invoke(context, value, "to_time");
|
98
105
|
return (Object)tmvalue.getJavaDate();
|
99
106
|
}
|
107
|
+
// needs to check Set since Set responses to "to_a"
|
108
|
+
if (value.respondsTo("intersection")) {
|
109
|
+
return getPersistentSet(context, value);
|
110
|
+
}
|
100
111
|
//System.out.println("NOT YET CONVERTED");
|
101
112
|
//System.out.println("RESPONDSTO? TO_A:" + value.respondsTo("to_a"));
|
102
113
|
if (value.respondsTo("to_a")) { // might be Set for cardinality many type
|
103
|
-
|
104
|
-
List<Object> list = new ArrayList<Object>();
|
105
|
-
while (true) {
|
106
|
-
IRubyObject element = ruby_array.shift(context);
|
107
|
-
if (element.isNil()) break;
|
108
|
-
list.add(DiametricUtils.convertRubyToJava(context, element));
|
109
|
-
}
|
110
|
-
return Collections.unmodifiableList(list);
|
114
|
+
return getList(context, value);
|
111
115
|
}
|
112
116
|
if (value instanceof DiametricObject) {
|
113
117
|
return ((DiametricObject)value).toJava();
|
114
118
|
}
|
115
119
|
return (Object)value.toJava(Object.class);
|
116
120
|
}
|
117
|
-
|
121
|
+
|
122
|
+
static IPersistentSet getPersistentSet(ThreadContext context, IRubyObject value) {
|
123
|
+
return PersistentHashSet.create((List)value.callMethod(context, "to_a"));
|
124
|
+
}
|
125
|
+
|
126
|
+
static List<Object> getList(ThreadContext context, IRubyObject value) {
|
127
|
+
RubyArray ruby_array = (RubyArray)RuntimeHelpers.invoke(context, value, "to_a");
|
128
|
+
List<Object> list = new ArrayList<Object>();
|
129
|
+
while (true) {
|
130
|
+
IRubyObject element = ruby_array.shift(context);
|
131
|
+
if (element.isNil()) break;
|
132
|
+
list.add(DiametricUtils.convertRubyToJava(context, element));
|
133
|
+
}
|
134
|
+
return Collections.unmodifiableList(list);
|
135
|
+
}
|
136
|
+
|
118
137
|
static IRubyObject convertJavaToRuby(ThreadContext context, Object value) {
|
119
138
|
Ruby runtime = context.getRuntime();
|
139
|
+
if (value == null) return context.getRuntime().getNil();
|
120
140
|
if (value instanceof String) return RubyString.newString(runtime, (String)value);
|
121
141
|
if (value instanceof Boolean) return RubyBoolean.newBoolean(runtime, (Boolean)value);
|
122
142
|
if (value instanceof Long) return RubyFixnum.newFixnum(runtime, (Long)value);
|
@@ -126,6 +146,14 @@ public class DiametricUtils {
|
|
126
146
|
if (value instanceof java.math.BigInteger) return RubyBignum.newBignum(runtime, ((java.math.BigInteger)value).longValue());
|
127
147
|
if (value instanceof Double) return RubyFloat.newFloat(runtime, (Double)value);
|
128
148
|
if (value instanceof Date) return RubyTime.newTime(runtime, ((Date)value).getTime());
|
149
|
+
if (value instanceof Set) {
|
150
|
+
return getDiametricSet(context, (Set)value);
|
151
|
+
}
|
152
|
+
if ((value instanceof APersistentVector) ||
|
153
|
+
(value instanceof LazySeq) ||
|
154
|
+
(value instanceof PersistentVector.ChunkedSeq)){
|
155
|
+
return getDiametricCollection(context, (List)value);
|
156
|
+
}
|
129
157
|
if (value instanceof java.util.UUID) {
|
130
158
|
RubyClass clazz = (RubyClass)context.getRuntime().getClassFromPath("Diametric::Persistence::UUID");
|
131
159
|
DiametricUUID diametric_uuid = (DiametricUUID)clazz.allocate();
|
@@ -135,6 +163,20 @@ public class DiametricUtils {
|
|
135
163
|
return JavaUtil.convertJavaToUsableRubyObject(runtime, value);
|
136
164
|
}
|
137
165
|
|
166
|
+
static IRubyObject getDiametricSet(ThreadContext context, Set value) {
|
167
|
+
RubyClass clazz = (RubyClass)context.getRuntime().getClassFromPath("Diametric::Persistence::Set");
|
168
|
+
DiametricSet diametric_set = (DiametricSet)clazz.allocate();
|
169
|
+
diametric_set.init(value);
|
170
|
+
return diametric_set;
|
171
|
+
}
|
172
|
+
|
173
|
+
static IRubyObject getDiametricCollection(ThreadContext context, List value) {
|
174
|
+
RubyClass clazz = (RubyClass)context.getRuntime().getClassFromPath("Diametric::Persistence::Collection");
|
175
|
+
DiametricCollection diametric_collection = (DiametricCollection)clazz.allocate();
|
176
|
+
diametric_collection.init((List)value);
|
177
|
+
return diametric_collection;
|
178
|
+
}
|
179
|
+
|
138
180
|
static List<Object> convertRubyTxDataToJava(ThreadContext context, IRubyObject arg) {
|
139
181
|
List<Object> tx_data = null;
|
140
182
|
if (arg instanceof RubyArray) {
|
data/lib/diametric/entity.rb
CHANGED
@@ -317,12 +317,12 @@ module Diametric
|
|
317
317
|
if parent.class.attributes[e][:value_type] == "ref"
|
318
318
|
ref = parent.instance_variable_get("@#{e.to_s}")
|
319
319
|
if ref.is_a?(Fixnum) || ref.is_a?(Java::DatomicQuery::EntityMap)
|
320
|
-
child =
|
320
|
+
child = reify(ref, connection)
|
321
321
|
child = resolve_ref_dbid(child, connection)
|
322
322
|
parent.instance_variable_set("@#{e.to_s}", child)
|
323
323
|
elsif ref.is_a?(Set)
|
324
324
|
children = ref.inject(Set.new) do |memo, entity|
|
325
|
-
child =
|
325
|
+
child = reify(entity, connection)
|
326
326
|
memo.add(child)
|
327
327
|
memo
|
328
328
|
end
|
@@ -333,7 +333,7 @@ module Diametric
|
|
333
333
|
parent
|
334
334
|
end
|
335
335
|
|
336
|
-
def
|
336
|
+
def reify(thing, conn_or_db=nil, resolve=false)
|
337
337
|
conn_or_db ||= Diametric::Persistence::Peer.connect.db
|
338
338
|
|
339
339
|
if conn_or_db.respond_to?(:db)
|
@@ -350,6 +350,8 @@ module Diametric
|
|
350
350
|
else
|
351
351
|
entity = conn_or_db.entity(dbid)
|
352
352
|
end
|
353
|
+
elsif thing.kind_of? java.lang.Long
|
354
|
+
entity = conn_or_db.entity(Diametric::Persistence::Object.new(thing))
|
353
355
|
elsif thing.respond_to?(:to_java)
|
354
356
|
dbid = thing.to_java
|
355
357
|
entity = conn_or_db.entity(dbid)
|
@@ -365,7 +367,7 @@ module Diametric
|
|
365
367
|
match_data = /:([a-zA-Z0-9_]+)\/([a-zA-Z0-9_]+)/.match(key)
|
366
368
|
instance.send("#{match_data[2]}=", entity[key])
|
367
369
|
end
|
368
|
-
instance.send("dbid=", Diametric::Persistence::Object.new(
|
370
|
+
instance.send("dbid=", Diametric::Persistence::Object.new(entity.get("db/id")))
|
369
371
|
|
370
372
|
if resolve
|
371
373
|
instance = resolve_ref_dbid(instance, conn_or_db)
|
@@ -378,7 +380,7 @@ module Diametric
|
|
378
380
|
if self.instance_variable_get("@peer")
|
379
381
|
connection ||= Diametric::Persistence::Peer.connect
|
380
382
|
end
|
381
|
-
|
383
|
+
reify(id, connection)
|
382
384
|
end
|
383
385
|
|
384
386
|
# Returns the prefix for this model used in Datomic. Can be
|
@@ -45,21 +45,21 @@ module Diametric
|
|
45
45
|
end
|
46
46
|
end
|
47
47
|
|
48
|
-
def all(connection=nil, resolve=
|
48
|
+
def all(connection=nil, resolve=true)
|
49
49
|
if self.instance_variable_get("@peer")
|
50
50
|
connection ||= Diametric::Persistence::Peer.connect
|
51
51
|
end
|
52
52
|
Diametric::Query.new(self, connection, resolve).all
|
53
53
|
end
|
54
54
|
|
55
|
-
def first(conditions = {}, connection=nil, resolve=
|
55
|
+
def first(conditions = {}, connection=nil, resolve=true)
|
56
56
|
if self.instance_variable_get("@peer")
|
57
57
|
connection ||= Diametric::Persistence::Peer.connect
|
58
58
|
end
|
59
59
|
where(conditions, connection, resolve).first
|
60
60
|
end
|
61
61
|
|
62
|
-
def where(conditions = {}, connection=nil, resolve=
|
62
|
+
def where(conditions = {}, connection=nil, resolve=true)
|
63
63
|
if self.instance_variable_get("@peer")
|
64
64
|
connection ||= Diametric::Persistence::Peer.connect
|
65
65
|
end
|
@@ -102,7 +102,6 @@ module Diametric
|
|
102
102
|
child.instance_variable_set("@previously_changed", child.changes)
|
103
103
|
child.changed_attributes.clear
|
104
104
|
child.dbid = resolve_tempid(map, child.dbid)
|
105
|
-
child.instance_variable_set("@tx_map", map)
|
106
105
|
end
|
107
106
|
resolve_changes(queue, map) unless queue.empty?
|
108
107
|
end
|
@@ -116,7 +115,7 @@ module Diametric
|
|
116
115
|
if result
|
117
116
|
query_string = ":#{result[1]}/_#{result[2]}"
|
118
117
|
entities = Diametric::Persistence::Peer.reverse_q(args[0].db, self.dbid, query_string)
|
119
|
-
entities.collect {|e| self.class.
|
118
|
+
entities.collect {|e| self.class.reify(e, args[0])}
|
120
119
|
else
|
121
120
|
super
|
122
121
|
end
|
@@ -127,7 +126,7 @@ module Diametric
|
|
127
126
|
entity = self.new
|
128
127
|
dbid = dbid.to_i if dbid.is_a?(String)
|
129
128
|
connection ||= Diametric::Persistence::Peer.connect
|
130
|
-
entity = self.
|
129
|
+
entity = self.reify(dbid, connection, resolve)
|
131
130
|
entity
|
132
131
|
end
|
133
132
|
|
@@ -138,15 +137,7 @@ module Diametric
|
|
138
137
|
else
|
139
138
|
db = conn_or_db
|
140
139
|
end
|
141
|
-
|
142
|
-
results = Diametric::Persistence::Peer.q(query, db, args)
|
143
|
-
# Diametric query expects the first element of each array in
|
144
|
-
# results is dbid. Wraps dbid here by
|
145
|
-
# Diametric::Persistence::Object to make it consistent
|
146
|
-
results.each do |r|
|
147
|
-
r[0] = Diametric::Persistence::Object.new(r[0])
|
148
|
-
end
|
149
|
-
results
|
140
|
+
Diametric::Persistence::Peer.q(query, db, args)
|
150
141
|
end
|
151
142
|
end
|
152
143
|
end
|
data/lib/diametric/query.rb
CHANGED
@@ -81,23 +81,22 @@ module Diametric
|
|
81
81
|
filter = filter.map { |e| convert_filter_element(e) }
|
82
82
|
filter = EDN::Type::List.new(*filter)
|
83
83
|
end
|
84
|
-
|
85
84
|
query.filters += [[filter]]
|
86
85
|
query
|
87
86
|
end
|
88
87
|
|
89
88
|
def peer_filter(*filter)
|
90
89
|
query = self.dup
|
91
|
-
|
92
90
|
if filter.first.is_a?(Array)
|
93
91
|
filter = filter.first
|
94
92
|
end
|
95
93
|
filter_attrs << filter[1].to_s
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
94
|
+
query_filter = []
|
95
|
+
query_filter << filter[0].to_s
|
96
|
+
query_filter << "?#{filter[1].to_s}"
|
97
|
+
query_filter << filter[2..-1]
|
98
|
+
query_filter = query_filter.flatten
|
99
|
+
query.filters += [query_filter]
|
101
100
|
query
|
102
101
|
end
|
103
102
|
|
@@ -113,9 +112,9 @@ module Diametric
|
|
113
112
|
res = model.q(*data, @conn_or_db)
|
114
113
|
collapse_results(res).each do |entity|
|
115
114
|
if self.model.instance_variable_get("@peer") && @resolve
|
116
|
-
yield model.
|
115
|
+
yield model.reify(entity.first, @conn_or_db, @resolve)
|
117
116
|
elsif self.model.instance_variable_get("@peer")
|
118
|
-
yield entity
|
117
|
+
yield entity
|
119
118
|
# The map is for compatibility with Java peer persistence.
|
120
119
|
# TODO remove if possible
|
121
120
|
else
|
@@ -127,8 +126,13 @@ module Diametric
|
|
127
126
|
# Return all query results.
|
128
127
|
#
|
129
128
|
# @return [Array<Entity>] Query results.
|
130
|
-
|
131
|
-
|
129
|
+
# or Set([Array<dbid>]) for Peer without resolve option
|
130
|
+
def all(conn_or_db=@conn_or_db)
|
131
|
+
if self.model.instance_variable_get("@peer") && !@resolve
|
132
|
+
model.q(*data, conn_or_db)
|
133
|
+
else
|
134
|
+
map { |x| x }
|
135
|
+
end
|
132
136
|
end
|
133
137
|
|
134
138
|
# Create a Datomic query from the conditions and filters passed to this
|
@@ -177,7 +181,7 @@ EOQ
|
|
177
181
|
clauses = conditions.keys.inject("") do |memo, attribute|
|
178
182
|
memo + "[?e " + model.namespace(model.prefix, attribute) + " ?#{attribute} ] "
|
179
183
|
end
|
180
|
-
from = conditions.inject("
|
184
|
+
from = conditions.inject("") {|memo, kv| memo + "?#{kv.shift} "}
|
181
185
|
args = conditions.map { |_, v| v }
|
182
186
|
end
|
183
187
|
|
@@ -186,8 +190,16 @@ EOQ
|
|
186
190
|
clauses = filter_attrs.inject(clauses) do |memo, attribute|
|
187
191
|
memo + "[?e " + model.namespace(model.prefix, attribute) + " ?#{attribute} ] "
|
188
192
|
end
|
193
|
+
from ||= ""
|
194
|
+
from = filter_attrs.inject(from) {|from, attr| from + "?#{attr}_value "}
|
195
|
+
filter_query =
|
196
|
+
"[" +
|
197
|
+
filters.inject("") {|memo, filter| memo + "(#{filter[0]} #{filter[1]} #{filter[1]}_value) "} +
|
198
|
+
"]"
|
199
|
+
args ||= []
|
200
|
+
args = filters.inject(args) {|args, filter| args + filter[2..-1]}
|
189
201
|
end
|
190
|
-
query = "[:find ?e :in $ #{from} :where #{clauses} #{
|
202
|
+
query = "[:find ?e :in $ [#{from}] :where #{clauses} #{filter_query}]"
|
191
203
|
end
|
192
204
|
|
193
205
|
[query, args]
|
@@ -216,7 +228,7 @@ EOQ
|
|
216
228
|
end
|
217
229
|
|
218
230
|
def collapse_results(res)
|
219
|
-
return res
|
231
|
+
return res if self.model.instance_variable_get("@peer")
|
220
232
|
|
221
233
|
res.group_by(&:first).map do |dbid, results|
|
222
234
|
# extract dbid from results
|
data/lib/diametric/version.rb
CHANGED
data/lib/diametric_service.jar
CHANGED
Binary file
|
@@ -55,7 +55,7 @@ describe Developer, :jruby => true do
|
|
55
55
|
result = query.all
|
56
56
|
result.size.should == 1
|
57
57
|
|
58
|
-
developer = Developer.
|
58
|
+
developer = Developer.reify(result.first.first, @conn.db, false)
|
59
59
|
friends = developer.friends
|
60
60
|
friends.each do |f|
|
61
61
|
f.should be_a(Java::DatomicQuery::EntityMap)
|
@@ -77,7 +77,7 @@ describe Developer, :jruby => true do
|
|
77
77
|
query = Diametric::Query.new(Developer, @conn)
|
78
78
|
result = query.all
|
79
79
|
result.size.should == 3
|
80
|
-
resolved_result = result.map {|m| Developer.
|
80
|
+
resolved_result = result.map {|m| Developer.reify(m.first, @conn)}
|
81
81
|
resolved_result.collect(&:nerd_rate).should =~ [50, 98, 80]
|
82
82
|
end
|
83
83
|
|
@@ -94,7 +94,7 @@ describe Developer, :jruby => true do
|
|
94
94
|
ryan.save(@conn)
|
95
95
|
|
96
96
|
query = Diametric::Query.new(Developer, @conn).filter(:>, :nerd_rate, 70)
|
97
|
-
query_data = "[:find ?e :in $ :where [?e :developer/nerd_rate ?nerd_rate] [(> ?nerd_rate
|
97
|
+
query_data = "[:find ?e :in $ [?nerd_rate_value] :where [?e :developer/nerd_rate ?nerd_rate] [(> ?nerd_rate ?nerd_rate_value)]]"
|
98
98
|
query.data.first.gsub(" ", "").should == query_data.gsub(" ", "")
|
99
99
|
result = query.all
|
100
100
|
result.size.should == 2
|
@@ -99,7 +99,7 @@ if is_jruby?
|
|
99
99
|
|
100
100
|
it 'should get ids from datomic' do
|
101
101
|
results = Diametric::Persistence::Peer.q("[:find ?c :where [?c :person/name]]", @connection.db)
|
102
|
-
results.class.should ==
|
102
|
+
results.class.should == Diametric::Persistence::Set
|
103
103
|
results.size.should be >= 3
|
104
104
|
#puts results.inspect
|
105
105
|
end
|
@@ -107,23 +107,21 @@ if is_jruby?
|
|
107
107
|
it 'should get names from datomic' do
|
108
108
|
results = Diametric::Persistence::Peer.q("[:find ?c ?name :where [?c :person/name ?name]]\
|
109
109
|
", @connection.db)
|
110
|
-
results.
|
111
|
-
results.
|
112
|
-
results.flatten.should include("Chris")
|
113
|
-
#puts results.inspect
|
110
|
+
results.collect { |r| r[1] }.should =~ ["Alice", "Bob", "Chris"]
|
111
|
+
results.collect { |r| r if r.include?("Alice") }.compact.size.should == 1
|
114
112
|
end
|
115
113
|
|
116
114
|
it 'should get entity by id' do
|
117
115
|
results = Diametric::Persistence::Peer.q("[:find ?c :where [?c :person/name]]",\
|
118
116
|
@connection.db)
|
119
|
-
id = results
|
117
|
+
id = results.first.first
|
120
118
|
@connection.db.entity(id).should be_true
|
121
119
|
end
|
122
120
|
|
123
121
|
it 'should get keys from entity id' do
|
124
122
|
results = Diametric::Persistence::Peer.q("[:find ?c :where [?c :person/name]]",\
|
125
123
|
@connection.db)
|
126
|
-
id = results
|
124
|
+
id = results.first.first
|
127
125
|
entity = @connection.db.entity(id)
|
128
126
|
entity.keys.should include(":person/name")
|
129
127
|
#puts entity.keys
|
@@ -132,13 +130,432 @@ if is_jruby?
|
|
132
130
|
it 'should get value from entity id' do
|
133
131
|
results = Diametric::Persistence::Peer.q("[:find ?c :where [?c :person/name]]",\
|
134
132
|
@connection.db)
|
135
|
-
id = results
|
133
|
+
id = results.first.first
|
136
134
|
entity = @connection.db.entity(id)
|
137
135
|
value = entity.get(entity.keys[0])
|
138
136
|
value.should match(/Alice|Bob|Chris/)
|
139
137
|
#puts value
|
140
138
|
end
|
141
139
|
end
|
140
|
+
|
141
|
+
context Diametric::Persistence::Collection do
|
142
|
+
before(:all) do
|
143
|
+
vector = Java::ClojureLang::PersistentVector.create(12, 23, 34, 45, 56, 67)
|
144
|
+
@collection = Diametric::Persistence::Collection.wrap(vector)
|
145
|
+
@seq = Diametric::Persistence::Collection.be_lazy(vector)
|
146
|
+
vector2 = Java::ClojureLang::PersistentVector.create(12, false, 23, nil, 34, 45, nil, 56, nil, false, 67)
|
147
|
+
@collection2 = Diametric::Persistence::Collection.wrap(vector2)
|
148
|
+
@seq2 = Diametric::Persistence::Collection.be_lazy(vector2)
|
149
|
+
empty_vector = Java::ClojureLang::PersistentVector.create()
|
150
|
+
@empty_collection = Diametric::Persistence::Collection.wrap(empty_vector)
|
151
|
+
@empty_seq = Diametric::Persistence::Collection.be_lazy(empty_vector)
|
152
|
+
end
|
153
|
+
|
154
|
+
it 'should raise error for & method' do
|
155
|
+
expect { @collection & [100, 200] }.to raise_error(RuntimeError)
|
156
|
+
end
|
157
|
+
|
158
|
+
it 'should raise error for assoc method' do
|
159
|
+
expect { @collection.assoc("something") }.to raise_error(RuntimeError)
|
160
|
+
end
|
161
|
+
|
162
|
+
it 'should repeat elements by * method' do
|
163
|
+
@collection.*(2).should == [12, 23, 34, 45, 56, 67, 12, 23, 34, 45, 56, 67]
|
164
|
+
@collection.*(",").should == "12,23,34,45,56,67"
|
165
|
+
end
|
166
|
+
|
167
|
+
it 'should concat other array' do
|
168
|
+
@collection.+([100, 200]).should == [12, 23, 34, 45, 56, 67, 100, 200]
|
169
|
+
end
|
170
|
+
|
171
|
+
it 'should get difference from other array' do
|
172
|
+
@collection.-([12, 45, 67]).should == [23, 34, 56]
|
173
|
+
end
|
174
|
+
|
175
|
+
it 'should return length' do
|
176
|
+
@collection.length.should == 6
|
177
|
+
@collection.size.should == 6
|
178
|
+
@seq.length.should == 6
|
179
|
+
@seq.size.should == 6
|
180
|
+
end
|
181
|
+
|
182
|
+
it 'should return string expression' do
|
183
|
+
@collection.to_s.should == "[12, 23, 34, 45, 56, 67]"
|
184
|
+
@seq.to_s.should == "[12, 23, 34, 45, 56, 67]"
|
185
|
+
end
|
186
|
+
|
187
|
+
it 'should return object or nil for [index]' do
|
188
|
+
@collection[0].should == 12
|
189
|
+
@collection[4].should == 56
|
190
|
+
@collection[6].should == nil
|
191
|
+
@collection[-3].should == 45
|
192
|
+
@collection[0].should == 12
|
193
|
+
@collection[4].should == 56
|
194
|
+
@collection[6].should == nil
|
195
|
+
@collection[-3].should == 45
|
196
|
+
|
197
|
+
@seq[0].should == 12
|
198
|
+
@seq[4].should == 56
|
199
|
+
@seq[6].should == nil
|
200
|
+
@seq[-3].should == 45
|
201
|
+
@seq[0].should == 12
|
202
|
+
@seq[4].should == 56
|
203
|
+
@seq[6].should == nil
|
204
|
+
@seq[-3].should == 45
|
205
|
+
end
|
206
|
+
|
207
|
+
it 'should return new collection or nil for [start, length]' do
|
208
|
+
@collection[1, 2].should == [23, 34]
|
209
|
+
@collection[7, 1].should == nil
|
210
|
+
@collection[6, 1].should == []
|
211
|
+
@collection[-2, 5].should == [56, 67]
|
212
|
+
@collection[3, -1].should == nil
|
213
|
+
|
214
|
+
@seq[1, 2].should == [23, 34]
|
215
|
+
@seq[7, 1].should == nil
|
216
|
+
@seq[6, 1].should == []
|
217
|
+
@seq[-2, 5].should == [56, 67]
|
218
|
+
@seq[3, -1].should == nil
|
219
|
+
end
|
220
|
+
|
221
|
+
it 'should return new collection or nil for [range]' do
|
222
|
+
@collection[1..3].should == [23, 34, 45]
|
223
|
+
@collection[1...3].should == [23, 34]
|
224
|
+
@collection[5..10].should == [67]
|
225
|
+
@collection[6..10].should == []
|
226
|
+
@collection[7..10].should == nil
|
227
|
+
|
228
|
+
@seq[1..3].should == [23, 34, 45]
|
229
|
+
@seq[1...3].should == [23, 34]
|
230
|
+
@seq[5..10].should == [67]
|
231
|
+
@seq[6..10].should == []
|
232
|
+
@seq[7..10].should == nil
|
233
|
+
end
|
234
|
+
|
235
|
+
it 'should return object or nil at(index)' do
|
236
|
+
@collection.at(4).should == 56
|
237
|
+
@collection.at(-1).should == 67
|
238
|
+
|
239
|
+
@seq.at(4).should == 56
|
240
|
+
@seq.at(-1).should == 67
|
241
|
+
end
|
242
|
+
|
243
|
+
it 'should raise error for bsearch method' do
|
244
|
+
expect { @collection.bsearch {|x| x} }.to raise_error(RuntimeError)
|
245
|
+
end
|
246
|
+
|
247
|
+
it 'should raise error for clear method' do
|
248
|
+
expect { @collection.clear }.to raise_error(RuntimeError)
|
249
|
+
end
|
250
|
+
|
251
|
+
it 'should return new array for collect or map method' do
|
252
|
+
@collection.collect {|x| x > 40 }.should == [false, false, false, true, true, true]
|
253
|
+
@collection.map(&:to_s).should == ["12", "23", "34", "45", "56", "67"]
|
254
|
+
|
255
|
+
@seq.collect {|x| x > 40 }.should == [false, false, false, true, true, true]
|
256
|
+
@seq.map(&:to_s).should == ["12", "23", "34", "45", "56", "67"]
|
257
|
+
end
|
258
|
+
|
259
|
+
it 'should raise error for collect! or map! method' do
|
260
|
+
expect { @collection.collect! {|x| x > 40 } }.to raise_error(RuntimeError)
|
261
|
+
expect { @collection.map!(&:to_s) }.to raise_error(RuntimeError)
|
262
|
+
end
|
263
|
+
|
264
|
+
it 'should strip nil element out from vector but not false for compact method' do
|
265
|
+
@collection2.compact.should == [12, false, 23, 34, 45, 56, false, 67]
|
266
|
+
|
267
|
+
@seq2.compact.should == [12, false, 23, 34, 45, 56, false, 67]
|
268
|
+
end
|
269
|
+
|
270
|
+
it 'should raise error for compact! method' do
|
271
|
+
expect { @collection.compact! }.to raise_error(RuntimeError)
|
272
|
+
end
|
273
|
+
|
274
|
+
it 'should raise error for concat method' do
|
275
|
+
expect { @collection.concat([100, 200]) }.to raise_error(RuntimeError)
|
276
|
+
end
|
277
|
+
|
278
|
+
it 'should count speicfied object for count method' do
|
279
|
+
@collection.count.should == 6
|
280
|
+
@collection2.count(false).should == 2
|
281
|
+
@collection2.count(100).should == 0
|
282
|
+
@collection2.count(67).should == 1
|
283
|
+
@collection2.count(nil).should == 3
|
284
|
+
|
285
|
+
@seq.count.should == 6
|
286
|
+
@seq2.count(false).should == 2
|
287
|
+
@seq2.count(100).should == 0
|
288
|
+
@seq2.count(67).should == 1
|
289
|
+
@seq2.count(nil).should == 3
|
290
|
+
end
|
291
|
+
|
292
|
+
it 'should raise error for cycle method' do
|
293
|
+
expect { @collection.cycle { |x| x } }.to raise_error(RuntimeError)
|
294
|
+
expect { @collection.cycle(2) { |x| x } }.to raise_error(RuntimeError)
|
295
|
+
end
|
296
|
+
|
297
|
+
it 'should raise error for delete method' do
|
298
|
+
expect { @collection.delete(12) }.to raise_error(RuntimeError)
|
299
|
+
expect { @collection.delete(100) { "not found" } }.to raise_error(RuntimeError)
|
300
|
+
end
|
301
|
+
|
302
|
+
it 'should raise error for delete_at and slice! method' do
|
303
|
+
expect { @collection.delete_at(2) }.to raise_error(RuntimeError)
|
304
|
+
expect { @collection.slice!(2) }.to raise_error(RuntimeError)
|
305
|
+
expect { @collection.slice!(2, 2) }.to raise_error(RuntimeError)
|
306
|
+
expect { @collection.slice!(2, 2) }.to raise_error(RuntimeError)
|
307
|
+
expect { @collection.slice!(0...2) }.to raise_error(RuntimeError)
|
308
|
+
end
|
309
|
+
|
310
|
+
it 'should raise error for delete_if and reject! method' do
|
311
|
+
expect { @collection.delete_if {|x| x > 30} }.to raise_error(RuntimeError)
|
312
|
+
expect { @collection.reject! {|x| x < 30} }.to raise_error(RuntimeError)
|
313
|
+
end
|
314
|
+
|
315
|
+
it 'should drop or take elements' do
|
316
|
+
@collection.drop(2).should == [34, 45, 56, 67]
|
317
|
+
@collection.take(3).should == [45, 56, 67]
|
318
|
+
|
319
|
+
@seq.drop(2).should == [34, 45, 56, 67]
|
320
|
+
@seq.take(3).should == [45, 56, 67]
|
321
|
+
end
|
322
|
+
|
323
|
+
it 'should drop or take elements while block returns true' do
|
324
|
+
@collection.drop_while {|x| x < 30}.should == [34, 45, 56, 67]
|
325
|
+
@collection2.take_while {|x| x != nil}.should == [nil, 34, 45, nil, 56, nil, false, 67]
|
326
|
+
|
327
|
+
@seq.drop_while {|x| x < 30}.should == [34, 45, 56, 67]
|
328
|
+
@seq2.take_while {|x| x != nil}.should == [nil, 34, 45, nil, 56, nil, false, 67]
|
329
|
+
end
|
330
|
+
|
331
|
+
it 'should iterate elements' do
|
332
|
+
result = []
|
333
|
+
@collection.each {|e| result << e.to_s}
|
334
|
+
result.should == ["12", "23", "34", "45", "56", "67"]
|
335
|
+
|
336
|
+
result = []
|
337
|
+
@collection.each_index {|e| result << e.to_s}
|
338
|
+
result.should == ["0", "1", "2", "3", "4", "5"]
|
339
|
+
|
340
|
+
result = []
|
341
|
+
@seq.each {|e| result << e.to_s}
|
342
|
+
result.should == ["12", "23", "34", "45", "56", "67"]
|
343
|
+
|
344
|
+
result = []
|
345
|
+
@seq.each_index {|e| result << e.to_s}
|
346
|
+
result.should == ["0", "1", "2", "3", "4", "5"]
|
347
|
+
end
|
348
|
+
|
349
|
+
it 'should return true or false for empty test' do
|
350
|
+
@collection.empty?.should == false
|
351
|
+
@empty_collection.empty?.should == true
|
352
|
+
|
353
|
+
@seq.empty?.should == false
|
354
|
+
@empty_seq.empty?.should == true
|
355
|
+
end
|
356
|
+
|
357
|
+
it 'should return true or false for eql? test' do
|
358
|
+
@collection.eql?([12, 23, 34, 45, 56, 67]).should be_true
|
359
|
+
@collection.eql?(@collection2).should be_false
|
360
|
+
|
361
|
+
@seq.eql?([12, 23, 34, 45, 56, 67]).should be_true
|
362
|
+
@seq.eql?(@seq2).should be_false
|
363
|
+
end
|
364
|
+
|
365
|
+
it 'should fetch a value or raise IndexError/default/block value' do
|
366
|
+
@collection.fetch(1).should == 23
|
367
|
+
@collection.fetch(-1).should == 67
|
368
|
+
@collection.fetch(100, "have a nice day").should == "have a nice day"
|
369
|
+
message = ""
|
370
|
+
@collection.fetch(-100) {|i| message = "#{i} is out of bounds"}
|
371
|
+
message.should == "-100 is out of bounds"
|
372
|
+
|
373
|
+
@seq.fetch(1).should == 23
|
374
|
+
@seq.fetch(-1).should == 67
|
375
|
+
@seq.fetch(100, "have a nice day").should == "have a nice day"
|
376
|
+
message = ""
|
377
|
+
@seq.fetch(-100) {|i| message = "#{i} is out of bounds"}
|
378
|
+
message.should == "-100 is out of bounds"
|
379
|
+
end
|
380
|
+
|
381
|
+
it 'should raise error for fill method' do
|
382
|
+
expect { @collection.fill("x") }.to raise_error(RuntimeError)
|
383
|
+
expect { @collection.fill("z", 2, 2) }.to raise_error(RuntimeError)
|
384
|
+
expect { @collection.fill("y", 0..1) }.to raise_error(RuntimeError)
|
385
|
+
expect { @collection.fill {|i| i*i} }.to raise_error(RuntimeError)
|
386
|
+
expect { @collection.fill(-2) {|i| i*i} }.to raise_error(RuntimeError)
|
387
|
+
end
|
388
|
+
|
389
|
+
it 'should return index of the first matched object' do
|
390
|
+
@collection.find_index(34).should == 2
|
391
|
+
@collection2.find_index(nil).should == 3
|
392
|
+
@collection.find_index(100).should == nil
|
393
|
+
@collection.find_index { |x| x % 7 == 0 }.should == 4
|
394
|
+
@collection.find_index { |x| x < 0 }.should == nil
|
395
|
+
@collection.index(45).should == 3
|
396
|
+
@collection2.index(false).should == 1
|
397
|
+
@collection2.index(true).should == nil
|
398
|
+
@collection.index { |x| x.odd? }.should == 1
|
399
|
+
@collection.index { |x| x > 100 }.should == nil
|
400
|
+
|
401
|
+
@seq.find_index(34).should == 2
|
402
|
+
@seq2.find_index(nil).should == 3
|
403
|
+
@seq.find_index(100).should == nil
|
404
|
+
@seq.find_index { |x| x % 7 == 0 }.should == 4
|
405
|
+
@seq.find_index { |x| x < 0 }.should == nil
|
406
|
+
@seq.index(45).should == 3
|
407
|
+
@seq2.index(false).should == 1
|
408
|
+
@seq2.index(true).should == nil
|
409
|
+
@seq.index { |x| x.odd? }.should == 1
|
410
|
+
@seq.index { |x| x > 100 }.should == nil
|
411
|
+
end
|
412
|
+
|
413
|
+
it 'should return first element or first n elements' do
|
414
|
+
@collection.first.should == 12
|
415
|
+
@collection.first(3).should == [12, 23, 34]
|
416
|
+
@collection.first(100).should == [12, 23, 34, 45, 56, 67]
|
417
|
+
|
418
|
+
@seq.first.should == 12
|
419
|
+
@seq.first(3).should == [12, 23, 34]
|
420
|
+
@seq.first(100).should == [12, 23, 34, 45, 56, 67]
|
421
|
+
end
|
422
|
+
|
423
|
+
it 'should raise error for flatten/flatten! methods' do
|
424
|
+
expect { @collection.flatten }.to raise_error(RuntimeError)
|
425
|
+
expect { @collection.flatten(2) }.to raise_error(RuntimeError)
|
426
|
+
expect { @collection.flatten! }.to raise_error(RuntimeError)
|
427
|
+
expect { @collection.flatten(100) }.to raise_error(RuntimeError)
|
428
|
+
end
|
429
|
+
|
430
|
+
it 'should return true from frozen? method' do
|
431
|
+
@collection.frozen?.should == true
|
432
|
+
|
433
|
+
@seq.frozen?.should == true
|
434
|
+
end
|
435
|
+
|
436
|
+
it 'should return truethiness for include? method' do
|
437
|
+
@collection.include?(56).should be_true
|
438
|
+
@collection2.include?(nil).should be_true
|
439
|
+
@collection2.include?(false).should be_true
|
440
|
+
@collection.include?("a").should be_false
|
441
|
+
|
442
|
+
@seq.include?(56).should be_true
|
443
|
+
@seq2.include?(nil).should be_true
|
444
|
+
@seq2.include?(false).should be_true
|
445
|
+
@seq.include?("a").should be_false
|
446
|
+
end
|
447
|
+
|
448
|
+
it 'should raise error for replace method' do
|
449
|
+
expect { @collection.replace(["x", "y", "z"]) }.to raise_error(RuntimeError)
|
450
|
+
end
|
451
|
+
|
452
|
+
it 'should raise error for insert method' do
|
453
|
+
expect { @collection.insert(2, 99) }.to raise_error(RuntimeError)
|
454
|
+
expect { @collection.insert(-2, 1, 2, 3) }.to raise_error(RuntimeError)
|
455
|
+
end
|
456
|
+
|
457
|
+
it 'should return string representation' do
|
458
|
+
@collection.inspect.should == "[12, 23, 34, 45, 56, 67]"
|
459
|
+
|
460
|
+
@seq.inspect.should == "[12, 23, 34, 45, 56, 67]"
|
461
|
+
end
|
462
|
+
|
463
|
+
it 'should return joined string' do
|
464
|
+
@collection.join.should == "122334455667"
|
465
|
+
@collection.join(", ").should == "12, 23, 34, 45, 56, 67"
|
466
|
+
|
467
|
+
@seq.join.should == "122334455667"
|
468
|
+
@seq.join(", ").should == "12, 23, 34, 45, 56, 67"
|
469
|
+
end
|
470
|
+
|
471
|
+
it 'should raise error for keep_if and select! methods' do
|
472
|
+
expect { @collection.keep_if {|v| v == 0} }.to raise_error(RuntimeError)
|
473
|
+
expect { @collection.keep_if }.to raise_error(RuntimeError)
|
474
|
+
expect { @collection.select! {|v| v == 0} }.to raise_error(RuntimeError)
|
475
|
+
expect { @collection.select! }.to raise_error(RuntimeError)
|
476
|
+
end
|
477
|
+
|
478
|
+
it 'should return last elements' do
|
479
|
+
@collection.last.should == 67
|
480
|
+
@collection.last(2).should == [56, 67]
|
481
|
+
|
482
|
+
@seq.last.should == 67
|
483
|
+
@seq.last(2).should == [56, 67]
|
484
|
+
end
|
485
|
+
end
|
486
|
+
|
487
|
+
context Diametric::Persistence::Set do
|
488
|
+
before(:each) do
|
489
|
+
java_set = java.util.HashSet.new([0, 1, 2, 3, 4, 5, 6])
|
490
|
+
@set = Diametric::Persistence::Set.wrap(java_set)
|
491
|
+
java_set2 = java.util.HashSet.new([0, 11, 2, 3, 44, 5, 66])
|
492
|
+
@set2 = Diametric::Persistence::Set.wrap(java_set)
|
493
|
+
end
|
494
|
+
|
495
|
+
it 'should return intersection' do
|
496
|
+
@set.&(Set.new([3, 6, 9])).should == [3, 6].to_set
|
497
|
+
@set.intersection(Set.new([0, 4, 8])).should == [0, 4].to_set
|
498
|
+
end
|
499
|
+
|
500
|
+
it 'should return union' do
|
501
|
+
@set.|(Set.new([3, 6, 9])).should == [0, 1, 2, 3, 4, 5, 6, 9].to_set
|
502
|
+
@set.union(Set.new([0, 4, 8])).should == [0, 1, 2, 3, 4, 5, 6, 8].to_set
|
503
|
+
end
|
504
|
+
|
505
|
+
it 'should return length' do
|
506
|
+
@set.length.should == 7
|
507
|
+
@set.size.should == 7
|
508
|
+
end
|
509
|
+
|
510
|
+
it 'should return false for empty test' do
|
511
|
+
@set.empty?.should == false
|
512
|
+
end
|
513
|
+
|
514
|
+
it 'should test inclusion' do
|
515
|
+
@set.include?(3).should == true
|
516
|
+
@set.include?(-1).should == false
|
517
|
+
end
|
518
|
+
|
519
|
+
it 'should return first element' do
|
520
|
+
[0, 1, 2, 3, 4, 5, 6].should include(@set.first)
|
521
|
+
end
|
522
|
+
|
523
|
+
it 'should iterate elements' do
|
524
|
+
@set.each do |e|
|
525
|
+
[0, 1, 2, 3, 4, 5, 6].should include(e)
|
526
|
+
end
|
527
|
+
end
|
528
|
+
|
529
|
+
it 'should return collected array' do
|
530
|
+
ret = @set.collect { |i| i * i }
|
531
|
+
ret.should =~ [0, 1, 4, 9, 16, 25, 36]
|
532
|
+
end
|
533
|
+
|
534
|
+
it 'should group the element' do
|
535
|
+
ret = @set.group_by { |i| i % 3 }
|
536
|
+
ret[0].should =~ [0, 3, 6]
|
537
|
+
ret[1].should =~ [1, 4]
|
538
|
+
ret[2].should =~ [2, 5]
|
539
|
+
end
|
540
|
+
|
541
|
+
it 'should group by the length' do
|
542
|
+
s = java.util.HashSet.new(["Homer", "Marge", "Bart", "Lisa", "Abraham", "Herb"])
|
543
|
+
set_of_words = Diametric::Persistence::Set.wrap(s)
|
544
|
+
ret = set_of_words.group_by {|w| w.length }
|
545
|
+
ret[4].should =~ ["Bart", "Lisa", "Herb"]
|
546
|
+
ret[5].should =~ ["Homer", "Marge"]
|
547
|
+
ret[7].should =~ ["Abraham"]
|
548
|
+
end
|
549
|
+
|
550
|
+
it 'should group each array by the first element' do
|
551
|
+
s = java.util.HashSet.new([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
|
552
|
+
set_of_ary = Diametric::Persistence::Set.wrap(s)
|
553
|
+
ret = set_of_ary.group_by(&:first)
|
554
|
+
ret[1].should == [[1, 2, 3]]
|
555
|
+
ret[4].should == [[4, 5, 6]]
|
556
|
+
ret[7].should == [[7, 8, 9]]
|
557
|
+
end
|
558
|
+
end
|
142
559
|
end
|
143
560
|
end
|
144
561
|
|