Java tutorial
/******************************************************************************* * Copyright (c) 2011 Google, Inc. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Google, Inc. - initial API and implementation *******************************************************************************/ package org.eclipse.wb.tests.designer.XWT.model.property; import org.eclipse.wb.internal.core.model.property.Property; import org.eclipse.wb.internal.core.model.property.editor.BooleanPropertyEditor; import org.eclipse.wb.internal.core.model.property.editor.StringComboPropertyEditor; import org.eclipse.wb.internal.core.model.util.PropertyUtils; import org.eclipse.wb.internal.core.utils.jdt.core.CodeUtils; import org.eclipse.wb.internal.core.utils.reflect.ReflectionUtils; import org.eclipse.wb.internal.core.utils.state.EditorWarning; import org.eclipse.wb.internal.core.xml.model.property.GenericProperty; import org.eclipse.wb.internal.xwt.model.property.editor.style.StylePropertyEditor; import org.eclipse.wb.internal.xwt.model.widgets.CompositeInfo; import org.eclipse.wb.internal.xwt.model.widgets.ControlInfo; import org.eclipse.wb.tests.designer.XWT.model.XwtModelTest; import org.eclipse.jface.action.ActionContributionItem; import org.eclipse.jface.action.IAction; import org.eclipse.jface.action.IContributionItem; import org.eclipse.jface.action.IMenuManager; import org.eclipse.jface.action.MenuManager; import org.eclipse.jface.action.Separator; import static org.fest.assertions.Assertions.assertThat; import org.apache.commons.lang.StringUtils; import java.text.MessageFormat; import java.util.Arrays; import java.util.Comparator; /** * Test for {@link StylePropertyEditor}. * * @author scheglov_ke */ public class StylePropertyEditorTest extends XwtModelTest { private GenericProperty m_styleProperty; private StylePropertyEditor m_editor; private Property[] m_properties; //////////////////////////////////////////////////////////////////////////// // // Life cycle // //////////////////////////////////////////////////////////////////////////// @Override protected void configureNewProject() throws Exception { super.configureNewProject(); setFileContentSrc("test/SWT.java", getSource("package test;", "public interface SWT {", " int NONE = 0;", " int B0 = 1 << 0;", " int B1 = 1 << 1;", " int B2 = 1 << 2;", " int B3 = 1 << 3;", " //", " int R1 = 1 << 4;", " int R2 = 1 << 5;", " int R3 = 1 << 6;", " int R4 = 1 << 7;", " // mix", " int B0_B1 = B0 | B1;", " int B0_B2 = B0 | B2;", " int B0_R2 = B0 | R2;", "}")); waitForAutoBuild(); forgetCreatedResources(); } //////////////////////////////////////////////////////////////////////////// // // Exit zone :-) XXX // //////////////////////////////////////////////////////////////////////////// public void _test_exit() throws Exception { System.exit(0); } //////////////////////////////////////////////////////////////////////////// // // Set // //////////////////////////////////////////////////////////////////////////// public void test_Set_1() throws Exception { parseStyleProperties("set|B0 B1 B2:specialName"); { assertThat(m_properties).hasSize(3); // titles assertEquals("b0", m_properties[0].getTitle()); assertEquals("b1", m_properties[1].getTitle()); assertEquals("specialName", m_properties[2].getTitle()); // always modified assertTrue(m_properties[0].isModified()); assertTrue(m_properties[1].isModified()); assertTrue(m_properties[2].isModified()); // values for (Property property : m_properties) { assertInstanceOf(BooleanPropertyEditor.class, property.getEditor()); assertEquals(false, property.getValue()); } } // initial state assertEditorText("[]"); // "B0" := true m_properties[0].setValue(Boolean.TRUE); assertEquals(Boolean.TRUE, m_properties[0].getValue()); assertStyleSource("B0"); assertEditorText("[B0]"); // "B2" := true m_properties[2].setValue(Boolean.TRUE); assertEquals(Boolean.TRUE, m_properties[2].getValue()); assertStyleSource("B0 | B2"); assertEditorText("[B0, B2]"); // "B0" := unknown m_properties[0].setValue(Property.UNKNOWN_VALUE); assertEquals(Boolean.FALSE, m_properties[0].getValue()); assertStyleSource("B2"); assertEditorText("[B2]"); // "B2" := unknown m_properties[2].setValue(Property.UNKNOWN_VALUE); assertEquals(Boolean.FALSE, m_properties[2].getValue()); assertStyleSource(null); assertEditorText("[]"); } public void test_Set_ignoreIfNoSuchField() throws Exception { parseStyleProperties("set|B0 noSuchField"); // check String[] names = PropertyUtils.getTitles(m_properties); assertThat(names).containsOnly("b0"); // warnings expected checkWarning("StylePropertyEditor: can not find field test.SWT.noSuchField"); } //////////////////////////////////////////////////////////////////////////// // // Select // //////////////////////////////////////////////////////////////////////////// public void test_Select_1() throws Exception { parseStyleProperties("set|B0 B1", "select0|align R1 R1 R2 R3"); // check sub properties String[] subNames = { "align", "b0", "b1" }; assertEquals(subNames.length, m_properties.length); for (int i = 1; i < 3; i++) { Property property = m_properties[i]; assertEquals(subNames[i], property.getTitle()); assertInstanceOf(BooleanPropertyEditor.class, property.getEditor()); assertEquals(false, property.getValue()); } // Property alignProperty = m_properties[0]; assertEquals(subNames[0], alignProperty.getTitle()); assertEquals("R1", alignProperty.getValue()); // "B0" := true m_properties[1].setValue(true); assertEquals(true, m_properties[1].getValue()); assertStyleSource("B0"); assertEditorText("[B0]"); // "align" := R2 alignProperty.setValue("R2"); assertEquals("R2", alignProperty.getValue()); assertStyleSource("B0 | R2"); assertEditorText("[B0, R2]"); // "align" := R3 alignProperty.setValue("R3"); assertEquals("R3", alignProperty.getValue()); assertStyleSource("B0 | R3"); assertEditorText("[B0, R3]"); // "B0" := false m_properties[1].setValue(false); assertEquals(false, m_properties[1].getValue()); assertStyleSource("R3"); assertEditorText("[R3]"); // "align" := R1 alignProperty.setValue("R1"); assertEquals("R1", alignProperty.getValue()); assertStyleSource(null); assertEditorText("[]"); // "align" := R2 alignProperty.setValue("R2"); assertEquals("R2", alignProperty.getValue()); assertStyleSource("R2"); assertEditorText("[R2]"); // "align" := unknown alignProperty.setValue(Property.UNKNOWN_VALUE); assertEquals("R1", alignProperty.getValue()); assertStyleSource(null); assertEditorText("[]"); } public void test_Select_ignoreInNoSuchField() throws Exception { parseStyleProperties("select0|align 15 15 R1 noSuchField"); assertThat(PropertyUtils.getTitles(m_properties)).containsOnly("align"); Property alignProperty = m_properties[0]; // assertEquals("align", alignProperty.getTitle()); assertEquals("15", alignProperty.getValue()); // assertInstanceOf(StringComboPropertyEditor.class, alignProperty.getEditor()); String[] items = (String[]) ReflectionUtils.getFieldObject(alignProperty.getEditor(), "m_items"); assertEquals(2, items.length); assertEquals("15", items[0]); assertEquals("R1", items[1]); // check warnings checkWarning("StylePropertyEditor: can not find field test.SWT.noSuchField"); } //////////////////////////////////////////////////////////////////////////// // // Macro // //////////////////////////////////////////////////////////////////////////// public void test_Macro_1() throws Exception { parseStyleProperties("set|B0 B1 B2 B3", "macro0|mix B0_B1 B0_B2 R1"); Property property_B0 = m_properties[0]; Property property_B1 = m_properties[1]; Property property_B2 = m_properties[2]; Property property_B3 = m_properties[3]; Property propertyMix = m_properties[4]; // "B0" := true property_B0.setValue(true); assertStyleSource("B0"); assertEquals("", propertyMix.getValue()); assertEditorText("[B0]"); // "mix" := B0_B1 propertyMix.setValue("B0_B1"); assertEquals("B0_B1", propertyMix.getValue()); assertEquals(true, property_B0.getValue()); assertEquals(true, property_B1.getValue()); assertEquals(false, property_B2.getValue()); assertEquals(false, property_B3.getValue()); assertStyleSource("B0_B1"); assertEditorText("[B0_B1]"); // add "B3" property_B3.setValue(true); assertEquals("B0_B1", propertyMix.getValue()); assertEquals(true, property_B0.getValue()); assertEquals(true, property_B1.getValue()); assertEquals(false, property_B2.getValue()); assertEquals(true, property_B3.getValue()); assertStyleSource("B0_B1 | B3"); assertEditorText("[B0_B1, B3]"); // set "R1", change style fully propertyMix.setValue("R1"); assertEquals("R1", propertyMix.getValue()); assertEquals(false, property_B0.getValue()); assertEquals(false, property_B1.getValue()); assertEquals(false, property_B2.getValue()); assertEquals(false, property_B3.getValue()); assertStyleSource("R1"); assertEditorText("[R1]"); } public void test_Macro_2() throws Exception { parseStyleProperties("set|B0 B1", "macro0|mix B0_B1 R1"); Property property_B0 = m_properties[0]; Property property_B1 = m_properties[1]; Property propertyMix = m_properties[2]; // "mix" := B0_B1 propertyMix.setValue("B0_B1"); assertEquals("B0_B1", propertyMix.getValue()); assertEquals(true, property_B0.getValue()); assertEquals(true, property_B1.getValue()); assertStyleSource("B0_B1"); assertEditorText("[B0_B1]"); // remove "B0" property_B0.setValue(false); assertEquals("", propertyMix.getValue()); assertEquals(false, property_B0.getValue()); assertEquals(true, property_B1.getValue()); assertStyleSource("B1"); assertEditorText("[B1]"); } public void test_Macro_ignoreIfNoSuchField() throws Exception { parseStyleProperties("macro0|mix B0_B1 noSuchField"); assertThat(PropertyUtils.getTitles(m_properties)).containsOnly("mix"); Property mixProperty = m_properties[0]; // assertEquals("mix", mixProperty.getTitle()); assertEquals("", mixProperty.getValue()); // assertInstanceOf(StringComboPropertyEditor.class, mixProperty.getEditor()); String[] items = (String[]) ReflectionUtils.getFieldObject(mixProperty.getEditor(), "m_items"); assertThat(items).containsOnly("B0_B1", ""); // check warnings checkWarning("StylePropertyEditor: can not find field test.SWT.noSuchField"); } public void test_Macro_ifMacro_thenNoSelect() throws Exception { parseStyleProperties("", new String[] { "select0|align R1 R1 R2", "macro0|mix B0_R2" }); Property propertySelect = m_properties[0]; Property propertyMix = m_properties[1]; // initially no values assertEquals("R1", propertySelect.getValue()); assertEquals("", propertyMix.getValue()); // set "R2" propertySelect.setValue("R2"); assertEquals("R2", propertySelect.getValue()); assertEquals("", propertyMix.getValue()); assertStyleSource("R2"); assertEditorText("[R2]"); // "mix" := B0_R2 propertyMix.setValue("B0_R2"); assertEquals("R2", propertySelect.getValue()); assertEquals("B0_R2", propertyMix.getValue()); assertStyleSource("B0_R2"); assertEditorText("[B0_R2]"); } //////////////////////////////////////////////////////////////////////////// // // Popup // //////////////////////////////////////////////////////////////////////////// IContributionItem[] styleItems; private void prepareStyleItems(boolean cascade) throws Exception { // prepare "Style" menu IMenuManager styleMenu; { MenuManager manager = getDesignerMenuManager(); m_editor.contributeActions(m_styleProperty, manager, "Style", cascade); styleMenu = findChildMenuManager(manager, "Style"); assertNotNull(styleMenu); } // remember items styleItems = styleMenu.getItems(); } public void test_popup() throws Exception { parseStyleProperties("set|B0 B1 B2", "select0|align R1 R1 R2 R3"); prepareStyleItems(false); // check items assertThat(styleItems).hasSize(7); IContributionItem item_B0 = styleItems[0]; IContributionItem item_R2 = styleItems[5]; checkItem("b0", IAction.AS_CHECK_BOX, false, item_B0); checkItem("b1", IAction.AS_CHECK_BOX, false, styleItems[1]); checkItem("b2", IAction.AS_CHECK_BOX, false, styleItems[2]); assertInstanceOf(Separator.class, styleItems[3]); checkItem("R1", IAction.AS_RADIO_BUTTON, true, styleItems[4]); checkItem("R2", IAction.AS_RADIO_BUTTON, false, item_R2); checkItem("R3", IAction.AS_RADIO_BUTTON, false, styleItems[6]); // run "B0" ((ActionContributionItem) item_B0).getAction().run(); assertStyleSource("B0"); // select "R2" ((ActionContributionItem) item_R2).getAction().setChecked(true); ((ActionContributionItem) item_R2).getAction().run(); assertStyleSource("B0 | R2"); } public void test_popup_boolean() throws Exception { parseStyleProperties("B1", new String[] { "set|B0 B1 B2" }); // check items { prepareStyleItems(false); assertThat(styleItems).hasSize(3); IContributionItem item_B0 = styleItems[0]; IContributionItem item_B1 = styleItems[1]; IContributionItem item_B2 = styleItems[2]; checkItem("b0", IAction.AS_CHECK_BOX, false, item_B0); checkItem("b1", IAction.AS_CHECK_BOX, true, item_B1); checkItem("b2", IAction.AS_CHECK_BOX, false, item_B2); // run "B2" ((ActionContributionItem) item_B2).getAction().run(); } // check again { prepareStyleItems(false); assertThat(styleItems).hasSize(3); IContributionItem item_B0 = styleItems[0]; IContributionItem item_B1 = styleItems[1]; IContributionItem item_B2 = styleItems[2]; checkItem("b0", IAction.AS_CHECK_BOX, false, item_B0); checkItem("b1", IAction.AS_CHECK_BOX, true, item_B1); checkItem("b2", IAction.AS_CHECK_BOX, true, item_B2); } } public void test_popup_select() throws Exception { parseStyleProperties("R2", new String[] { "select0|align R1 R1 R2 R3" }); // check items { prepareStyleItems(false); assertThat(styleItems).hasSize(4); assertInstanceOf(Separator.class, styleItems[0]); IContributionItem item_R1 = styleItems[1]; IContributionItem item_R2 = styleItems[2]; IContributionItem item_R3 = styleItems[3]; checkItem("R1", IAction.AS_RADIO_BUTTON, false, item_R1); checkItem("R2", IAction.AS_RADIO_BUTTON, true, item_R2); checkItem("R3", IAction.AS_RADIO_BUTTON, false, item_R3); // run "R3" { IAction action_R3 = ((ActionContributionItem) item_R3).getAction(); action_R3.setChecked(true); action_R3.run(); } } // check again { prepareStyleItems(false); assertThat(styleItems).hasSize(4); assertInstanceOf(Separator.class, styleItems[0]); IContributionItem item_R1 = styleItems[1]; IContributionItem item_R2 = styleItems[2]; IContributionItem item_R3 = styleItems[3]; checkItem("R1", IAction.AS_RADIO_BUTTON, false, item_R1); checkItem("R2", IAction.AS_RADIO_BUTTON, false, item_R2); checkItem("R3", IAction.AS_RADIO_BUTTON, true, item_R3); } } public void test_popup_cascade() throws Exception { parseStyleProperties("set|B0 B1", "select0|align R1 R1 R2 R3"); prepareStyleItems(true); // assertThat(styleItems).hasSize(4); checkItem("b0", IAction.AS_CHECK_BOX, false, styleItems[0]); checkItem("b1", IAction.AS_CHECK_BOX, false, styleItems[1]); assertInstanceOf(Separator.class, styleItems[2]); assertInstanceOf(MenuManager.class, styleItems[3]); // IMenuManager alignMenu = (IMenuManager) styleItems[3]; IContributionItem[] alignItems = alignMenu.getItems(); assertThat(alignItems).hasSize(4); assertInstanceOf(Separator.class, alignItems[0]); checkItem("R1", IAction.AS_RADIO_BUTTON, true, alignItems[1]); checkItem("R2", IAction.AS_RADIO_BUTTON, false, alignItems[2]); checkItem("R3", IAction.AS_RADIO_BUTTON, false, alignItems[3]); } public void test_popup_macro() throws Exception { parseStyleProperties("", new String[] { "set|B0", "macro0|mix B0_B1 B0_B2" }); prepareStyleItems(false); // check items { assertThat(styleItems).hasSize(1 + 1 + 2); checkItem("b0", IAction.AS_CHECK_BOX, false, styleItems[0]); assertInstanceOf(Separator.class, styleItems[1]); checkItem("B0_B1", IAction.AS_RADIO_BUTTON, false, styleItems[2]); checkItem("B0_B2", IAction.AS_RADIO_BUTTON, false, styleItems[3]); // run "B0_B1" { IAction action_B0_B1 = ((ActionContributionItem) styleItems[2]).getAction(); action_B0_B1.setChecked(true); action_B0_B1.run(); } } // check again { prepareStyleItems(false); assertThat(styleItems).hasSize(1 + 1 + 2); checkItem("b0", IAction.AS_CHECK_BOX, true, styleItems[0]); assertInstanceOf(Separator.class, styleItems[1]); checkItem("B0_B1", IAction.AS_RADIO_BUTTON, true, styleItems[2]); checkItem("B0_B2", IAction.AS_RADIO_BUTTON, false, styleItems[3]); } } private static void checkItem(String text, int style, boolean value, IContributionItem item) throws Exception { assertInstanceOf(ActionContributionItem.class, item); ActionContributionItem contributionItem = (ActionContributionItem) item; IAction action = contributionItem.getAction(); assertNotNull(action); assertEquals(text, action.getText()); assertEquals(style, action.getStyle()); assertEquals(value, action.isChecked()); } //////////////////////////////////////////////////////////////////////////// // // Clipboard // //////////////////////////////////////////////////////////////////////////// public void test_clipboard() throws Exception { final CompositeInfo shell = parse("// filler filler filler filler filler", "// filler filler filler filler filler", "<Shell>", " <Shell.layout>", " <RowLayout/>", " </Shell.layout>", " <Button wbp:name='button' text='My button' x:Style='CHECK'/>", "</Shell>"); refresh(); // do copy/paste { ControlInfo button = getObjectByName("button"); doCopyPaste(button, new PasteProcedure<ControlInfo>() { public void run(ControlInfo copy) throws Exception { shell.getLayout().command_CREATE(copy, null); } }); } assertXML("// filler filler filler filler filler", "// filler filler filler filler filler", "<Shell>", " <Shell.layout>", " <RowLayout/>", " </Shell.layout>", " <Button wbp:name='button' text='My button' x:Style='CHECK'/>", " <Button text='My button' x:Style='CHECK'/>", "</Shell>"); } //////////////////////////////////////////////////////////////////////////// // // Utils // //////////////////////////////////////////////////////////////////////////// private void assertEditorText(String text) throws Exception { assertEquals(text, getPropertyText(m_styleProperty)); } private void assertStyleSource(String styleSource) { assertXML("// filler filler filler filler filler", "// filler filler filler filler filler", "<Shell>", " <t:TestComposite" + getStylePropertySource(styleSource) + "/>", "</Shell>"); } private static String getStylePropertySource(String styles) { String source; if (styles != null) { source = " x:Style='"; for (String part : StringUtils.split(styles, " |")) { source += "(t:SWT)." + part; source += " | "; } source = StringUtils.removeEnd(source, " | "); source += "'"; } else { source = ""; } return source; } private void parseStyleProperties(String... styleLines) throws Exception { parseStyleProperties(null, styleLines); } private void parseStyleProperties(String styles, String[] styleLines0) throws Exception { setFileContentSrc("test/TestComposite.java", getJavaSource("public class TestComposite extends Composite {", " public TestComposite(Composite parent, int style) {", " super(parent, SWT.NONE);", " }", " protected void checkSubclass () {", " }", "}")); // convert: name|value into "parameter" line String[] styleLines = new String[styleLines0.length]; for (int i = 0; i < styleLines0.length; i++) { String line = styleLines0[i]; int index = line.indexOf('|'); String name = line.substring(0, index); String value = line.substring(index + 1); styleLines[i] = MessageFormat.format("<parameter name=''{0}''>{1}</parameter>", name, value); } // prepare description String[] lines; lines = new String[] { "<?xml version='1.0' encoding='UTF-8'?>", "<component xmlns='http://www.eclipse.org/wb/WBPComponent'>", " <constructors>", " <constructor>", " <parameter type='int' defaultSource='test.SWT.NONE'>", " <editor id='style'>", " <parameter name='class'>test.SWT</parameter>" }; lines = CodeUtils.join(lines, styleLines); lines = CodeUtils.join(lines, new String[] { " <!-- filler filler filler filler filler -->", " </editor>", " </parameter>", " </constructor>", " </constructors>", "</component>" }); setFileContentSrc("test/TestComposite.wbp-component.xml", getSource(lines)); waitForAutoBuild(); // parse parseStyleProperties0("Style", new String[] { "// filler filler filler filler filler", "<Shell>", " <t:TestComposite" + getStylePropertySource(styles) + "/>", "</Shell>" }); } private void parseStyleProperties0(String propertyPath, String[] lines) throws Exception { CompositeInfo panel = parse(lines); panel.refresh(); // prepare "style" property ControlInfo component = panel.getChildrenControls().get(0); m_styleProperty = (GenericProperty) PropertyUtils.getByPath(component, propertyPath); // use its editor m_editor = (StylePropertyEditor) m_styleProperty.getEditor(); m_properties = m_editor.getProperties(m_styleProperty); Arrays.sort(m_properties, new Comparator<Property>() { public int compare(Property o1, Property o2) { return o1.getTitle().compareTo(o2.getTitle()); } }); } private void checkWarning(String message) throws Exception { boolean find = false; for (EditorWarning warning : m_lastContext.getWarnings()) { find = message.equals(warning.getMessage()); if (find) { break; } } assertTrue(find); } }