/*
 * Copyright 2008 Google Inc.
 * 
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 * 
 * http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */
package com.google.gwt.dom.client;

import com.google.gwt.junit.client.GWTTestCase;

/**
 * Tests the {@link SelectElement} and {@link OptionElement} classes.
 */
public class SelectTests extends GWTTestCase {

  @Override
  public String getModuleName() {
    return "com.google.gwt.dom.DOMTest";
  }

  /**
   * add, remove
   */
  public void testAddRemove() {
    Document doc = Document.get();
    SelectElement select = doc.createSelectElement();
    doc.getBody().appendChild(select);

    OptionElement opt0 = doc.createOptionElement();
    OptionElement opt1 = doc.createOptionElement();
    OptionElement opt2 = doc.createOptionElement();
    opt0.setText("foo");
    opt1.setText("bar");
    opt2.setText("baz");
    opt0.setValue("0");
    opt1.setValue("1");
    opt2.setValue("2");

    select.appendChild(opt0);
    select.appendChild(opt1);
    select.appendChild(opt2);

    assertEquals("3 options expected", 3, select.getOptions().getLength());
    assertEquals("[0] == opt0", opt0, select.getOptions().getItem(0));
    assertEquals("[1] == opt1", opt1, select.getOptions().getItem(1));
    assertEquals("[2] == opt2", opt2, select.getOptions().getItem(2));

    select.remove(1);
    assertNull("null parent expected when removed", opt1.getParentElement());

    select.add(opt1, opt0);
    assertEquals("[0] == opt1", opt1, select.getOptions().getItem(0));
    assertEquals("[1] == opt0", opt0, select.getOptions().getItem(1));
  }

  /**
   * selectedIndex, option.selected
   */
  public void testSelection() {
    Document doc = Document.get();
    SelectElement select = doc.createSelectElement();
    doc.getBody().appendChild(select);

    OptionElement opt0 = doc.createOptionElement();
    OptionElement opt1 = doc.createOptionElement();
    OptionElement opt2 = doc.createOptionElement();
    opt0.setText("foo");
    opt1.setText("bar");
    opt2.setText("baz");
    opt0.setValue("0");
    opt1.setValue("1");
    opt2.setValue("2");

    select.appendChild(opt0);
    select.appendChild(opt1);
    select.appendChild(opt2);

    // Single selection.
    opt0.setSelected(true);
    assertTrue(opt0.isSelected());
    assertEquals(0, select.getSelectedIndex());

    opt1.setSelected(true);
    assertFalse(opt0.isSelected());
    assertTrue(opt1.isSelected());
    assertEquals(1, select.getSelectedIndex());
  }

  /**
   * multiple
   */
  public void testMultipleSelection() {
    Document doc = Document.get();
    SelectElement select = doc.createSelectElement(true);
    doc.getBody().appendChild(select);

    OptionElement opt0 = doc.createOptionElement();
    OptionElement opt1 = doc.createOptionElement();
    OptionElement opt2 = doc.createOptionElement();
    opt0.setText("foo");
    opt1.setText("bar");
    opt2.setText("baz");
    opt0.setValue("0");
    opt1.setValue("1");
    opt2.setValue("2");

    select.appendChild(opt0);
    select.appendChild(opt1);
    select.appendChild(opt2);

    // Multiple selection.
    opt0.setSelected(true);
    opt1.setSelected(true);
    opt2.setSelected(true);

    assertTrue(select.isMultiple());
    assertTrue(opt0.isSelected());
    assertTrue(opt1.isSelected());
    assertTrue(opt2.isSelected());
  }
}
