// 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('intl_message_test');

#import('../lib/intl.dart');
#import('../../unittest/unittest.dart');
#import('../lib/message_lookup_local.dart');

/** Tests the MessageFormat library in dart. */

class Person {
  String firstName, lastName;
  Person(this.firstName, this.lastName);
}

main() {
  test('Run all tests', () {
    initializeMessages('en_US').then(expectAsync1(runTests));
  });
}

runTests(_) {
  test('Trivial Message', () {
    hello() => Intl.message('Hello, world!',
        desc: 'hello world string');
    expect(hello(), equals('Hello, world!'));
  });

  test('Message with one parameter', () {
    lucky(number) => Intl.message('Your lucky number is $number',
        desc: 'number str', examples: {'number': 2});
    expect(lucky(3), equals('Your lucky number is 3'));
  });

  test('Message with multiple plural cases (whole message)', () {
    emails(number) => Intl.message(
        Intl.plural(number,
          {'0': 'There are no emails left.',
           '1': 'There is one email left.',
           'other': 'There are $number emails left.'}),
          desc: 'Message telling user how many emails will be sent.',
          examples: {'number': 32});
    expect(emails(5), equals('There are 5 emails left.'));
    expect(emails(0), equals('There are no emails left.'));
    expect(emails(1), equals('There is one email left.'));
  });

  test('Message with multiple plural cases (partial message)', () {
    emails(number) => Intl.message(
      "There ${Intl.plural(number,
        {'0': 'are',
         '1': 'is',
         'other': 'are'})} $number messages left.",
          desc: 'Message telling user how many emails will be sent.',
          examples: {'number': 32});
    expect(emails(5), equals('There are 5 messages left.'));
    expect(emails(0), equals('There are 0 messages left.'));
    expect(emails(1), equals('There is 1 messages left.'));
  });

  test('Message with dictionary parameter', () {
    hello(dict) => Intl.message(
        "Hello, my name is ${dict['first']} ${dict['last']}",
        desc: "States a person's name.",
        examples: {'first': 'Ford', 'last': 'Prefect'});
    expect(hello({'first' : 'Ford', 'last' : 'Prefect'}),
      equals('Hello, my name is Ford Prefect'));
  });

  test('Message with object parameter', () {
    hello(person) => Intl.message(
        "Hello, my name is ${person.firstName} ${person.lastName}.",
        desc: "States a person's name.",
        examples: {'first': 'Ford', 'last' : 'Prefect'});
    var ford = new Person('Ford', 'Prefect');
    expect(hello(ford), equals('Hello, my name is Ford Prefect.'));
  });

  test('WithLocale test', () {
    hello() => Intl.message('locale=${Intl.getCurrentLocale()}',
        desc: 'explains the locale');
    expect(Intl.withLocale('en-US', () => hello()), equals('locale=en-US'));
  });

  test('Test passing locale', () {
    hello(a_locale) => Intl.message('locale=${Intl.getCurrentLocale()}',
        desc: 'explains the locale', locale: a_locale);
    expect(hello('en-US'), equals('locale=en_US'));
  });
}
