Skip to content

Commit

Permalink
feat: support comparison operators for missing edm types (#2519)
Browse files Browse the repository at this point in the history
* feat: use OrderableEdmTypeField for all primitive odata types

* feat: change string filter function to be orderable

* fix: add missing orderable edm types

* fix: adjust generator test to OrderableEdmTypeField

* fix: add missing orderable for Edm.String

* chore: re-generate test services

* fix: linter and prettier

* docs: update changeset

* fix: add missing OrderableEdmTypeField and remove redundant EdmTypeField

* fix: type test

* chore: add type tests for additional comparison operators and edm types
  • Loading branch information
ZhongpinWang authored Jun 7, 2022
1 parent c927634 commit c3166ff
Show file tree
Hide file tree
Showing 225 changed files with 546 additions and 473 deletions.
6 changes: 6 additions & 0 deletions .changeset/empty-lobsters-explain.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
'@sap-cloud-sdk/generator': minor
'@sap-cloud-sdk/odata-common': minor
---

[Compatibility Note] Change `Edm.String`, `Edm.Boolean` and `Edm.Guid` to be orderable to support `lt`/`lessThan()`, `le`/`lessOrEqual()`, `gt`/`greaterThan()`, and `ge`/`greaterOrEqual` operators. Re-generate odata services to adopt the changes.
Empty file modified packages/generator-common/CHANGELOG.md
100644 → 100755
Empty file.
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ describe('field-type-class', () => {
{
kind: StructureKind.Property,
name: 'complexity',
type: "EdmTypeField<EntityT, DeSerializersT, 'Edm.String', false, false>",
type: "OrderableEdmTypeField<EntityT, DeSerializersT, 'Edm.String', false, false>",
initializer:
"this._fieldBuilder.buildEdmTypeField('Complexity', 'Edm.String', false)",
docs: [
Expand Down
6 changes: 3 additions & 3 deletions packages/generator/src/generator-utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -122,9 +122,9 @@ const edmToTsTypeMapping: EdmTypeMappingWithoutEnum = {
};

const edmToFieldTypeMapping: EdmTypeMapping = {
'Edm.String': 'EdmTypeField',
'Edm.Boolean': 'EdmTypeField',
'Edm.Guid': 'EdmTypeField',
'Edm.String': 'OrderableEdmTypeField',
'Edm.Boolean': 'OrderableEdmTypeField',
'Edm.Guid': 'OrderableEdmTypeField',
'Edm.Decimal': 'OrderableEdmTypeField',
'Edm.Int16': 'OrderableEdmTypeField',
'Edm.Int32': 'OrderableEdmTypeField',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ exports[`entity api class gets proper class content 1`] = `
}
private _schema?: {
ENTITY_NAME: EdmTypeField<Breakfast<DeSerializers>, DeSerializersT, 'Edm.String', false, true>,
ENTITY_NAME: OrderableEdmTypeField<Breakfast<DeSerializers>, DeSerializersT, 'Edm.String', false, true>,
NUMBER_OF_EGGS: OrderableEdmTypeField<Breakfast<DeSerializers>, DeSerializersT, 'Edm.Decimal', true, true>,
BREAKFAST_TIME: OrderableEdmTypeField<Breakfast<DeSerializers>, DeSerializersT, 'Edm.DateTime', false, true>,
/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ exports[`entity api file gets proper file 1`] = `
"import { Breakfast } from './Breakfast';
import { BreakfastRequestBuilder } from './BreakfastRequestBuilder';
import { BrunchApi } from './BrunchApi';
import { CustomField, defaultDeSerializers, DefaultDeSerializers, DeSerializers, AllFields, entityBuilder, EntityBuilderType, EntityApi, FieldBuilder, Time, EdmTypeField, OrderableEdmTypeField, OneToOneLink } from '@sap-cloud-sdk/odata-v2';
import { CustomField, defaultDeSerializers, DefaultDeSerializers, DeSerializers, AllFields, entityBuilder, EntityBuilderType, EntityApi, FieldBuilder, Time, OrderableEdmTypeField, OneToOneLink } from '@sap-cloud-sdk/odata-v2';
export class BreakfastApi<DeSerializersT extends DeSerializers = DefaultDeSerializers> implements
EntityApi<
Breakfast<
Expand Down Expand Up @@ -88,7 +88,7 @@ export class BreakfastApi<DeSerializersT extends DeSerializers = DefaultDeSerial
}
private _schema?: {
ENTITY_NAME: EdmTypeField<Breakfast<DeSerializers>, DeSerializersT, 'Edm.String', false, true>,
ENTITY_NAME: OrderableEdmTypeField<Breakfast<DeSerializers>, DeSerializersT, 'Edm.String', false, true>,
NUMBER_OF_EGGS: OrderableEdmTypeField<Breakfast<DeSerializers>, DeSerializersT, 'Edm.Decimal', true, true>,
BREAKFAST_TIME: OrderableEdmTypeField<Breakfast<DeSerializers>, DeSerializersT, 'Edm.DateTime', false, true>,
/**
Expand Down
4 changes: 2 additions & 2 deletions packages/generator/src/imports.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ const bigNumberProperty = {
const stringProperty = {
jsType: 'string',
edmType: 'Edm.String',
fieldType: 'EdmTypeField'
fieldType: 'OrderableEdmTypeField'
} as VdmProperty;

const numberProperty = {
Expand Down Expand Up @@ -113,7 +113,7 @@ describe('imports', () => {
momentProperty,
timeProperty
])
).toEqual(['EdmTypeField', 'OrderableEdmTypeField']);
).toEqual(['OrderableEdmTypeField']);
});

it('contains unique one-to-many link import', () => {
Expand Down
2 changes: 1 addition & 1 deletion packages/generator/src/request-builder/class.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ describe('request builder class', () => {
staticPropertyName: 'BREAKFAST_TIME',
propertyNameAsParam: 'pWith',
jsType: 'string',
fieldType: 'EdmTypeField',
fieldType: 'OrderableEdmTypeField',
originalName: 'With',
edmType: 'Edm.String',
description: 'Breakfast accompaniment.',
Expand Down
2 changes: 1 addition & 1 deletion packages/generator/src/service-generator.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ describe('service-generator', () => {
propertyNameAsParam: 'stringProperty',
edmType: 'Edm.String',
jsType: 'string',
fieldType: 'EdmTypeField',
fieldType: 'OrderableEdmTypeField',
description: '',
nullable: true,
maxLength: '10',
Expand Down
8 changes: 4 additions & 4 deletions packages/generator/test/test-util/data-model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ export const entityName: VdmProperty = {
staticPropertyName: 'ENTITY_NAME',
propertyNameAsParam: 'entityName',
jsType: 'string',
fieldType: 'EdmTypeField',
fieldType: 'OrderableEdmTypeField',
originalName: 'EntityName',
edmType: 'Edm.String',
description: 'The name of the entity.',
Expand Down Expand Up @@ -123,7 +123,7 @@ export const complexMeal: VdmComplexType = {
originalName: 'Complexity',
description: 'something something very good',
edmType: 'Edm.String',
fieldType: 'EdmTypeField',
fieldType: 'OrderableEdmTypeField',
nullable: false,
instancePropertyName: 'complexity',
propertyNameAsParam: 'complexity',
Expand Down Expand Up @@ -168,7 +168,7 @@ export const complexDesert: VdmComplexType = {
originalName: 'Name',
description: 'name of the desert',
edmType: 'Edm.String',
fieldType: 'EdmTypeField',
fieldType: 'OrderableEdmTypeField',
nullable: false,
instancePropertyName: 'name',
propertyNameAsParam: 'name',
Expand Down Expand Up @@ -227,7 +227,7 @@ const orderBreakfastBuilder = (isNullable: boolean): VdmFunctionImport => ({
description: 'Breakfast includes a honey toast',
edmType: 'Edm.Boolean',
jsType: 'boolean',
fieldType: 'EdmTypeField'
fieldType: 'OrderableEdmTypeField'
}
],
parametersTypeName: 'Params',
Expand Down
10 changes: 8 additions & 2 deletions packages/odata-common/src/edm-types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,10 @@ export type OrderableEdmType =
| 'Edm.Time'
| 'Edm.Date'
| 'Edm.Duration'
| 'Edm.TimeOfDay';
| 'Edm.TimeOfDay'
| 'Edm.String'
| 'Edm.Boolean'
| 'Edm.Guid';

/**
* Convenience function to check whether a given EDM type is of type [[OrderableEdmType]].
Expand All @@ -112,6 +115,9 @@ export function isOrderableEdmType(edmType: EdmTypeShared<'any'>): boolean {
'Edm.Time',
'Edm.Date',
'Edm.Duration',
'Edm.TimeOfDay'
'Edm.TimeOfDay',
'Edm.String',
'Edm.Boolean',
'Edm.Guid'
].includes(edmType);
}
2 changes: 1 addition & 1 deletion packages/odata-common/src/filter/filter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { EntityBase, EntityIdentifiable, ODataVersionOf } from '../entity-base';
import type { FilterFunction } from './filter-function-base';
import type { Filterable } from './filterable';

type FilterOperatorString = 'eq' | 'ne';
type FilterOperatorString = 'eq' | 'ne' | 'lt' | 'le' | 'gt' | 'ge';
type FilterOperatorBoolean = 'eq' | 'ne';
type FilterOperatorNumber = 'eq' | 'ne' | 'lt' | 'le' | 'gt' | 'ge';
/**
Expand Down
8 changes: 3 additions & 5 deletions packages/odata-common/src/filter/string-filter-function.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,14 @@
import { EntityBase } from '../entity-base';
import {
FilterFunction,
FilterFunctionParameterType
} from './filter-function-base';
import { FilterFunctionParameterType } from './filter-function-base';
import { OrderableFilterFunction } from './orderable-filter-function';

/**
* Representation of a filter function, that returns a value of type string.
* @internal
*/
export class StringFilterFunction<
EntityT extends EntityBase
> extends FilterFunction<EntityT, string> {
> extends OrderableFilterFunction<EntityT, string> {
/**
* Creates an instance of StringFilterFunction.
* @param functionName - Name of the function that returns a string value.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ describe('Number Field', () => {
checkFilter(filter, fieldName, 'ne', filterValue);
});

it('should create filter for "lessThen"', () => {
it('should create filter for "lessThan"', () => {
const filter = field.lessThan(filterValue);
checkFilter(filter, fieldName, 'lt', filterValue);
});
Expand Down Expand Up @@ -90,7 +90,7 @@ describe('Number Field', () => {
checkFilter(filter, `${parentFieldName}/${fieldName}`, 'ne', filterValue);
});

it('should create filter for "lessThen"', () => {
it('should create filter for "lessThan"', () => {
const filter = field.lessThan(filterValue);
expect(field._fieldName).toBe(fieldName);
checkFilter(filter, `${parentFieldName}/${fieldName}`, 'lt', filterValue);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import {
EntityBuilderType,
EntityApi,
FieldBuilder,
EdmTypeField
OrderableEdmTypeField
} from '@sap-cloud-sdk/odata-v4';
export declare class AirlinesApi<
DeSerializersT extends DeSerializers = DefaultDeSerializers
Expand All @@ -29,7 +29,7 @@ export declare class AirlinesApi<
get fieldBuilder(): FieldBuilder<typeof Airlines, DeSerializersT>;
private _schema?;
get schema(): {
AIRLINE_CODE: EdmTypeField<
AIRLINE_CODE: OrderableEdmTypeField<
Airlines<
DeSerializers<
any,
Expand Down Expand Up @@ -58,7 +58,7 @@ export declare class AirlinesApi<
false,
true
>;
NAME: EdmTypeField<
NAME: OrderableEdmTypeField<
Airlines<
DeSerializers<
any,
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import {
EntityBuilderType,
EntityApi,
FieldBuilder,
EdmTypeField
OrderableEdmTypeField
} from '@sap-cloud-sdk/odata-v4';
export class AirlinesApi<
DeSerializersT extends DeSerializers = DefaultDeSerializers
Expand Down Expand Up @@ -65,14 +65,14 @@ export class AirlinesApi<
}

private _schema?: {
AIRLINE_CODE: EdmTypeField<
AIRLINE_CODE: OrderableEdmTypeField<
Airlines<DeSerializers>,
DeSerializersT,
'Edm.String',
false,
true
>;
NAME: EdmTypeField<
NAME: OrderableEdmTypeField<
Airlines<DeSerializers>,
DeSerializersT,
'Edm.String',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import {
EdmTypeField,
Entity,
FieldOptions,
OrderableEdmTypeField,
PropertyMetadata
} from '@sap-cloud-sdk/odata-v4';
/**
Expand Down Expand Up @@ -58,7 +59,13 @@ export declare class AirportLocationField<
* Representation of the [[AirportLocation.address]] property for query construction.
* Use to reference this property in query operations such as 'filter' in the fluent request API.
*/
address: EdmTypeField<EntityT, DeSerializersT, 'Edm.String', false, false>;
address: OrderableEdmTypeField<
EntityT,
DeSerializersT,
'Edm.String',
false,
false
>;
/**
* Representation of the [[AirportLocation.city]] property for query construction.
* Use to reference this property in query operations such as 'filter' in the fluent request API.
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit c3166ff

Please sign in to comment.