/*
 * 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,
    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;
};
