Skip to content

Commit

Permalink
Merge pull request #74 from Eyas/enum-build-branch
Browse files Browse the repository at this point in the history
Enum build branch
  • Loading branch information
Eyas committed Jan 16, 2020
2 parents a054bdf + 7848621 commit 4218425
Show file tree
Hide file tree
Showing 6 changed files with 223 additions and 13 deletions.
37 changes: 24 additions & 13 deletions src/ts/enum.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,20 +34,31 @@ export class EnumValue {
readonly value: TSubject, types: ReadonlyArray<TTypeName>,
map: ClassMap) {
for (const type of types) {
// "Type" containment.
// A Topic can have multiple types. So the triple we're adding now could
// either be:
// 1. An already processed well-known type (e.g. the Topic is also a
// Class,
// as well as being an enum).
// 2. The Type of the Enum.
// If a Subject has a "Type", then it either means:
// 1- Type is Class - This topic represents an object that can be
// represented as a class (usually, a node/object).
// 2- Type is DataType - This topic represents an object that can
// represented as a raw value.
// 3- Type is Neither - This topic's IRI can be used in the place of that
// type to describe its value.
//
// e.g.: SurgicalProcedure (schema.org/SurgicalProcedure) is both a class
// having the "Class" type, and also an instance of the
// MedicalProcedureType (schema.org/MedicalProcedureType) enum.
// Therefore, an Enum will contain two TTypeName ObjectPredicates:
// one of Type=Class, and another of Type=MedicalProcedureType.
if (IsClassType(type) || IsDataType(type)) return;
// For example,
// - Thing is a Class only.
// - Text is a Class and a DataType.
// - DataType is a Class.
// - Wednesday is a DayOfWeek only.
//
// In Schema.org 3.4, some enumerations were both a Class and an Enum.
//
// For example, SurgicalProcedure was both an enum value for
// MedicalProcedureType and a class that can be described in its own
// right. It had type Class and MedicalProcedureType.
//
// For those cases, we make sure:
// (a) We add an EnumValue for all types that are not Class/DataType.
// (b) An EnumValue being a Class/DataType should not disqualify it from
// being an enum value for some other type (if it has one).
if (IsClassType(type) || IsDataType(type)) continue;

const enumObject = map.get(type.toString());
if (!enumObject) {
Expand Down
20 changes: 20 additions & 0 deletions test/baselines/surgical_procedure_3_4.nt
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<http://schema.org/SurgicalProcedure> <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://schema.org/MedicalProcedureType> .
<http://schema.org/SurgicalProcedure> <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://www.w3.org/2000/01/rdf-schema#Class> .
<http://schema.org/SurgicalProcedure> <http://schema.org/isPartOf> <http://health-lifesci.schema.org> .
<http://schema.org/SurgicalProcedure> <http://www.w3.org/2000/01/rdf-schema#subClassOf> <http://schema.org/MedicalProcedure> .
<http://schema.org/SurgicalProcedure> <http://www.w3.org/2000/01/rdf-schema#comment> "A type of medical procedure that involves invasive surgical techniques." .
<http://schema.org/SurgicalProcedure> <http://www.w3.org/2002/07/owl#equivalentClass> <http://purl.bioontology.org/ontology/SNOMEDCT/387713003> .
<http://schema.org/SurgicalProcedure> <http://www.w3.org/2002/07/owl#equivalentClass> <http://purl.bioontology.org/ontology/SNOMEDCT/387713003> .
<http://schema.org/MedicalProcedureType> <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://www.w3.org/2000/01/rdf-schema#Class> .
<http://schema.org/MedicalProcedureType> <http://www.w3.org/2000/01/rdf-schema#subClassOf> <http://schema.org/MedicalEnumeration> .
<http://schema.org/MedicalProcedureType> <http://schema.org/isPartOf> <http://health-lifesci.schema.org> .
<http://schema.org/MedicalProcedure> <http://schema.org/isPartOf> <http://health-lifesci.schema.org> .
<http://schema.org/MedicalProcedure> <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://www.w3.org/2000/01/rdf-schema#Class> .
<http://schema.org/MedicalProcedure> <http://www.w3.org/2000/01/rdf-schema#subClassOf> <http://schema.org/Thing> .
<http://schema.org/MedicalEnumeration> <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://www.w3.org/2000/01/rdf-schema#Class> .
<http://schema.org/MedicalEnumeration> <http://www.w3.org/2000/01/rdf-schema#subClassOf> <http://schema.org/Enumeration> .
<http://schema.org/Enumeration> <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://www.w3.org/2000/01/rdf-schema#Class> .
<http://schema.org/Enumeration> <http://www.w3.org/2000/01/rdf-schema#subClassOf> <http://schema.org/Intangible> .
<http://schema.org/Intangible> <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://www.w3.org/2000/01/rdf-schema#Class> .
<http://schema.org/Intangible> <http://www.w3.org/2000/01/rdf-schema#subClassOf> <http://schema.org/Thing> .
<http://schema.org/Thing> <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://www.w3.org/2000/01/rdf-schema#Class> .
43 changes: 43 additions & 0 deletions test/baselines/surgical_procedure_3_4.ts.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
type EnumerationBase = IntangibleBase;
export type Enumeration = ({
"@type": "Enumeration";
} & EnumerationBase) | MedicalEnumeration;

type IntangibleBase = ThingBase;
export type Intangible = ({
"@type": "Intangible";
} & IntangibleBase) | Enumeration;

type MedicalEnumerationBase = EnumerationBase;
export type MedicalEnumeration = ({
"@type": "MedicalEnumeration";
} & MedicalEnumerationBase) | MedicalProcedureType;

type MedicalProcedureBase = ThingBase;
export type MedicalProcedure = ({
"@type": "MedicalProcedure";
} & MedicalProcedureBase) | SurgicalProcedure;

type MedicalProcedureTypeBase = MedicalEnumerationBase;
export type MedicalProcedureType = "http://schema.org/SurgicalProcedure" | ({
"@type": "MedicalProcedureType";
} & MedicalProcedureTypeBase);
export const MedicalProcedureType = {
/** A type of medical procedure that involves invasive surgical techniques. */
SurgicalProcedure: ("http://schema.org/SurgicalProcedure" as const)
};

type SurgicalProcedureBase = MedicalProcedureBase;
/** A type of medical procedure that involves invasive surgical techniques. */
export type SurgicalProcedure = {
"@type": "SurgicalProcedure";
} & SurgicalProcedureBase;

type ThingBase = {
/** IRI identifying the canonical address of this object. */
"@id"?: string;
};
export type Thing = ({
"@type": "Thing";
} & ThingBase) | (Intangible | MedicalProcedure);

20 changes: 20 additions & 0 deletions test/baselines/surgical_procedure_3_4_v2.nt
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<http://schema.org/SurgicalProcedure> <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://www.w3.org/2000/01/rdf-schema#Class> .
<http://schema.org/SurgicalProcedure> <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://schema.org/MedicalProcedureType> .
<http://schema.org/SurgicalProcedure> <http://schema.org/isPartOf> <http://health-lifesci.schema.org> .
<http://schema.org/SurgicalProcedure> <http://www.w3.org/2000/01/rdf-schema#subClassOf> <http://schema.org/MedicalProcedure> .
<http://schema.org/SurgicalProcedure> <http://www.w3.org/2000/01/rdf-schema#comment> "A type of medical procedure that involves invasive surgical techniques." .
<http://schema.org/SurgicalProcedure> <http://www.w3.org/2002/07/owl#equivalentClass> <http://purl.bioontology.org/ontology/SNOMEDCT/387713003> .
<http://schema.org/SurgicalProcedure> <http://www.w3.org/2002/07/owl#equivalentClass> <http://purl.bioontology.org/ontology/SNOMEDCT/387713003> .
<http://schema.org/MedicalProcedureType> <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://www.w3.org/2000/01/rdf-schema#Class> .
<http://schema.org/MedicalProcedureType> <http://www.w3.org/2000/01/rdf-schema#subClassOf> <http://schema.org/MedicalEnumeration> .
<http://schema.org/MedicalProcedureType> <http://schema.org/isPartOf> <http://health-lifesci.schema.org> .
<http://schema.org/MedicalProcedure> <http://schema.org/isPartOf> <http://health-lifesci.schema.org> .
<http://schema.org/MedicalProcedure> <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://www.w3.org/2000/01/rdf-schema#Class> .
<http://schema.org/MedicalProcedure> <http://www.w3.org/2000/01/rdf-schema#subClassOf> <http://schema.org/Thing> .
<http://schema.org/MedicalEnumeration> <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://www.w3.org/2000/01/rdf-schema#Class> .
<http://schema.org/MedicalEnumeration> <http://www.w3.org/2000/01/rdf-schema#subClassOf> <http://schema.org/Enumeration> .
<http://schema.org/Enumeration> <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://www.w3.org/2000/01/rdf-schema#Class> .
<http://schema.org/Enumeration> <http://www.w3.org/2000/01/rdf-schema#subClassOf> <http://schema.org/Intangible> .
<http://schema.org/Intangible> <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://www.w3.org/2000/01/rdf-schema#Class> .
<http://schema.org/Intangible> <http://www.w3.org/2000/01/rdf-schema#subClassOf> <http://schema.org/Thing> .
<http://schema.org/Thing> <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://www.w3.org/2000/01/rdf-schema#Class> .
43 changes: 43 additions & 0 deletions test/baselines/surgical_procedure_3_4_v2.ts.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
type EnumerationBase = IntangibleBase;
export type Enumeration = ({
"@type": "Enumeration";
} & EnumerationBase) | MedicalEnumeration;

type IntangibleBase = ThingBase;
export type Intangible = ({
"@type": "Intangible";
} & IntangibleBase) | Enumeration;

type MedicalEnumerationBase = EnumerationBase;
export type MedicalEnumeration = ({
"@type": "MedicalEnumeration";
} & MedicalEnumerationBase) | MedicalProcedureType;

type MedicalProcedureBase = ThingBase;
export type MedicalProcedure = ({
"@type": "MedicalProcedure";
} & MedicalProcedureBase) | SurgicalProcedure;

type MedicalProcedureTypeBase = MedicalEnumerationBase;
export type MedicalProcedureType = "http://schema.org/SurgicalProcedure" | ({
"@type": "MedicalProcedureType";
} & MedicalProcedureTypeBase);
export const MedicalProcedureType = {
/** A type of medical procedure that involves invasive surgical techniques. */
SurgicalProcedure: ("http://schema.org/SurgicalProcedure" as const)
};

type SurgicalProcedureBase = MedicalProcedureBase;
/** A type of medical procedure that involves invasive surgical techniques. */
export type SurgicalProcedure = {
"@type": "SurgicalProcedure";
} & SurgicalProcedureBase;

type ThingBase = {
/** IRI identifying the canonical address of this object. */
"@id"?: string;
};
export type Thing = ({
"@type": "Thing";
} & ThingBase) | (Intangible | MedicalProcedure);

73 changes: 73 additions & 0 deletions test/ts/enum_test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
/**
* Copyright 2020 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

import {expect} from 'chai';
import {stub} from 'sinon';
import {UrlNode} from '../../src/triples/types';
import {EnumValue} from '../../src/ts/enum';
import {makeClass, makeClassMap} from '../helpers/make_class';

describe('EnumValue', () => {
describe('constructor', () => {
it('Throws when referencing a non-existent type', () => {
const map = makeClassMap(
makeClass('https://schema.org/Foo'),
makeClass('https://schema.org/Bar'),
makeClass('https://schema.org/Baz'));
expect(
() => new EnumValue(
UrlNode.Parse('https://schema.org/Wednesday'),
[UrlNode.Parse('https://schema.org/DayOfWeek')], map))
.to.throw('Couldn\'t find');
});

it('Works fine when called for plain enum', () => {
const dayOfWeek = makeClass('https://schema.org/DayOfWeek');
const addEnum = stub(dayOfWeek, 'addEnum');
const map = makeClassMap(
makeClass('https://schema.org/Foo'),
makeClass('https://schema.org/Bar'), dayOfWeek);

const myEnum = new EnumValue(
UrlNode.Parse('https://schema.org/Wednesday'),
[UrlNode.Parse('https://schema.org/DayOfWeek')], map);

expect(addEnum.calledWith(myEnum)).to.be.true;
addEnum.restore();
});

it('Works fine when called for an enum/class', () => {
const medicalProcedureType =
makeClass('https://schema.org/MedicalProcedureType');
const addEnum = stub(medicalProcedureType, 'addEnum');

const map = makeClassMap(
makeClass('https://schema.org/Foo'),
makeClass('https://schema.org/Bar'), medicalProcedureType);

const myEnum = new EnumValue(
UrlNode.Parse('https://schema.org/SurgicalProcedure'),
[
UrlNode.Parse('https://schema.org/MedicalProcedureType'),
UrlNode.Parse('http://www.w3.org/2000/01/rdf-schema#Class')
],
map);

expect(addEnum.calledWith(myEnum)).to.be.true;
addEnum.restore();
});
});
});

0 comments on commit 4218425

Please sign in to comment.