summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPhilip Chimento <philip.chimento@gmail.com>2022-08-10 05:13:14 +0000
committerPhilip Chimento <philip.chimento@gmail.com>2022-08-10 05:13:14 +0000
commit2a1930b0ccc47bbd550e6cee453ca395e7496b10 (patch)
tree6b1de07fdd8047cec79df08f47f4692c0e2e2db9
parent8bc3a8969f4a9c36a888121166abb96f71bce624 (diff)
parent0a28bf36b1fb073f4b01400a57d88dbd75f8c8f3 (diff)
downloadgjs-2a1930b0ccc47bbd550e6cee453ca395e7496b10.tar.gz
Merge branch '496-set-attribute' into 'master'
Gio: Add overrides for File.set_attribute and FileInfo.set_attribute Closes #496 See merge request GNOME/gjs!788
-rw-r--r--installed-tests/js/testGio.js79
-rw-r--r--modules/core/overrides/Gio.js61
2 files changed, 140 insertions, 0 deletions
diff --git a/installed-tests/js/testGio.js b/installed-tests/js/testGio.js
index fc94bb58..c2281fae 100644
--- a/installed-tests/js/testGio.js
+++ b/installed-tests/js/testGio.js
@@ -341,3 +341,82 @@ describe('Gio.FileEnumerator overrides', function () {
expect(count).toBeGreaterThan(0);
});
});
+
+describe('Non-introspectable file attribute overrides', function () {
+ let numExpectedWarnings, file, info;
+ const flags = [Gio.FileQueryInfoFlags.NONE, null];
+
+ function expectWarnings(count) {
+ numExpectedWarnings = count;
+ for (let c = 0; c < count; c++) {
+ GLib.test_expect_message('Gjs', GLib.LogLevelFlags.LEVEL_WARNING,
+ '*not introspectable*');
+ }
+ }
+
+ function assertWarnings(testName) {
+ for (let c = 0; c < numExpectedWarnings; c++) {
+ GLib.test_assert_expected_messages_internal('Gjs', 'testGio.js', 0,
+ `test Gio.${testName}`);
+ }
+ numExpectedWarnings = 0;
+ }
+
+ beforeEach(function () {
+ numExpectedWarnings = 0;
+ [file] = Gio.File.new_tmp('XXXXXX');
+ info = file.query_info('standard::*', ...flags);
+ });
+
+ it('invalid means unsetting the attribute', function () {
+ expectWarnings(2);
+ expect(() =>
+ file.set_attribute('custom::remove', Gio.FileAttributeType.INVALID, null, ...flags))
+ .toThrowError(/not introspectable/);
+ expect(() => info.set_attribute('custom::remove', Gio.FileAttributeType.INVALID)).not.toThrow();
+ assertWarnings();
+ });
+
+ it('works for boolean', function () {
+ expectWarnings(2);
+ expect(() =>
+ file.set_attribute(Gio.FILE_ATTRIBUTE_STANDARD_IS_HIDDEN, Gio.FileAttributeType.BOOLEAN, false, ...flags))
+ .toThrowError(/not introspectable/);
+ expect(() => info.set_attribute(Gio.FILE_ATTRIBUTE_STANDARD_IS_HIDDEN, Gio.FileAttributeType.BOOLEAN, false))
+ .not.toThrow();
+ assertWarnings();
+ });
+
+ it('works for uint32', function () {
+ expectWarnings(2);
+ expect(() => file.set_attribute(Gio.FILE_ATTRIBUTE_TIME_MODIFIED_USEC, Gio.FileAttributeType.UINT32, 123456, ...flags))
+ .not.toThrow();
+ expect(() => info.set_attribute(Gio.FILE_ATTRIBUTE_TIME_MODIFIED_USEC, Gio.FileAttributeType.UINT32, 654321))
+ .not.toThrow();
+ assertWarnings();
+ });
+
+ it('works for uint64', function () {
+ expectWarnings(2);
+ expect(() => file.set_attribute(Gio.FILE_ATTRIBUTE_TIME_MODIFIED, Gio.FileAttributeType.UINT64, Date.now() / 1000, ...flags))
+ .not.toThrow();
+ expect(() => info.set_attribute(Gio.FILE_ATTRIBUTE_TIME_MODIFIED, Gio.FileAttributeType.UINT64, Date.now() / 1000))
+ .not.toThrow();
+ assertWarnings();
+ });
+
+ it('works for object', function () {
+ expectWarnings(2);
+ const icon = Gio.ThemedIcon.new_from_names(['list-add-symbolic']);
+ expect(() =>
+ file.set_attribute(Gio.FILE_ATTRIBUTE_STANDARD_ICON, Gio.FileAttributeType.OBJECT, icon, ...flags))
+ .toThrowError(/not introspectable/);
+ expect(() => info.set_attribute(Gio.FILE_ATTRIBUTE_STANDARD_ICON, Gio.FileAttributeType.OBJECT, icon))
+ .not.toThrow();
+ assertWarnings();
+ });
+
+ afterEach(function () {
+ file.delete_async(GLib.PRIORITY_DEFAULT, null, (obj, res) => obj.delete_finish(res));
+ });
+});
diff --git a/modules/core/overrides/Gio.js b/modules/core/overrides/Gio.js
index 6303b802..37df69d9 100644
--- a/modules/core/overrides/Gio.js
+++ b/modules/core/overrides/Gio.js
@@ -462,6 +462,14 @@ function _promisify(proto, asyncFunc, finishFunc = undefined) {
};
}
+function _notIntrospectableError(funcName, replacement) {
+ return new Error(`${funcName} is not introspectable. Use ${replacement} instead.`);
+}
+
+function _warnNotIntrospectable(funcName, replacement) {
+ logError(_notIntrospectableError(funcName, replacement));
+}
+
function _init() {
Gio = this;
@@ -545,6 +553,59 @@ function _init() {
return this.replace_contents_bytes_async(contents, etag, make_backup, flags, cancellable, callback);
};
+ // Best-effort attempt to replace set_attribute(), which is not
+ // introspectable due to the pointer argument
+ Gio.File.prototype.set_attribute = function set_attribute(attribute, type, value, flags, cancellable) {
+ _warnNotIntrospectable('Gio.File.prototype.set_attribute', 'set_attribute_{type}');
+
+ switch (type) {
+ case Gio.FileAttributeType.STRING:
+ return this.set_attribute_string(attribute, value, flags, cancellable);
+ case Gio.FileAttributeType.BYTE_STRING:
+ return this.set_attribute_byte_string(attribute, value, flags, cancellable);
+ case Gio.FileAttributeType.UINT32:
+ return this.set_attribute_uint32(attribute, value, flags, cancellable);
+ case Gio.FileAttributeType.INT32:
+ return this.set_attribute_int32(attribute, value, flags, cancellable);
+ case Gio.FileAttributeType.UINT64:
+ return this.set_attribute_uint64(attribute, value, flags, cancellable);
+ case Gio.FileAttributeType.INT64:
+ return this.set_attribute_int64(attribute, value, flags, cancellable);
+ case Gio.FileAttributeType.INVALID:
+ case Gio.FileAttributeType.BOOLEAN:
+ case Gio.FileAttributeType.OBJECT:
+ case Gio.FileAttributeType.STRINGV:
+ throw _notIntrospectableError('This attribute type', 'Gio.FileInfo');
+ }
+ };
+
+ Gio.FileInfo.prototype.set_attribute = function set_attribute(attribute, type, value) {
+ _warnNotIntrospectable('Gio.FileInfo.prototype.set_attribute', 'set_attribute_{type}');
+
+ switch (type) {
+ case Gio.FileAttributeType.INVALID:
+ return this.remove_attribute(attribute);
+ case Gio.FileAttributeType.STRING:
+ return this.set_attribute_string(attribute, value);
+ case Gio.FileAttributeType.BYTE_STRING:
+ return this.set_attribute_byte_string(attribute, value);
+ case Gio.FileAttributeType.BOOLEAN:
+ return this.set_attribute_boolean(attribute, value);
+ case Gio.FileAttributeType.UINT32:
+ return this.set_attribute_uint32(attribute, value);
+ case Gio.FileAttributeType.INT32:
+ return this.set_attribute_int32(attribute, value);
+ case Gio.FileAttributeType.UINT64:
+ return this.set_attribute_uint64(attribute, value);
+ case Gio.FileAttributeType.INT64:
+ return this.set_attribute_int64(attribute, value);
+ case Gio.FileAttributeType.OBJECT:
+ return this.set_attribute_object(attribute, value);
+ case Gio.FileAttributeType.STRINGV:
+ return this.set_attribute_stringv(attribute, value);
+ }
+ };
+
Gio.FileEnumerator.prototype[Symbol.iterator] = function* FileEnumeratorIterator() {
while (true) {
try {