"use strict";

describe("interfaces", function () {

    describe("gpf.interfaces.IUnknown", function () {

        it("exists", function () {
            assert("function" === typeof gpf.interfaces.IUnknown);
        });

        it("is an interface", function () {
            var exceptionCaught;
            try {
                var instance = new gpf.interfaces.IUnknown();
                assert(instance);
            } catch (e) {
                exceptionCaught = e;
            }
            assert(exceptionCaught instanceof gpf.Error.InterfaceConstructorFunction);
        });

    });

    describe("gpf.interfaces.isImplementedBy", function () {

        function TestRawClass () {}
        TestRawClass.prototype = {
            queryInterface: function (oneParameter) {
                return oneParameter;
            }
        };

        var TestGPFClass = gpf.define({
            $class: "TestGPFClass",
            queryInterface: function (oneParameter) {
                return oneParameter;
            }
        });

        it("validates literal objects (using interface constructor)", function () {
            assert(true === gpf.interfaces.isImplementedBy(gpf.interfaces.IUnknown, {
                queryInterface: function (oneParameter) {
                    return oneParameter;
                }
            }));
        });

        it("validates instances from a raw JavaScript class (using interface name)", function () {
            var obj = new TestRawClass();
            assert(true === gpf.interfaces.isImplementedBy("gpf.interfaces.IUnknown", obj));
        });

        it("validates a raw JavaScript class", function () {
            assert(true === gpf.interfaces.isImplementedBy("gpf.interfaces.IUnknown", TestRawClass));
        });

        it("validates instances from a GPF class", function () {
            var obj = new TestGPFClass();
            assert(true === gpf.interfaces.isImplementedBy(gpf.interfaces.IUnknown, obj));
        });

        it("validates a GPF class", function () {
            assert(true === gpf.interfaces.isImplementedBy(gpf.interfaces.IUnknown, TestGPFClass));
        });

        it("rejects member if not a method", function () {
            assert(false === gpf.interfaces.isImplementedBy("gpf.interfaces.IUnknown", {
                queryInterface: "Not a method"
            }));
        });

        it("rejects member if parameters count does not match (none)", function () {
            assert(false === gpf.interfaces.isImplementedBy("gpf.interfaces.IUnknown", {
                queryInterface: function () {}
            }));
        });

        it("rejects member if parameters count does not match (more)", function () {
            assert(false === gpf.interfaces.isImplementedBy(gpf.interfaces.IUnknown, {
                queryInterface: function (a, b, c) {
                    return a + b + c;
                }
            }));
        });

    });

});

@@ -42,24 +42,52 @@
 ction () %7B%0A%0A
+    function _ignore () %7B%7D%0A%0A
     describe
@@ -2975,12 +2975,2027 @@
    %7D);%0A%0A
+    describe(%22gpf.interfaces.query%22, function () %7B%0A%0A        function ITest () %7B%7D%0A        ITest.prototype.test = function (a, b) %7B%0A            return a + b;%0A        %7D;%0A%0A        it(%22returns the object if it implements the interface (using interface name)%22, function () %7B%0A            var obj = %7B%0A                queryInterface: function (oneParameter) %7B%0A                    return oneParameter;%0A                %7D%0A            %7D;%0A            assert(obj === gpf.interfaces.query(%22gpf.interfaces.IUnknown%22, obj));%0A        %7D);%0A%0A        it(%22returns the object if it implements the interface (using interface specifier)%22, function () %7B%0A            var obj = %7B%0A                test: function (a, b) %7B%0A                    _ignore(a, b);%0A                %7D%0A            %7D;%0A            assert(obj === gpf.interfaces.query(ITest, obj));%0A        %7D);%0A%0A        it(%22returns null if IUnknown is implemented but not the expected interface%22, function () %7B%0A            assert(null === gpf.interfaces.query(ITest, %7B%0A                queryInterface: function (oneParameter) %7B%0A                    _ignore(oneParameter);%0A                    return null; // Because this is the expected interface%0A                %7D%0A            %7D));%0A        %7D);%0A%0A        it(%22uses IUnknown to get the expected interface%22, function () %7B%0A            assert(null !== gpf.interfaces.query(ITest, %7B%0A                queryInterface: function (interfaceSpecifier) %7B%0A                    assert(interfaceSpecifier === ITest);%0A                    return %7B%0A                        test: function (a, b) %7B%0A                            _ignore(a, b);%0A                        %7D%0A                    %7D;%0A                %7D%0A            %7D));%0A        %7D);%0A%0A        it(%22returns undefined if neither the expected interface or IUnknown are implemented%22, function () %7B%0A            assert(undefined === gpf.interfaces.query(ITest, %7B%0A                queryInterface: function () %7B // Not matching IUnknown%0A                    return null;%0A                %7D%0A            %7D));%0A        %7D);%0A%0A    %7D);%0A%0A
 %7D);%0A

FIX #150