blob: 340197110fb60408b88d822a2d2ef525bf58c2eb [file] [log] [blame]
/**
* Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
* for details. All rights reserved. Use of this source code is governed by a
* BSD-style license that can be found in the LICENSE file.
*/
library number_format_test;
import 'package:unittest/unittest.dart';
import 'package:intl/number_symbols_data.dart';
import 'package:intl/intl.dart';
import 'number_test_data.dart';
import 'dart:math';
/**
* Tests the Numeric formatting library in dart.
*/
var testNumbersWeCanReadBack = {
"0.001": 0.001,
"0.01": 0.01,
"0.1": 0.1,
"1": 1,
"2": 2.0,
"10": 10,
"100": 100,
"1,000": 1000,
"2,000,000,000,000": 2000000000000,
"0.123": 0.123,
"1,234": 1234.0,
"1.234": 1.234,
"1.23": 1.230,
"NaN": double.NAN,
"∞": double.INFINITY,
"-∞": double.NEGATIVE_INFINITY,
};
/** Test numbers that we can't parse because we lose precision in formatting.*/
var testNumbersWeCannotReadBack = {
"3.142" : PI,
};
/** Test numbers that won't work in Javascript because they're too big. */
var testNumbersOnlyForTheVM = {
"10,000,000,000,000,000,000,000,000,000,000" :
10000000000000000000000000000000,
};
get allTestNumbers =>
new Map.from(testNumbersWeCanReadBack)
..addAll(testNumbersWeCannotReadBack)
..addAll(inJavaScript() ? {} : testNumbersOnlyForTheVM);
var testExponential = const {
"1E-3" : 0.001,
"1E-2": 0.01,
"1.23E0" : 1.23
};
// TODO(alanknight): Test against currency, which requires generating data
// for the three different forms that this now supports.
// TODO(alanknight): Test against scientific, which requires significant
// digit support.
List<NumberFormat> standardFormats(String locale) {
return [
new NumberFormat.decimalPattern(locale),
new NumberFormat.percentPattern(locale)
];
}
// Pay no attention to the hint. This is here deliberately to have different
// behavior in the Dart VM versus Javascript so we can distinguish the two.
inJavaScript() => 1 is double;
main() {
// For data from a list of locales, run each locale's data as a separate
// test so we can see exactly which ones pass or fail.
var mainList = numberTestData;
var sortedLocales = new List.from(numberFormatSymbols.keys);
sortedLocales.sort((a, b) => a.compareTo(b));
for (var locale in sortedLocales) {
var testFormats = standardFormats(locale);
var list = mainList.take(testFormats.length + 1).iterator;
mainList = mainList.skip(testFormats.length + 1);
var nextLocaleFromList = (list..moveNext()).current;
test("Test against ICU data for $locale", () {
expect(locale, nextLocaleFromList);
for (var format in testFormats) {
var formatted = format.format(123);
var expected = (list..moveNext()).current;
expect(formatted, expected);
var readBack = format.parse(formatted);
expect(readBack, 123);
}
});
}
test('Simple set of numbers', () {
var number = new NumberFormat();
for (var x in allTestNumbers.keys) {
var formatted = number.format(allTestNumbers[x]);
expect(formatted, x);
if (!testNumbersWeCannotReadBack.containsKey(x)) {
var readBack = number.parse(formatted);
// Even among ones we can read back, we can't test NaN for equality.
if (allTestNumbers[x].isNaN) {
expect(readBack.isNaN, isTrue);
} else {
expect(readBack, allTestNumbers[x]);
}
}
}
});
test('Exponential form', () {
var number = new NumberFormat("#.###E0");
for (var x in testExponential.keys) {
var formatted = number.format(testExponential[x]);
expect(formatted, x);
var readBack = number.parse(formatted);
expect(testExponential[x], readBack);
}
});
test('Explicit currency name', () {
var amount = 1000000.32;
var usConvention = new NumberFormat.currencyPattern('en_US', '€');
var formatted = usConvention.format(amount);
expect(formatted, '€1,000,000.32');
var readBack = usConvention.parse(formatted);
expect(readBack, amount);
var swissConvention = new NumberFormat.currencyPattern('de_CH', r'$');
formatted = swissConvention.format(amount);
var nbsp = new String.fromCharCode(0xa0);
expect(formatted, r"$" + nbsp + "1'000'000.32");
readBack = swissConvention.parse(formatted);
expect(readBack, amount);
/// Verify we can leave off the currency and it gets filled in.
var plainSwiss = new NumberFormat.currencyPattern('de_CH');
formatted = plainSwiss.format(amount);
expect(formatted, r"CHF" + nbsp + "1'000'000.32");
readBack = plainSwiss.parse(formatted);
expect(readBack, amount);
// Verify that we can pass null in order to specify the currency symbol
// but use the default locale.
var defaultLocale = new NumberFormat.currencyPattern(null, 'Smurfs');
formatted = defaultLocale.format(amount);
// We don't know what the exact format will be, but it should have Smurfs.
expect(formatted.contains('Smurfs'), isTrue);
readBack = defaultLocale.parse(formatted);
expect(readBack, amount);
});
test('Unparseable', () {
var format = new NumberFormat.currencyPattern();
expect(() => format.parse("abcdefg"), throwsFormatException);
expect(() => format.parse(""), throwsFormatException);
expect(() => format.parse("1.0zzz"), throwsFormatException);
expect(() => format.parse("-∞+1"), throwsFormatException);
});
}