diametric 0.1.1-java → 0.1.2-java
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/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 +24 -22
@@ -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
|
|