/*
 * Copyright (C) 2013 Google Inc. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1.  Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 * 2.  Redistributions in binary form must reproduce the above copyright
 *     notice, this list of conditions and the following disclaimer in the
 *     documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

[
    LegacyNoInterfaceObject,
    ImplementationLacksVTable,
    ExportMacro=WEBCORE_TESTSUPPORT_EXPORT,
] interface TypeConversions {
    attribute byte testByte;
    attribute [EnforceRange] byte testEnforceRangeByte;
    attribute [Clamp] byte testClampByte;
    attribute octet testOctet;
    attribute [EnforceRange] octet testEnforceRangeOctet;
    attribute [Clamp] octet testClampOctet;

    attribute short testShort;
    attribute [EnforceRange] short testEnforceRangeShort;
    attribute [Clamp] short testClampShort;
    attribute unsigned short testUnsignedShort;
    attribute [EnforceRange] unsigned short testEnforceRangeUnsignedShort;
    attribute [Clamp] unsigned short testClampUnsignedShort;

    attribute long testLong;
    attribute [EnforceRange] long testEnforceRangeLong;
    attribute [Clamp] long testClampLong;
    attribute unsigned long testUnsignedLong;
    attribute [EnforceRange] unsigned long testEnforceRangeUnsignedLong;
    attribute [Clamp] unsigned long testClampUnsignedLong;

    attribute long long testLongLong;
    attribute [EnforceRange] long long testEnforceRangeLongLong;
    attribute [Clamp] long long testClampLongLong;
    attribute unsigned long long testUnsignedLongLong;
    attribute [EnforceRange] unsigned long long testEnforceRangeUnsignedLongLong;
    attribute [Clamp] unsigned long long testClampUnsignedLongLong;

    readonly attribute unrestricted double testImpureNaNUnrestrictedDouble;
    readonly attribute unrestricted double testImpureNaN2UnrestrictedDouble;
    readonly attribute unrestricted double testQuietNaNUnrestrictedDouble;
    readonly attribute unrestricted double testPureNaNUnrestrictedDouble;

    attribute float testFloat;
    attribute unrestricted float testUnrestrictedFloat;

    attribute DOMString testString;
    attribute ByteString testByteString;
    attribute USVString testUSVString;
    attribute [LegacyNullToEmptyString] DOMString testTreatNullAsEmptyString;

    undefined setTestLongRecord(record<DOMString, long> record);
    record<DOMString, long> testLongRecord();

    undefined setTestNodeRecord(record<USVString, Node> record);
    record<USVString, Node> testNodeRecord();

    undefined setTestSequenceRecord(record<ByteString, sequence<DOMString>> record);
    record<ByteString, sequence<DOMString>> testSequenceRecord();

    attribute (DOMString or long or boolean or Node or sequence<long>) testUnion;

    attribute TypeConversionsDictionary testDictionary;

    attribute (DOMString or [Clamp] long or sequence<[Clamp] long>) testClampUnion;
    attribute (DOMString or [EnforceRange] long or sequence<[EnforceRange] long>) testEnforceRangeUnion;
    attribute ([LegacyNullToEmptyString] DOMString or long or sequence<[LegacyNullToEmptyString] DOMString>) testTreatNullAsEmptyStringUnion;
};

[
    JSGenerateToJSObject
] dictionary TypeConversionsOtherDictionary {
    long longValue = 0;
    DOMString stringValue = "";
};

[
    JSGenerateToJSObject
] dictionary TypeConversionsDictionary {
    long longValue = 0;
    DOMString stringValue = "";
    [LegacyNullToEmptyString] DOMString treatNullAsEmptyStringValue = "";
    sequence<DOMString> sequenceValue = [];
    (Node or sequence<DOMString> or TypeConversionsOtherDictionary) unionValue = null;
    [Clamp] long clampLongValue = 0;
    [EnforceRange] long enforceRangeLongValue = 0;
};
