From ad0825d42c1ddfe24ac7489fb324ec0635b45d85 Mon Sep 17 00:00:00 2001 From: Christian Kandeler Date: Tue, 16 May 2023 13:34:52 +0200 Subject: Support Date properties Fixes: QBS-1735 Change-Id: Ide0800d397c5c45c9b4129b732bd27d0d374b7b2 Reviewed-by: Ivan Komissarov --- src/lib/corelib/tools/scripttools.cpp | 12 ++++++++++++ src/shared/quickjs/quickjs.c | 20 ++++++++++++++++++++ src/shared/quickjs/quickjs.h | 3 +++ .../testdata/date-property/date-property.qbs | 18 ++++++++++++++++++ tests/auto/blackbox/tst_blackbox.cpp | 7 +++++++ tests/auto/blackbox/tst_blackbox.h | 1 + 6 files changed, 61 insertions(+) create mode 100644 tests/auto/blackbox/testdata/date-property/date-property.qbs diff --git a/src/lib/corelib/tools/scripttools.cpp b/src/lib/corelib/tools/scripttools.cpp index 4953bbbb5..a9fa1955d 100644 --- a/src/lib/corelib/tools/scripttools.cpp +++ b/src/lib/corelib/tools/scripttools.cpp @@ -43,6 +43,7 @@ #include #include +#include namespace qbs { namespace Internal { @@ -235,6 +236,8 @@ JSValue makeJsVariant(JSContext *ctx, const QVariant &v) return JS_NewInt64(ctx, v.toInt()); case QMetaType::Bool: return JS_NewBool(ctx, v.toBool()); + case QMetaType::QDateTime: + return JS_NewDate(ctx, v.toDateTime().toString(Qt::ISODateWithMs).toUtf8().constData()); case QMetaType::QVariantMap: return makeJsVariantMap(ctx, v.toMap()); default: @@ -277,6 +280,15 @@ static QVariant getJsVariantImpl(JSContext *ctx, JSValue val, QList pat } return l; } + if (JS_IsDate(val)) { + ScopedJsValue toString(ctx, getJsProperty(ctx, val, QLatin1String("toISOString"))); + if (!JS_IsFunction(ctx, toString)) + return {}; + ScopedJsValue dateString(ctx, JS_Call(ctx, toString, val, 0, nullptr)); + if (!JS_IsString(dateString)) + return {}; + return QDateTime::fromString(getJsString(ctx, dateString), Qt::ISODateWithMs); + } if (JS_IsObject(val)) { if (path.contains(val)) return {}; diff --git a/src/shared/quickjs/quickjs.c b/src/shared/quickjs/quickjs.c index 5dee09b93..578fd3a26 100644 --- a/src/shared/quickjs/quickjs.c +++ b/src/shared/quickjs/quickjs.c @@ -54321,3 +54321,23 @@ JS_BOOL JS_IsRegExp(JSContext *ctx, JSValue val) return FALSE; return JS_VALUE_GET_OBJ(val)->class_id == JS_CLASS_REGEXP; } + +int JS_IsDate(JSValue v) +{ + JSObject *p; + if (JS_VALUE_GET_TAG(v) != JS_TAG_OBJECT) + return FALSE; + return JS_VALUE_GET_OBJ(v)->class_id == JS_CLASS_DATE; +} + +JSValue JS_NewDate(JSContext *ctx, const char *s) +{ + JSValue dateString = JS_NewString(ctx, s); + JSAtom constrAtom = JS_NewAtom(ctx, "Date"); + JSValue constr = JS_GetGlobalVar(ctx, constrAtom, FALSE); + JSValue date = js_date_constructor(ctx, constr, 1, &dateString); + JS_FreeValue(ctx, constr); + JS_FreeValue(ctx, dateString); + JS_FreeAtom(ctx, constrAtom); + return date; +} diff --git a/src/shared/quickjs/quickjs.h b/src/shared/quickjs/quickjs.h index 73ba9a58e..fbea4af3d 100644 --- a/src/shared/quickjs/quickjs.h +++ b/src/shared/quickjs/quickjs.h @@ -667,6 +667,9 @@ JS_BOOL JS_IsConstructor(JSContext* ctx, JSValueConst val); JS_BOOL JS_SetConstructorBit(JSContext *ctx, JSValueConst func_obj, JS_BOOL val); JS_BOOL JS_IsArrayBuffer(JSValueConst v); +JSValue JS_NewDate(JSContext *ctx, const char *s); +JS_BOOL JS_IsDate(JSValueConst v); + JSValue JS_NewArray(JSContext *ctx); int JS_IsArray(JSContext *ctx, JSValueConst val); diff --git a/tests/auto/blackbox/testdata/date-property/date-property.qbs b/tests/auto/blackbox/testdata/date-property/date-property.qbs new file mode 100644 index 000000000..ffd584802 --- /dev/null +++ b/tests/auto/blackbox/testdata/date-property/date-property.qbs @@ -0,0 +1,18 @@ +Product { + type: "date" + property var theDate: new Date(1999, 11, 31); + Rule { + multiplex: true + Artifact { filePath: "dummy"; fileTags: "date" } + prepare: { + var cmd = new JavaScriptCommand; + cmd.silent = true; + cmd.sourceCode = function() { + var d = product.theDate; + console.info("The stored date was " + d.getFullYear() + '-' + (d.getMonth() + 1) + '-' + + d.getDate()); + }; + return cmd; + } + } +} diff --git a/tests/auto/blackbox/tst_blackbox.cpp b/tests/auto/blackbox/tst_blackbox.cpp index e8934c403..164521422 100644 --- a/tests/auto/blackbox/tst_blackbox.cpp +++ b/tests/auto/blackbox/tst_blackbox.cpp @@ -2028,6 +2028,13 @@ void TestBlackbox::cpuFeatures() } } +void TestBlackbox::dateProperty() +{ + QDir::setCurrent(testDataDir + "/date-property"); + QCOMPARE(runQbs(), 0); + QVERIFY2(m_qbsStdout.contains("The stored date was 1999-12-31"), m_qbsStdout.constData()); +} + void TestBlackbox::renameDependency() { QDir::setCurrent(testDataDir + "/renameDependency"); diff --git a/tests/auto/blackbox/tst_blackbox.h b/tests/auto/blackbox/tst_blackbox.h index 9abc84897..4f8e898aa 100644 --- a/tests/auto/blackbox/tst_blackbox.h +++ b/tests/auto/blackbox/tst_blackbox.h @@ -93,6 +93,7 @@ private slots: void conflictingPropertyValues_data(); void conflictingPropertyValues(); void cpuFeatures(); + void dateProperty(); void dependenciesProperty(); void dependencyScanningLoop(); void deprecatedProperty(); -- cgit v1.2.1