1ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/*
2ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru**********************************************************************
385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho*   Copyright (C) 1999-2009, International Business Machines
4ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru*   Corporation and others.  All Rights Reserved.
5ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru**********************************************************************
6ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru*   Date        Name        Description
7ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru*   12/09/99    aliu        Ported from Java.
8ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru**********************************************************************
9ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru*/
10ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
11ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "unicode/utypes.h"
12ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
13ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#if !UCONFIG_NO_COLLATION
14ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
15ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "thcoll.h"
16ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "unicode/utypes.h"
17ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "unicode/coll.h"
18ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "unicode/sortkey.h"
19ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "unicode/ustring.h"
20ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "cstring.h"
21ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "filestrm.h"
22ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "textfile.h"
23ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
24ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/**
25ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * The TestDictionary test expects a file of this name, with this
26ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * encoding, to be present in the directory $ICU/source/test/testdata.
27ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru */
28ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru//#define TEST_FILE           "th18057.txt"
29ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
30ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/**
31ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * This is the most failures we show in TestDictionary.  If this number
32ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * is < 0, we show all failures.
33ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru */
34ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#define MAX_FAILURES_TO_SHOW -1
35ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
36ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruCollationThaiTest::CollationThaiTest() {
37ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    UErrorCode status = U_ZERO_ERROR;
38ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    coll = Collator::createInstance(Locale("th", "TH", ""), status);
39ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if (coll && U_SUCCESS(status)) {
40ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        //coll->setStrength(Collator::TERTIARY);
41ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    } else {
42ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        delete coll;
43ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        coll = 0;
44ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
45ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
46ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
47ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruCollationThaiTest::~CollationThaiTest() {
48ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    delete coll;
49ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
50ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
51ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruvoid CollationThaiTest::runIndexedTest(int32_t index, UBool exec, const char* &name,
52ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                                       char* /*par*/) {
53ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
54ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if((!coll) && exec) {
5585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho      dataerrln(__FILE__ " cannot test - failed to create collator.");
56ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru      name = "some test";
57ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru      return;
58ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
59ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
60ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    switch (index) {
61ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        TESTCASE(0,TestDictionary);
62ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        TESTCASE(1,TestCornerCases);
63ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        TESTCASE(2,TestNamesList);
64ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        TESTCASE(3,TestInvalidThai);
65ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        TESTCASE(4,TestReordering);
66ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        default: name = ""; break;
67ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
68ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
69ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
70ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/**
71ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * Read the external names list, and confirms that the collator
72ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * gets the same results when comparing lines one to another
73ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * using regular and iterative comparison.
74ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru */
75ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruvoid CollationThaiTest::TestNamesList(void) {
76ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if (coll == 0) {
77ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        errln("Error: could not construct Thai collator");
78ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        return;
79ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
80ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
81ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    UErrorCode ec = U_ZERO_ERROR;
82ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    TextFile names("TestNames_Thai.txt", "UTF16LE", ec);
83ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if (U_FAILURE(ec)) {
84ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        logln("Can't open TestNames_Thai.txt: %s; skipping test",
85ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru              u_errorName(ec));
86ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        return;
87ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
88ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
89ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    //
90ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    // Loop through each word in the dictionary and compare it to the previous
91ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    // word.  They should be in sorted order.
92ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    //
93ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    UnicodeString lastWord, word;
94ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    //int32_t failed = 0;
95ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    int32_t wordCount = 0;
96ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    while (names.readLineSkippingComments(word, ec, FALSE) && U_SUCCESS(ec)) {
97ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
98ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        // Show the first 8 words being compared, so we can see what's happening
99ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        ++wordCount;
100ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        if (wordCount <= 8) {
101ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            UnicodeString str;
102ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            logln((UnicodeString)"Word " + wordCount + ": " + IntlTest::prettify(word, str));
103ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
104ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
105ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        if (lastWord.length() > 0) {
106ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            Collator::EComparisonResult result = coll->compare(lastWord, word);
107ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            doTest(coll, lastWord, word, result);
108ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
109ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        lastWord = word;
110ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
111ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
112ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    assertSuccess("readLine", ec);
113ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
114ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    logln((UnicodeString)"Words checked: " + wordCount);
115ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
116ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
117ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/**
118ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * Read the external dictionary file, which is already in proper
119ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * sorted order, and confirm that the collator compares each line as
120ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * preceding the following line.
121ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru */
122ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruvoid CollationThaiTest::TestDictionary(void) {
123ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if (coll == 0) {
124ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        errln("Error: could not construct Thai collator");
125ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        return;
126ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
127ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
128ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    UErrorCode ec = U_ZERO_ERROR;
129ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    TextFile riwords("riwords.txt", "UTF8", ec);
130ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if (U_FAILURE(ec)) {
131ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        logln("Can't open riwords.txt: %s; skipping test",
132ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru              u_errorName(ec));
133ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        return;
134ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
135ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
136ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    //
137ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    // Loop through each word in the dictionary and compare it to the previous
138ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    // word.  They should be in sorted order.
139ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    //
140ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    UnicodeString lastWord, word;
141ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    int32_t failed = 0;
142ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    int32_t wordCount = 0;
143ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    while (riwords.readLineSkippingComments(word, ec, FALSE) && U_SUCCESS(ec)) {
144ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
145ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        // Show the first 8 words being compared, so we can see what's happening
146ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        ++wordCount;
147ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        if (wordCount <= 8) {
148ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            UnicodeString str;
149ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            logln((UnicodeString)"Word " + wordCount + ": " + IntlTest::prettify(word, str));
150ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
151ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
152ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        if (lastWord.length() > 0) {
153ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            // line enabled for j2720
154ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            doTest(coll, lastWord, word, Collator::LESS);
155ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            int32_t result = coll->compare(lastWord, word);
156ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
157ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            if (result >= 0) {
158ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                failed++;
159ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                if (MAX_FAILURES_TO_SHOW < 0 || failed <= MAX_FAILURES_TO_SHOW) {
160ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                    UnicodeString str;
161ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                    UnicodeString msg =
162ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                        UnicodeString("--------------------------------------------\n")
163ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                        + riwords.getLineNumber()
164ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                        + " compare(" + IntlTest::prettify(lastWord, str);
165ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                    msg += UnicodeString(", ")
166ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                        + IntlTest::prettify(word, str) + ") returned " + result
167ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                        + ", expected -1\n";
168ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                    UErrorCode status = U_ZERO_ERROR;
169ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                    CollationKey k1, k2;
170ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                    coll->getCollationKey(lastWord, k1, status);
171ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                    coll->getCollationKey(word, k2, status);
172ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                    if (U_FAILURE(status)) {
173ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                        errln((UnicodeString)"Fail: getCollationKey returned " + u_errorName(status));
174ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                        return;
175ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                    }
176ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                    msg.append("key1: ").append(prettify(k1, str)).append("\n");
177ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                    msg.append("key2: ").append(prettify(k2, str));
178ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                    errln(msg);
179ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                }
180ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            }
181ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
182ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        lastWord = word;
183ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
184ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
185ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    assertSuccess("readLine", ec);
186ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
187ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if (failed != 0) {
188ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        if (failed > MAX_FAILURES_TO_SHOW) {
189ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            errln((UnicodeString)"Too many failures; only the first " +
190ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                  MAX_FAILURES_TO_SHOW + " failures were shown");
191ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
192ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        errln((UnicodeString)"Summary: " + failed + " of " + (riwords.getLineNumber() - 1) +
193ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru              " comparisons failed");
194ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
195ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
196ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    logln((UnicodeString)"Words checked: " + wordCount);
197ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
198ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
199ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/**
200ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * Odd corner conditions taken from "How to Sort Thai Without Rewriting Sort",
201ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * by Doug Cooper, http://seasrc.th.net/paper/thaisort.zip
202ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru */
203ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruvoid CollationThaiTest::TestCornerCases(void) {
204ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    const char* TESTS[] = {
205ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        // Shorter words precede longer
206ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        "\\u0e01",                               "<",    "\\u0e01\\u0e01",
207ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
208ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        // Tone marks are considered after letters (i.e. are primary ignorable)
209ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        "\\u0e01\\u0e32",                        "<",    "\\u0e01\\u0e49\\u0e32",
210ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
211ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        // ditto for other over-marks
212ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        "\\u0e01\\u0e32",                        "<",    "\\u0e01\\u0e32\\u0e4c",
213ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
214ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        // commonly used mark-in-context order.
215ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        // In effect, marks are sorted after each syllable.
216ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        "\\u0e01\\u0e32\\u0e01\\u0e49\\u0e32",   "<",    "\\u0e01\\u0e48\\u0e32\\u0e01\\u0e49\\u0e32",
217ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
218ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        // Hyphens and other punctuation follow whitespace but come before letters
219ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        "\\u0e01\\u0e32",                        "<",    "\\u0e01\\u0e32-",
220ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        "\\u0e01\\u0e32-",                       "<",    "\\u0e01\\u0e32\\u0e01\\u0e32",
221ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
222ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        // Doubler follows an indentical word without the doubler
223ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        "\\u0e01\\u0e32",                        "<",    "\\u0e01\\u0e32\\u0e46",
224ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        "\\u0e01\\u0e32\\u0e46",                 "<",    "\\u0e01\\u0e32\\u0e01\\u0e32",
225ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
226ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
227ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        // \\u0e45 after either \\u0e24 or \\u0e26 is treated as a single
228ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        // combining character, similar to "c < ch" in traditional spanish.
229ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        // TODO: beef up this case
230ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        "\\u0e24\\u0e29\\u0e35",                 "<",    "\\u0e24\\u0e45\\u0e29\\u0e35",
231ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        "\\u0e26\\u0e29\\u0e35",                 "<",    "\\u0e26\\u0e45\\u0e29\\u0e35",
232ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
233ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        // Vowels reorder, should compare \\u0e2d and \\u0e34
234ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        "\\u0e40\\u0e01\\u0e2d",                 "<",    "\\u0e40\\u0e01\\u0e34",
235ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
236ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        // Tones are compared after the rest of the word (e.g. primary ignorable)
237ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        "\\u0e01\\u0e32\\u0e01\\u0e48\\u0e32",   "<",    "\\u0e01\\u0e49\\u0e32\\u0e01\\u0e32",
238ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
239ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        // Periods are ignored entirely
240ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        "\\u0e01.\\u0e01.",                      "<",    "\\u0e01\\u0e32",
241ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    };
242ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    const int32_t TESTS_length = (int32_t)(sizeof(TESTS)/sizeof(TESTS[0]));
243ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
244ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if (coll == 0) {
245ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        errln("Error: could not construct Thai collator");
246ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        return;
247ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
248ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    compareArray(*coll, TESTS, TESTS_length);
249ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
250ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
251ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru//------------------------------------------------------------------------
252ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// Internal utilities
253ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru//------------------------------------------------------------------------
254ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
255ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruvoid CollationThaiTest::compareArray(Collator& c, const char* tests[],
256ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                                     int32_t testsLength) {
257ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    for (int32_t i = 0; i < testsLength; i += 3) {
258ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
259ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        Collator::EComparisonResult expect;
260ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        if (tests[i+1][0] == '<') {
261ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru          expect = Collator::LESS;
262ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        } else if (tests[i+1][0] == '>') {
263ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru          expect = Collator::GREATER;
264ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        } else if (tests[i+1][0] == '=') {
265ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru          expect = Collator::EQUAL;
266ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        } else {
267ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            // expect = Integer.decode(tests[i+1]).intValue();
268ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            errln((UnicodeString)"Error: unknown operator " + tests[i+1]);
269ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            return;
270ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
271ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
272ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        UnicodeString s1, s2;
273ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        parseChars(s1, tests[i]);
274ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        parseChars(s2, tests[i+2]);
275ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
276ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        doTest(&c, s1, s2, expect);
277ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#if 0
278ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        UErrorCode status = U_ZERO_ERROR;
279ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        int32_t result = c.compare(s1, s2);
280ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        if (sign(result) != sign(expect))
281ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        {
282ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            UnicodeString t1, t2;
283ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            errln(UnicodeString("") +
284ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                  i/3 + ": compare(" + IntlTest::prettify(s1, t1)
285ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                  + " , " + IntlTest::prettify(s2, t2)
286ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                  + ") got " + result + "; expected " + expect);
287ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
288ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            CollationKey k1, k2;
289ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            c.getCollationKey(s1, k1, status);
290ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            c.getCollationKey(s2, k2, status);
291ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            if (U_FAILURE(status)) {
292ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                errln((UnicodeString)"Fail: getCollationKey returned " + u_errorName(status));
293ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                return;
294ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            }
295ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            errln((UnicodeString)"  key1: " + prettify(k1, t1) );
296ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            errln((UnicodeString)"  key2: " + prettify(k2, t2) );
297ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
298ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        else
299ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        {
300ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            // Collator.compare worked OK; now try the collation keys
301ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            CollationKey k1, k2;
302ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            c.getCollationKey(s1, k1, status);
303ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            c.getCollationKey(s2, k2, status);
304ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            if (U_FAILURE(status)) {
305ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                errln((UnicodeString)"Fail: getCollationKey returned " + u_errorName(status));
306ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                return;
307ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            }
308ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
309ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            result = k1.compareTo(k2);
310ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            if (sign(result) != sign(expect)) {
311ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                UnicodeString t1, t2;
312ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                errln(UnicodeString("") +
313ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                      i/3 + ": key(" + IntlTest::prettify(s1, t1)
314ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                      + ").compareTo(key(" + IntlTest::prettify(s2, t2)
315ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                      + ")) got " + result + "; expected " + expect);
316ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
317ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                errln((UnicodeString)"  " + prettify(k1, t1) + " vs. " + prettify(k2, t2));
318ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            }
319ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
320ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#endif
321ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
322ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
323ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
324ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruint8_t CollationThaiTest::sign(int32_t i) {
325ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if (i < 0) return -1;
326ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if (i > 0) return 1;
327ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    return 0;
328ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
329ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
330ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/**
331ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * Set a UnicodeString corresponding to the given string.  Use
332ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * UnicodeString and the default converter, unless we see the sequence
333ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * "\\u", in which case we interpret the subsequent escape.
334ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru */
335ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruUnicodeString& CollationThaiTest::parseChars(UnicodeString& result,
336ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                                             const char* chars) {
337ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    return result = CharsToUnicodeString(chars);
338ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
339ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
340ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruUCollator *thaiColl = NULL;
341ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
342ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruU_CDECL_BEGIN
343ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic int U_CALLCONV
344ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruStrCmp(const void *p1, const void *p2) {
345ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru  return ucol_strcoll(thaiColl, *(UChar **) p1, -1,  *(UChar **)p2, -1);
346ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
347ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruU_CDECL_END
348ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
349ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
350ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#define LINES 6
351ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
352ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruvoid CollationThaiTest::TestInvalidThai(void) {
353ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru  const char *tests[LINES] = {
354ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    "\\u0E44\\u0E01\\u0E44\\u0E01",
355ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    "\\u0E44\\u0E01\\u0E01\\u0E44",
356ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    "\\u0E01\\u0E44\\u0E01\\u0E44",
357ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    "\\u0E01\\u0E01\\u0E44\\u0E44",
358ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    "\\u0E44\\u0E44\\u0E01\\u0E01",
359ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    "\\u0E01\\u0E44\\u0E44\\u0E01",
360ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru  };
361ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
362ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru  UChar strings[LINES][20];
363ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
364ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru  UChar *toSort[LINES];
365ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
366ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru  int32_t i = 0, j = 0, len = 0;
367ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
368ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru  UErrorCode coll_status = U_ZERO_ERROR;
369ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru  UnicodeString iteratorText;
370ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
371ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru  thaiColl = ucol_open ("th_TH", &coll_status);
372ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru  if (U_FAILURE(coll_status)) {
373ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    errln("Error opening Thai collator: %s", u_errorName(coll_status));
374ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    return;
375ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru  }
376ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
377ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru  CollationElementIterator* c = ((RuleBasedCollator *)coll)->createCollationElementIterator( iteratorText );
378ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
379ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru  for(i = 0; i < (int32_t)(sizeof(tests)/sizeof(tests[0])); i++) {
380ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    len = u_unescape(tests[i], strings[i], 20);
381ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    strings[i][len] = 0;
382ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    toSort[i] = strings[i];
383ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru  }
384ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
385ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru  qsort (toSort, LINES, sizeof (UChar *), StrCmp);
386ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
387ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru  for (i=0; i < LINES; i++)
388ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru  {
389ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    logln("%i", i);
390ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru      for (j=i+1; j < LINES; j++) {
391ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru          if (ucol_strcoll (thaiColl, toSort[i], -1, toSort[j], -1) == UCOL_GREATER)
392ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru          {
393ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru              // inconsistency ordering found!
394ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            errln("Inconsistent ordering between strings %i and %i", i, j);
395ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru          }
396ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru      }
397ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru      iteratorText.setTo(toSort[i]);
398ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru      c->setText(iteratorText, coll_status);
399ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru      backAndForth(*c);
400ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru  }
401ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
402ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
403ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru  ucol_close(thaiColl);
404ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru  delete c;
405ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
406ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
407ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruvoid CollationThaiTest::TestReordering(void) {
408ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru  const char *tests[] = {
409ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                          "\\u0E41c\\u0301",       "=", "\\u0E41\\u0107", // composition
410ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                          "\\u0E41\\uD835\\uDFCE", "<", "\\u0E41\\uD835\\uDFCF", // supplementaries
411ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                          "\\u0E41\\uD834\\uDD5F", "=", "\\u0E41\\uD834\\uDD58\\uD834\\uDD65", // supplementary composition decomps to supplementary
412ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                          "\\u0E41\\uD87E\\uDC02", "=", "\\u0E41\\u4E41", // supplementary composition decomps to BMP
413ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                          "\\u0E41\\u0301",        "=", "\\u0E41\\u0301", // unsafe (just checking backwards iteration)
414ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                          "\\u0E41\\u0301\\u0316", "=", "\\u0E41\\u0316\\u0301",
415ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                          // after UCA 4.1, the two lines below are not equal anymore do not have equal sign
416ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                          "\\u0e24\\u0e41",        "<", "\\u0e41\\u0e24", // exiting contraction bug
417ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                          "\\u0e3f\\u0e3f\\u0e24\\u0e41", "<", "\\u0e3f\\u0e3f\\u0e41\\u0e24",
418ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
419ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                          "abc\\u0E41c\\u0301",       "=", "abc\\u0E41\\u0107", // composition
420ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                          "abc\\u0E41\\uD834\\uDC00", "<", "abc\\u0E41\\uD834\\uDC01", // supplementaries
421ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                          "abc\\u0E41\\uD834\\uDD5F", "=", "abc\\u0E41\\uD834\\uDD58\\uD834\\uDD65", // supplementary composition decomps to supplementary
422ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                          "abc\\u0E41\\uD87E\\uDC02", "=", "abc\\u0E41\\u4E41", // supplementary composition decomps to BMP
423ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                          "abc\\u0E41\\u0301",        "=", "abc\\u0E41\\u0301", // unsafe (just checking backwards iteration)
424ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                          "abc\\u0E41\\u0301\\u0316", "=", "abc\\u0E41\\u0316\\u0301",
425ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
426ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                          "\\u0E41c\\u0301abc",       "=", "\\u0E41\\u0107abc", // composition
427ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                          "\\u0E41\\uD834\\uDC00abc", "<", "\\u0E41\\uD834\\uDC01abc", // supplementaries
428ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                          "\\u0E41\\uD834\\uDD5Fabc", "=", "\\u0E41\\uD834\\uDD58\\uD834\\uDD65abc", // supplementary composition decomps to supplementary
429ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                          "\\u0E41\\uD87E\\uDC02abc", "=", "\\u0E41\\u4E41abc", // supplementary composition decomps to BMP
430ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                          "\\u0E41\\u0301abc",        "=", "\\u0E41\\u0301abc", // unsafe (just checking backwards iteration)
431ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                          "\\u0E41\\u0301\\u0316abc", "=", "\\u0E41\\u0316\\u0301abc",
432ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
433ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                          "abc\\u0E41c\\u0301abc",       "=", "abc\\u0E41\\u0107abc", // composition
434ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                          "abc\\u0E41\\uD834\\uDC00abc", "<", "abc\\u0E41\\uD834\\uDC01abc", // supplementaries
435ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                          "abc\\u0E41\\uD834\\uDD5Fabc", "=", "abc\\u0E41\\uD834\\uDD58\\uD834\\uDD65abc", // supplementary composition decomps to supplementary
436ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                          "abc\\u0E41\\uD87E\\uDC02abc", "=", "abc\\u0E41\\u4E41abc", // supplementary composition decomps to BMP
437ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                          "abc\\u0E41\\u0301abc",        "=", "abc\\u0E41\\u0301abc", // unsafe (just checking backwards iteration)
438ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                          "abc\\u0E41\\u0301\\u0316abc", "=", "abc\\u0E41\\u0316\\u0301abc",
439ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                        };
440ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
441ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru  compareArray(*coll, tests, sizeof(tests)/sizeof(tests[0]));
442ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
443ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru  const char *rule = "& c < ab";
444ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru  const char *testcontraction[] = { "\\u0E41ab", ">", "\\u0E41c"}; // After UCA 4.1 Thai are normal so won't break a contraction
445ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru  UnicodeString rules;
446ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru  UErrorCode status = U_ZERO_ERROR;
447ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru  parseChars(rules, rule);
448ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru  RuleBasedCollator *rcoll = new RuleBasedCollator(rules, status);
449ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru  if(U_SUCCESS(status)) {
450ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    compareArray(*rcoll, testcontraction, 3);
451ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    delete rcoll;
452ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru  } else {
453ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    errln("Couldn't instantiate collator from rules");
454ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru  }
455ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
456ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
457ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
458ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
459ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#endif /* #if !UCONFIG_NO_COLLATION */
460