Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Fetching contributors…

Cannot retrieve contributors at this time

1173 lines (1073 sloc) 45.116 kb
using System;
using System.Linq;
using EditorUtils;
using Microsoft.VisualStudio.Text;
using Microsoft.VisualStudio.Text.Editor;
using Vim.Extensions;
using Vim.Interpreter;
using Xunit;
namespace Vim.UnitTest
{
public abstract class InterpreterTest : VimTestBase
{
protected IVimBufferData _vimBufferData;
protected IVimBuffer _vimBuffer;
protected IVimTextBuffer _vimTextBuffer;
protected ITextBuffer _textBuffer;
protected ITextView _textView;
protected IVimData _vimData;
protected global::Vim.Interpreter.Interpreter _interpreter;
protected TestableStatusUtil _statusUtil;
protected IVimGlobalSettings _globalSettings;
protected IVimLocalSettings _localSettings;
protected IVimWindowSettings _windowSettings;
protected IKeyMap _keyMap;
/// <summary>
/// A valid directory in the file system
/// </summary>
protected static string ValidDirectoryPath
{
get { return Environment.GetFolderPath(Environment.SpecialFolder.UserProfile); }
}
/// <summary>
/// An invalid directory in the file system
/// </summary>
protected static string InvalidDirectoryPath
{
get { return @"q:\invalid\path"; }
}
protected void Create(params string[] lines)
{
_statusUtil = new TestableStatusUtil();
_vimData = Vim.VimData;
_vimBufferData = CreateVimBufferData(
CreateTextView(lines),
statusUtil: _statusUtil);
_vimBuffer = CreateVimBuffer(_vimBufferData);
_vimTextBuffer = _vimBufferData.VimTextBuffer;
_windowSettings = _vimBufferData.WindowSettings;
_localSettings = _vimBufferData.LocalSettings;
_globalSettings = _localSettings.GlobalSettings;
_textBuffer = _vimBufferData.TextBuffer;
_textView = _vimBufferData.TextView;
_interpreter = new global::Vim.Interpreter.Interpreter(
_vimBuffer,
CommonOperationsFactory.GetCommonOperations(_vimBufferData),
FoldManagerFactory.GetFoldManager(_vimBufferData.TextView),
new FileSystem(),
BufferTrackingService);
_keyMap = Vim.KeyMap;
}
/// <summary>
/// Parse and run the specified command
/// </summary>
protected void ParseAndRun(string command)
{
var parseResult = Parser.ParseLineCommand(command);
Assert.True(parseResult.IsSucceeded);
_interpreter.RunLineCommand(parseResult.AsSucceeded().Item);
}
public sealed class Copy : InterpreterTest
{
/// <summary>
/// Copy to a single line
/// </summary>
[Fact]
public void ToSingleLine()
{
Create("cat", "dog", "fish", "tree");
_textView.MoveCaretToLine(2);
ParseAndRun("co 1");
Assert.Equal(
new[] { "cat", "fish", "dog", "fish", "tree" },
_textBuffer.GetLines().ToArray());
Assert.Equal(_textBuffer.GetLine(1).Start, _textView.GetCaretPoint());
}
/// <summary>
/// When copying to a line range the paste should come after the first line and
/// not the last as is common with other commands
/// </summary>
[Fact]
public void ToLineRange()
{
Create("cat", "dog", "fish", "tree");
_textView.MoveCaretToLine(3);
ParseAndRun("co 1,3");
Assert.Equal(
new[] { "cat", "tree", "dog", "fish", "tree" },
_textBuffer.GetLines().ToArray());
Assert.Equal(_textBuffer.GetLine(1).Start, _textView.GetCaretPoint());
}
/// <summary>
/// Copy to a single line plus a count should be copied to line + count
/// </summary>
[Fact]
public void ToSingleLineAndCount()
{
Create("cat", "dog", "fish", "bear", "tree");
_textView.MoveCaretToLine(4);
ParseAndRun("co 1 2");
Assert.Equal(
new[] { "cat", "dog", "fish", "tree", "bear", "tree" },
_textBuffer.GetLines().ToArray());
Assert.Equal(_textBuffer.GetLine(3).Start, _textView.GetCaretPoint());
}
/// <summary>
/// When copying to a line range and a count the count is simply ignored
/// </summary>
[Fact]
public void ToLineRangeAndCount()
{
Create("cat", "dog", "fish", "bear", "tree");
_textView.MoveCaretToLine(4);
ParseAndRun("co 1,3 2");
Assert.Equal(
new[] { "cat", "tree", "dog", "fish", "bear", "tree" },
_textBuffer.GetLines().ToArray());
Assert.Equal(_textBuffer.GetLine(1).Start, _textView.GetCaretPoint());
}
}
public sealed class Substitute : InterpreterTest
{
/// <summary>
/// When an empty string is provided for the pattern string then the pattern from the last
/// substitute
/// </summary>
[Fact]
public void EmptySearchUsesLastSearch()
{
Create("cat tree");
Vim.VimData.LastPatternData = new PatternData("cat", new Path(0));
ParseAndRun("s//dog/");
Assert.Equal("dog tree", _textBuffer.GetLine(0).GetText());
}
/// <summary>
/// Make sure that back slashes are properly handled in the replace
/// </summary>
[Fact]
public void Backslashes()
{
Create("cat");
ParseAndRun(@"s/a/\\\\");
Assert.Equal(@"c\\t", _textBuffer.GetLine(0).GetText());
}
[Fact]
public void DoubleQuotesPattern()
{
Create(@"""cat""");
ParseAndRun(@"s/""cat""/dog");
Assert.Equal("dog", _textBuffer.GetLine(0).GetText());
}
[Fact]
public void DoubleQuotesReplace()
{
Create(@"cat");
ParseAndRun(@"s/cat/""dog""");
Assert.Equal(@"""dog""", _textBuffer.GetLine(0).GetText());
}
/// <summary>
/// This is a bit of a special case around the escape sequence for a new line. The escape
/// actually escapes the backslash and doesn't add a new line
/// </summary>
[Fact]
public void EscapedLooksLikeNewLine()
{
Create("cat", "dog");
ParseAndRun(@"s/$/\\n\\/");
Assert.Equal(@"cat\n\", _textBuffer.GetLine(0).GetText());
Assert.Equal(@"dog", _textBuffer.GetLine(1).GetText());
}
/// <summary>
/// The $ marker needs to be treated as a zero width assertion. Don't replace the new line
/// just the rest of the string
/// </summary>
[Fact]
public void WordAndEndOfLine()
{
Create("cat cat", "fish");
ParseAndRun(@"s/cat$/dog/");
Assert.Equal("cat dog", _textBuffer.GetLine(0).GetText());
Assert.Equal("fish", _textBuffer.GetLine(1).GetText());
}
/// <summary>
/// Matching $ as part of the regex is a zero width match. It can't be used to delete the
/// end of the line
/// </summary>
[Fact]
public void EndOfLineIsZeroWidth()
{
Create("cat", "dog", "fish");
ParseAndRun(@"%s/$//");
Assert.Equal(3, _textBuffer.CurrentSnapshot.LineCount);
}
/// <summary>
/// Make sure a replace here at the end of the line happens after
/// </summary>
[Fact]
public void EndOfLineIsZeroWidth2()
{
Create("cat", "dog", "fish");
ParseAndRun(@"%s/$/ hat/");
Assert.Equal(
new[] { "cat hat", "dog hat", "fish hat" },
_textBuffer.GetLines().ToArray());
}
[Fact]
public void EndOfLineWithGroupReplace()
{
Create(
@" { ""cat"", CAT_VALUE /* 100 */ },",
@" { ""dog"", BAT_VALUE /* 101 */ },",
@" { ""bat"", BAT_VALUE /* 102 */ }");
ParseAndRun(@"%s/\(\s\+\){\s*\(""\w\+"",\).*$/\1\2/");
Assert.Equal(3, _textBuffer.CurrentSnapshot.LineCount);
Assert.Equal(@" ""cat"",", _textBuffer.GetLine(0).GetText());
Assert.Equal(@" ""dog"",", _textBuffer.GetLine(1).GetText());
Assert.Equal(@" ""bat"",", _textBuffer.GetLine(2).GetText());
}
/// <summary>
/// The \n character is not zero width and can be used to delete the new line
/// </summary>
[Fact]
public void NewLineIsNotZeroWidth()
{
Create("cat", "dog", "fish");
ParseAndRun(@"s/\n//");
Assert.Equal("catdog", _textBuffer.GetLine(0).GetText());
Assert.Equal("fish", _textBuffer.GetLine(1).GetText());
}
}
public sealed class Set : InterpreterTest
{
/// <summary>
/// Print out the modified settings
/// </summary>
[Fact]
public void PrintModifiedSettings()
{
Create("");
_localSettings.ExpandTab = true;
ParseAndRun("set");
Assert.Equal("notimeout" + Environment.NewLine + "expandtab", _statusUtil.LastStatus);
}
/// <summary>
/// Test the assignment of a string value
/// </summary>
[Fact]
public void Assign_StringValue_Global()
{
Create("");
ParseAndRun(@"set sections=cat");
Assert.Equal("cat", _globalSettings.Sections);
}
/// <summary>
/// Test the assignment of a local string value
/// </summary>
[Fact]
public void Assign_StringValue_Local()
{
Create("");
ParseAndRun(@"set nrformats=alpha");
Assert.Equal("alpha", _localSettings.NumberFormats);
}
/// <summary>
/// Make sure we can use set for a numbered value setting
/// </summary>
[Fact]
public void Assign_NumberValue()
{
Create("");
ParseAndRun(@"set ts=42");
Assert.Equal(42, _localSettings.TabStop);
}
/// <summary>
/// Assign multiple values and verify it works
/// </summary>
[Fact]
public void Assign_Many()
{
Create("");
ParseAndRun(@"set ai vb ts=42");
Assert.Equal(42, _localSettings.TabStop);
Assert.True(_localSettings.AutoIndent);
Assert.True(_globalSettings.VisualBell);
}
/// <summary>
/// Make sure that if there are mulitple assignments and one is unsupported that the
/// others work
///
/// Raised in issue #764
/// </summary>
[Fact]
public void Assign_ManyUnsupported()
{
Create("");
ParseAndRun(@"set vb t_vb=");
Assert.True(_globalSettings.VisualBell);
}
/// <summary>
/// Toggle a toggle option off
/// </summary>
[Fact]
public void Toggle_Off()
{
Create("");
_localSettings.ExpandTab = true;
ParseAndRun(@"set noet");
Assert.False(_localSettings.ExpandTab);
}
/// <summary>
/// Invert a toggle setting to on
/// </summary
[Fact]
public void Toggle_InvertOn()
{
Create("");
_localSettings.ExpandTab = false;
ParseAndRun(@"set et!");
Assert.True(_localSettings.ExpandTab);
}
/// <summary>
/// Make sure that we can toggle the options that have an underscore in them
/// </summary>
[Fact]
public void Toggle_OptionWithUnderscore()
{
Create("");
Assert.True(_globalSettings.UseEditorIndent);
ParseAndRun(@"set novsvim_useeditorindent");
Assert.False(_globalSettings.UseEditorIndent);
}
/// <summary>
/// Make sure we can deal with a trailing comment
/// </summary>
[Fact]
public void Toggle_TrailingComment()
{
Create("");
_localSettings.AutoIndent = false;
ParseAndRun(@"set ai ""what's going on?");
Assert.True(_localSettings.AutoIndent);
}
/// <summary>
/// Invert a toggle setting to off
/// </summary
[Fact]
public void Toggle_InvertOff()
{
Create("");
_localSettings.ExpandTab = true;
ParseAndRun(@"set et!");
Assert.False(_localSettings.ExpandTab);
}
/// <summary>
/// Make sure that we can handle window settings as well in the interpreter
/// </summary>
[Fact]
public void Toggle_WindowSetting()
{
Create("");
ParseAndRun(@"set cursorline");
Assert.True(_windowSettings.CursorLine);
}
}
public sealed class QuickFixTest : InterpreterTest
{
private void AssertQuickFix(string command, QuickFix quickFix, int count, bool hasBang)
{
var didRun = false;
VimHost.RunQuickFixFunc =
(qf, c, h) =>
{
Assert.Equal(quickFix, qf);
Assert.Equal(count, c);
Assert.Equal(hasBang, h);
didRun = true;
};
Create("");
ParseAndRun(command);
Assert.True(didRun);
}
[Fact]
public void Next()
{
AssertQuickFix("cn", QuickFix.Next, 1, hasBang: false);
AssertQuickFix("1cn", QuickFix.Next, 1, hasBang: false);
AssertQuickFix("2cn", QuickFix.Next, 2, hasBang: false);
AssertQuickFix("2cn!", QuickFix.Next, 2, hasBang: true);
}
[Fact]
public void Previous()
{
AssertQuickFix("cp", QuickFix.Previous, 1, hasBang: false);
AssertQuickFix("1cp", QuickFix.Previous, 1, hasBang: false);
AssertQuickFix("2cp", QuickFix.Previous, 2, hasBang: false);
AssertQuickFix("2cp!", QuickFix.Previous, 2, hasBang: true);
}
}
public sealed class Misc : InterpreterTest
{
private LineRangeSpecifier ParseLineRange(string lineRangeText)
{
var result = Parser.ParseRange(lineRangeText);
Assert.True(!result.Item1.IsNone);
Assert.Equal("", result.Item2);
return result.Item1;
}
private SnapshotLineRange ParseAndGetLineRange(string lineRangeText)
{
var lineRange = ParseLineRange(lineRangeText);
return _interpreter.GetLineRange(lineRange).Value;
}
[Fact]
public void Behave_Mswin()
{
Create("");
ParseAndRun("behave mswin");
Assert.Equal(SelectModeOptions.Keyboard | SelectModeOptions.Mouse, _globalSettings.SelectModeOptions);
Assert.Equal("popup", _globalSettings.MouseModel);
Assert.Equal(KeyModelOptions.StartSelection | KeyModelOptions.StopSelection, _globalSettings.KeyModelOptions);
Assert.Equal("exclusive", _globalSettings.Selection);
}
[Fact]
public void Behave_Xterm()
{
Create("");
ParseAndRun("behave xterm");
Assert.Equal(SelectModeOptions.None, _globalSettings.SelectModeOptions);
Assert.Equal("extend", _globalSettings.MouseModel);
Assert.Equal(KeyModelOptions.None, _globalSettings.KeyModelOptions);
Assert.Equal("inclusive", _globalSettings.Selection);
}
/// <summary>
/// Don't execute a line that starts with a comment
/// </summary>
[Fact]
public void CommentLine_Set()
{
Create("");
_localSettings.AutoIndent = false;
ParseAndRun(@"""set ai");
Assert.False(_localSettings.AutoIndent);
}
/// <summary>
/// Don't execute a line that starts with a comment
/// </summary>
[Fact]
public void CommentLine_Delete()
{
Create("dog", "cat");
ParseAndRun(@"""del");
Assert.Equal("dog", _textBuffer.GetLine(0).GetText());
Assert.Equal("cat", _textBuffer.GetLine(1).GetText());
}
/// <summary>
/// The delete of the last line in the ITextBuffer should reduce the line count
/// </summary>
[Fact]
public void Delete_LastLine()
{
Create("cat", "dog");
_textView.MoveCaretToLine(1);
ParseAndRun("del");
Assert.Equal(1, _textBuffer.CurrentSnapshot.LineCount);
Assert.Equal("cat", _textBuffer.GetLine(0).GetText());
Assert.Equal(0, _textView.GetCaretPoint().Position);
}
/// <summary>
/// The delete of the first line in the ITextBuffer should reduce the line count
/// </summary>
[Fact]
public void Delete_FirstLine()
{
Create("cat", "dog");
ParseAndRun("del");
Assert.Equal(1, _textBuffer.CurrentSnapshot.LineCount);
Assert.Equal("dog", _textBuffer.GetLine(0).GetText());
Assert.Equal(0, _textView.GetCaretPoint().Position);
}
/// <summary>
/// Running :del on a single line should cause the line contents to be deleted
/// but not crash
/// </summary>
[Fact]
public void Delete_OneLine()
{
Create("cat");
ParseAndRun("del");
Assert.Equal(1, _textBuffer.CurrentSnapshot.LineCount);
Assert.Equal("", _textBuffer.GetLine(0).GetText());
}
/// <summary>
/// The delete of the multiple lines including the last line should reduce by the
/// appropriate number of lines
/// </summary>
[Fact]
public void Delete_MultipleLastLine()
{
Create("cat", "dog", "fish", "tree");
_textView.MoveCaretToLine(1);
ParseAndRun("2,$del");
Assert.Equal(1, _textBuffer.CurrentSnapshot.LineCount);
Assert.Equal("cat", _textBuffer.GetLine(0).GetText());
Assert.Equal(0, _textView.GetCaretPoint().Position);
}
/// <summary>
/// No arguments means delete the current line
/// </summary>
[Fact]
public void Delete_CurrentLine()
{
Create("foo", "bar");
ParseAndRun("del");
Assert.Equal("foo" + Environment.NewLine, UnnamedRegister.StringValue);
Assert.Equal("bar", _textView.GetLine(0).GetText());
}
/// <summary>
/// When count is in back it's a range of lines
/// </summary>
[Fact]
public void Delete_SeveralLines()
{
Create("foo", "bar", "baz");
ParseAndRun("dele 2");
Assert.Equal("baz", _textView.GetLine(0).GetText());
Assert.Equal("foo" + Environment.NewLine + "bar" + Environment.NewLine, UnnamedRegister.StringValue);
}
/// <summary>
/// Delete only the specified line when count is in front
/// </summary>
[Fact]
public void Delete_SpecificLineNumber()
{
Create("foo", "bar", "baz");
ParseAndRun("2del");
Assert.Equal("foo", _textView.GetLine(0).GetText());
Assert.Equal("baz", _textView.GetLine(1).GetText());
Assert.Equal("bar" + Environment.NewLine, UnnamedRegister.StringValue);
}
/// <summary>
/// Handle the case where the adjustment simply occurs on the current line
/// </summary>
[Fact]
public void GetLine_AdjustmentOnCurrent()
{
Create("cat", "dog", "bear");
var range = _interpreter.GetLine(LineSpecifier.NewAdjustmentOnCurrent(1));
Assert.Equal(_textBuffer.GetLine(1).LineNumber, range.Value.LineNumber);
}
[Fact]
public void LineRange_FullFile()
{
Create("foo", "bar");
var lineRange = ParseAndGetLineRange("%");
var tss = _textBuffer.CurrentSnapshot;
Assert.Equal(new SnapshotSpan(tss, 0, tss.Length), lineRange.ExtentIncludingLineBreak);
}
[Fact]
public void LineRange_CurrentLine()
{
Create("foo", "bar");
var lineRange = ParseAndGetLineRange(".");
Assert.Equal(_textBuffer.GetLineRange(0), lineRange);
}
[Fact]
public void LineRange_CurrentLineWithCurrentLine()
{
Create("foo", "bar");
var lineRange = ParseAndGetLineRange(".,.");
Assert.Equal(_textBuffer.GetLineRange(0), lineRange);
}
[Fact]
public void LineRange_LineNumberRange()
{
Create("a", "b", "c");
var lineRange = ParseAndGetLineRange("1,2");
Assert.Equal(_textBuffer.GetLineRange(0, 1), lineRange);
}
[Fact]
public void LineRange_SingleLine1()
{
Create("foo", "bar");
var lineRange = ParseAndGetLineRange("1");
Assert.Equal(0, lineRange.StartLineNumber);
Assert.Equal(1, lineRange.Count);
}
[Fact]
public void LineRange_MarkWithLineNumber()
{
Create("foo", "bar", "tree");
_vimTextBuffer.SetLocalMark(LocalMark.OfChar('c').Value, 0, 1);
var lineRange = ParseAndGetLineRange("'c,2");
Assert.Equal(_textBuffer.GetLineRange(0, 1), lineRange);
}
[Fact]
public void LineRange_MarkWithMark()
{
Create("foo", "bar");
_vimTextBuffer.SetLocalMark(LocalMark.NewLetter(Letter.C), 0, 0);
_vimTextBuffer.SetLocalMark(LocalMark.NewLetter(Letter.B), 1, 0);
var lineRange = ParseAndGetLineRange("'c,'b");
Assert.Equal(_textBuffer.GetLineRange(0, 1), lineRange);
}
/// <summary>
/// Combine a global mark with a line number
/// </summary>
[Fact]
public void LineRange_GlobalMarkAndLineNumber()
{
Create("foo bar", "bar", "baz");
Vim.MarkMap.SetGlobalMark(Letter.A, _vimTextBuffer, 0, 2);
var lineRange = ParseAndGetLineRange("'A,2");
Assert.Equal(_textBuffer.GetLineRange(0, 1), lineRange);
}
/// <summary>
/// Change the directory to a valid directory
/// </summary>
[Fact]
public void ChangeDirectory_Valid()
{
Create("");
ParseAndRun("cd " + ValidDirectoryPath);
Assert.Equal(ValidDirectoryPath, _vimData.CurrentDirectory);
}
/// <summary>
/// Change the global directory should invalidate the local directory
/// </summary>
[Fact]
public void ChangeDirectory_InvalidateLocal()
{
Create("");
_vimBuffer.CurrentDirectory = FSharpOption.Create(@"c:\");
ParseAndRun("cd " + ValidDirectoryPath);
Assert.Equal(ValidDirectoryPath, _vimData.CurrentDirectory);
Assert.True(_vimBuffer.CurrentDirectory.IsNone());
}
/// <summary>
/// Change the local directory to a valid directory
/// </summary>
[Fact]
public void ChangeLocalDirectory_Valid()
{
Create("");
_vimData.CurrentDirectory = @"c:\";
ParseAndRun("lcd " + ValidDirectoryPath);
Assert.Equal(@"c:\", _vimData.CurrentDirectory);
Assert.Equal(ValidDirectoryPath, _vimBuffer.CurrentDirectory.Value);
}
/// <summary>
/// Test the use of the "del" command with global
/// </summary>
[Fact]
public void Global_Delete()
{
Create("cat", "dog", "fish");
ParseAndRun("g/a/del");
Assert.Equal("dog", _textBuffer.GetLine(0).GetText());
Assert.Equal("fish", _textBuffer.GetLine(1).GetText());
Assert.Equal(0, _textView.GetCaretPoint().Position);
}
/// <summary>
/// Test the use of the "del" command with global for a negative match
/// </summary>
[Fact]
public void Global_Delete_NotMatch()
{
Create("cat", "dog", "fish");
ParseAndRun("g!/a/del");
Assert.Equal("cat", _textBuffer.GetLine(0).GetText());
Assert.Equal(1, _textBuffer.CurrentSnapshot.LineCount);
Assert.Equal(0, _textView.GetCaretPoint().Position);
}
/// <summary>
/// Test the use of the "del" command with global and alternate separators
/// </summary>
[Fact]
public void Global_Delete_AlternateSeparators()
{
Create("cat", "dog", "fish");
ParseAndRun("g,a,del");
Assert.Equal("dog", _textBuffer.GetLine(0).GetText());
Assert.Equal("fish", _textBuffer.GetLine(1).GetText());
Assert.Equal(0, _textView.GetCaretPoint().Position);
}
/// <summary>
/// Test out the :global command with put
/// </summary>
[Fact]
public void Global_Put()
{
Create("cat", "dog", "fash");
UnnamedRegister.UpdateValue("bat");
ParseAndRun("g,a,put");
Assert.Equal("cat", _textBuffer.GetLine(0).GetText());
Assert.Equal("bat", _textBuffer.GetLine(1).GetText());
Assert.Equal("dog", _textBuffer.GetLine(2).GetText());
Assert.Equal("fash", _textBuffer.GetLine(3).GetText());
Assert.Equal("bat", _textBuffer.GetLine(4).GetText());
Assert.Equal(_textView.GetPointInLine(4, 0), _textView.GetCaretPoint());
}
/// <summary>
/// Can't get the range for a mark that doesn't exist
/// </summary>
[Fact]
public void LineRange_BadMark()
{
Create("foo bar", "baz");
var lineRange = _interpreter.GetLineRange(ParseLineRange("'c,2"));
Assert.True(lineRange.IsNone());
}
[Fact]
public void LineRange_LineNumberWithPlus()
{
Create("foo", "bar", "baz", "jaz");
var lineRange = ParseAndGetLineRange("1+2");
Assert.Equal(2, lineRange.StartLineNumber);
Assert.Equal(1, lineRange.Count);
}
/// <summary>
/// Make sure that we treat a plus with no trailing value as a + 1
/// </summary>
[Fact]
public void LineRange_LineNumberWithPlusAndNoValue()
{
Create("foo", "bar", "baz");
var lineRange = ParseAndGetLineRange("1+");
Assert.Equal(1, lineRange.StartLineNumber);
Assert.Equal(1, lineRange.Count);
}
/// <summary>
/// Test the + with a range
/// </summary>
[Fact]
public void LineRange_LineNumberWithPlusInRange()
{
Create("foo", "bar", "baz", "jaz", "aoeu", "za,.p");
var lineRange = ParseAndGetLineRange("1+1,3");
Assert.Equal(1, lineRange.StartLineNumber);
Assert.Equal(2, lineRange.LastLineNumber);
}
[Fact]
public void LineRange_LineNumberWithMinus()
{
Create("foo", "bar", "baz", "jaz", "aoeu", "za,.p");
var lineRange = ParseAndGetLineRange("1-1");
Assert.Equal(_textBuffer.GetLineRange(0), lineRange);
}
[Fact]
public void LineRange_LineNumberWithMinusAndNoValue()
{
Create("foo", "bar", "baz", "jaz", "aoeu", "za,.p");
var lineRange = ParseAndGetLineRange("2-");
Assert.Equal(_textBuffer.GetLineRange(0), lineRange);
}
[Fact]
public void LineRange_LineNumberWithMinus2()
{
Create("foo", "bar", "baz", "jaz", "aoeu", "za,.p");
var lineRange = ParseAndGetLineRange("5-3");
Assert.Equal(_textBuffer.GetLineRange(1), lineRange);
}
[Fact]
public void LineRange_LineNumberWithMinusInRange()
{
Create("foo", "bar", "baz", "jaz", "aoeu", "za,.p");
var lineRange = ParseAndGetLineRange("1,5-2");
Assert.Equal(_textBuffer.GetLineRange(0, 2), lineRange);
}
[Fact]
public void LineRange_LastLine()
{
Create("cat", "tree", "dog");
var lineRange = ParseAndGetLineRange("$");
Assert.Equal(_textBuffer.GetLineRange(2), lineRange);
}
[Fact]
public void LineRange_LastLine_OneLineBuffer()
{
Create("cat");
var lineRange = ParseAndGetLineRange("$");
Assert.Equal(_textBuffer.GetLineRange(0), lineRange);
}
[Fact]
public void LineRange_CurrentToEnd()
{
Create("cat", "tree", "dog");
var lineRange = ParseAndGetLineRange(".,$");
Assert.Equal(_textBuffer.GetLineRange(0, 2), lineRange);
}
[Fact]
public void LineRange_RightSideIncrementsLeft()
{
Create("cat", "dog", "bear", "frog", "tree");
var lineRange = ParseAndGetLineRange(".,+2");
Assert.Equal(_textBuffer.GetLineRange(0, 2), lineRange);
}
[Fact]
public void LineRange_LeftSideIncrementsCurrent()
{
Create("cat", "dog", "bear", "frog", "tree");
var lineRange = ParseAndGetLineRange(".,+2");
Assert.Equal(_textBuffer.GetLineRange(0, 2), lineRange);
}
/// <summary>
/// Make sure we can clear out key mappings with the "mapc" command
/// </summary>
[Fact]
public void MapKeys_Clear()
{
Create("");
Action<string, KeyRemapMode[]> testMapClear =
(command, toClearModes) =>
{
foreach (var keyRemapMode in KeyRemapMode.All)
{
Assert.True(_keyMap.MapWithNoRemap("a", "b", keyRemapMode));
}
};
_keyMap.ClearAll();
testMapClear("mapc", new[] { KeyRemapMode.Normal, KeyRemapMode.Visual, KeyRemapMode.Command, KeyRemapMode.OperatorPending });
testMapClear("nmapc", new[] { KeyRemapMode.Normal });
testMapClear("vmapc", new[] { KeyRemapMode.Visual, KeyRemapMode.Select });
testMapClear("xmapc", new[] { KeyRemapMode.Visual });
testMapClear("smapc", new[] { KeyRemapMode.Select });
testMapClear("omapc", new[] { KeyRemapMode.OperatorPending });
testMapClear("mapc!", new[] { KeyRemapMode.Insert, KeyRemapMode.Command });
testMapClear("imapc", new[] { KeyRemapMode.Insert });
testMapClear("cmapc", new[] { KeyRemapMode.Command });
}
[Fact]
public void Move_BackOneLine()
{
Create("fish", "cat", "dog", "tree");
_textView.MoveCaretToLine(2);
ParseAndRun("move -2");
Assert.Equal("fish", _textView.GetLine(0).GetText());
Assert.Equal("dog", _textView.GetLine(1).GetText());
Assert.Equal("cat", _textView.GetLine(2).GetText());
Assert.Equal("tree", _textView.GetLine(3).GetText());
}
[Fact]
public void PrintCurrentDirectory_Global()
{
Create();
ParseAndRun("pwd");
Assert.Equal(_vimData.CurrentDirectory, _statusUtil.LastStatus);
}
/// <summary>
/// The print current directory command should prefer the window directory
/// over the global one
/// </summary>
[Fact]
public void PrintCurrentDirectory_Local()
{
Create();
_vimBuffer.CurrentDirectory = FSharpOption.Create(@"c:\");
ParseAndRun("pwd");
Assert.Equal(@"c:\", _statusUtil.LastStatus);
}
/// <summary>
/// Ensure the Put command is linewise even if the register is marked as characterwise
/// </summary>
[Fact]
public void Put_ShouldBeLinewise()
{
Create("foo", "bar");
UnnamedRegister.UpdateValue("hey", OperationKind.CharacterWise);
ParseAndRun("put");
Assert.Equal("foo", _textBuffer.GetLine(0).GetText());
Assert.Equal("hey", _textBuffer.GetLine(1).GetText());
}
/// <summary>
/// Ensure that when the ! is present that the appropriate option is passed along
/// </summary>
[Fact]
public void Put_BangShouldPutTextBefore()
{
Create("foo", "bar");
UnnamedRegister.UpdateValue("hey", OperationKind.CharacterWise);
ParseAndRun("put!");
Assert.Equal("hey", _textBuffer.GetLine(0).GetText());
Assert.Equal("foo", _textBuffer.GetLine(1).GetText());
}
/// <summary>
/// By default the retab command should affect the entire ITextBuffer and not include
/// space strings
/// </summary>
[Fact]
public void Retab_Default()
{
Create(" cat", "\tdog");
_localSettings.ExpandTab = true;
_localSettings.TabStop = 2;
ParseAndRun("retab");
Assert.Equal(" cat", _textBuffer.GetLine(0).GetText());
Assert.Equal(" dog", _textBuffer.GetLine(1).GetText());
}
/// <summary>
/// The ! operator should force the command to include spaces
/// </summary>
[Fact]
public void Retab_WithBang()
{
Create(" cat", " dog");
_localSettings.ExpandTab = false;
_localSettings.TabStop = 2;
ParseAndRun("retab!");
Assert.Equal("\tcat", _textBuffer.GetLine(0).GetText());
Assert.Equal("\tdog", _textBuffer.GetLine(1).GetText());
}
/// <summary>
/// Make sure the basic command is passed down to the func
/// </summary>
[Fact]
public void ShellCommand_Simple()
{
Create("");
var didRun = false;
VimHost.RunCommandFunc =
(command, args, _) =>
{
Assert.Equal("/c git status", args);
didRun = true;
return "";
};
ParseAndRun(@"!git status");
Assert.True(didRun);
}
/// <summary>
/// Do a simple replacement of a ! in the shell command
/// </summary>
[Fact]
public void ShellCommand_BangReplacement()
{
Create("");
Vim.VimData.LastShellCommand = FSharpOption.Create("cat");
var didRun = false;
VimHost.RunCommandFunc =
(command, args, _) =>
{
Assert.Equal("/c git status cat", args);
didRun = true;
return "";
};
ParseAndRun(@"!git status !");
Assert.True(didRun);
}
/// <summary>
/// Don't replace a ! which occurs after a \
/// </summary>
[Fact]
public void ShellCommand_BangNoReplace()
{
Create("");
var didRun = false;
VimHost.RunCommandFunc =
(command, args, _) =>
{
Assert.Equal("/c git status !", args);
didRun = true;
return "";
};
ParseAndRun(@"!git status \!");
Assert.True(didRun);
}
/// <summary>
/// Raise an error message if there is no previous command and a bang relpacement
/// isr requested. Shouldn't run any command in this case
/// </summary>
[Fact]
public void ShellCommand_BangReplacementFails()
{
Create("");
var didRun = false;
VimHost.RunCommandFunc = delegate { didRun = true; return ""; };
ParseAndRun(@"!git status !");
Assert.False(didRun);
Assert.Equal(Resources.Common_NoPreviousShellCommand, _statusUtil.LastError);
}
[Fact]
public void TabNext_NoCount()
{
Create("");
ParseAndRun("tabn");
Assert.Equal(Path.Forward, VimHost.GoToNextTabData.Item1);
Assert.Equal(1, VimHost.GoToNextTabData.Item2);
}
/// <summary>
/// :tabn with a count
/// </summary>
[Fact]
public void TabNext_WithCount()
{
Create("");
ParseAndRun("tabn 3");
Assert.Equal(Path.Forward, VimHost.GoToNextTabData.Item1);
Assert.Equal(3, VimHost.GoToNextTabData.Item2);
}
[Fact]
public void TabPrevious_NoCount()
{
Create("");
ParseAndRun("tabp");
Assert.Equal(Path.Backward, VimHost.GoToNextTabData.Item1);
Assert.Equal(1, VimHost.GoToNextTabData.Item2);
}
[Fact]
public void TabPrevious_NoCount_AltName()
{
Create("");
ParseAndRun("tabN");
Assert.Equal(Path.Backward, VimHost.GoToNextTabData.Item1);
Assert.Equal(1, VimHost.GoToNextTabData.Item2);
}
/// <summary>
/// :tabp with a count
/// </summary>
[Fact]
public void TabPrevious_WithCount()
{
Create("");
ParseAndRun("tabp 3");
Assert.Equal(Path.Backward, VimHost.GoToNextTabData.Item1);
Assert.Equal(3, VimHost.GoToNextTabData.Item2);
}
/// <summary>
/// Simple visual studio command
/// </summary>
[Fact]
public void VisualStudioCommand_Simple()
{
Create("");
var didRun = false;
VimHost.RunVisualStudioCommandFunc =
(command, argument) =>
{
Assert.Equal("Build.BuildSelection", command);
Assert.Equal("", argument);
didRun = true;
};
ParseAndRun("vsc Build.BuildSelection");
Assert.True(didRun);
}
/// <summary>
/// Simple visual studio command with an argument
/// </summary>
[Fact]
public void VisualStudioCommand_WithArgument()
{
Create("");
var didRun = false;
VimHost.RunVisualStudioCommandFunc =
(command, argument) =>
{
Assert.Equal("Build.BuildSelection", command);
Assert.Equal("Arg", argument);
didRun = true;
};
ParseAndRun("vsc Build.BuildSelection Arg");
Assert.True(didRun);
}
}
}
}
Jump to Line
Something went wrong with that request. Please try again.