Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[helpers] Fix isInstant & Improve helpers in general #348

Merged
merged 1 commit into from
Jun 19, 2024
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
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
Loading