diff options
23 files changed, 123 insertions, 52 deletions
diff --git a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/widgets/AlertsWidget.java b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/widgets/AlertsWidget.java index 604b491b436..426f35f93f8 100644 --- a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/widgets/AlertsWidget.java +++ b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/widgets/AlertsWidget.java @@ -19,10 +19,9 @@ */
package org.sonar.plugins.core.widgets;
-import org.sonar.api.web.AbstractRubyTemplate;
-import org.sonar.api.web.Description;
-import org.sonar.api.web.RubyRailsWidget;
+import org.sonar.api.web.*;
+@WidgetLayout(WidgetLayoutType.NONE)
@Description("Display current alerts on the project.")
public class AlertsWidget extends AbstractRubyTemplate implements RubyRailsWidget {
public String getId() {
diff --git a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/widgets/DescriptionWidget.java b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/widgets/DescriptionWidget.java index 52f47b03b62..f3304e46073 100644 --- a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/widgets/DescriptionWidget.java +++ b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/widgets/DescriptionWidget.java @@ -19,10 +19,9 @@ */
package org.sonar.plugins.core.widgets;
-import org.sonar.api.web.AbstractRubyTemplate;
-import org.sonar.api.web.Description;
-import org.sonar.api.web.RubyRailsWidget;
+import org.sonar.api.web.*;
+@WidgetLayout(WidgetLayoutType.NONE)
@Description("Displays general project information taken from the pom.xml")
public class DescriptionWidget extends AbstractRubyTemplate implements RubyRailsWidget {
public String getId() {
diff --git a/plugins/sonar-core-plugin/src/main/resources/org/sonar/plugins/core/widgets/_extended_analysis.html.erb b/plugins/sonar-core-plugin/src/main/resources/org/sonar/plugins/core/widgets/_extended_analysis.html.erb index b2c4f1cedc1..86c1eec3b0f 100644 --- a/plugins/sonar-core-plugin/src/main/resources/org/sonar/plugins/core/widgets/_extended_analysis.html.erb +++ b/plugins/sonar-core-plugin/src/main/resources/org/sonar/plugins/core/widgets/_extended_analysis.html.erb @@ -8,7 +8,6 @@ if file_complexity || function_complexity || class_complexity || paragraph_complexity complexity=measure('complexity') %> -<div class="widget"> <div class="dashbox" > <h3>Complexity</h3> <% if function_complexity %> @@ -106,6 +105,5 @@ if file_distribution <% end %> <div class="clear"></div> -</div> <% end %> diff --git a/plugins/sonar-core-plugin/src/main/resources/org/sonar/plugins/core/widgets/_static_analysis.html.erb b/plugins/sonar-core-plugin/src/main/resources/org/sonar/plugins/core/widgets/_static_analysis.html.erb index d654238d02c..f8baf7ad4d3 100644 --- a/plugins/sonar-core-plugin/src/main/resources/org/sonar/plugins/core/widgets/_static_analysis.html.erb +++ b/plugins/sonar-core-plugin/src/main/resources/org/sonar/plugins/core/widgets/_static_analysis.html.erb @@ -3,7 +3,6 @@ if measure('lines') || measure('ncloc') files=measure('files') statements=measure('statements') %> -<div class="widget"> <table width="100%"> <tr> <td valign="top" width="48%" nowrap> @@ -61,5 +60,4 @@ if measure('lines') || measure('ncloc') </td> </tr> </table> -</div> <% end %>
\ No newline at end of file diff --git a/plugins/sonar-core-plugin/src/main/resources/org/sonar/plugins/core/widgets/code_coverage.html.erb b/plugins/sonar-core-plugin/src/main/resources/org/sonar/plugins/core/widgets/code_coverage.html.erb index 82dcc03258e..422c131f96b 100644 --- a/plugins/sonar-core-plugin/src/main/resources/org/sonar/plugins/core/widgets/code_coverage.html.erb +++ b/plugins/sonar-core-plugin/src/main/resources/org/sonar/plugins/core/widgets/code_coverage.html.erb @@ -2,7 +2,6 @@ code_coverage_measure=measure(Metric::COVERAGE) tests_measure=measure(Metric::TESTS) if code_coverage_measure || tests_measure %> -<div class="widget"> <div class="yui-g"> <div class="yui-u first"> <div class="dashbox"> @@ -43,5 +42,4 @@ if code_coverage_measure || tests_measure %> <% end %> </div> </div> -</div> <% end %> diff --git a/plugins/sonar-core-plugin/src/main/resources/org/sonar/plugins/core/widgets/comments_duplications.html.erb b/plugins/sonar-core-plugin/src/main/resources/org/sonar/plugins/core/widgets/comments_duplications.html.erb index aabb5c642e6..28f28552123 100644 --- a/plugins/sonar-core-plugin/src/main/resources/org/sonar/plugins/core/widgets/comments_duplications.html.erb +++ b/plugins/sonar-core-plugin/src/main/resources/org/sonar/plugins/core/widgets/comments_duplications.html.erb @@ -1,5 +1,4 @@ <% if measure(Metric::LINES) || measure(Metric::NCLOC) %> -<div class="widget"> <table width="100%"> <tr> <td valign="top" width="48%" nowrap> @@ -35,5 +34,4 @@ </td> </tr> </table> -</div> <% end %>
\ No newline at end of file diff --git a/plugins/sonar-core-plugin/src/main/resources/org/sonar/plugins/core/widgets/custom_measures.html.erb b/plugins/sonar-core-plugin/src/main/resources/org/sonar/plugins/core/widgets/custom_measures.html.erb index 4fc22a71d71..d53de7b202d 100644 --- a/plugins/sonar-core-plugin/src/main/resources/org/sonar/plugins/core/widgets/custom_measures.html.erb +++ b/plugins/sonar-core-plugin/src/main/resources/org/sonar/plugins/core/widgets/custom_measures.html.erb @@ -6,7 +6,6 @@ } %> <% if is_admin?(@snapshot) || measures.size>0 %> - <div class="widget"> <script type="text/javascript"> function selectReviewMetric(){ $$('.review_description_update').each(function(element) { @@ -66,5 +65,4 @@ </div> <% end %> <div class="clear"></div> - </div> <% end %> diff --git a/plugins/sonar-core-plugin/src/main/resources/org/sonar/plugins/core/widgets/description.html.erb b/plugins/sonar-core-plugin/src/main/resources/org/sonar/plugins/core/widgets/description.html.erb index aee61ede107..2a876313e9b 100644 --- a/plugins/sonar-core-plugin/src/main/resources/org/sonar/plugins/core/widgets/description.html.erb +++ b/plugins/sonar-core-plugin/src/main/resources/org/sonar/plugins/core/widgets/description.html.erb @@ -3,8 +3,6 @@ <%= h @project.description %><br/> <% end %> - <%= @project.name %> - Key : <%= @project.key %><br/> <% if @project.language %> Language : <%= @project.language %><br/> diff --git a/plugins/sonar-core-plugin/src/main/resources/org/sonar/plugins/core/widgets/events.html.erb b/plugins/sonar-core-plugin/src/main/resources/org/sonar/plugins/core/widgets/events.html.erb index 41a9415f667..1a2755b5af5 100644 --- a/plugins/sonar-core-plugin/src/main/resources/org/sonar/plugins/core/widgets/events.html.erb +++ b/plugins/sonar-core-plugin/src/main/resources/org/sonar/plugins/core/widgets/events.html.erb @@ -1,5 +1,5 @@ <% if @project.project? %> -<div class="widget" id="widget_events"><div id="events_portlet"></div></div> +<div id="widget_events"><div id="events_portlet"></div></div> <script> <%= remote_function(:update => "events_portlet", :url => { :controller => :project, :action => :events, :id => @snapshot.id }, :method => 'get') %> </script> diff --git a/plugins/sonar-core-plugin/src/main/resources/org/sonar/plugins/core/widgets/rules.html.erb b/plugins/sonar-core-plugin/src/main/resources/org/sonar/plugins/core/widgets/rules.html.erb index a1cc13ed827..dbcad0d1d5c 100644 --- a/plugins/sonar-core-plugin/src/main/resources/org/sonar/plugins/core/widgets/rules.html.erb +++ b/plugins/sonar-core-plugin/src/main/resources/org/sonar/plugins/core/widgets/rules.html.erb @@ -1,5 +1,5 @@ <% if measure(Metric::LINES) %> -<div class="widget" id="widget_rules"> +<div id="widget_rules"> <table width="100%"> <tr> <td valign="top"> diff --git a/plugins/sonar-design-plugin/src/main/resources/org/sonar/plugins/design/ui/widgets/chidamber_kemerer.html.erb b/plugins/sonar-design-plugin/src/main/resources/org/sonar/plugins/design/ui/widgets/chidamber_kemerer.html.erb index 936a6f7efec..2f772d05ce7 100644 --- a/plugins/sonar-design-plugin/src/main/resources/org/sonar/plugins/design/ui/widgets/chidamber_kemerer.html.erb +++ b/plugins/sonar-design-plugin/src/main/resources/org/sonar/plugins/design/ui/widgets/chidamber_kemerer.html.erb @@ -6,7 +6,6 @@ if lcom || rfc rfc_distribution=measure('rfc_distribution') suspect_lcom4_density=measure('suspect_lcom4_density') %> -<div class="widget"> <table width="100%"> <tbody> <tr> @@ -48,5 +47,4 @@ if lcom || rfc </tr> </tbody> </table> -</div> <% end %> diff --git a/plugins/sonar-design-plugin/src/main/resources/org/sonar/plugins/design/ui/widgets/file_design.html.erb b/plugins/sonar-design-plugin/src/main/resources/org/sonar/plugins/design/ui/widgets/file_design.html.erb index 6f53a2478d5..70041753975 100644 --- a/plugins/sonar-design-plugin/src/main/resources/org/sonar/plugins/design/ui/widgets/file_design.html.erb +++ b/plugins/sonar-design-plugin/src/main/resources/org/sonar/plugins/design/ui/widgets/file_design.html.erb @@ -4,7 +4,6 @@ file_cycles=measure('file_cycles') file_feedback_edges=measure('file_feedback_edges') %> -<div class="widget"> <table width="100%"> <tbody> <tr> @@ -28,7 +27,6 @@ </tr> </tbody> </table> -</div> <% end %>
\ No newline at end of file diff --git a/plugins/sonar-design-plugin/src/main/resources/org/sonar/plugins/design/ui/widgets/package_design.html.erb b/plugins/sonar-design-plugin/src/main/resources/org/sonar/plugins/design/ui/widgets/package_design.html.erb index c4903328ace..59136259ee1 100644 --- a/plugins/sonar-design-plugin/src/main/resources/org/sonar/plugins/design/ui/widgets/package_design.html.erb +++ b/plugins/sonar-design-plugin/src/main/resources/org/sonar/plugins/design/ui/widgets/package_design.html.erb @@ -2,7 +2,6 @@ package_tangle_index=measure('package_tangle_index') if package_tangle_index %> -<div class="widget"> <table width="100%"> <tbody> <tr> @@ -34,7 +33,6 @@ </tr> </tbody> </table> -</div> <% end %>
\ No newline at end of file diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/web/AbstractDashboardWidget.java b/sonar-plugin-api/src/main/java/org/sonar/api/web/AbstractDashboardWidget.java index be9d0415405..dcc5ca2179f 100644 --- a/sonar-plugin-api/src/main/java/org/sonar/api/web/AbstractDashboardWidget.java +++ b/sonar-plugin-api/src/main/java/org/sonar/api/web/AbstractDashboardWidget.java @@ -27,10 +27,10 @@ package org.sonar.api.web; public abstract class AbstractDashboardWidget extends AbstractRubyTemplate implements RubyRailsWidget { public String getId() { - return getClass().toString(); + return getClass().getSimpleName(); } public String getTitle() { - return getClass().toString(); + return getClass().getSimpleName(); } } diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/web/WidgetLayout.java b/sonar-plugin-api/src/main/java/org/sonar/api/web/WidgetLayout.java new file mode 100644 index 00000000000..81a0b872605 --- /dev/null +++ b/sonar-plugin-api/src/main/java/org/sonar/api/web/WidgetLayout.java @@ -0,0 +1,34 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2009 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * Sonar is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * Sonar is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with Sonar; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ +package org.sonar.api.web; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * @since 2.4 + */ +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.TYPE) +public @interface WidgetLayout { + WidgetLayoutType value(); +} diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/web/WidgetLayoutType.java b/sonar-plugin-api/src/main/java/org/sonar/api/web/WidgetLayoutType.java new file mode 100644 index 00000000000..dc542cb750c --- /dev/null +++ b/sonar-plugin-api/src/main/java/org/sonar/api/web/WidgetLayoutType.java @@ -0,0 +1,32 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2009 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * Sonar is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * Sonar is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with Sonar; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ +package org.sonar.api.web; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * @since 2.4 + */ +public enum WidgetLayoutType { + DEFAULT, NONE +}
\ No newline at end of file diff --git a/sonar-server/src/main/java/org/sonar/server/ui/ViewProxy.java b/sonar-server/src/main/java/org/sonar/server/ui/ViewProxy.java index 7cb7159bcf0..59fae3ac6a5 100644 --- a/sonar-server/src/main/java/org/sonar/server/ui/ViewProxy.java +++ b/sonar-server/src/main/java/org/sonar/server/ui/ViewProxy.java @@ -37,8 +37,9 @@ public class ViewProxy<V extends View> implements Comparable<ViewProxy> { private String[] resourceLanguages = {}; private String[] defaultForMetrics = {}; private String description = ""; - private WidgetProperty[] properties = {}; - private String[] categories = {}; + private WidgetProperty[] widgetProperties = {}; + private String[] widgetCategories = {}; + private WidgetLayoutType widgetLayout = WidgetLayoutType.DEFAULT; private boolean isDefaultTab = false; private boolean isWidget = false; @@ -87,14 +88,19 @@ public class ViewProxy<V extends View> implements Comparable<ViewProxy> { description = descriptionAnnotation.value(); } - WidgetProperties widgetProperties = AnnotationUtils.getClassAnnotation(view, WidgetProperties.class); - if (widgetProperties != null) { - properties = widgetProperties.value(); + WidgetProperties propAnnotation = AnnotationUtils.getClassAnnotation(view, WidgetProperties.class); + if (propAnnotation != null) { + this.widgetProperties = propAnnotation.value(); } - WidgetCategory widgetCategory = AnnotationUtils.getClassAnnotation(view, WidgetCategory.class); - if (widgetCategory != null) { - categories = widgetCategory.value(); + WidgetCategory categAnnotation = AnnotationUtils.getClassAnnotation(view, WidgetCategory.class); + if (categAnnotation != null) { + widgetCategories = categAnnotation.value(); + } + + WidgetLayout layoutAnnotation = AnnotationUtils.getClassAnnotation(view, WidgetLayout.class); + if (layoutAnnotation != null) { + widgetLayout = layoutAnnotation.value(); } isWidget = (view instanceof Widget); @@ -116,12 +122,12 @@ public class ViewProxy<V extends View> implements Comparable<ViewProxy> { return description; } - public WidgetProperty[] getProperties() { - return properties; + public WidgetProperty[] getWidgetProperties() { + return widgetProperties; } - public String[] getCategories() { - return categories; + public String[] getWidgetCategories() { + return widgetCategories; } public String[] getSections() { @@ -160,13 +166,17 @@ public class ViewProxy<V extends View> implements Comparable<ViewProxy> { return view instanceof GwtPage; } + public WidgetLayoutType getWidgetLayout() { + return widgetLayout; + } + public boolean isEditable() { - return !ArrayUtils.isEmpty(properties); + return !ArrayUtils.isEmpty(widgetProperties); } public boolean hasRequiredProperties() { boolean requires = false; - for (WidgetProperty property : properties) { + for (WidgetProperty property : widgetProperties) { if (!property.optional() && StringUtils.isEmpty(property.defaultValue())) { requires = true; } diff --git a/sonar-server/src/main/webapp/WEB-INF/app/controllers/dashboard_controller.rb b/sonar-server/src/main/webapp/WEB-INF/app/controllers/dashboard_controller.rb index 50d872a104c..289bb1b7138 100644 --- a/sonar-server/src/main/webapp/WEB-INF/app/controllers/dashboard_controller.rb +++ b/sonar-server/src/main/webapp/WEB-INF/app/controllers/dashboard_controller.rb @@ -111,7 +111,7 @@ class DashboardController < ApplicationController #TODO check owner of dashboard definition=java_facade.getWidget(widget.widget_key) errors_by_property_key={} - definition.getProperties().each do |property_def| + definition.getWidgetProperties().each do |property_def| value=params[property_def.key()] || property_def.defaultValue() value='false' if value.empty? && property_def.type.name()==WidgetProperty::TYPE_BOOLEAN @@ -201,10 +201,10 @@ class DashboardController < ApplicationController def load_widget_definitions(filter_on_category=nil) @widget_definitions=java_facade.getWidgets() @widget_categories=[] - @widget_definitions.each {|definition| @widget_categories<<definition.getCategories()} + @widget_definitions.each {|definition| @widget_categories<<definition.getWidgetCategories()} @widget_categories=@widget_categories.flatten.uniq.sort unless filter_on_category.blank? - @widget_definitions=@widget_definitions.select{|definition| definition.getCategories().to_a.include?(filter_on_category)} + @widget_definitions=@widget_definitions.select{|definition| definition.getWidgetCategories().to_a.include?(filter_on_category)} end end diff --git a/sonar-server/src/main/webapp/WEB-INF/app/views/dashboard/_configure_widget.html.erb b/sonar-server/src/main/webapp/WEB-INF/app/views/dashboard/_configure_widget.html.erb index d592eceb471..86472f3de6b 100644 --- a/sonar-server/src/main/webapp/WEB-INF/app/views/dashboard/_configure_widget.html.erb +++ b/sonar-server/src/main/webapp/WEB-INF/app/views/dashboard/_configure_widget.html.erb @@ -21,7 +21,7 @@ <% form_remote_tag :url => {:action => 'save_widget', :wid => widget.id, :id => params[:id]}, :method => :post do -%> <table class="form"> <tbody> - <% definition.getProperties().each do |property_def| + <% definition.getWidgetProperties().each do |property_def| value=widget.property_value(property_def.key(), property_def.defaultValue()) %> <tr> @@ -57,7 +57,14 @@ <![endif]--> <div class="transparent"></div> <% if widget_body.include? '<' %> - <%= widget_body %> + <% + default_layout=(definition.getWidgetLayout().name()=='DEFAULT') + if default_layout + %> + <div class="widget"> + <% end %> + <%= widget_body -%> + <% if default_layout %><div class="clear"> </div></div><% end %> <% else %> <div class="widget"><p>No data</p></div> <% end %> diff --git a/sonar-server/src/main/webapp/WEB-INF/app/views/dashboard/_widget.html.erb b/sonar-server/src/main/webapp/WEB-INF/app/views/dashboard/_widget.html.erb index e6ff5c55943..c97d62e69ae 100644 --- a/sonar-server/src/main/webapp/WEB-INF/app/views/dashboard/_widget.html.erb +++ b/sonar-server/src/main/webapp/WEB-INF/app/views/dashboard/_widget.html.erb @@ -11,7 +11,14 @@ if widget_body.include?('<') %> - <%= widget_body %> + <% + default_layout=(definition.getWidgetLayout().name()=='DEFAULT') + if default_layout + %> + <div class="widget"> + <% end %> + <%= widget_body -%> + <% if default_layout %><div class="clear"> </div></div><% end %> <% end %> diff --git a/sonar-server/src/main/webapp/WEB-INF/app/views/dashboards/_widget.html.erb b/sonar-server/src/main/webapp/WEB-INF/app/views/dashboards/_widget.html.erb index d7c834d0f50..17d5e6f135e 100644 --- a/sonar-server/src/main/webapp/WEB-INF/app/views/dashboards/_widget.html.erb +++ b/sonar-server/src/main/webapp/WEB-INF/app/views/dashboards/_widget.html.erb @@ -1,5 +1,5 @@ <%
- properties_available=widget_view.getProperties() && widget_view.getProperties().size() != 0
+ properties_available=widget_view.getWidgetProperties() && widget_view.getWidgetProperties().size() != 0
if !properties_available || (widget && widget.state==Widget::STATE_ACTIVE)
begin
@@ -51,7 +51,7 @@ :before => "$(this).down('.widgetid').value=$(this).up('.block').identify().split('_').pop();hide_block_info($(this).up('.block'))" do -%>
<table class="form" align="center" style="border-collapse:separate;border-spacing:5px;">
<tbody>
- <% widget_view.getProperties().each do |property|
+ <% widget_view.getWidgetProperties().each do |property|
db_property_value=widget.widget_property_value(property.key()) if widget
entered_value=params[property.key()]
entered_value=property.defaultValue() if !entered_value || entered_value.empty?
diff --git a/sonar-server/src/main/webapp/stylesheets/dashboard.css b/sonar-server/src/main/webapp/stylesheets/dashboard.css index 321454fa79a..a275105d8c6 100644 --- a/sonar-server/src/main/webapp/stylesheets/dashboard.css +++ b/sonar-server/src/main/webapp/stylesheets/dashboard.css @@ -49,7 +49,7 @@ /*CONFIGURATION*/ #dashboard #widget_defs { - height: 130px; + height: 150px; overflow-y: auto; background-color: #FFF6BF; border: 2px solid #FFD324; @@ -70,6 +70,7 @@ margin: 3px; white-space: normal; vertical-align: top; + height: 80px; } #dashboard ul.widget_categs li { padding-right: 5px; diff --git a/sonar-server/src/test/java/org/sonar/server/ui/ViewProxyTest.java b/sonar-server/src/test/java/org/sonar/server/ui/ViewProxyTest.java index c93558678e0..edc78acaafa 100644 --- a/sonar-server/src/test/java/org/sonar/server/ui/ViewProxyTest.java +++ b/sonar-server/src/test/java/org/sonar/server/ui/ViewProxyTest.java @@ -119,7 +119,7 @@ public class ViewProxyTest { public void widgetShouldBeEditable() { ViewProxy proxy = new ViewProxy<Widget>(new EditableWidget()); assertThat(proxy.isEditable(), is(true)); - assertThat(proxy.getProperties().length, is(2)); + assertThat(proxy.getWidgetProperties().length, is(2)); } @Test |