blob: def91de65a776a654fb2946309badd7c07583a50 [file] [log] [blame]
/*
* Copyright (c) 2015 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
*/
package com.google.eclipse.protobuf.ui.commands.semicolon;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.is;
import org.eclipse.swt.custom.StyledTextContent;
import org.eclipse.text.edits.ReplaceEdit;
import org.eclipse.text.edits.TextEdit;
import org.eclipse.xtext.nodemodel.ICompositeNode;
import org.eclipse.xtext.nodemodel.util.NodeModelUtils;
import org.junit.Rule;
import org.junit.Test;
import org.mockito.Mockito;
import com.google.eclipse.protobuf.junit.core.XtextRule;
import com.google.eclipse.protobuf.protobuf.Group;
import com.google.eclipse.protobuf.protobuf.Literal;
import com.google.eclipse.protobuf.protobuf.MessageField;
import com.google.eclipse.protobuf.ui.plugin.ProtobufEditorPlugIn;
import com.google.inject.Inject;
public class SmartSemicolonHandlerTest {
@Rule
public XtextRule xtext = XtextRule.createWith(ProtobufEditorPlugIn.injector());
@Inject
private SmartSemicolonHandler handler;
// // ignore errors
// syntax = "proto2";
//
// message Message {
// optional bool incomplete
// }
@Test public void shouldDetermineFirstIndexToBe1() {
MessageField incomplete = xtext.find("incomplete", MessageField.class);
assertThat(handler.determineNewIndex(incomplete), is(1L));
}
// // ignore errors
// syntax = "proto2";
//
// message Message {
// optional bool in_message = 2;
// optional group outer_group = 4 {
// optional bool in_outer_group = 5;
// optional group inner_group = 3 {
// optional bool in_inner_group = 1;
// optional bool incomplete
// }
// }
// }
@Test public void shouldDetermineCorrectIndexInsideOfGroups() {
MessageField incomplete = xtext.find("incomplete", MessageField.class);
assertThat(handler.determineNewIndex(incomplete), is(6L));
}
// // ignore errors
// syntax = "proto2";
//
// message Message {
// optional bool in_message = 2;
// optional group outer_group = 4 {
// optional bool in_outer_group = 5;
// optional group inner_group = 3 {
// optional bool in_inner_group = 1;
// }
// }
// optional bool incomplete
// }
@Test public void shouldDetermineCorrectIndexOutsideOfGroups() {
MessageField incomplete = xtext.find("incomplete", MessageField.class);
assertThat(handler.determineNewIndex(incomplete), is(6L));
}
// // ignore errors
// syntax = "proto2";
//
// message Message {
// optional bool in_message = 2;
// message InnerMessage {
// optional bool in_inner_message = 4;
// optional bool incomplete
// }
// }
@Test public void shouldDetermineCorrectIndexInsideOfNestedMessage() {
MessageField incomplete = xtext.find("incomplete", MessageField.class);
assertThat(handler.determineNewIndex(incomplete), is(5L));
}
// // ignore errors
// syntax = "proto2";
//
// message Message {
// optional bool in_message = 2;
// message InnerMessage {
// optional bool in_inner_message = 4;
// }
// optional bool incomplete
// }
@Test public void shouldDetermineCorrectIndexOutsideOfNestedMessage() {
MessageField incomplete = xtext.find("incomplete", MessageField.class);
assertThat(handler.determineNewIndex(incomplete), is(3L));
}
// // ignore errors
// syntax = "proto2";
//
// message Message {
// optional bool foo = 1;
// reserved 3;
// optional bool incomplete
// }
@Test public void shouldDetermineCorrectIndexWithSingleReserved() {
MessageField incomplete = xtext.find("incomplete", MessageField.class);
assertThat(handler.determineNewIndex(incomplete), is(4L));
}
// // ignore errors
// syntax = "proto2";
//
// message Message {
// optional bool foo = 1;
// reserved 3, 5 to 7;
// optional bool incomplete
// }
@Test public void shouldDetermineCorrectIndexWithReservedRange() {
MessageField incomplete = xtext.find("incomplete", MessageField.class);
assertThat(handler.determineNewIndex(incomplete), is(8L));
}
// // ignore errors
// syntax = "proto2";
//
// message Message {
// optional bool incomplete
// }
@Test public void shouldComplete() {
String incompleteFieldName = "incomplete";
MessageField incomplete = xtext.find(incompleteFieldName, MessageField.class);
ICompositeNode node = NodeModelUtils.getNode(incomplete);
ReplaceEdit indexEdit = handler.completeWithIndex(node, 1);
assertThat(indexEdit.getOffset(),
is(xtext.text().indexOf(incompleteFieldName) + incompleteFieldName.length()));
assertThat(indexEdit.getText(), is(" = 1;"));
}
// // ignore errors
// syntax = "proto2";
//
// message Message {
// optional bool incomplete
// =
// }
@Test public void shouldCompleteAfterExistingEquals() {
MessageField incomplete = xtext.find("incomplete", MessageField.class);
ICompositeNode node = NodeModelUtils.getNode(incomplete);
ReplaceEdit indexEdit = handler.completeWithIndex(node, 1);
String equalsAtStartOfLine = " =";
assertThat(indexEdit.getOffset(),
is(xtext.text().indexOf(equalsAtStartOfLine) + equalsAtStartOfLine.length()));
assertThat(indexEdit.getText(), is(" 1;"));
}
// // ignore errors
// syntax = "proto2";
//
// message Message {
// optional bool incomplete [ default = true; ];
// }
@Test public void shouldCompleteWithoutSemicolonBeforeOptionBracket() {
String incompleteFieldName = "incomplete";
MessageField incomplete = xtext.find(incompleteFieldName, MessageField.class);
ICompositeNode node = NodeModelUtils.getNode(incomplete);
ReplaceEdit indexEdit = handler.completeWithIndex(node, 1);
assertThat(indexEdit.getOffset(),
is(xtext.text().indexOf(incompleteFieldName) + incompleteFieldName.length()));
assertThat(indexEdit.getText(), is(" = 1 "));
}
// // ignore errors
// syntax = "proto2";
//
// message Message {
// optional group incomplete {
// }
// }
@Test public void shouldCompleteWithoutSemicolonBeforeGroupBrace() {
String incompleteGroupName = "incomplete";
Group incomplete = xtext.find(incompleteGroupName, Group.class);
ICompositeNode node = NodeModelUtils.getNode(incomplete);
ReplaceEdit indexEdit = handler.completeWithIndex(node, 1);
assertThat(indexEdit.getOffset(),
is(xtext.text().indexOf(incompleteGroupName) + incompleteGroupName.length()));
assertThat(indexEdit.getText(), is(" = 1 "));
}
@Test public void shouldDeleteTrailingWhitespace() {
String trailingWhitespace = " ";
String lineContent = " optional bool foo" + trailingWhitespace;
int lineNumber = 10;
int lineStartOffset = 100;
int insertionOffset = lineStartOffset + lineContent.lastIndexOf(trailingWhitespace);
StyledTextContent content = Mockito.mock(StyledTextContent.class);
Mockito.when(content.getLineAtOffset(insertionOffset)).thenReturn(lineNumber);
Mockito.when(content.getOffsetAtLine(lineNumber)).thenReturn(lineStartOffset);
Mockito.when(content.getLine(lineNumber)).thenReturn(lineContent);
TextEdit trailingWhitespaceEdit = handler.deleteTrailingWhitespace(content, insertionOffset);
assertThat(trailingWhitespaceEdit.getOffset(), is(insertionOffset));
assertThat(trailingWhitespaceEdit.getLength(), is(trailingWhitespace.length()));
}
// // ignore errors
// syntax = "proto2";
//
// // Next Id: 2
// message Message {
// optional bool field = 1;
// optional bool incomplete
// }
@Test public void shouldUpdateNextIndexComment() {
MessageField incomplete = xtext.find("incomplete", MessageField.class);
ReplaceEdit commentEdit = handler.updateNextIndexComment(incomplete, 3);
String pattern = "Next Id: ";
assertThat(commentEdit.getOffset(), is(xtext.text().indexOf(pattern) + pattern.length()));
assertThat(commentEdit.getText(), is("3"));
}
// // ignore errors
// syntax = "proto2";
//
// /*
// * Next Id: 2
// */
// message Message {
// optional bool field = 1;
// optional bool incomplete
// }
@Test public void shouldUpdateMultilineComment() {
MessageField incomplete = xtext.find("incomplete", MessageField.class);
ReplaceEdit commentEdit = handler.updateNextIndexComment(incomplete, 3);
String pattern = "Next Id: ";
assertThat(commentEdit.getOffset(), is(xtext.text().indexOf(pattern) + pattern.length()));
assertThat(commentEdit.getText(), is("3"));
}
// // ignore errors
// syntax = "proto2";
//
// enum Enum {
// ONE = 1;
// TWO = 2;
// THREE = 3;
// FOUR
// // Next Id: 4
// }
@Test public void shouldUpdateNextIndexCommentAtEndOfEnum() {
Literal incomplete = xtext.find("FOUR", Literal.class);
ReplaceEdit commentEdit = handler.updateNextIndexComment(incomplete, 5);
String pattern = "Next Id: ";
assertThat(commentEdit.getOffset(), is(xtext.text().indexOf(pattern) + pattern.length()));
assertThat(commentEdit.getText(), is("5"));
}
// // ignore errors
// syntax = "proto2";
//
// // My Favorite Number: 200
// message Message {
// optional bool field = 1;
// optional bool incomplete
// }
@Test public void shouldNotUpdateOtherComment() {
MessageField incomplete = xtext.find("incomplete", MessageField.class);
ReplaceEdit commentEdit = handler.updateNextIndexComment(incomplete, 3);
assertThat(commentEdit, is((ReplaceEdit) null));
}
}