Skip to content

Commit

Permalink
[helpers] Fix isInstant & Improve helpers in general (#348)
Browse files Browse the repository at this point in the history
Fixes #346.

Signed-off-by: Florian Hotze <[email protected]>
  • Loading branch information
florian-h05 authored Jun 19, 2024
1 parent 5126ede commit a14dc10
Show file tree
Hide file tree
Showing 8 changed files with 35 additions and 33 deletions.
38 changes: 12 additions & 26 deletions src/helpers.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,5 @@
// Helper functions used internally across the library

const utils = require('./utils');
const javaZDT = Java.type('java.time.ZonedDateTime');
const javaDuration = Java.type('java.time.Duration');
const javaInstant = Java.type('java.time.Instant');
const javaTimeSeries = Java.type('org.openhab.core.types.TimeSeries');

/**
* @typedef { import("./items/items").Item } Item
* @private
Expand Down Expand Up @@ -53,98 +47,90 @@ function _toOpenhabPrimitiveType (value) {
* Checks whether the given object is an instance of {@link items.Item}.
*
* To be used when instanceof checks don't work because of circular dependencies or webpack compilation.
* Checks constructor name or unique properties, because constructor name does not work for the webpacked globals injection.
* Checks unique property <code>rawItem</code>, because constructor name does not work for the webpacked globals injection.
*
* @param {*} o
* @returns {boolean}
* @private
*/
function _isItem (o) {
if (typeof o !== 'object') return false;
return ((o.constructor && o.constructor.name === 'Item') || typeof o.rawItem === 'object');
return typeof o.rawItem === 'object';
}

/**
* Checks whether the given object is an instance of {@link Quantity}.
*
* To be used when instanceof checks don't work because of circular dependencies or webpack compilation.
* Checks constructor name or unique properties, because constructor name does not work for the webpacked globals injection.
* Checks unique property <code>rawQtyType</code>, because constructor name does not work for the webpacked globals injection.
*
* @param {*} o
* @returns {boolean}
* @private
*/
function _isQuantity (o) {
if (typeof o !== 'object') return false;
return ((o.constructor && o.constructor.name === 'Quantity') || typeof o.rawQtyType === 'object');
return typeof o.rawQtyType === 'object';
}

/**
* Checks whether the given object is an instance of {@link time.ZonedDateTime}.
*
* To be used when instanceof checks don't work because of circular dependencies or webpack compilation.
* Checks constructor name or unique properties, because constructor name does not work for the webpacked globals injection.
* Checks <code>_isZonedDateTime</code> property, because constructor name does not work for the webpacked globals injection.
*
* @param {*} o
* @returns {boolean}
* @private
*/
function _isZonedDateTime (o) {
if (typeof o !== 'object') return false;
return (((o.constructor && o.constructor.name === 'ZonedDateTime')) ||
(!utils.isJsInstanceOfJavaType(o, javaZDT) && typeof o.withFixedOffsetZone === 'function')
);
return o._isZonedDateTime === true;
}

/**
* Checks whether the given object is an instance of {@link time.Duration}.
*
* To be used when instanceof checks don't work because of circular dependencies or webpack compilation.
* Checks constructor name or unique properties, because constructor name does not work for the webpacked globals injection.
* Checks <code>_isDuration</code> property, because constructor name does not work for the webpacked globals injection.
*
* @param {*} o
* @returns {boolean}
* @private
*/
function _isDuration (o) {
if (typeof o !== 'object') return false;
return (((o.constructor && o.constructor.name === 'Duration')) ||
(!utils.isJsInstanceOfJavaType(o, javaDuration) && typeof o.minusDuration === 'function' && typeof o.toNanos === 'function')
);
return o._isDuration === true;
}

/**
* Checks whether the given object is an instance of {@link time.Instant}.
*
* To be used when instanceof checks don't work because of circular dependencies or webpack compilation.
* Checks constructor name or unique properties, because constructor name does not work for the webpacked globals injection
* Checks <code>_isInstant</code> property, because constructor name does not work for the webpacked globals injection.
*
* @param {*} o
* @returns {boolean}
* @private
*/
function _isInstant (o) {
if (typeof o !== 'object') return false;
return (((o.constructor && o.constructor.name === 'Instant')) ||
(!utils.isJsInstanceOfJavaType(o, javaInstant) && typeof o.policy === 'string' && typeof o.ofEpochMicro === 'function' && typeof o.ofEpochMilli === 'function' && o.ofEpochSecond === 'function')
);
return o._isInstant === true;
}

/**
* Checks whether the given object is an instance of {@link items.TimeSeries}.
*
* To be used when instanceof checks don't work because of circular dependencies or webpack compilation.
* Checks constructor name or unique properties, because constructor name does not work for the webpacked globals injection.
* Checks <code>_isTimeSeries</code> property, because constructor name does not work for the webpacked globals injection.
*
* @param {*} o
* @return {boolean}
* @private
*/
function _isTimeSeries (o) {
if (typeof o !== 'object') return false;
return (((o.constructor && o.constructor.name === 'TimeSeries')) ||
(!utils.isJsInstanceOfJavaType(o, javaTimeSeries) && _isInstant(o.begin) && _isInstant(o.end))
);
return o._isTimeSeries === true;
}

module.exports = {
Expand Down
5 changes: 5 additions & 0 deletions src/items/time-series.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,11 @@ const { _isInstant } = require('../helpers');
* @memberof items
*/
class TimeSeries {
/**
* @type {boolean}
* @private
*/
_isTimeSeries = true;
#states = [];
#policy;

Expand Down
9 changes: 7 additions & 2 deletions src/time.js
Original file line number Diff line number Diff line change
Expand Up @@ -454,9 +454,14 @@ time.ZonedDateTime.prototype.toOpenHabString = function () {
return this.toString().replace(/\[[^\]]*]$/, '');
};

// Add fields to allow identification of the object type
time.ZonedDateTime.prototype._isZonedDateTime = true;
time.Duration.prototype._isDuration = true;
time.Instant.prototype._isInstant = true;

module.exports = {
...time,
toZDT,
parseString: _parseString,
parseISO8601: _parseISO8601
_parseString,
_parseISO8601
};
1 change: 1 addition & 0 deletions test/quantity.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ const { getQuantity, Quantity, QuantityError, _toBigDecimalOrQtyType, _toQtyType

class Item {
constructor (rawState) {
this.rawItem = {}; // required for _isItem
this.rawState = rawState;
}
}
Expand Down
4 changes: 2 additions & 2 deletions test/time.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ describe('time.js', () => {
});

describe('parseString', () => {
const parseString = time.parseString;
const parseString = time._parseString;

describe('accepts ISO patterns without the "T" for Blockly', () => {
it.each([
Expand All @@ -42,7 +42,7 @@ describe('time.js', () => {
});

describe('parseISO8601', () => {
const parseISO8601 = time.parseISO8601;
const parseISO8601 = time._parseISO8601;
const ZonedDateTime = require('@js-joda/core').ZonedDateTime;

describe('parses ISO Date', () => {
Expand Down
5 changes: 5 additions & 0 deletions types/items/time-series.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,11 @@ declare class TimeSeries {
* @param {string} policy TimeSeries policy <code>ADD</code> or <code>REPLACE</code>
*/
constructor(policy: string);
/**
* @type {boolean}
* @private
*/
private _isTimeSeries;
/**
* The persistence policy of this TimeSeries
*
Expand Down
2 changes: 1 addition & 1 deletion types/items/time-series.d.ts.map

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

4 changes: 2 additions & 2 deletions types/time.d.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
declare const _exports: {
toZDT: typeof toZDT;
parseString: typeof _parseString;
parseISO8601: typeof _parseISO8601;
_parseString: typeof _parseString;
_parseISO8601: typeof _parseISO8601;
nativeJs(date: any, zone?: time.ZoneId): time.ZonedDateTime;
convert(temporal: time.LocalDate | time.Instant | time.ZonedDateTime | time.LocalDateTime, zone?: time.ZoneId): {
toDate: () => Date;
Expand Down

0 comments on commit a14dc10

Please sign in to comment.