Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 21 additions & 1 deletion examples/browser/cql4browsers.js
Original file line number Diff line number Diff line change
Expand Up @@ -2412,6 +2412,13 @@ class Interval {
return new Interval(this.low, this.high, lowClosed, highClosed);
}
}
pointFrom() {
const start = this.start();
if (cmp.equals(start, this.end())) {
return start;
}
throw new Error('PointFrom operator may only be used on an interval containing a single point.');
}
toString() {
const start = this.lowClosed ? '[' : '(';
const end = this.highClosed ? ']' : ')';
Expand Down Expand Up @@ -5085,7 +5092,7 @@ var __importStar = (this && this.__importStar) || (function () {
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
exports.Collapse = exports.Expand = exports.Ends = exports.Starts = exports.End = exports.Start = exports.Size = exports.Width = exports.OverlapsBefore = exports.OverlapsAfter = exports.Overlaps = exports.MeetsBefore = exports.MeetsAfter = exports.Meets = exports.Interval = void 0;
exports.Collapse = exports.Expand = exports.Ends = exports.Starts = exports.End = exports.Start = exports.Size = exports.Width = exports.PointFrom = exports.OverlapsBefore = exports.OverlapsAfter = exports.Overlaps = exports.MeetsBefore = exports.MeetsAfter = exports.Meets = exports.Interval = void 0;
exports.doContains = doContains;
exports.doProperContains = doProperContains;
exports.doIncludes = doIncludes;
Expand Down Expand Up @@ -5263,6 +5270,19 @@ class OverlapsBefore extends expression_1.Expression {
}
}
exports.OverlapsBefore = OverlapsBefore;
class PointFrom extends expression_1.Expression {
constructor(json) {
super(json);
}
async exec(ctx) {
const interval = await this.arg?.execute(ctx);
if (interval == null) {
return null;
}
return interval.pointFrom();
}
}
exports.PointFrom = PointFrom;
// Delegated to by overloaded#Union
function doUnion(a, b) {
return a.union(b);
Expand Down
11 changes: 11 additions & 0 deletions src/datatypes/interval.ts
Original file line number Diff line number Diff line change
Expand Up @@ -647,6 +647,17 @@ export class Interval {
}
}

pointFrom() {
const start = this.start();
if (cmp.equals(start, this.end())) {
return start;
}

throw new Error(
'PointFrom operator may only be used on an interval containing a single point.'
);
}

toString() {
const start = this.lowClosed ? '[' : '(';
const end = this.highClosed ? ']' : ')';
Expand Down
14 changes: 14 additions & 0 deletions src/elm/interval.ts
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,20 @@ export class OverlapsBefore extends Expression {
}
}

export class PointFrom extends Expression {
constructor(json: any) {
super(json);
}

async exec(ctx: Context) {
const interval = await this.arg?.execute(ctx);
if (interval == null) {
return null;
}
return interval.pointFrom();
}
}

// Delegated to by overloaded#Union
export function doUnion(a: any, b: any) {
return a.union(b);
Expand Down
4 changes: 4 additions & 0 deletions test/datatypes/interval-data.ts
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,10 @@ export default () => {
DateTime.parse('2012-01-01T00:00:00.0'),
DateTime.parse('2012-07-01T00:00:00.0')
);
data['unitIvl'] = new TestInterval(
DateTime.parse('2012-01-01T00:00:00.0'),
DateTime.parse('2012-01-01T00:00:00.0')
);
data['bef2012'] = TestDateTime.parse('2011-06-01T00:00:00.0');
data['beg2012'] = TestDateTime.parse('2012-01-01T00:00:00.0');
data['mid2012'] = TestDateTime.parse('2012-06-01T00:00:00.0');
Expand Down
141 changes: 141 additions & 0 deletions test/datatypes/interval-test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1933,6 +1933,83 @@ describe('DateTimeInterval', () => {
x.toYear.meetsBefore(y.closed).should.be.false();
});
});

describe('pointFrom', () => {
it('should return the point value for a unit interval', () => {
const point = DateTime.parse('2012-01-01T00:00:00.0+00');
const ivl = new Interval(point, point);

ivl.pointFrom().should.eql(point);
});

it('should throw on pointFrom call if not a unit interval', () => {
const ivl = new Interval(
DateTime.parse('2012-01-01T00:00:00.0+00'),
DateTime.parse('2025-01-01T00:00:00.0+00')
);
should(() => ivl.pointFrom()).throw(Error);
});

it('should return the point value for a unit interval with open low bound', () => {
const point = DateTime.parse('2012-01-01T00:00:00.0+00');
const ivl = new Interval(point.predecessor(), point, false, true);

ivl.pointFrom().should.eql(point);
});

it('should return the point value for a unit interval with open high bound', () => {
const point = DateTime.parse('2012-01-01T00:00:00.0+00');
const ivl = new Interval(point, point.successor(), true, false);

ivl.pointFrom().should.eql(point);
});

it('should throw for a non-unit interval with closed high bound', () => {
const point = DateTime.parse('2012-01-01T00:00:00.0+00');
const ivl = new Interval(point, point.successor(), true, true);

should(() => ivl.pointFrom()).throw(Error);
});

it('should return the value for a unit interval with null (max) high bound', () => {
const ivl = new Interval(MAX_DATETIME_VALUE, null);

ivl.pointFrom().should.eql(MAX_DATETIME_VALUE);
});

it('should return the value for a unit interval with null (min) low bound', () => {
const ivl = new Interval(null, MIN_DATETIME_VALUE);

ivl.pointFrom().should.eql(MIN_DATETIME_VALUE);
});

it('should return the point value for a unit interval with limited precision', () => {
const point = DateTime.parse('2012-01-01');
const ivl = new Interval(point, point);

ivl.pointFrom().should.eql(point);
});

it('should throw for an interval with closed null high bound', function () {
const ivl = new Interval(DateTime.parse('2012-01-01T00:00:00.0+00'), null);
should(() => ivl.pointFrom()).throw(Error);
});

it('should throw for an interval with open null high bound', function () {
const ivl = new Interval(DateTime.parse('2012-01-01T00:00:00.0+00'), null, true, false);
should(() => ivl.pointFrom()).throw(Error);
});

it('should throw for an interval with closed null low bound', function () {
const ivl = new Interval(null, DateTime.parse('2012-01-01T00:00:00.0+00'));
should(() => ivl.pointFrom()).throw(Error);
});

it('should throw for an interval with open null low bound', function () {
const ivl = new Interval(null, DateTime.parse('2012-01-01T00:00:00.0+00'), false, true);
should(() => ivl.pointFrom()).throw(Error);
});
});
});

describe('IntegerInterval', () => {
Expand Down Expand Up @@ -3713,6 +3790,43 @@ describe('IntegerInterval', () => {
uIvl.meetsBefore(uIvl).should.be.false();
});
});

describe('pointFrom', () => {
it('should return the point value for a unit interval', () => {
const ivl = new Interval(0, 0);
ivl.pointFrom().should.eql(0);
});

it('should throw on pointFrom call if not a unit interval', () => {
const ivl = new Interval(0, 1);
should(() => ivl.pointFrom()).throw(Error);
});

it('should return the point value for a unit interval', () => {
const ivl = new Interval(12, 12);
ivl.pointFrom().should.eql(12);
});

it('should throw on pointFrom call if not a unit interval', () => {
const ivl = new Interval(8, 9);
should(() => ivl.pointFrom()).throw(Error);
});

it('should return the point from an interval with an open high bound', async function () {
const ivl = new Interval(100, 101, true, false);
ivl.pointFrom().should.eql(100);
});

it('should throw for an interval with null high bound', function () {
const ivl = new Interval(23, null);
should(() => ivl.pointFrom()).throw(Error);
});

it('should throw for an interval with undefined width', function () {
const ivl = new Interval(0, 0, false, false);
should(() => ivl.pointFrom()).throw(Error);
});
Comment on lines +3825 to +3828

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure if this is even a valid interval, but throwing seems like the right thing to do.

});
});

describe('LongInterval', () => {
Expand Down Expand Up @@ -5493,6 +5607,33 @@ describe('LongInterval', () => {
uIvl.meetsBefore(uIvl).should.be.false();
});
});

describe('pointFrom', () => {
it('should return the point value for a unit interval', () => {
const ivl = new Interval(10n, 10n);
ivl.pointFrom().should.eql(10n);
});

it('should throw on pointFrom call if not a unit interval', () => {
const ivl = new Interval(0n, 1n);
should(() => ivl.pointFrom()).throw(Error);
});

it('should return the point from an interval with an open high bound', async function () {
const ivl = new Interval(5n, 6n, true, false);
ivl.pointFrom().should.eql(5n);
});

it('should throw for an interval with null high bound', function () {
const ivl = new Interval(0n, null);
should(() => ivl.pointFrom()).throw(Error);
});

it('should throw for an interval with undefined width', function () {
const ivl = new Interval(0n, 0n, false, false);
should(() => ivl.pointFrom()).throw(Error);
});
});
});

describe('DecimalInterval', () => {
Expand Down
10 changes: 10 additions & 0 deletions test/elm/interval/data.cql
Original file line number Diff line number Diff line change
Expand Up @@ -1008,6 +1008,16 @@ define OpenNotNull: end of Interval(DateTime(2012, 1, 1), DateTime(2013, 1, 1))
define OpenLongNotNull: end of Interval(1L, 3L)
define OpenNull: end of Interval(DateTime(2013, 1, 1), null)

// @Test: PointFrom
define IntegerPoint: point from Interval[4, 4]
define IntegerOpenHighPoint: point from Interval[4, 5)
define LongPoint: point from Interval[4294967296L, 4294967296L]
define EmptyIntervalPoint: point from Interval(0, 0)
define DateTimePoint: point from Interval[DateTime(2012, 1, 1), DateTime(2012, 1, 1)]
Comment thread
cmoesel marked this conversation as resolved.
define NullPoint: point from (null as Interval<Integer>)
define NonUnitPoint: point from Interval[1, 4]
define NullHighPoint: point from Interval[1, null]

// @Test: Starts
define TestStartsNull: Interval[null, null] starts Interval[1, 10]
define IntegerIntervalStartsTrue: Interval[4,10] starts Interval[4, 15]
Expand Down
Loading
Loading