[gjs: 4/7] tests: Move some tests around



commit 25abb7c284369cbe624c0e750c640cf80442b3c3
Author: Philip Chimento <philip chimento gmail com>
Date:   Tue Aug 6 17:38:01 2019 -0700

    tests: Move some tests around
    
    Test suites in testGIMarshalling, testEverythingBasic, or
    testEverythingEncapsulated, that aren't part of the GIMarshallingTests
    or Regress test suites from gobject-introspection, don't need to be in
    those respective files.
    
    The vfunc test is more appropriate for testGObjectClass and the GError
    test is more appropriate for testExceptions.
    
    The new file testIntrospection.js is a good place for the sort of
    catch-all test that tests how certain aspects of introspection are
    implemented in GJS.
    
    GObject overrides, on the other hand, should be tested in a file
    specific for them. We already have testGObjectClass,
    testGObjectInterface, and testParamSpec where GObject overrides are
    tested, but those are kind of separate topics and not necessarily the
    right place for a general override such as GObject.set() to live. We
    create a new testGObject.js file for overrides like that.

 Makefile-test.am                                 |   2 +
 installed-tests/js/testEverythingBasic.js        | 125 -----------------------
 installed-tests/js/testEverythingEncapsulated.js |  18 +---
 installed-tests/js/testExceptions.js             |  26 +++++
 installed-tests/js/testGIMarshalling.js          |  71 -------------
 installed-tests/js/testGObject.js                |  50 +++++++++
 installed-tests/js/testGObjectClass.js           |  63 ++++++++++++
 installed-tests/js/testIntrospection.js          | 105 +++++++++++++++++++
 8 files changed, 247 insertions(+), 213 deletions(-)
---
diff --git a/Makefile-test.am b/Makefile-test.am
index d2233ee4..ddef920d 100644
--- a/Makefile-test.am
+++ b/Makefile-test.am
@@ -207,11 +207,13 @@ common_jstests_files =                                            \
        installed-tests/js/testGettext.js                       \
        installed-tests/js/testGIMarshalling.js                 \
        installed-tests/js/testGLib.js                          \
+       installed-tests/js/testGObject.js                       \
        installed-tests/js/testGObjectClass.js                  \
        installed-tests/js/testGObjectInterface.js              \
        installed-tests/js/testGTypeClass.js                    \
        installed-tests/js/testGio.js                           \
        installed-tests/js/testImporter.js                      \
+       installed-tests/js/testIntrospection.js                 \
        installed-tests/js/testLang.js                          \
        installed-tests/js/testLegacyByteArray.js               \
        installed-tests/js/testLegacyClass.js                   \
diff --git a/installed-tests/js/testEverythingBasic.js b/installed-tests/js/testEverythingBasic.js
index bd42deab..ffd5bb16 100644
--- a/installed-tests/js/testEverythingBasic.js
+++ b/installed-tests/js/testEverythingBasic.js
@@ -2,13 +2,10 @@ const Regress = imports.gi.Regress;
 const WarnLib = imports.gi.WarnLib;
 
 // We use Gio to have some objects that we know exist
-imports.gi.versions.Gdk = '3.0';
 imports.gi.versions.Gtk = '3.0';
-const Gdk = imports.gi.Gdk;
 const GLib = imports.gi.GLib;
 const Gio = imports.gi.Gio;
 const GObject = imports.gi.GObject;
-const Gtk = imports.gi.Gtk;
 
 describe('Life, the Universe and Everything', function () {
     it('includes booleans', function () {
@@ -115,18 +112,6 @@ describe('Life, the Universe and Everything', function () {
                 runTest(bytes, 'MAX', 'test_int');
             });
         });
-
-        it('warns when conversion is lossy', function () {
-            GLib.test_expect_message('Gjs', GLib.LogLevelFlags.LEVEL_WARNING,
-                '*cannot be safely stored*');
-            GLib.test_expect_message('Gjs', GLib.LogLevelFlags.LEVEL_WARNING,
-                '*cannot be safely stored*');
-            void GLib.MAXINT64;
-            void GLib.MAXUINT64;
-            GLib.test_assert_expected_messages_internal('Gjs',
-                'testEverythingBasic.js', 0,
-                'Limits warns when conversion is lossy');
-        });
     });
 
     describe('No implicit conversion to unsigned', function () {
@@ -137,11 +122,6 @@ describe('Life, the Universe and Everything', function () {
         });
     });
 
-    it('throws when constructor called without new', function () {
-        expect(() => Gio.AppLaunchContext())
-            .toThrowError(/Constructor called as normal method/);
-    });
-
     describe('String arrays', function () {
         it('marshalling in', function () {
             expect(Regress.test_strv_in(['1', '2', '3'])).toBeTruthy();
@@ -405,60 +385,10 @@ describe('Life, the Universe and Everything', function () {
             .toEqual('value2');
     });
 
-    it('enum has a $gtype property', function () {
-        expect(Regress.TestEnumUnsigned.$gtype).toBeDefined();
-    });
-
-    it('enum $gtype property is enumerable', function () {
-        expect('$gtype' in Regress.TestEnumUnsigned).toBeTruthy();
-    });
-
-    it('Number converts error to quark', function () {
-        expect(Regress.TestError.quark()).toEqual(Number(Regress.TestError));
-    });
-
     it('converts enum to string', function () {
         expect(Regress.TestEnum.param(Regress.TestEnum.VALUE4)).toEqual('value4');
     });
 
-    it('can be answered with GObject.set()', function () {
-        let o = new Regress.TestObj();
-        o.set({string: 'Answer', int: 42});
-        expect(o.string).toBe('Answer');
-        expect(o.int).toBe(42);
-    });
-
-    describe('Object properties on GtkBuilder-constructed objects', function () {
-        let o1;
-        beforeAll(function () {
-            Gtk.init(null);
-        });
-
-        beforeEach(function () {
-            const ui = `
-                <interface>
-                  <object class="GtkButton" id="button">
-                    <property name="label">Click me</property>
-                  </object>
-                </interface>`;
-
-            let builder = Gtk.Builder.new_from_string(ui, -1);
-            o1 = builder.get_object('button');
-        });
-
-        it('are found on the GObject itself', function () {
-            expect(o1.label).toBe('Click me');
-        });
-
-        it('are found on the GObject\'s parents', function () {
-            expect(o1.visible).toBeFalsy();
-        });
-
-        it('are found on the GObject\'s interfaces', function () {
-            expect(o1.action_name).toBeNull();
-        });
-    });
-
     describe('Object-valued GProperty', function () {
         let o1, t1, t2;
         beforeEach(function () {
@@ -578,30 +508,6 @@ describe('Life, the Universe and Everything', function () {
         }).pend('Not yet implemented');
     });
 
-    describe('Signal alternative syntax', function () {
-        let o, handler;
-        beforeEach(function () {
-            handler = jasmine.createSpy('handler');
-            o = new Regress.TestObj();
-            let handlerId = GObject.signal_connect(o, 'test', handler);
-            handler.and.callFake(() =>
-                GObject.signal_handler_disconnect(o, handlerId));
-
-            GObject.signal_emit_by_name(o, 'test');
-        });
-
-        it('handler is called with the right object', function () {
-            expect(handler).toHaveBeenCalledTimes(1);
-            expect(handler).toHaveBeenCalledWith(o);
-        });
-
-        it('disconnected handler is not called', function () {
-            handler.calls.reset();
-            GObject.signal_emit_by_name(o, 'test');
-            expect(handler).not.toHaveBeenCalled();
-        });
-    });
-
     it('torture signature 0', function () {
         let [y, z, q] = Regress.test_torture_signature_0(42, 'foo', 7);
         expect(Math.floor(y)).toEqual(42);
@@ -679,32 +585,6 @@ describe('Life, the Universe and Everything', function () {
         expect(Number(Gio.IOErrorEnum)).toEqual(Gio.io_error_quark());
     });
 
-    describe('thrown GError', function () {
-        let err;
-        beforeEach(function () {
-            try {
-                let file = Gio.file_new_for_path("\\/,.^!@&$_don't exist");
-                file.read(null);
-            } catch (x) {
-                err = x;
-            }
-        });
-
-        it('is an instance of error enum type', function () {
-            expect(err instanceof Gio.IOErrorEnum).toBeTruthy();
-        });
-
-        it('matches error domain and code', function () {
-            expect(err.matches(Gio.io_error_quark(), Gio.IOErrorEnum.NOT_FOUND))
-                .toBeTruthy();
-        });
-
-        it('has properties for domain and code', function () {
-            expect(err.domain).toEqual(Gio.io_error_quark());
-            expect(err.code).toEqual(Gio.IOErrorEnum.NOT_FOUND);
-        });
-    });
-
     it('GError callback', function (done) {
         Regress.test_gerror_callback(e => {
             expect(e instanceof Gio.IOErrorEnum).toBeTruthy();
@@ -842,9 +722,4 @@ describe('Life, the Universe and Everything', function () {
                 .not.toThrow();
         });
     });
-
-    it('presents GdkAtom as string', function () {
-        expect(Gdk.Atom.intern('CLIPBOARD', false)).toBe('CLIPBOARD');
-        expect(Gdk.Atom.intern('NONE', false)).toBe(null);
-    });
 });
diff --git a/installed-tests/js/testEverythingEncapsulated.js 
b/installed-tests/js/testEverythingEncapsulated.js
index 45d13cf3..fd42cd8d 100644
--- a/installed-tests/js/testEverythingEncapsulated.js
+++ b/installed-tests/js/testEverythingEncapsulated.js
@@ -1,5 +1,4 @@
-const {GLib, GObject, Regress} = imports.gi;
-const System = imports.system;
+const {GObject, Regress} = imports.gi;
 
 describe('Introspected structs', function () {
     let struct;
@@ -289,21 +288,6 @@ describe('Introspected function length', function () {
     });
 });
 
-describe('Garbage collection of introspected objects', function () {
-    // This tests a regression that would very rarely crash, but
-    // when run under valgrind this code would show use-after-free.
-    it('collects objects properly with signals connected', function (done) {
-        function orphanObject() {
-            let obj = new Regress.TestObj();
-            obj.connect('notify', () => {});
-        }
-
-        orphanObject();
-        System.gc();
-        GLib.idle_add(GLib.PRIORITY_LOW, () => done());
-    });
-});
-
 describe('Introspected interface', function () {
     const Implementor = GObject.registerClass({
         Implements: [Regress.TestInterface],
diff --git a/installed-tests/js/testExceptions.js b/installed-tests/js/testExceptions.js
index 66514f8e..8e7b1e1d 100644
--- a/installed-tests/js/testExceptions.js
+++ b/installed-tests/js/testExceptions.js
@@ -165,3 +165,29 @@ describe('Exception from function with too few arguments', function () {
         expect(() => file.read()).toThrowError(/Gio\.File\.read/);
     });
 });
+
+describe('thrown GError', function () {
+    let err;
+    beforeEach(function () {
+        try {
+            let file = Gio.file_new_for_path("\\/,.^!@&$_don't exist");
+            file.read(null);
+        } catch (x) {
+            err = x;
+        }
+    });
+
+    it('is an instance of error enum type', function () {
+        expect(err).toEqual(jasmine.any(Gio.IOErrorEnum));
+    });
+
+    it('matches error domain and code', function () {
+        expect(err.matches(Gio.io_error_quark(), Gio.IOErrorEnum.NOT_FOUND))
+            .toBeTruthy();
+    });
+
+    it('has properties for domain and code', function () {
+        expect(err.domain).toEqual(Gio.io_error_quark());
+        expect(err.code).toEqual(Gio.IOErrorEnum.NOT_FOUND);
+    });
+});
diff --git a/installed-tests/js/testGIMarshalling.js b/installed-tests/js/testGIMarshalling.js
index 50a76dee..915261a3 100644
--- a/installed-tests/js/testGIMarshalling.js
+++ b/installed-tests/js/testGIMarshalling.js
@@ -692,68 +692,6 @@ describe('Virtual function', function () {
     });
 });
 
-describe('GObject virtual function', function () {
-    it('can have its property read', function () {
-        expect(GObject.Object.prototype.vfunc_constructed).toBeTruthy();
-    });
-
-    it('can have its property overridden with an anonymous function', function () {
-        let callback;
-
-        let key = 'vfunc_constructed';
-
-        class _SimpleTestClass1 extends GObject.Object {}
-
-        if (GObject.Object.prototype.vfunc_constructed) {
-            let parentFunc = GObject.Object.prototype.vfunc_constructed;
-            _SimpleTestClass1.prototype[key] = function (...args) {
-                parentFunc.call(this, ...args);
-                callback('123');
-            };
-        } else {
-            _SimpleTestClass1.prototype[key] = function () {
-                callback('abc');
-            };
-        }
-
-        callback = jasmine.createSpy('callback');
-
-        const SimpleTestClass1 = GObject.registerClass({GTypeName: 'SimpleTestClass1'}, _SimpleTestClass1);
-        new SimpleTestClass1();
-
-        expect(callback).toHaveBeenCalledWith('123');
-    });
-
-    it('can access the parent prototype with super()', function () {
-        let callback;
-
-        class _SimpleTestClass2 extends GObject.Object {
-            vfunc_constructed() {
-                super.vfunc_constructed();
-                callback('vfunc_constructed');
-            }
-        }
-
-        callback = jasmine.createSpy('callback');
-
-        const SimpleTestClass2 = GObject.registerClass({GTypeName: 'SimpleTestClass2'}, _SimpleTestClass2);
-        new SimpleTestClass2();
-
-        expect(callback).toHaveBeenCalledWith('vfunc_constructed');
-    });
-
-    it('handles non-existing properties', function () {
-        const _SimpleTestClass3 = class extends GObject.Object {};
-
-        _SimpleTestClass3.prototype.vfunc_doesnt_exist = function () {};
-
-        if (GObject.Object.prototype.vfunc_doesnt_exist)
-            fail('Virtual function should not exist');
-
-        expect(() => GObject.registerClass({GTypeName: 'SimpleTestClass3'}, _SimpleTestClass3)).toThrow();
-    });
-});
-
 describe('Interface', function () {
     it('can be returned', function () {
         let ifaceImpl = new GIMarshallingTests.InterfaceImpl();
@@ -783,12 +721,3 @@ describe('GObject properties', function () {
         expect(() => (obj.some_readonly = 35)).toThrow();
     });
 });
-
-describe('GDestroyNotify parameters', function () {
-    it('throws when encountering a GDestroyNotify not associated with a callback', function () {
-        // the 'destroy' argument applies to the data, which is not supported in
-        // gobject-introspection
-        expect(() => Gio.MemoryInputStream.new_from_data('foobar'))
-            .toThrowError(/destroy/);
-    });
-});
diff --git a/installed-tests/js/testGObject.js b/installed-tests/js/testGObject.js
new file mode 100644
index 00000000..bf56bb17
--- /dev/null
+++ b/installed-tests/js/testGObject.js
@@ -0,0 +1,50 @@
+// This is where overrides in modules/overrides/GObject.js are tested, except
+// for the class machinery, interface machinery, and GObject.ParamSpec, which
+// are big enough to get their own files.
+
+const {GLib, GObject} = imports.gi;
+
+describe('GObject overrides', function () {
+    const TestObj = GObject.registerClass({
+        Properties: {
+            int: GObject.ParamSpec.int('int', '', '', GObject.ParamFlags.READWRITE,
+                0, GLib.MAXINT32, 0),
+            string: GObject.ParamSpec.string('string', '', '',
+                GObject.ParamFlags.READWRITE, ''),
+        },
+        Signals: {
+            test: {},
+        },
+    }, class TestObj extends GObject.Object {});
+
+    it('GObject.set()', function () {
+        const o = new TestObj();
+        o.set({string: 'Answer', int: 42});
+        expect(o.string).toBe('Answer');
+        expect(o.int).toBe(42);
+    });
+
+    describe('Signal alternative syntax', function () {
+        let o, handler;
+        beforeEach(function () {
+            handler = jasmine.createSpy('handler');
+            o = new TestObj();
+            const handlerId = GObject.signal_connect(o, 'test', handler);
+            handler.and.callFake(() =>
+                GObject.signal_handler_disconnect(o, handlerId));
+
+            GObject.signal_emit_by_name(o, 'test');
+        });
+
+        it('handler is called with the right object', function () {
+            expect(handler).toHaveBeenCalledTimes(1);
+            expect(handler).toHaveBeenCalledWith(o);
+        });
+
+        it('disconnected handler is not called', function () {
+            handler.calls.reset();
+            GObject.signal_emit_by_name(o, 'test');
+            expect(handler).not.toHaveBeenCalled();
+        });
+    });
+});
diff --git a/installed-tests/js/testGObjectClass.js b/installed-tests/js/testGObjectClass.js
index dafdec1a..0a68c576 100644
--- a/installed-tests/js/testGObjectClass.js
+++ b/installed-tests/js/testGObjectClass.js
@@ -390,3 +390,66 @@ describe('GObject class with decorator', function () {
             /\[object instance wrapper GType:Gjs_Derived jsobj@0x[a-f0-9]+ native@0x[a-f0-9]+\]/);
     });
 });
+
+describe('GObject virtual function', function () {
+    it('can have its property read', function () {
+        expect(GObject.Object.prototype.vfunc_constructed).toBeTruthy();
+    });
+
+    it('can have its property overridden with an anonymous function', function () {
+        let callback;
+
+        let key = 'vfunc_constructed';
+
+        class _SimpleTestClass1 extends GObject.Object {}
+
+        if (GObject.Object.prototype.vfunc_constructed) {
+            let parentFunc = GObject.Object.prototype.vfunc_constructed;
+            _SimpleTestClass1.prototype[key] = function (...args) {
+                parentFunc.call(this, ...args);
+                callback('123');
+            };
+        } else {
+            _SimpleTestClass1.prototype[key] = function () {
+                callback('abc');
+            };
+        }
+
+        callback = jasmine.createSpy('callback');
+
+        const SimpleTestClass1 = GObject.registerClass({GTypeName: 'SimpleTestClass1'}, _SimpleTestClass1);
+        new SimpleTestClass1();
+
+        expect(callback).toHaveBeenCalledWith('123');
+    });
+
+    it('can access the parent prototype with super()', function () {
+        let callback;
+
+        class _SimpleTestClass2 extends GObject.Object {
+            vfunc_constructed() {
+                super.vfunc_constructed();
+                callback('vfunc_constructed');
+            }
+        }
+
+        callback = jasmine.createSpy('callback');
+
+        const SimpleTestClass2 = GObject.registerClass({GTypeName: 'SimpleTestClass2'}, _SimpleTestClass2);
+        new SimpleTestClass2();
+
+        expect(callback).toHaveBeenCalledWith('vfunc_constructed');
+    });
+
+    it('handles non-existing properties', function () {
+        const _SimpleTestClass3 = class extends GObject.Object {};
+
+        _SimpleTestClass3.prototype.vfunc_doesnt_exist = function () {};
+
+        if (GObject.Object.prototype.vfunc_doesnt_exist)
+            fail('Virtual function should not exist');
+
+
+        expect(() => GObject.registerClass({GTypeName: 'SimpleTestClass3'}, _SimpleTestClass3)).toThrow();
+    });
+});
diff --git a/installed-tests/js/testIntrospection.js b/installed-tests/js/testIntrospection.js
new file mode 100644
index 00000000..814beb27
--- /dev/null
+++ b/installed-tests/js/testIntrospection.js
@@ -0,0 +1,105 @@
+// Various tests having to do with how introspection is implemented in GJS
+
+imports.gi.versions.Gdk = '3.0';
+imports.gi.versions.Gtk = '3.0';
+const {Gdk, Gio, GLib, GObject, Gtk} = imports.gi;
+const System = imports.system;
+
+describe('GLib.DestroyNotify parameter', function () {
+    it('throws when encountering a GDestroyNotify not associated with a callback', function () {
+        // the 'destroy' argument applies to the data, which is not supported in
+        // gobject-introspection
+        expect(() => Gio.MemoryInputStream.new_from_data('foobar'))
+            .toThrowError(/destroy/);
+    });
+});
+
+describe('Unsafe integer marshalling', function () {
+    it('warns when conversion is lossy', function () {
+        GLib.test_expect_message('Gjs', GLib.LogLevelFlags.LEVEL_WARNING,
+            '*cannot be safely stored*');
+        GLib.test_expect_message('Gjs', GLib.LogLevelFlags.LEVEL_WARNING,
+            '*cannot be safely stored*');
+        void GLib.MAXINT64;
+        void GLib.MAXUINT64;
+        GLib.test_assert_expected_messages_internal('Gjs',
+            'testEverythingBasic.js', 0,
+            'Limits warns when conversion is lossy');
+    });
+});
+
+describe('Constructor', function () {
+    it('throws when constructor called without new', function () {
+        expect(() => Gio.AppLaunchContext())
+            .toThrowError(/Constructor called as normal method/);
+    });
+});
+
+describe('Enum classes', function () {
+    it('enum has a $gtype property', function () {
+        expect(Gio.BusType.$gtype).toBeDefined();
+    });
+
+    it('enum $gtype property is enumerable', function () {
+        expect('$gtype' in Gio.BusType).toBeTruthy();
+    });
+});
+
+describe('GError domains', function () {
+    it('Number converts error to quark', function () {
+        expect(Gio.ResolverError.quark()).toEqual(Number(Gio.ResolverError));
+    });
+});
+
+describe('Object properties on GtkBuilder-constructed objects', function () {
+    let o1;
+    beforeAll(function () {
+        Gtk.init(null);
+    });
+
+    beforeEach(function () {
+        const ui = `
+            <interface>
+              <object class="GtkButton" id="button">
+                <property name="label">Click me</property>
+              </object>
+            </interface>`;
+
+        let builder = Gtk.Builder.new_from_string(ui, -1);
+        o1 = builder.get_object('button');
+    });
+
+    it('are found on the GObject itself', function () {
+        expect(o1.label).toBe('Click me');
+    });
+
+    it('are found on the GObject\'s parents', function () {
+        expect(o1.visible).toBeFalsy();
+    });
+
+    it('are found on the GObject\'s interfaces', function () {
+        expect(o1.action_name).toBeNull();
+    });
+});
+
+describe('Garbage collection of introspected objects', function () {
+    // This tests a regression that would very rarely crash, but
+    // when run under valgrind this code would show use-after-free.
+    it('collects objects properly with signals connected', function (done) {
+        function orphanObject() {
+            let obj = new GObject.Object();
+            obj.connect('notify', () => {});
+        }
+
+        orphanObject();
+        System.gc();
+        GLib.idle_add(GLib.PRIORITY_LOW, () => done());
+    });
+});
+
+describe('Gdk.Atom', function () {
+    it('is presented as string', function () {
+        expect(Gdk.Atom.intern('CLIPBOARD', false)).toBe('CLIPBOARD');
+        expect(Gdk.Atom.intern('NONE', false)).toBe(null);
+    });
+});


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]