Commit 09898e8e77a38f812e080c3f1ffbdd28182bd14f

Jannik Zschiesche 2015-06-13T16:37:07

Support language inclusion tests By using composed language names "language+language2+language3" you can test language inclusion or do integration tests.

diff --git a/tests/helper/prism-loader.js b/tests/helper/prism-loader.js
index 1f1426a..df34951 100644
--- a/tests/helper/prism-loader.js
+++ b/tests/helper/prism-loader.js
@@ -11,12 +11,21 @@ module.exports = {
 	/**
 	 * Creates a new Prism instance with the given language loaded
 	 *
-	 * @param {string} language
+	 * @param {string|string[]} languages
 	 * @returns {Prism}
 	 */
-	createInstance: function (language) {
-		var Prism = this.createEmptyPrism();
-		return this.loadLanguage(language, Prism);
+	createInstance: function (languages) {
+		var context = {
+			loadedLanguages: [],
+			Prism: this.createEmptyPrism()
+		};
+		languages = Array.isArray(languages) ? languages : [languages];
+
+		for (var i = 0, l = languages.length; i < l; i++) {
+			context = this.loadLanguage(languages[i], context);
+		}
+
+		return context.Prism;
 	},
 
 
@@ -26,26 +35,31 @@ module.exports = {
 	 *
 	 * @private
 	 * @param {string} language
-	 * @param {Prism} Prism
-	 * @returns {Prism}
+	 * @param {{loadedLanguages: string[], Prism: Prism}} context
 	 */
-	loadLanguage: function (language, Prism) {
+	loadLanguage: function (language, context) {
 		if (!languagesCatalog[language])
 		{
 			throw new Error("Language '" + language + "' not found.");
 		}
 
+		// the given language was already loaded
+		if (-1 < context.loadedLanguages.indexOf(language)) {
+			return context;
+		}
+
 		// if the language has a dependency -> load it first
 		if (languagesCatalog[language].require)
 		{
-			Prism = this.loadLanguage(languagesCatalog[language].require, Prism);
+			context = this.loadLanguage(languagesCatalog[language].require, context);
 		}
 
 		// load the language itself
 		var languageSource = this.loadFileSource(language);
-		var context = this.runFileWithContext(languageSource, {Prism: Prism});
+		context.Prism = this.runFileWithContext(languageSource, {Prism: context.Prism}).Prism;
+		context.loadedLanguages.push(language);
 
-		return context.Prism;
+		return context;
 	},
 
 
@@ -88,7 +102,7 @@ module.exports = {
 	 *
 	 * @private
 	 * @param {string} fileSource
-	 * @param {*}context
+	 * @param {*} [context]
 	 *
 	 * @returns {*}
 	 */
diff --git a/tests/helper/test-case.js b/tests/helper/test-case.js
index 9bec510..095cba0 100644
--- a/tests/helper/test-case.js
+++ b/tests/helper/test-case.js
@@ -38,18 +38,30 @@ module.exports = {
 	/**
 	 * Runs the given test case file and asserts the result
 	 *
-	 * @param {string} language
+	 * The passed language identifier can either be a language like "css" or a composed language
+	 * identifier like "css+markup". Composed identifiers can be used for testing language inclusion.
+	 *
+	 * When testing language inclusion, the first given language is the main language which will be passed
+	 * to Prism for highlighting ("css+markup" will result in a call to Prism to highlight with the "css" grammar).
+	 * But it will be ensured, that the additional passed languages will be loaded too.
+	 *
+	 * The languages will be loaded in the order they were provided.
+	 *
+	 * @param {string} languageIdentifier
 	 * @param {string} filePath
 	 */
-	runTestCase: function (language, filePath) {
+	runTestCase: function (languageIdentifier, filePath) {
 		var testCase = this.parseTestCaseFile(filePath);
+		var languages = languageIdentifier.split("+");
 
 		if (null === testCase) {
 			throw new Error("Test case file has invalid format, please read the docs.");
 		}
 
-		var Prism = PrismLoader.createInstance(language);
-		var compiledTokenStream = Prism.tokenize(testCase.testSource, Prism.languages[language]);
+		var Prism = PrismLoader.createInstance(languages);
+		// the first language is the main language to highlight
+		var mainLanguageGrammar = Prism.languages[languages[0]];
+		var compiledTokenStream = Prism.tokenize(testCase.testSource, mainLanguageGrammar);
 		var simplifiedTokenStream = this.transformCompiledTokenStream(compiledTokenStream);
 
 		assert.deepEqual(simplifiedTokenStream, testCase.expectedTokenStream, testCase.comment);