blob: 3e0df69cb2e61ecd56b393b4238eae5887b226c8 [file] [log] [blame]
/*
* Copyright (C) 2015 The Android Open Source Project
*
* 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.android.tools.idea.uibuilder.palette;
import com.android.annotations.NonNull;
import junit.framework.TestCase;
import org.intellij.lang.annotations.Language;
import org.jdom.Document;
import org.jdom.input.SAXBuilder;
import java.io.StringReader;
import java.util.Collections;
import java.util.List;
public class NlPaletteModelTest extends TestCase {
private NlPaletteModel model = new NlPaletteModel();
@Language("XML")
private static final String FRAME_LAYOUT_CREATION =
"<FrameLayout\n" +
" android:layout_width=\"match_parent\"\n" +
" android:layout_height=\"match_parent\">\n" +
"</FrameLayout>";
@Language("XML")
private static final String HORIZONTAL_LINEAR_LAYOUT_CREATION =
"<LinearLayout\n" +
" android:layout_width=\"match_parent\"\n" +
" android:layout_height=\"match_parent\">\n" +
"</LinearLayout>";
@Language("XML")
private static final String VERTICAL_LINEAR_LAYOUT_CREATION =
"<LinearLayout\n" +
" android:orientation=\"vertical\"\n" +
" android:layout_width=\"match_parent\"\n" +
" android:layout_height=\"match_parent\">\n" +
"</LinearLayout>";
@Language("XML")
private static final String CONSTRAINT_LAYOUT_CREATION =
"<ConstraintLayout\n" +
" android:layout_width=\"match_parent\"\n" +
" android:layout_height=\"match_parent\">\n" +
"</ConstraintLayout>";
@Language("XML")
private static final String SINGLE_GROUP_WITH_ITEM_OVERRIDES =
"<meta-model>\n" +
" <palette>\n" +
" <group name=\"Layouts\">\n" +
" <item tag=\"FrameLayout\" id=\"FrameLayoutId\"/>\n" +
" <item tag=\"LinearLayout\"\n" +
" title=\"LinearLayout (Horizontal)\"\n" +
" icon=\"AndroidIcons.Views.LinearLayout\"\n" +
" tooltip=\"A Layout for a single row.\">\n" +
" <item title=\"LinearLayout (Vertical)\"\n" +
" icon=\"AndroidIcons.Views.VerticalLinearLayout\"\n" +
" tooltip=\"A Layout for a single column.\">\n" +
" <creation>\n" +
" <![CDATA[\n" + VERTICAL_LINEAR_LAYOUT_CREATION +
" ]]>\n" +
" </creation>\n" +
" </item>\n" +
" </item>\n" +
" </group>\n" +
" </palette>\n" +
"\n" +
" <meta model=\"com.intellij.android.designer.model.RadViewContainer\"\n" +
" layout=\"com.intellij.android.designer.model.layout.RadFrameLayout\"\n" +
" class=\"android.widget.FrameLayout\"\n" +
" tag=\"FrameLayout\"\n" +
" fill=\"opposite\">\n" +
"\n" +
" <palette title=\"FrameLayout\" icon=\"AndroidIcons.Views.FrameLayout\"\n" +
" tooltip=\"A Layout for a single item.\"/>\n" +
"\n" +
" <morphing to=\"TableLayout GridLayout RelativeLayout\"/>\n" +
"\n" +
" <properties important=\"foreground foregroundGravity\"\n" +
" expert=\"layout:gravity.fill layout:gravity.clip layout:gravity.start layout:gravity.end\"\n" +
" />\n" +
"\n" +
" <creation>\n" +
" <![CDATA[\n" + FRAME_LAYOUT_CREATION +
" ]]>\n" +
" </creation>\n" +
" </meta>\n" +
"\n" +
"" +
" <meta model=\"com.intellij.android.designer.model.RadViewContainer\"\n" +
" layout=\"com.intellij.android.designer.model.layout.RadLinearLayout\"\n" +
" class=\"android.widget.LinearLayout\"\n" +
" tag=\"LinearLayout\"\n" +
" fill=\"opposite\">\n" +
"\n" +
" <presentation title=\" (%orientation%)\"/>\n" +
"\n" +
" <palette title=\"LinearLayout\" icon=\"AndroidIcons.Views.LinearLayout\"\n" +
" tooltip=\"A Layout that arranges its children in a single row or column.\"/>\n" +
"\n" +
" <morphing to=\"RadioGroup TableLayout GridLayout RelativeLayout\"/>\n" +
"\n" +
" <properties inplace=\"orientation\"\n" +
" important=\"orientation gravity baselineAligned measureWithLargestChild showDividers\"\n" +
" expert=\"layout:gravity.fill layout:gravity.clip layout:gravity.start layout:gravity.end\"\n" +
" top=\"gravity orientation\"\n" +
" />\n" +
"\n" +
" <creation>\n" +
" <![CDATA[\n" + HORIZONTAL_LINEAR_LAYOUT_CREATION +
" ]]>\n" +
" </creation>\n" +
" </meta>\n" +
"\n" +
"</meta-model>";
private static final List<NlPaletteGroup> GROUP_WITH_ITEM_OVERRIDES = Collections.singletonList(
makeGroup("Layouts",
new NlPaletteItem("FrameLayout", "AndroidIcons.Views.FrameLayout", "A Layout for a single item.", FRAME_LAYOUT_CREATION, "FrameLayoutId", "", "FrameLayout", null),
new NlPaletteItem("LinearLayout (Horizontal)", "AndroidIcons.Views.LinearLayout", "A Layout for a single row.", HORIZONTAL_LINEAR_LAYOUT_CREATION, "HorizontalLayout", "", "LinearLayout", " (%orientation%)"),
new NlPaletteItem("LinearLayout (Vertical)", "AndroidIcons.Views.VerticalLinearLayout", "A Layout for a single column.", VERTICAL_LINEAR_LAYOUT_CREATION, "VerticalLayout", "", "LinearLayout", " (%orientation%)"))
);
public void testSingleGroupWithItemOverrides() throws Exception {
model.loadPalette(loadDocument(SINGLE_GROUP_WITH_ITEM_OVERRIDES));
assertGroupsEquals(GROUP_WITH_ITEM_OVERRIDES, model.getGroups());
}
@Language("XML")
private static final String SINGLE_GROUP_WITH_MISSING_DATA =
"<meta-model>\n" +
" <palette>\n" +
" <group name=\"Layouts\">\n" +
" <item tag=\"SomeOtherLayout\"/>\n" + // Has no model section
" <item tag=\"FrameLayout\"/>\n" + // Model section is missing a palette subsection
" <item tag=\"LinearLayout\"/>\n" + // Model section has a palette section with a missing title
" <item tag=\"ConstraintLayout\"/>\n" + // Model section has a palette section with a missing icon and tooltip
" </group>\n" +
" </palette>\n" +
"\n" +
" <meta model=\"com.intellij.android.designer.model.RadViewContainer\"\n" +
" layout=\"com.intellij.android.designer.model.layout.RadFrameLayout\"\n" +
" class=\"android.widget.FrameLayout\"\n" +
" tag=\"FrameLayout\"\n" +
" fill=\"opposite\">\n" +
"\n" + // Missing palette
" <morphing to=\"TableLayout GridLayout RelativeLayout\"/>\n" +
"\n" +
" <properties important=\"foreground foregroundGravity\"\n" +
" expert=\"layout:gravity.fill layout:gravity.clip layout:gravity.start layout:gravity.end\"\n" +
" />\n" +
"\n" +
" <creation>\n" +
" <![CDATA[\n" + FRAME_LAYOUT_CREATION +
" ]]>\n" +
" </creation>\n" +
" </meta>\n" +
"\n" +
" <meta model=\"com.intellij.android.designer.model.RadViewContainer\"\n" +
" layout=\"com.intellij.android.designer.model.layout.RadLinearLayout\"\n" +
" class=\"android.widget.LinearLayout\"\n" +
" tag=\"LinearLayout\"\n" +
" fill=\"opposite\">\n" +
"\n" +
" <presentation title=\" (%orientation%)\"/>\n" +
"\n" +
" <palette icon=\"AndroidIcons.Views.LinearLayout\"\n" +
" tooltip=\"A Layout that arranges its children in a single row or column.\"/>\n" +
"\n" +
" <morphing to=\"RadioGroup TableLayout GridLayout RelativeLayout\"/>\n" +
"\n" +
" <properties inplace=\"orientation\"\n" +
" important=\"orientation gravity baselineAligned measureWithLargestChild showDividers\"\n" +
" expert=\"layout:gravity.fill layout:gravity.clip layout:gravity.start layout:gravity.end\"\n" +
" top=\"gravity orientation\"\n" +
" />\n" +
"\n" +
" <creation>\n" +
" <![CDATA[\n" + HORIZONTAL_LINEAR_LAYOUT_CREATION +
" ]]>\n" +
" </creation>\n" +
" </meta>\n" +
"\n" +
" <meta model=\"com.intellij.android.designer.model.RadViewContainer\"\n" +
" layout=\"com.intellij.android.designer.model.layout.RadConstraintLayout\"\n" +
" class=\"android.widget.ConstraintLayout\"\n" +
" tag=\"ConstraintLayout\"\n" +
" fill=\"opposite\">\n" +
"\n" +
" <palette title=\"ConstraintLayout\"/>\n" +
"\n" +
" <morphing to=\"TableLayout GridLayout RelativeLayout\"/>\n" +
"\n" +
" <properties important=\"foreground foregroundGravity\"\n" +
" expert=\"layout:gravity.fill layout:gravity.clip layout:gravity.start layout:gravity.end\"\n" +
" />\n" +
"\n" +
" <creation>\n" +
" <![CDATA[\n" + CONSTRAINT_LAYOUT_CREATION +
" ]]>\n" +
" </creation>\n" +
" </meta>\n" +
"\n" +
"</meta-model>";
private static final List<NlPaletteGroup> GROUP_WITH_MISSING_DATA = Collections.singletonList(
makeGroup("Layouts", new NlPaletteItem("ConstraintLayout", "", "", CONSTRAINT_LAYOUT_CREATION, "ConstraintLayout", "", "ConstraintLayout", null))
);
public void testGroupWithMissingData() throws Exception {
model.loadPalette(loadDocument(SINGLE_GROUP_WITH_MISSING_DATA));
assertGroupsEquals(GROUP_WITH_MISSING_DATA, model.getGroups());
}
@NonNull
private static NlPaletteGroup makeGroup(String title, NlPaletteItem... items) {
NlPaletteGroup group = new NlPaletteGroup(title);
for (NlPaletteItem item : items) {
group.add(item);
}
return group;
}
private static void assertGroupsEquals(List<NlPaletteGroup> expectedGroups, List<NlPaletteGroup> actualGroups) {
for (int i=0; i<expectedGroups.size(); i++) {
if (i >= actualGroups.size()) {
break;
}
NlPaletteGroup expectedGroup = expectedGroups.get(i);
NlPaletteGroup actualGroup = actualGroups.get(i);
assertEquals(String.format("group[%d].title", i), expectedGroup.getTitle(), actualGroup.getTitle());
for (int j=0; j<expectedGroup.getItems().size(); j++) {
if (j >= actualGroup.getItems().size()) {
break;
}
NlPaletteItem expectedItem = expectedGroup.getItems().get(j);
NlPaletteItem actualItem = actualGroup.getItems().get(j);
assertEquals(String.format("group[%d].item[%d].title", i, j), expectedItem.getTitle(), actualItem.getTitle());
assertEquals(String.format("group[%d].item[%d].icon", i, j), expectedItem.getIconPath(), actualItem.getIconPath());
assertEquals(String.format("group[%d].item[%d].tooltip", i, j), expectedItem.getTooltip(), actualItem.getTooltip());
assertEquals(String.format("group[%d].item[%d].creation", i, j), expectedItem.getRepresentation(), actualItem.getRepresentation().trim());
assertEquals(String.format("group[%d].item[%d].structureTitle", i, j), expectedItem.getStructureTitle(), actualItem.getStructureTitle());
assertEquals(String.format("group[%d].item[%d].structureFormat", i, j), expectedItem.getStructureFormat(), actualItem.getStructureFormat());
}
assertEquals(String.format("group[%d].items.length", i), expectedGroup.getItems().size(), actualGroup.getItems().size());
}
assertEquals("groups.length", expectedGroups.size(), actualGroups.size());
}
private static Document loadDocument(String xml) throws Exception {
return new SAXBuilder().build(new StringReader(xml));
}
}