diff options
author | Marco Trevisan (Treviño) <mail@3v1n0.net> | 2021-04-22 22:35:49 +0200 |
---|---|---|
committer | Marco Trevisan (Treviño) <mail@3v1n0.net> | 2021-04-22 22:58:57 +0200 |
commit | f897012f9075733b530aa07f9f40a24f724f311b (patch) | |
tree | d1fce5dd29d1d68980c1e672112084f7256a92e2 /installed-tests/js/testGObjectDestructionAccess.js | |
parent | 08bf63bfea524e9a4a3ccc4656e1d161336a38eb (diff) | |
download | gjs-f897012f9075733b530aa07f9f40a24f724f311b.tar.gz |
testGObjectDestructionAccess: Ensure that disposed wrappers are unbound
When an object is disposed we discard its wrapper, if a new wrapper for
such objects is created it will stay connected to the object till the
wrapper is alive or the object is finalized.
However, we need to make sure that also the "disposed" wrapper object is
always unbound from its wrapped or we'll crash as in issue #395.
To test this, we can just repeatedly get from a C function a disposed
object so that we're going it to rewrap it over and over.
Diffstat (limited to 'installed-tests/js/testGObjectDestructionAccess.js')
-rw-r--r-- | installed-tests/js/testGObjectDestructionAccess.js | 59 |
1 files changed, 39 insertions, 20 deletions
diff --git a/installed-tests/js/testGObjectDestructionAccess.js b/installed-tests/js/testGObjectDestructionAccess.js index 63819f5e..1ec25c14 100644 --- a/installed-tests/js/testGObjectDestructionAccess.js +++ b/installed-tests/js/testGObjectDestructionAccess.js @@ -172,18 +172,29 @@ describe('Disposed or finalized GObject', function () { GjsTestTools.reset(); }); - it('is marked as disposed when it is a manually disposed property', function () { - const emblem = new Gio.EmblemedIcon({ - gicon: new Gio.ThemedIcon({name: 'alarm'}), + [true, false].forEach(gc => { + it(`is marked as disposed when it is a manually disposed property ${gc ? '' : 'not '}garbage collected`, function () { + const emblem = new Gio.EmblemedIcon({ + gicon: new Gio.ThemedIcon({name: 'alarm'}), + }); + + let {gicon} = emblem; + gicon.run_dispose(); + gicon = null; + System.gc(); + + Array(10).fill().forEach(() => { + // We need to repeat the test to ensure that we disassociate + // wrappers from disposed objects on destruction. + gicon = emblem.gicon; + expect(gicon.toString()).toMatch( + /\[object \(DISPOSED\) instance wrapper .* jsobj@0x[a-f0-9]+ native@0x[a-f0-9]+\]/); + + gicon = null; + if (gc) + System.gc(); + }); }); - - let {gicon} = emblem; - gicon.run_dispose(); - gicon = null; - System.gc(); - - expect(emblem.gicon.toString()).toMatch( - /\[object \(DISPOSED\) instance wrapper .* jsobj@0x[a-f0-9]+ native@0x[a-f0-9]+\]/); }); it('calls dispose vfunc on explicit disposal only', function () { @@ -258,15 +269,23 @@ describe('Disposed or finalized GObject', function () { 'generates a warn if already disposed at garbage collection'); }); - it('created from other function is marked as disposed', function () { - let file = Gio.File.new_for_path('/'); - GjsTestTools.save_object(file); - file.run_dispose(); - file = null; - System.gc(); - - expect(GjsTestTools.get_saved()).toMatch( - /\[object \(DISPOSED\) instance wrapper GType:GLocalFile jsobj@0x[a-f0-9]+ native@0x[a-f0-9]+\]/); + [true, false].forEach(gc => { + it(`created from other function is marked as disposed and ${gc ? '' : 'not '}garbage collected`, function () { + let file = Gio.File.new_for_path('/'); + GjsTestTools.save_object(file); + file.run_dispose(); + file = null; + System.gc(); + + Array(10).fill().forEach(() => { + // We need to repeat the test to ensure that we disassociate + // wrappers from disposed objects on destruction. + expect(GjsTestTools.peek_saved()).toMatch( + /\[object \(DISPOSED\) instance wrapper GType:GLocalFile jsobj@0x[a-f0-9]+ native@0x[a-f0-9]+\]/); + if (gc) + System.gc(); + }); + }); }); it('returned from function is marked as disposed', function () { |