Skip to content

Commit fd6c2fd

Browse files
Merge pull request #183 from bcgsc/bugfix/KBDEV-1337-orderPreferredOntologyTerms
Bugfix/kbdev 1337 order preferred ontology terms
2 parents 27979ba + b3faebb commit fd6c2fd

2 files changed

Lines changed: 94 additions & 98 deletions

File tree

src/graphkb.js

Lines changed: 28 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -131,67 +131,60 @@ const convertRecordToQueryFilters = (record) => {
131131
* @returns {Number} the sorting number (-1, 0, +1)
132132
*/
133133
const orderPreferredOntologyTerms = (term1, term2) => {
134-
// prefer non-deprecated terms
135-
if (term1.deprecated && !term2.deprecated) {
136-
return 1;
137-
} if (term2.deprecated && !term1.deprecated) {
134+
// prefer non-deprecated terms over deprecated ones
135+
if (!term1.deprecated && term2.deprecated) {
138136
return -1;
137+
} if (term1.deprecated && !term2.deprecated) {
138+
return 1;
139139
}
140140
// prefer terms with independent sourceId
141141
if (term1.alias === false & term2.alias !== false) {
142142
return -1;
143-
} if (term2.alias === false & term1.alias !== false) {
143+
} if (term1.alias !== false & term2.alias === false) {
144144
return 1;
145145
}
146-
if (term1.dependency == null & term2.dependency != null) {
146+
if (nullOrUndefined(term1.dependency) & !nullOrUndefined(term2.dependency)) {
147147
return -1;
148-
} if (term2.dependency == null & term1.dependency != null) {
148+
} if (!nullOrUndefined(term1.dependency) & nullOrUndefined(term2.dependency)) {
149149
return 1;
150150
}
151151
// when terms have the same sourceId and source
152-
if (term1.sourceId === term2.sourceId && rid(term1.source, true) === rid(term2.source, true)) {
152+
if (
153+
(term1.sourceId && term1.sourceId === term2.sourceId)
154+
&& (rid(term1.source, true) && rid(term1.source, true) === rid(term2.source, true))
155+
) {
153156
// prefer generic to versioned terms (will not be together unless version not specified)
154-
if (nullOrUndefined(term1.sourceIdVersion) && !(term2.sourceIdVersion)) {
157+
if (nullOrUndefined(term1.sourceIdVersion) && !nullOrUndefined(term2.sourceIdVersion)) {
155158
return -1;
156-
} if (nullOrUndefined(term2.sourceIdVersion) && !(term1.sourceIdVersion)) {
159+
} if (!nullOrUndefined(term1.sourceIdVersion) && nullOrUndefined(term2.sourceIdVersion)) {
157160
return 1;
158161
}
159162
// prefer newer/later versions
160-
if (term1.sourceIdVersion < term2.sourceIdVersion) {
163+
if (term1.sourceIdVersion > term2.sourceIdVersion) {
161164
return -1;
162-
} if (term1.sourceIdVersion > term2.sourceIdVersion) {
165+
} if (term1.sourceIdVersion < term2.sourceIdVersion) {
163166
return 1;
164167
}
165-
// prefer newer/later source version
166-
if (term1.source && term2.source) {
167-
if (term1.source.version < term2.source.version) {
168-
return -1;
169-
} if (term1.source.version > term2.source.version) {
170-
return 1;
171-
}
172-
}
173-
// prefer terms with descriptions
174-
if (term1.description && !term2.description) {
175-
return -1;
176-
} if (!term1.description && term2.description) {
177-
return 1;
178-
}
179-
} if (term1.source && term2.source) {
168+
} else if (term1.source && term2.source) {
180169
// use source rank to sort results
181170
if (term1.source.sort < term2.source.sort) {
182171
return -1;
183172
} if (term1.source.sort > term2.source.sort) {
184173
return 1;
185-
} if (term1.source.version < term2.source.version) {
186-
return -1;
187-
} if (term1.source.version > term2.source.version) {
188-
return 1;
189-
} if (term1.description && !term2.description) {
190-
return -1;
191-
} if (!term1.description && term2.description) {
192-
return 1;
193174
}
194175
}
176+
// prefer terms with descriptions
177+
if (term1.description && !term2.description) {
178+
return -1;
179+
} if (!term1.description && term2.description) {
180+
return 1;
181+
}
182+
// prefer terms most recently updated
183+
if (term1.updatedAt > term2.updatedAt) {
184+
return -1;
185+
} if (term1.updatedAt < term2.updatedAt) {
186+
return 1;
187+
}
195188
return 0;
196189
};
197190

test/graphkb.test.js

Lines changed: 66 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -5,102 +5,105 @@ const {
55
} = require('../src/graphkb');
66

77
describe('orderPreferredOntologyTerms', () => {
8-
test('prefer non-deprecated', () => {
8+
test('prefer non-deprecated terms over deprecated ones', () => {
99
expect(orderPreferredOntologyTerms(
10-
{ deprecated: true }, { deprecated: false },
11-
)).toBe(1);
12-
expect(orderPreferredOntologyTerms(
13-
{ deprecated: false }, { deprecated: true },
10+
{ deprecated: false },
11+
{ deprecated: true },
1412
)).toBe(-1);
13+
expect(orderPreferredOntologyTerms(
14+
{ deprecated: true },
15+
{ deprecated: false },
16+
)).toBe(1);
1517
});
1618

1719
test('prefer terms with independent sourceId', () => {
1820
expect(orderPreferredOntologyTerms(
19-
{ alias: false }, { alias: true },
21+
{ alias: false },
22+
{ alias: true },
2023
)).toBe(-1);
2124
expect(orderPreferredOntologyTerms(
22-
{ alias: true }, { alias: false },
25+
{ alias: true },
26+
{ alias: false },
2327
)).toBe(1);
2428
expect(orderPreferredOntologyTerms(
25-
{ }, { dependency: true },
29+
{ },
30+
{ dependency: true },
2631
)).toBe(-1);
2732
expect(orderPreferredOntologyTerms(
28-
{ dependency: true }, { },
33+
{ dependency: true },
34+
{ },
2935
)).toBe(1);
3036
});
3137

32-
test('prefer generic to versioned terms', () => {
38+
test('prefer terms with descriptions', () => {
3339
expect(orderPreferredOntologyTerms(
34-
{ }, { sourceIdVersion: '' },
40+
{ description: 'a description' },
41+
{ description: '' },
3542
)).toBe(-1);
3643
expect(orderPreferredOntologyTerms(
37-
{ sourceIdVersion: '' }, { },
44+
{ description: '' },
45+
{ description: 'a description' },
3846
)).toBe(1);
3947
});
4048

41-
test('prefer newer version of same record', () => {
49+
test('prefer terms most recently updated', () => {
4250
expect(orderPreferredOntologyTerms(
43-
{ sourceIdVersion: '2019-10-08' }, { sourceIdVersion: '2020-10-08' },
51+
{ updatedAt: 1639435944133 },
52+
{ updatedAt: 1565316882229 },
4453
)).toBe(-1);
4554
expect(orderPreferredOntologyTerms(
46-
{ sourceIdVersion: '2020-10-08' }, { sourceIdVersion: '2019-10-08' },
55+
{ updatedAt: 1565316882229 },
56+
{ updatedAt: 1639435944133 },
4757
)).toBe(1);
4858
});
4959

50-
test('prefer newer source version of same record', () => {
51-
expect(orderPreferredOntologyTerms(
52-
{ source: { version: 1 }, sourceIdVersion: '2019-10-08' },
53-
{ source: { version: 2 }, sourceIdVersion: '2019-10-08' },
54-
)).toBe(-1);
60+
test('fallback to 0 if there is no prefered one', () => {
5561
expect(orderPreferredOntologyTerms(
56-
{ source: { version: 2 }, sourceIdVersion: '2019-10-08' },
57-
{ source: { version: 1 }, sourceIdVersion: '2019-10-08' },
58-
)).toBe(1);
62+
{ },
63+
{ },
64+
)).toBe(0);
5965
});
6066

61-
test('prefer terms with descriptions', () => {
62-
expect(orderPreferredOntologyTerms(
63-
{ description: 'a description', sourceIdVersion: '2019-10-08' },
64-
{ description: '', sourceIdVersion: '2019-10-08' },
65-
)).toBe(-1);
66-
expect(orderPreferredOntologyTerms(
67-
{ description: '', sourceIdVersion: '2019-10-08' },
68-
{ description: 'a description', sourceIdVersion: '2019-10-08' },
69-
)).toBe(1);
70-
});
67+
describe('when terms DO have the same source and sourceId', () => {
68+
const term = { source: { '@rid': '#123:45' }, sourceId: '1' };
7169

72-
test('use source rank to sort results', () => {
73-
expect(orderPreferredOntologyTerms(
74-
{ source: { sort: 1 }, sourceId: 1 },
75-
{ source: { sort: 2 }, sourceId: 2 },
76-
)).toBe(-1);
77-
expect(orderPreferredOntologyTerms(
78-
{ source: { sort: 2 }, sourceId: 1 },
79-
{ source: { sort: 1 }, sourceId: 2 },
80-
)).toBe(1);
81-
expect(orderPreferredOntologyTerms(
82-
{ source: { version: 1 }, sourceId: 1 },
83-
{ source: { version: 2 }, sourceId: 2 },
84-
)).toBe(-1);
85-
expect(orderPreferredOntologyTerms(
86-
{ source: { version: 2 }, sourceId: 1 },
87-
{ source: { version: 1 }, sourceId: 2 },
88-
)).toBe(1);
89-
expect(orderPreferredOntologyTerms(
90-
{ description: 'a description', source: {}, sourceId: 1 },
91-
{ description: '', source: {}, sourceId: 2 },
92-
)).toBe(-1);
93-
expect(orderPreferredOntologyTerms(
94-
{ description: '', source: {}, sourceId: 1 },
95-
{ description: 'a description', source: {}, sourceId: 2 },
96-
)).toBe(1);
70+
test('prefer generic to versioned terms', () => {
71+
expect(orderPreferredOntologyTerms(
72+
{ ...term },
73+
{ ...term, sourceIdVersion: '2020-10-08' },
74+
)).toBe(-1);
75+
expect(orderPreferredOntologyTerms(
76+
{ ...term, sourceIdVersion: '2020-10-08' },
77+
{ ...term },
78+
)).toBe(1);
79+
});
80+
81+
test('prefer newer version of same record', () => {
82+
expect(orderPreferredOntologyTerms(
83+
{ ...term, sourceIdVersion: '2020-10-08' },
84+
{ ...term, sourceIdVersion: '2019-10-08' },
85+
)).toBe(-1);
86+
expect(orderPreferredOntologyTerms(
87+
{ ...term, sourceIdVersion: '2019-10-08' },
88+
{ ...term, sourceIdVersion: '2020-10-08' },
89+
)).toBe(1);
90+
});
9791
});
9892

99-
test('fallback to 0 if there is no prefered one', () => {
100-
expect(orderPreferredOntologyTerms(
101-
{ source: { }, sourceId: 1 },
102-
{ source: { }, sourceId: 2 },
103-
)).toBe(0);
93+
describe('when terms DO NOT have the same source and sourceId combination', () => {
94+
const term1 = { source: { '@rid': '#123:45' }, sourceId: '1' };
95+
const term2 = { source: { '@rid': '#123:46' }, sourceId: '2' };
96+
97+
test('use source rank to sort results', () => {
98+
expect(orderPreferredOntologyTerms(
99+
{ ...term1, source: { sort: 1 } },
100+
{ ...term2, source: { sort: 2 } },
101+
)).toBe(-1);
102+
expect(orderPreferredOntologyTerms(
103+
{ ...term1, source: { sort: 2 } },
104+
{ ...term2, source: { sort: 1 } },
105+
)).toBe(1);
106+
});
104107
});
105108
});
106109

0 commit comments

Comments
 (0)