Skip to content
This repository was archived by the owner on Oct 9, 2023. It is now read-only.

Commit 2cc594f

Browse files
Extend concept type API (#254)
## What is the goal of this PR? We catch up client-nodejs with the Java client version 2.9.0, which exposes an extended set of APIs on `Type`s. We implement: * `ThingType.get_owns_explicit()` and `ThingType.get_owns_overridden` * `AttributeType.get_owners_explicit()` * `ThingType.get_plays_explicit()` * `ThingType.get_plays_overridden()` * `RelationType.get_relates_explicit()` and `RelationType.get_relates_overridden()` We also implement new behaviour test steps required to cover these APIs. ## What are the changes implemented in this PR? * Update `typedb-protocol` to version 2.9.0, and synchronise the naming conventions that were updated * Implement Concept `Type` APIs that were missing, matching the requirements released in client-java 2.9.0 * Update any required changes in the lower-level packges to build requests * update `typedb-behaviour` to latest and implement news steps required to test the new APIs * Disambiguate clashing behaviour steps by adding type hints to them
1 parent b42231f commit 2cc594f

File tree

15 files changed

+355
-58
lines changed

15 files changed

+355
-58
lines changed

dependencies/vaticle/artifacts.bzl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ def vaticle_typedb_artifacts():
2929
artifact_name = "typedb-server-{platform}-{version}.{ext}",
3030
tag_source = deployment["artifact.release"],
3131
commit_source = deployment["artifact.snapshot"],
32-
commit = "0f84e6577b6ef60dac838b604e6d66222c512957",
32+
tag = "2.9.0",
3333
)
3434

3535
def vaticle_typedb_cluster_artifacts():
@@ -39,5 +39,5 @@ def vaticle_typedb_cluster_artifacts():
3939
artifact_name = "typedb-cluster-all-{platform}-{version}.{ext}",
4040
tag_source = deployment_private["artifact.release"],
4141
commit_source = deployment_private["artifact.snapshot"],
42-
commit = "aa8531f154d7c74c8922c71a252022c650c1be0c"
42+
tag = "2.9.0",
4343
)

dependencies/vaticle/repositories.bzl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,12 +32,12 @@ def vaticle_typedb_common():
3232
git_repository(
3333
name = "vaticle_typedb_common",
3434
remote = "https://github.com/vaticle/typedb-common",
35-
commit = "d11cee9745e4559450ef4ccb140d4e9781587932" # sync-marker: do not remove this comment, this is used for sync-dependencies by @vaticle_typedb_common
35+
tag = "2.9.0" # sync-marker: do not remove this comment, this is used for sync-dependencies by @vaticle_typedb_common
3636
)
3737

3838
def vaticle_typedb_behaviour():
3939
git_repository(
4040
name = "vaticle_typedb_behaviour",
4141
remote = "https://github.com/vaticle/typedb-behaviour",
42-
commit = "7aa405c01eb46b8a28867bc49c4f8c0427c32d52", # sync-marker: do not remove this comment, this is used for sync-dependencies by @vaticle_typedb_behaviour
42+
commit = "6e462bcbef73c75405264777069a22bca696a644" # sync-marker: do not remove this comment, this is used for sync-dependencies by @vaticle_typedb_behaviour
4343
)

requirements.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,6 @@
3232
## Dependencies
3333

3434
# IMPORTANT: Any changes to these dependencies should be copied to requirements_dev.txt.
35-
typedb-protocol==2.6.0
35+
typedb-protocol==2.9.0
3636
grpcio==1.43.0
3737
protobuf==3.15.5

requirements_dev.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@
3030

3131
## Dependencies
3232

33-
typedb-protocol==2.6.0
33+
typedb-protocol==2.9.0
3434
grpcio==1.43.0
3535
protobuf==3.15.5
3636

tests/behaviour/concept/type/attributetype/attribute_type_steps.py

Lines changed: 42 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,12 +34,14 @@ def step_impl(context: Context, type_label: str, value_type: str):
3434

3535
@step("attribute({type_label}) get value type: {value_type}")
3636
def step_impl(context: Context, type_label: str, value_type: str):
37-
assert_that(context.tx().concepts().get_attribute_type(type_label).get_value_type(), is_(parse_value_type(value_type)))
37+
assert_that(context.tx().concepts().get_attribute_type(type_label).get_value_type(),
38+
is_(parse_value_type(value_type)))
3839

3940

4041
@step("attribute({type_label}) get supertype value type: {value_type}")
4142
def step_impl(context: Context, type_label: str, value_type: str):
42-
supertype = context.tx().concepts().get_attribute_type(type_label).as_remote(context.tx()).get_supertype().as_attribute_type()
43+
supertype = context.tx().concepts().get_attribute_type(type_label).as_remote(
44+
context.tx()).get_supertype().as_attribute_type()
4345
assert_that(supertype.get_value_type(), is_(parse_value_type(value_type)))
4446

4547

@@ -129,6 +131,26 @@ def step_impl(context: Context, type_label: str):
129131
assert_that(actuals, not_(has_item(owner_label)))
130132

131133

134+
@step("attribute({type_label}) get key owners explicit contain")
135+
def step_impl(context: Context, type_label: str):
136+
owner_labels = [parse_label(s) for s in parse_list(context.table)]
137+
attribute_type = context.tx().concepts().get_attribute_type(type_label)
138+
actuals = list(
139+
map(lambda tt: tt.get_label(), attribute_type.as_remote(context.tx()).get_owners_explicit(only_key=True)))
140+
for owner_label in owner_labels:
141+
assert_that(actuals, has_item(owner_label))
142+
143+
144+
@step("attribute({type_label}) get key owners explicit do not contain")
145+
def step_impl(context: Context, type_label: str):
146+
owner_labels = [parse_label(s) for s in parse_list(context.table)]
147+
attribute_type = context.tx().concepts().get_attribute_type(type_label)
148+
actuals = list(
149+
map(lambda tt: tt.get_label(), attribute_type.as_remote(context.tx()).get_owners_explicit(only_key=True)))
150+
for owner_label in owner_labels:
151+
assert_that(actuals, not_(has_item(owner_label)))
152+
153+
132154
@step("attribute({type_label}) get attribute owners contain")
133155
def step_impl(context: Context, type_label: str):
134156
owner_labels = [parse_label(s) for s in parse_list(context.table)]
@@ -145,3 +167,21 @@ def step_impl(context: Context, type_label: str):
145167
actuals = list(map(lambda tt: tt.get_label(), attribute_type.as_remote(context.tx()).get_owners(only_key=False)))
146168
for owner_label in owner_labels:
147169
assert_that(actuals, not_(has_item(owner_label)))
170+
171+
172+
@step("attribute({type_label}) get attribute owners explicit contain")
173+
def step_impl(context: Context, type_label: str):
174+
owner_labels = [parse_label(s) for s in parse_list(context.table)]
175+
attribute_type = context.tx().concepts().get_attribute_type(type_label)
176+
actuals = list(map(lambda tt: tt.get_label(), attribute_type.as_remote(context.tx()).get_owners_explicit(only_key=False)))
177+
for owner_label in owner_labels:
178+
assert_that(actuals, has_item(owner_label))
179+
180+
181+
@step("attribute({type_label}) get attribute owners explicit do not contain")
182+
def step_impl(context: Context, type_label: str):
183+
owner_labels = [parse_label(s) for s in parse_list(context.table)]
184+
attribute_type = context.tx().concepts().get_attribute_type(type_label)
185+
actuals = list(map(lambda tt: tt.get_label(), attribute_type.as_remote(context.tx()).get_owners_explicit(only_key=False)))
186+
for owner_label in owner_labels:
187+
assert_that(actuals, not_(has_item(owner_label)))

tests/behaviour/concept/type/relationtype/relation_type_steps.py

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,12 @@ def step_impl(context: Context, relation_label: str, role_label: str, is_null):
8080
assert_that(context.tx().concepts().get_relation_type(relation_label).as_remote(context.tx()).get_relates(role_label) is None, is_(is_null))
8181

8282

83+
@step("relation({relation_label}) get overridden role({role_label}) is null: {is_null}")
84+
def step_impl(context: Context, relation_label: str, role_label: str, is_null):
85+
is_null = parse_bool(is_null)
86+
assert_that(context.tx().concepts().get_relation_type(relation_label).as_remote(context.tx()).get_relates_overridden(role_label) is None, is_(is_null))
87+
88+
8389
@step("relation({relation_label}) get role({role_label}) set label: {new_label}")
8490
def step_impl(context: Context, relation_label: str, role_label: str, new_label: str):
8591
context.tx().concepts().get_relation_type(relation_label).as_remote(context.tx()).get_relates(role_label).as_remote(context.tx()).set_label(new_label)
@@ -90,6 +96,11 @@ def step_impl(context: Context, relation_label: str, role_label: str, get_label:
9096
assert_that(context.tx().concepts().get_relation_type(relation_label).as_remote(context.tx()).get_relates(role_label).as_remote(context.tx()).get_label().name(), is_(get_label))
9197

9298

99+
@step("relation({relation_label}) get overridden role({role_label}) get label: {get_label}")
100+
def step_impl(context: Context, relation_label: str, role_label: str, get_label: str):
101+
assert_that(context.tx().concepts().get_relation_type(relation_label).as_remote(context.tx()).get_relates_overridden(role_label).as_remote(context.tx()).get_label().name(), is_(get_label))
102+
103+
93104
@step("relation({relation_label}) get role({role_label}) is abstract: {is_abstract}")
94105
def step_impl(context: Context, relation_label: str, role_label: str, is_abstract):
95106
is_abstract = parse_bool(is_abstract)
@@ -116,6 +127,26 @@ def step_impl(context: Context, relation_label: str):
116127
assert_that(actuals, not_(has_item(role_label)))
117128

118129

130+
def get_actual_related_role_explicit_labels(context: Context, relation_label: str):
131+
return [r.get_label() for r in context.tx().concepts().get_relation_type(relation_label).as_remote(context.tx()).get_relates_explicit()]
132+
133+
134+
@step("relation({relation_label}) get related explicit roles contain")
135+
def step_impl(context: Context, relation_label: str):
136+
role_labels = [parse_label(s) for s in parse_list(context.table)]
137+
actuals = get_actual_related_role_explicit_labels(context, relation_label)
138+
for role_label in role_labels:
139+
assert_that(actuals, has_item(role_label))
140+
141+
142+
@step("relation({relation_label}) get related explicit roles do not contain")
143+
def step_impl(context: Context, relation_label: str):
144+
role_labels = [parse_label(s) for s in parse_list(context.table)]
145+
actuals = get_actual_related_role_explicit_labels(context, relation_label)
146+
for role_label in role_labels:
147+
assert_that(actuals, not_(has_item(role_label)))
148+
149+
119150
@step("relation({relation_label}) get role({role_label}) get supertype: {super_label:ScopedLabel}")
120151
def step_impl(context: Context, relation_label: str, role_label: str, super_label: Label):
121152
supertype = context.tx().concepts().get_relation_type(super_label.scope()).as_remote(context.tx()).get_relates(super_label.name())

tests/behaviour/concept/type/thingtype/thing_type_steps.py

Lines changed: 98 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,9 @@
2222
from behave import *
2323
from hamcrest import *
2424

25-
from typedb.client import *
2625
from tests.behaviour.config.parameters import parse_bool, parse_list, RootLabel, parse_label
2726
from tests.behaviour.context import Context
27+
from typedb.client import *
2828

2929

3030
@step("put {root_label:RootLabel} type: {type_label}")
@@ -51,20 +51,20 @@ def step_impl(context: Context, root_label: RootLabel, type_label: str):
5151
context.get_thing_type(root_label, type_label).as_remote(context.tx()).delete()
5252

5353

54-
@step("{root_label:RootLabel}({type_label}) is null: {is_null}")
55-
def step_impl(context: Context, root_label: RootLabel, type_label: str, is_null):
54+
@step("{root_label:RootLabel}({type_label:Label}) is null: {is_null}")
55+
def step_impl(context: Context, root_label: RootLabel, type_label: Label, is_null):
5656
is_null = parse_bool(is_null)
57-
assert_that(context.get_thing_type(root_label, type_label) is None, is_(is_null))
57+
assert_that(context.get_thing_type(root_label, type_label.name()) is None, is_(is_null))
5858

5959

6060
@step("{root_label:RootLabel}({type_label}) set label: {new_label}")
6161
def step_impl(context: Context, root_label: RootLabel, type_label: str, new_label: str):
6262
context.get_thing_type(root_label, type_label).as_remote(context.tx()).set_label(new_label)
6363

6464

65-
@step("{root_label:RootLabel}({type_label}) get label: {get_label}")
66-
def step_impl(context: Context, root_label: RootLabel, type_label: str, get_label: str):
67-
assert_that(context.get_thing_type(root_label, type_label).as_remote(context.tx()).get_label().name(), is_(get_label))
65+
@step("{root_label:RootLabel}({type_label:Label}) get label: {get_label}")
66+
def step_impl(context: Context, root_label: RootLabel, type_label: Label, get_label: str):
67+
assert_that(context.get_thing_type(root_label, type_label.name()).as_remote(context.tx()).get_label().name(), is_(get_label))
6868

6969

7070
@step("{root_label:RootLabel}({type_label}) set abstract: {is_abstract}; throws exception")
@@ -229,18 +229,42 @@ def step_impl(context: Context, root_label: RootLabel, type_label: str, att_type
229229
context.get_thing_type(root_label, type_label).as_remote(context.tx()).unset_owns(attribute_type)
230230

231231

232+
def get_actual_owns_key_types(context: Context, root_label: RootLabel, type_label: str):
233+
return [t.get_label() for t in context.get_thing_type(root_label, type_label).as_remote(context.tx()).get_owns(keys_only=True)]
234+
235+
232236
@step("{root_label:RootLabel}({type_label}) get owns key types contain")
233237
def step_impl(context: Context, root_label: RootLabel, type_label: str):
234238
attribute_labels = [parse_label(s) for s in parse_list(context.table)]
235-
actuals = [t.get_label() for t in context.get_thing_type(root_label, type_label).as_remote(context.tx()).get_owns(keys_only=True)]
239+
actuals = get_actual_owns_key_types(context, root_label, type_label)
236240
for attribute_label in attribute_labels:
237241
assert_that(actuals, has_item(attribute_label))
238242

239243

240244
@step("{root_label:RootLabel}({type_label}) get owns key types do not contain")
241245
def step_impl(context: Context, root_label: RootLabel, type_label: str):
242246
attribute_labels = [parse_label(s) for s in parse_list(context.table)]
243-
actuals = [t.get_label() for t in context.get_thing_type(root_label, type_label).as_remote(context.tx()).get_owns(keys_only=True)]
247+
actuals = get_actual_owns_key_types(context, root_label, type_label)
248+
for attribute_label in attribute_labels:
249+
assert_that(actuals, not_(has_item(attribute_label)))
250+
251+
252+
def get_actual_owns_explicit_key_types(context: Context, root_label: RootLabel, type_label: str):
253+
return [t.get_label() for t in context.get_thing_type(root_label, type_label).as_remote(context.tx()).get_owns_explicit(keys_only=True)]
254+
255+
256+
@step("{root_label:RootLabel}({type_label}) get owns explicit key types contain")
257+
def step_impl(context: Context, root_label: RootLabel, type_label: str):
258+
attribute_labels = [parse_label(s) for s in parse_list(context.table)]
259+
actuals = get_actual_owns_explicit_key_types(context, root_label, type_label)
260+
for attribute_label in attribute_labels:
261+
assert_that(actuals, has_item(attribute_label))
262+
263+
264+
@step("{root_label:RootLabel}({type_label}) get owns explicit key types do not contain")
265+
def step_impl(context: Context, root_label: RootLabel, type_label: str):
266+
attribute_labels = [parse_label(s) for s in parse_list(context.table)]
267+
actuals = get_actual_owns_explicit_key_types(context, root_label, type_label)
244268
for attribute_label in attribute_labels:
245269
assert_that(actuals, not_(has_item(attribute_label)))
246270

@@ -279,22 +303,59 @@ def step_impl(context: Context, root_label: RootLabel, type_label: str, att_type
279303
context.get_thing_type(root_label, type_label).as_remote(context.tx()).set_owns(attribute_type)
280304

281305

306+
def get_actual_owns(context: Context, root_label: RootLabel, type_label: str):
307+
return [t.get_label() for t in context.get_thing_type(root_label, type_label).as_remote(context.tx()).get_owns()]
308+
309+
282310
@step("{root_label:RootLabel}({type_label}) get owns attribute types contain")
283311
def step_impl(context: Context, root_label: RootLabel, type_label: str):
284312
attribute_labels = [parse_label(s) for s in parse_list(context.table)]
285-
actuals = [t.get_label() for t in context.get_thing_type(root_label, type_label).as_remote(context.tx()).get_owns()]
313+
actuals = get_actual_owns(context, root_label, type_label)
286314
for attribute_label in attribute_labels:
287315
assert_that(actuals, has_item(attribute_label))
288316

289317

290318
@step("{root_label:RootLabel}({type_label}) get owns attribute types do not contain")
291319
def step_impl(context: Context, root_label: RootLabel, type_label: str):
292320
attribute_labels = [parse_label(s) for s in parse_list(context.table)]
293-
actuals = [t.get_label() for t in context.get_thing_type(root_label, type_label).as_remote(context.tx()).get_owns()]
321+
actuals = get_actual_owns(context, root_label, type_label)
294322
for attribute_label in attribute_labels:
295323
assert_that(actuals, not_(has_item(attribute_label)))
296324

297325

326+
def get_actual_owns_explicit(context: Context, root_label: RootLabel, type_label: str):
327+
return [t.get_label() for t in context.get_thing_type(root_label, type_label).as_remote(context.tx()).get_owns_explicit()]
328+
329+
330+
@step("{root_label:RootLabel}({type_label}) get owns explicit attribute types contain")
331+
def step_impl(context: Context, root_label: RootLabel, type_label: str):
332+
attribute_labels = [parse_label(s) for s in parse_list(context.table)]
333+
actuals = get_actual_owns_explicit(context, root_label, type_label)
334+
for attribute_label in attribute_labels:
335+
assert_that(actuals, has_item(attribute_label))
336+
337+
338+
@step("{root_label:RootLabel}({type_label}) get owns explicit attribute types do not contain")
339+
def step_impl(context: Context, root_label: RootLabel, type_label: str):
340+
attribute_labels = [parse_label(s) for s in parse_list(context.table)]
341+
actuals = get_actual_owns_explicit(context, root_label, type_label)
342+
for attribute_label in attribute_labels:
343+
assert_that(actuals, not_(has_item(attribute_label)))
344+
345+
346+
@step("{root_label:RootLabel}({type_label:Label}) get owns overridden attribute({attr_type_label}) is null: {is_null}")
347+
def step_impl(context: Context, root_label: RootLabel, type_label: Label, attr_type_label: str, is_null):
348+
is_null = parse_bool(is_null)
349+
attribute_type = context.tx().concepts().get_attribute_type(attr_type_label)
350+
assert_that(context.get_thing_type(root_label, type_label.name()).as_remote(context.tx()).get_owns_overridden(attribute_type) is None, is_(is_null))
351+
352+
353+
@step("{root_label:RootLabel}({type_label:Label}) get owns overridden attribute({attr_type_label}) get label: {label}")
354+
def step_impl(context: Context, root_label: RootLabel, type_label: Label, attr_type_label: str, label: str):
355+
attribute_type = context.tx().concepts().get_attribute_type(attr_type_label)
356+
assert_that(context.get_thing_type(root_label, type_label.name()).as_remote(context.tx()).get_owns_overridden(attribute_type).get_label().name(), is_(label))
357+
358+
298359
@step("{root_label:RootLabel}({type_label}) set plays role: {role_label:ScopedLabel} as {overridden_label:ScopedLabel}; throws exception")
299360
def step_impl(context: Context, root_label: RootLabel, type_label: str, role_label: Label, overridden_label: Label):
300361
role_type = context.tx().concepts().get_relation_type(role_label.scope()).as_remote(context.tx()).get_relates(role_label.name())
@@ -345,18 +406,42 @@ def step_impl(context: Context, root_label: RootLabel, type_label: str, role_lab
345406
context.get_thing_type(root_label, type_label).as_remote(context.tx()).unset_plays(role_type)
346407

347408

409+
def get_actual_plays(context: Context, root_label: RootLabel, type_label: str):
410+
return [t.get_label() for t in context.get_thing_type(root_label, type_label).as_remote(context.tx()).get_plays()]
411+
412+
348413
@step("{root_label:RootLabel}({type_label}) get playing roles contain")
349414
def step_impl(context: Context, root_label: RootLabel, type_label: str):
350415
role_labels = [parse_label(s) for s in parse_list(context.table)]
351-
actuals = [t.get_label() for t in context.get_thing_type(root_label, type_label).as_remote(context.tx()).get_plays()]
416+
actuals = get_actual_plays(context, root_label, type_label)
352417
for role_label in role_labels:
353418
assert_that(role_label, is_in(actuals))
354419

355420

356421
@step("{root_label:RootLabel}({type_label}) get playing roles do not contain")
357422
def step_impl(context: Context, root_label: RootLabel, type_label: str):
358423
role_labels = [parse_label(s) for s in parse_list(context.table)]
359-
actuals = [t.get_label() for t in context.get_thing_type(root_label, type_label).as_remote(context.tx()).get_plays()]
424+
actuals = get_actual_plays(context, root_label, type_label)
425+
for role_label in role_labels:
426+
assert_that(role_label, not_(is_in(actuals)))
427+
428+
429+
def get_actual_plays_explicit(context: Context, root_label: RootLabel, type_label: str):
430+
return [t.get_label() for t in context.get_thing_type(root_label, type_label).as_remote(context.tx()).get_plays_explicit()]
431+
432+
433+
@step("{root_label:RootLabel}({type_label}) get playing roles explicit contain")
434+
def step_impl(context: Context, root_label: RootLabel, type_label: str):
435+
role_labels = [parse_label(s) for s in parse_list(context.table)]
436+
actuals = get_actual_plays_explicit(context, root_label, type_label)
437+
for role_label in role_labels:
438+
assert_that(role_label, is_in(actuals))
439+
440+
441+
@step("{root_label:RootLabel}({type_label}) get playing roles explicit do not contain")
442+
def step_impl(context: Context, root_label: RootLabel, type_label: str):
443+
role_labels = [parse_label(s) for s in parse_list(context.table)]
444+
actuals = get_actual_plays_explicit(context, root_label, type_label)
360445
for role_label in role_labels:
361446
assert_that(role_label, not_(is_in(actuals)))
362447

0 commit comments

Comments
 (0)