package com.dmarcotte.handlebars.editor.actions;
import com.dmarcotte.handlebars.config.HbConfig;
import com.dmarcotte.handlebars.format.FormatterTestSettings;
import com.intellij.psi.codeStyle.CodeStyleSettingsManager;
/**
* These tests are based on other children of {@link com.intellij.testFramework.fixtures.LightPlatformCodeInsightFixtureTestCase},
* in particular {@code com.intellij.application.options.codeInsight.editor.quotes.SelectionQuotingTypedHandlerTest}
*/
public class HbTypedHandlerTest extends HbActionHandlerTest {
private boolean myPrevAutoCloseSetting;
private FormatterTestSettings formatterTestSettings;
@Override
protected void setUp() throws Exception {
super.setUp();
myPrevAutoCloseSetting = HbConfig.isAutoGenerateCloseTagEnabled();
HbConfig.setAutoGenerateCloseTagEnabled(true);
formatterTestSettings = new FormatterTestSettings(CodeStyleSettingsManager.getSettings(getProject()));
formatterTestSettings.setUp();
}
@Override
protected void tearDown() throws Exception {
HbConfig.setAutoGenerateCloseTagEnabled(myPrevAutoCloseSetting);
formatterTestSettings.tearDown();
super.tearDown();
}
/**
* Sanity check that we do nothing when something other than "}" completes a stache
*/
public void testNonStacheClosingCharacter() {
HbConfig.setAutoGenerateCloseTagEnabled(true);
doCharTest('X', "{{#foo}<caret>", "{{#foo}X<caret>");
HbConfig.setAutoGenerateCloseTagEnabled(false);
doCharTest('X', "{{#foo}<caret>", "{{#foo}X<caret>");
}
public void testCloseDoubleBraces() {
HbConfig.setAutocompleteMustachesEnabled(false);
doCharTest('}', "foo {{bar<caret>", "foo {{bar}<caret>");
doCharTest('}', "foo {{&bar<caret>", "foo {{&bar}<caret>");
doCharTest('}', "foo {{/bar<caret>", "foo {{/bar}<caret>");
HbConfig.setAutocompleteMustachesEnabled(true);
doCharTest('}', "foo {{bar<caret>", "foo {{bar}}<caret>");
doCharTest('}', "foo {{&bar<caret>", "foo {{&bar}}<caret>");
doCharTest('}', "foo {{/bar<caret>", "foo {{/bar}}<caret>");
HbConfig.setAutoGenerateCloseTagEnabled(true);
doCharTest('}', "foo {{#bar<caret>", "foo {{#bar}}<caret>{{/bar}}");
doCharTest('}', "foo {{^bar<caret>", "foo {{^bar}}<caret>{{/bar}}");
doCharTest('}', "foo {{#bar}}{{#baz<caret>{{/bar}}", "foo {{#bar}}{{#baz}}<caret>{{/baz}}{{/bar}}");
HbConfig.setAutoGenerateCloseTagEnabled(false);
doCharTest('}', "foo {{#bar<caret>", "foo {{#bar}}<caret>");
doCharTest('}', "foo {{^bar<caret>", "foo {{^bar}}<caret>");
doCharTest('}', "foo {{#bar}}{{#baz<caret>{{/bar}}", "foo {{#bar}}{{#baz}}<caret>{{/bar}}");
}
public void testCloseTripleBraces() {
HbConfig.setAutocompleteMustachesEnabled(false);
doCharTest('}', "foo {{{bar<caret>", "foo {{{bar}<caret>");
HbConfig.setAutocompleteMustachesEnabled(true);
doCharTest('}', "foo {{{bar<caret>", "foo {{{bar}}}<caret>");
}
public void testInsertCloseTagForOpenBlockStache() {
HbConfig.setAutoGenerateCloseTagEnabled(true);
doCharTest('}', "{{#foo}<caret>", "{{#foo}}<caret>{{/foo}}");
doCharTest('}', "{{#foo bar baz}<caret>", "{{#foo bar baz}}<caret>{{/foo}}");
doCharTest('}', "{{#foo bar baz bat=\"bam\"}<caret>", "{{#foo bar baz bat=\"bam\"}}<caret>{{/foo}}");
// test when caret is not at file boundary
doCharTest('}', "{{#foo}<caret>some\nother content", "{{#foo}}<caret>{{/foo}}some\nother content");
doCharTest('}', "{{#foo bar baz}<caret>some\nother content", "{{#foo bar baz}}<caret>{{/foo}}some\nother content");
doCharTest('}', "{{#foo bar baz bat=\"bam\"}<caret>some\nother content",
"{{#foo bar baz bat=\"bam\"}}<caret>{{/foo}}some\nother content");
HbConfig.setAutoGenerateCloseTagEnabled(false);
doCharTest('}', "{{#foo}<caret>", "{{#foo}}<caret>");
doCharTest('}', "{{#foo bar baz}<caret>", "{{#foo bar baz}}<caret>");
doCharTest('}', "{{#foo bar baz bat=\"bam\"}<caret>", "{{#foo bar baz bat=\"bam\"}}<caret>");
}
public void testInsertCloseTagForNestedBlocks() {
HbConfig.setAutoGenerateCloseTagEnabled(true);
doCharTest('}', "{{#foo}}{{#bar}<caret>{{/foo}}", "{{#foo}}{{#bar}}<caret>{{/bar}}{{/foo}}");
}
public void testInsertCloseTagForOpenInverseStache() {
HbConfig.setAutoGenerateCloseTagEnabled(true);
doCharTest('}', "{{^foo}<caret>", "{{^foo}}<caret>{{/foo}}");
doCharTest('}', "{{^foo bar baz}<caret>", "{{^foo bar baz}}<caret>{{/foo}}");
doCharTest('}', "{{^foo bar baz bat=\"bam\"}<caret>", "{{^foo bar baz bat=\"bam\"}}<caret>{{/foo}}");
// test when caret is not at file boundary
doCharTest('}', "{{^foo}<caret>some\nother content", "{{^foo}}<caret>{{/foo}}some\nother content");
doCharTest('}', "{{^foo bar baz}<caret>some\nother content", "{{^foo bar baz}}<caret>{{/foo}}some\nother content");
doCharTest('}', "{{^foo bar baz bat=\"bam\"}<caret>some\nother content",
"{{^foo bar baz bat=\"bam\"}}<caret>{{/foo}}some\nother content");
HbConfig.setAutoGenerateCloseTagEnabled(false);
doCharTest('}', "{{^foo}<caret>", "{{^foo}}<caret>");
doCharTest('}', "{{^foo bar baz}<caret>", "{{^foo bar baz}}<caret>");
doCharTest('}', "{{^foo bar baz bat=\"bam\"}<caret>", "{{^foo bar baz bat=\"bam\"}}<caret>");
}
public void testInsertCloseTagWithWhitespace() {
// ensure that we properly identify the "foo" even if there's whitespace between it and the open tag
HbConfig.setAutoGenerateCloseTagEnabled(true);
doCharTest('}', "{{# foo }<caret>", "{{# foo }}<caret>{{/foo}}");
}
public void testInsertCloseTagForComplexIds() {
HbConfig.setAutoGenerateCloseTagEnabled(true);
doCharTest('}', "{{#foo.bar}<caret>", "{{#foo.bar}}<caret>{{/foo.bar}}");
doCharTest('}', "{{#foo.bar.[baz bat]}<caret>", "{{#foo.bar.[baz bat]}}<caret>{{/foo.bar.[baz bat]}}");
}
public void testNoInsertCloseTagForExtraStaches() {
HbConfig.setAutoGenerateCloseTagEnabled(true);
doCharTest('}', "{{#foo}}<caret>", "{{#foo}}}<caret>");
}
public void testRegularStache() {
// ensure that nothing special happens for regular 'staches, whether autoGenerateCloseTag is enabled or not
HbConfig.setAutoGenerateCloseTagEnabled(true);
doCharTest('}', "{{foo}<caret>", "{{foo}}<caret>");
doCharTest('}', "{{foo bar baz}<caret>", "{{foo bar baz}}<caret>");
// test when caret is not at file boundary
HbConfig.setAutoGenerateCloseTagEnabled(true);
doCharTest('}', "{{foo}<caret>some\nother stuff", "{{foo}}<caret>some\nother stuff");
doCharTest('}', "{{foo bar baz}<caret>some\nother stuff", "{{foo bar baz}}<caret>some\nother stuff");
HbConfig.setAutoGenerateCloseTagEnabled(false);
doCharTest('}', "{{foo}<caret>", "{{foo}}<caret>");
doCharTest('}', "{{foo bar baz}<caret>", "{{foo bar baz}}<caret>");
}
/**
* Our typed handler relies on looking a couple of characters back
* make sure we're well behaved when there are none.
*/
public void testFirstCharTyped() {
HbConfig.setAutoGenerateCloseTagEnabled(true);
doCharTest('}', "<caret>", "}<caret>");
HbConfig.setAutoGenerateCloseTagEnabled(false);
doCharTest('}', "<caret>", "}<caret>");
}
/**
* Ensure that IDEA does not provide any automatic "}" insertion
*/
public void testSuppressNativeBracketInsert() {
HbConfig.setAutoGenerateCloseTagEnabled(true);
doCharTest('{', "<caret>", "{<caret>");
doCharTest('{', "{<caret>", "{{<caret>");
doCharTest('{', "{{<caret>", "{{{<caret>");
HbConfig.setAutoGenerateCloseTagEnabled(false);
doCharTest('{', "<caret>", "{<caret>");
doCharTest('{', "{<caret>", "{{<caret>");
doCharTest('{', "{{<caret>", "{{{<caret>");
}
public void testFormatOnCloseBlockCompleted1() {
doCharTest('}',
"{{#foo}}\n" +
" stuff\n" +
" {{/foo}<caret>",
"{{#foo}}\n" +
" stuff\n" +
"{{/foo}}<caret>");
}
public void testFormatOnCloseBlockCompleted2() {
doCharTest('}',
"{{#foo}}\n" +
" stuff\n" +
" {{/foo}<caret> other stuff",
"{{#foo}}\n" +
" stuff\n" +
"{{/foo}}<caret> other stuff");
}
public void testFormatOnCloseBlockCompleted3() {
doCharTest('}',
"{{#foo}}\n" +
" stuff\n" +
" {{/foo}<caret>\n" +
"other stuff",
"{{#foo}}\n" +
" stuff\n" +
"{{/foo}}<caret>\n" +
"other stuff");
}
public void testFormatDisabledCloseBlockCompleted() {
boolean previousFormatSetting = HbConfig.isFormattingEnabled();
HbConfig.setFormattingEnabled(false);
doCharTest('}',
"{{#foo}}\n" +
" stuff\n" +
" {{/foo}<caret>",
"{{#foo}}\n" +
" stuff\n" +
" {{/foo}}<caret>");
HbConfig.setFormattingEnabled(previousFormatSetting);
}
public void testFormatOnSimpleInverseCompleted1() {
doCharTest('}',
"{{#if}}\n" +
" if stuff\n" +
" {{else}<caret>",
"{{#if}}\n" +
" if stuff\n" +
"{{else}}<caret>");
}
public void testFormatOnSimpleInverseCompleted2() {
doCharTest('}',
"{{#if}}\n" +
" if stuff\n" +
" {{else}<caret> other stuff",
"{{#if}}\n" +
" if stuff\n" +
"{{else}}<caret> other stuff");
}
public void testFormatOnSimpleInverseCompleted3() {
doCharTest('}',
"{{#if}}\n" +
" if stuff\n" +
" {{else}<caret>\n" +
"other stuff",
"{{#if}}\n" +
" if stuff\n" +
"{{else}}<caret>\n" +
"other stuff");
}
public void testFormatDisabledSimpleInverseCompleted() {
boolean previousFormatSetting = HbConfig.isFormattingEnabled();
HbConfig.setFormattingEnabled(false);
doCharTest('}',
"{{#if}}\n" +
" if stuff\n" +
" {{else}<caret>",
"{{#if}}\n" +
" if stuff\n" +
" {{else}}<caret>");
HbConfig.setFormattingEnabled(previousFormatSetting);
}
public void testEnterBetweenBlockTags() {
doEnterTest(
"{{#foo}}<caret>{{/foo}}",
"{{#foo}}\n" +
" <caret>\n" +
"{{/foo}}"
);
}
public void testFormatterDisabledEnterBetweenBlockTags() {
boolean previousFormatSetting = HbConfig.isFormattingEnabled();
HbConfig.setFormattingEnabled(false);
doEnterTest(
"{{#foo}}<caret>{{/foo}}",
"{{#foo}}\n" +
"<caret>\n" +
"{{/foo}}"
);
HbConfig.setFormattingEnabled(previousFormatSetting);
}
public void testEnterNotBetweenBlockTags() {
doEnterTest(
"{{foo}}<caret>{{foo}}",
"{{foo}}\n" +
"<caret>{{foo}}"
);
}
public void testFinishingClosingTag() {
doCharTest(
'/',
"<div class=\"entry\">\n" +
" {{#if}}test{{<caret>\n" +
"</div>",
"<div class=\"entry\">\n" +
" {{#if}}test{{/if}}<caret>\n" +
"</div>"
);
doCharTest(
'/',
"<div class=\"entry\">\n" +
" {{#if}}test{<caret>\n" +
"</div>",
"<div class=\"entry\">\n" +
" {{#if}}test{{/if}}<caret>\n" +
"</div>"
);
}
}