BugĀ 527571 - Recorder/Generator misses CCombo selection

CCombo's selection triggers Modify event for Text.
Ignore this event in ModifyTextRule if the Text's parent is CCombo.

Add support in generator for ccombo.setText by adding
CComboTextModifyRule and ModifyCComboComplexRule.

Correct CComboSelectionRule. It should generate code for setSelection.

Change-Id: Icc22a44ee68222f6e8eb30cf22fcc57eb1e3a83f
Signed-off-by: Aparna Argade <aprsac@yahoo.com>
diff --git a/org.eclipse.swtbot.generator.test/src/org/eclipse/swtbot/generator/test/RecordCComboSelectionTest.java b/org.eclipse.swtbot.generator.test/src/org/eclipse/swtbot/generator/test/RecordCComboSelectionTest.java
new file mode 100644
index 0000000..66a9f4c
--- /dev/null
+++ b/org.eclipse.swtbot.generator.test/src/org/eclipse/swtbot/generator/test/RecordCComboSelectionTest.java
@@ -0,0 +1,35 @@
+/*******************************************************************************
+ * Copyright (c) 2017 Cadence Design Systems, Inc. and others.
+ * 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:
+ *    Aparna Argade - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.swtbot.generator.test;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.custom.CCombo;
+import org.eclipse.swt.widgets.Composite;
+import org.junit.Assert;
+import org.junit.Test;
+
+public class RecordCComboSelectionTest extends AbstractGeneratorTest {
+
+	@Override
+	protected void contributeToDialog(Composite container) {
+		CCombo ccombo = new CCombo(container, SWT.DROP_DOWN | SWT.READ_ONLY);
+		ccombo.add("1");
+		ccombo.add("2");
+	}
+
+	@Test
+	public void testModifyCombo() {
+		this.bot.ccomboBox().setSelection("2"); //$NON-NLS-1$
+		flushEvents();
+		Assert.assertEquals("bot.ccomboBox().setSelection(\"2\");", //$NON-NLS-1$
+				recorderShellBot().text().getText().trim());
+	}
+}
diff --git a/org.eclipse.swtbot.generator.test/src/org/eclipse/swtbot/generator/test/RecordCComboTextTest.java b/org.eclipse.swtbot.generator.test/src/org/eclipse/swtbot/generator/test/RecordCComboTextTest.java
new file mode 100644
index 0000000..5eab3e1
--- /dev/null
+++ b/org.eclipse.swtbot.generator.test/src/org/eclipse/swtbot/generator/test/RecordCComboTextTest.java
@@ -0,0 +1,34 @@
+/*******************************************************************************
+ * Copyright (c) 2017 Cadence Design Systems, Inc. and others.
+ * 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:
+ *    Aparna Argade - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.swtbot.generator.test;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.custom.CCombo;
+import org.eclipse.swt.widgets.Composite;
+import org.junit.Assert;
+import org.junit.Test;
+
+public class RecordCComboTextTest extends AbstractGeneratorTest {
+
+	@Override
+	protected void contributeToDialog(Composite container) {
+		new CCombo(container, SWT.DROP_DOWN);
+	}
+
+	@Test
+	public void testModifyCCombo() {
+		this.bot.ccomboBox().setText("kikoo"); //$NON-NLS-1$
+		flushEvents();
+		Assert.assertEquals("bot.ccomboBox().setText(\"kikoo\");", //$NON-NLS-1$
+				recorderShellBot().text().getText().trim());
+	}
+
+}
diff --git a/org.eclipse.swtbot.generator/src/org/eclipse/swtbot/generator/framework/WidgetUtils.java b/org.eclipse.swtbot.generator/src/org/eclipse/swtbot/generator/framework/WidgetUtils.java
index 3abefce..bf8bfa6 100644
--- a/org.eclipse.swtbot.generator/src/org/eclipse/swtbot/generator/framework/WidgetUtils.java
+++ b/org.eclipse.swtbot.generator/src/org/eclipse/swtbot/generator/framework/WidgetUtils.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2012 Red Hat Inc..
+ * Copyright (c) 2012, 2017 Red Hat Inc. and others.
  * 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
@@ -45,14 +45,18 @@
 		Composite parent = null;
 		do {
 			parent = control.getParent();
-			for (Control c : parent.getChildren()) {
-				if(c.equals(control)){
+			Control[] children = parent.getChildren();
+			if (children.length == 0) {
+				throw new RuntimeException("Could not determine index for widget " + control);
+			}
+			for (Control c : children) {
+				if (c.equals(control)) {
 					return index;
-				} else if (c.getClass().equals(control.getClass())){
+				} else if (c.getClass().equals(control.getClass())) {
 					index++;
 				}
 			}
-		} while(!(parent instanceof Shell));
+		} while (!(parent instanceof Shell));
 
 		throw new RuntimeException("Could not determine index for widget " + control);
 	}
@@ -119,7 +123,7 @@
 
 	private static Control getPreviousControl(Control control) {
 		int i = Arrays.asList(control.getParent().getChildren()).indexOf(control);
-		if (i == 0) {
+		if (i <= 0) {
 			return null;
 		}
 		return control.getParent().getChildren()[i - 1];
diff --git a/org.eclipse.swtbot.generator/src/org/eclipse/swtbot/generator/framework/rules/SWTBotGeneratorRules.java b/org.eclipse.swtbot.generator/src/org/eclipse/swtbot/generator/framework/rules/SWTBotGeneratorRules.java
index 4361763..c90899c 100644
--- a/org.eclipse.swtbot.generator/src/org/eclipse/swtbot/generator/framework/rules/SWTBotGeneratorRules.java
+++ b/org.eclipse.swtbot.generator/src/org/eclipse/swtbot/generator/framework/rules/SWTBotGeneratorRules.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2014 Red Hat Inc. and others.
+ * Copyright (c) 2014, 2018 Red Hat Inc. and others.
  * 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
@@ -26,11 +26,13 @@
 import org.eclipse.swtbot.generator.framework.GenerationSimpleRule;
 import org.eclipse.swtbot.generator.framework.Generator;
 import org.eclipse.swtbot.generator.framework.rules.annotation.TestAnnotationRule;
+import org.eclipse.swtbot.generator.framework.rules.complex.ModifyCComboComplexRule;
 import org.eclipse.swtbot.generator.framework.rules.complex.ModifyComboComplexRule;
 import org.eclipse.swtbot.generator.framework.rules.complex.ModifyStyledTextComplexRule;
 import org.eclipse.swtbot.generator.framework.rules.complex.ModifyTextComplexRule;
 import org.eclipse.swtbot.generator.framework.rules.complex.ToolBarMenuComplexRule;
 import org.eclipse.swtbot.generator.framework.rules.simple.CComboSelectionRule;
+import org.eclipse.swtbot.generator.framework.rules.simple.CComboTextModifyRule;
 import org.eclipse.swtbot.generator.framework.rules.simple.CTabItemActivateRule;
 import org.eclipse.swtbot.generator.framework.rules.simple.CheckTableItemRule;
 import org.eclipse.swtbot.generator.framework.rules.simple.CheckTreeItemRule;
@@ -80,6 +82,7 @@
 		res.add(new SelectListItemRule());
 		res.add(new CTabItemActivateRule());
 		res.add(new TabItemActivateRule());
+		res.add(new CComboTextModifyRule());
 		res.add(new PressShortCutRule());
 		res.add(new SelectTableItemRule());
 		res.add(new CheckTableItemRule());
@@ -121,6 +124,7 @@
 		cres.add(new ModifyTextComplexRule());
 		cres.add(new ModifyStyledTextComplexRule());
 		cres.add(new ModifyComboComplexRule());
+		cres.add(new ModifyCComboComplexRule());
 
 		IExtensionRegistry registry = RegistryFactory.getRegistry();
 		if (registry != null) {
diff --git a/org.eclipse.swtbot.generator/src/org/eclipse/swtbot/generator/framework/rules/complex/ModifyCComboComplexRule.java b/org.eclipse.swtbot.generator/src/org/eclipse/swtbot/generator/framework/rules/complex/ModifyCComboComplexRule.java
new file mode 100644
index 0000000..4a600ae
--- /dev/null
+++ b/org.eclipse.swtbot.generator/src/org/eclipse/swtbot/generator/framework/rules/complex/ModifyCComboComplexRule.java
@@ -0,0 +1,56 @@
+/*******************************************************************************
+ * Copyright (c) 2017 Cadence Design Systems, Inc. and others.
+ * 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:
+ *    Aparna Argade - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.swtbot.generator.framework.rules.complex;
+
+import java.util.List;
+
+import org.eclipse.swtbot.generator.framework.GenerationComplexRule;
+import org.eclipse.swtbot.generator.framework.GenerationSimpleRule;
+import org.eclipse.swtbot.generator.framework.rules.simple.CComboTextModifyRule;
+
+public class ModifyCComboComplexRule extends GenerationComplexRule{
+
+	private int textIndex;
+
+	@Override
+	public boolean appliesToPartially(GenerationSimpleRule rule, int i) {
+		if(i==0 &&  rule instanceof CComboTextModifyRule){ //first event, so we will store some identifier of text
+			this.textIndex = ((CComboTextModifyRule)rule).getTextIndex();
+		}
+		//check whether CComboTextModifyRule happened on the same text as the first one
+		//if not then it should be processed by another ModifyTextComplexRule
+		return rule instanceof CComboTextModifyRule && ((CComboTextModifyRule)rule).getTextIndex() == textIndex;
+	}
+
+	@Override
+	public boolean appliesTo(List<GenerationSimpleRule> rules) {
+		for(GenerationSimpleRule r: rules){
+			if (!(r instanceof CComboTextModifyRule)) {
+				return false;
+			} else if (((CComboTextModifyRule)r).getTextIndex() != this.textIndex){
+				return false;
+			}
+		}
+		return true;
+	}
+
+	@Override
+	public List<String> getActions() {
+		return ((CComboTextModifyRule)getInitializationRules().get(getInitializationRules().size()-1)).getActions();
+	}
+
+	@Override
+	public List<String> getImports() {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+}
diff --git a/org.eclipse.swtbot.generator/src/org/eclipse/swtbot/generator/framework/rules/simple/CComboSelectionRule.java b/org.eclipse.swtbot.generator/src/org/eclipse/swtbot/generator/framework/rules/simple/CComboSelectionRule.java
index 9010fe5..d5ef9ed 100644
--- a/org.eclipse.swtbot.generator/src/org/eclipse/swtbot/generator/framework/rules/simple/CComboSelectionRule.java
+++ b/org.eclipse.swtbot.generator/src/org/eclipse/swtbot/generator/framework/rules/simple/CComboSelectionRule.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2012 Red Hat Inc..
+ * Copyright (c) 2012, 2017 Red Hat Inc. and others.
  * 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
@@ -33,7 +33,7 @@
 
 	@Override
 	public void initializeForEvent(Event event) {
-		this.combo = (CCombo)event.widget;
+		this.combo = (CCombo) event.widget;
 		this.newSelection = this.combo.getText();
 		this.newSelectionIndex = this.combo.getSelectionIndex();
 		index = WidgetUtils.getIndex(this.combo);
@@ -50,7 +50,7 @@
 			res.append("bot.ccomboBox()");
 		}
 
-		res.append(".select(");
+		res.append(".setSelection(");
 		if (this.newSelection != null) {
 			res.append('"');
 			res.append(this.newSelection);
diff --git a/org.eclipse.swtbot.generator/src/org/eclipse/swtbot/generator/framework/rules/simple/CComboTextModifyRule.java b/org.eclipse.swtbot.generator/src/org/eclipse/swtbot/generator/framework/rules/simple/CComboTextModifyRule.java
new file mode 100644
index 0000000..b408137
--- /dev/null
+++ b/org.eclipse.swtbot.generator/src/org/eclipse/swtbot/generator/framework/rules/simple/CComboTextModifyRule.java
@@ -0,0 +1,77 @@
+/*******************************************************************************
+ * Copyright (c) 2017 Cadence Design Systems, Inc. and others.
+ * 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:
+ *    Aparna Argade - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.swtbot.generator.framework.rules.simple;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.custom.CCombo;
+import org.eclipse.swt.widgets.Event;
+import org.eclipse.swtbot.generator.framework.GenerationSimpleRule;
+import org.eclipse.swtbot.generator.framework.WidgetUtils;
+
+public class CComboTextModifyRule extends GenerationSimpleRule {
+
+	private int textIndex;
+	private String newValue;
+	private CCombo combo;
+
+	@Override
+	public boolean appliesTo(Event event) {
+		if (!(event.widget instanceof CCombo)) {
+			return false;
+		}
+		CCombo combo = (CCombo) event.widget;
+		return event.type == SWT.Modify && !Arrays.asList(combo.getItems()).contains(combo.getText());
+	}
+
+	@Override
+	public void initializeForEvent(Event event) {
+		this.combo = (CCombo) event.widget;
+		this.textIndex = WidgetUtils.getIndex(this.combo);
+		this.newValue = this.combo.getText();
+	}
+
+	public int getTextIndex() {
+		return textIndex;
+	}
+
+	public void setTextIndex(int textIndex) {
+		this.textIndex = textIndex;
+	}
+
+	@Override
+	public List<String> getActions() {
+		List<String> actions = new ArrayList<String>();
+		StringBuilder res = new StringBuilder();
+		res.append("bot.ccomboBox(");
+		if (textIndex != 0) {
+			res.append(textIndex);
+		}
+		res.append(").setText(\"" + this.newValue + "\")");
+		actions.add(res.toString());
+
+		return actions;
+	}
+
+	@Override
+	public List<String> getImports() {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+	@Override
+	public CCombo getWidget() {
+		return this.combo;
+	}
+}
diff --git a/org.eclipse.swtbot.generator/src/org/eclipse/swtbot/generator/framework/rules/simple/ModifyTextRule.java b/org.eclipse.swtbot.generator/src/org/eclipse/swtbot/generator/framework/rules/simple/ModifyTextRule.java
index 49243a2..ccd5a68 100644
--- a/org.eclipse.swtbot.generator/src/org/eclipse/swtbot/generator/framework/rules/simple/ModifyTextRule.java
+++ b/org.eclipse.swtbot.generator/src/org/eclipse/swtbot/generator/framework/rules/simple/ModifyTextRule.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2012 Red Hat Inc..
+ * Copyright (c) 2012, 2017 Red Hat Inc. and others.
  * 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
@@ -7,6 +7,7 @@
  *
  * Contributors:
  *    Mickael Istria (Red Hat) - initial API and implementation
+ *    Aparna Argade - Bug 527571
  *******************************************************************************/
 package org.eclipse.swtbot.generator.framework.rules.simple;
 
@@ -14,6 +15,7 @@
 import java.util.List;
 
 import org.eclipse.swt.SWT;
+import org.eclipse.swt.custom.CCombo;
 import org.eclipse.swt.widgets.Event;
 import org.eclipse.swt.widgets.Text;
 import org.eclipse.swt.widgets.Widget;
@@ -30,7 +32,8 @@
 	public boolean appliesTo(Event event) {
 		return event.widget instanceof Text && event.type == SWT.Modify &&
 				!((Text)event.widget).getText().isEmpty() &&
-				!((Text)event.widget).getText().equals(((Text)event.widget).getMessage());
+				!((Text)event.widget).getText().equals(((Text)event.widget).getMessage()) &&
+				!(((Text)event.widget).getParent() instanceof CCombo);
 	}
 
 	@Override