Testing Lexers
The LexerTestBase class can be used to create tests for lexers. It derives from BaseTestWithSingleProject, so it creates an in-memory ReSharper instance with a solution loaded that contains a single project. The project will consist of the file or files named in the test methods.
The input file, that gets added to the in-memory project, should be an example file in the custom language. The LexerTestBase class will create an instance of the language's ILexer, with the default implementation using the file extension to get an instance of the custom language's IProjectFileLanguageService, and then calling GetMixedLexerFactory.
The entire example file is then lexed, and the output file is compared against the gold file to ensure it matches. The output file is a stream of token types, one on each line. The value of the token type is the ToString implementation of the TokenNodeType instance, which is either the token's representation, or it's identifier (see token node types for more details on the representation and identifier).
For example, given the following CSS file - test01.css:
Then the test01.css.gold file would be:
Implementation
Derived classes will need to override RelativeTestDataPath to declare the path to the data and gold files, relative to the test\data folder.
Each test method can call one of the following methods, which allows specifying the base name used to create the input and gold file names:
DoNamedTestorDoNamedTest2- will use the name of the test method as the file base name. TheDoNamedTest2method will also strip anyTestprefix from the method first.DoOneTestorDoTestFilewill use the passed in string as the file base name.DoOneTestsimply callsDoTestFile.
The input file name that gets added to the in-memory project is created from the test's base file name, plus the value of the Extension property. This retrieves the extension from any attributes on the test method or class that implement ITestFileExtensionProvider. Typically, this is achieved by using the [TestFileExtension] attribute, and specifying the extension (with dot) in the constructor. This is usually taken as a constant value defined in the project file type:
Customisation
The LexerTestBase class allows for the behaviour of the class to be customised, by overriding various methods:
CreateLexer- the default implementation ofCreateLexerwill create an instance based on the file extension of the test file, and using the registered project file type'sIProjectFileLanguageService.GetMixedLexerFactory.The default implementation -
CreateLexer(IProjectFile pf, StreamReader sr)can be overridden directly, or theCreateLexer(StreamReader sr)helper method can be overridden instead, to simply create a new lexer based on the contents of the passed in stream reader:
WriteTokenis used to output the currentTokenNodeTypewhile lexing the file. It will call the defaultToStringimplementation, but can be overridden to provide more detail, if required. For example, this override will also output the token start and end offsets: