using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Configuration;
using System.IO;
using System.Runtime.Serialization.Json;
using System.Runtime.Serialization.Formatters;
//this version has been modified to not split each #check into an individual test
namespace Microsoft.Sputnik.Interop.ParserEngine
{
public static class ES5TestScript
{
private static int fileCounter;
private static StringBuilder negativeTestCases;
private static string globalScopeFileName = "\\SputnikGlobalScope.js";
private static string[] templates = {
ES5TestScript.GetTemplateFile(ResourceClass.BasicTemplate_FileName),
ES5TestScript.GetTemplateFile(ResourceClass.BasicPrereqTemplate_FileName),
ES5TestScript.GetTemplateFile(ResourceClass.BasicNegativeTemplate_FileName),
ES5TestScript.GetTemplateFile(ResourceClass.BasicNegativePrereqTemplate_FileName)
};
///
/// Output files counter
///
public static int OutputFileCounter
{
get
{
return fileCounter;
}
set
{
fileCounter = value;
}
}
///
/// Method to save the sputnik scripts in ES5 format
///
/// SputnikTestScript Object which will have all the details to be written to the file
/// Is the destination folder path
public static void Save(SputnikTestScript script, string root, string destinationPath)
{
string destDir = Path.Combine(destinationPath, Path.GetDirectoryName(script.pathFromRoot));
string buildContent = string.Empty;
string destFullPath = string.Empty;
string preCondition = string.IsNullOrEmpty(script.PreConditionCode) ? String.Empty : script.PreConditionCode;
int templateIndex = string.IsNullOrEmpty(preCondition) ? 0 : 1;
string body = script.Body;
if (script.IsNegative)
{
templateIndex += 2;
}
string template = templates[templateIndex];
Logger.WriteToLog("=====================================================================================");
Logger.WriteToLog("Source file={0}\n", script.FullPath);
Logger.WriteToLog("Destination(s)=");
if (script.id == "")
{
Console.Write(script.Header);
Console.WriteLine();
}
string[] args = { script.Header, script.id, script.path, InsertStringEscapes(script.assertion), InsertStringEscapes(script.description), script.ReplicationCode, body, preCondition, script.InitialComment };
destFullPath = Path.Combine(destDir, string.Format(@"{0}.js", script.id));
try
{
buildContent = string.Format(template, args);
string dirPath = Path.GetDirectoryName(destFullPath);
if (!Directory.Exists(dirPath))
Directory.CreateDirectory(dirPath);
using (TextWriter writeTestCase = File.CreateText(destFullPath))
{
writeTestCase.WriteLine(buildContent);
writeTestCase.Flush();
writeTestCase.Close();
OutputFileCounter++;
}
if (script.IsNegative)
{
//Add details in stringbuilder.
StringBuilder sb = new StringBuilder();
//sb.Append("GlobalScopeTests[script.pathFromRoot.Replace("\\", "/") + "\"]");
sb.Append("GlobalScopeTests[\"" + script.id + "\"]");
sb.Append("=");
string s = GetSerializedSputnikTestScript(new SputnikTestScript()
{
id = script.id,
path = script.path,
description = script.description,
assertion = script.assertion,
});
sb.Append(s.Substring(0, s.LastIndexOf('}')) + ",\"negative\":\".\"};");
if (negativeTestCases == null)
{
negativeTestCases = new StringBuilder();
}
else
{
negativeTestCases.Append("\n");
}
negativeTestCases.Append(sb.ToString());
}
Logger.WriteToLog(destFullPath);
}
catch (ArgumentException ex)
{
Logger.WriteToLog(ResourceClass.IOException, ex.Message);
}
catch (IOException ex)
{
Logger.WriteToLog(ResourceClass.IOException, ex.Message);
}
// }
}
///
/// Method to initialize the negative test record.
///
/// Is the destination folder path
public static void InitGlobals(string destination)
{
//Insert inital var name in Globals.js file.
if (!Directory.Exists(destination))
{
Directory.CreateDirectory(destination);
}
FileStream fs = new FileStream(destination.Remove(destination.LastIndexOf("\\")) + globalScopeFileName, FileMode.Create, FileAccess.Write);
StreamWriter sw = new StreamWriter(fs);
sw.Write("this.GlobalScopeTests = this.GlobalScopeTests || new Array();\n");
sw.Flush();
sw.Close();
fs.Close();
}
///
/// Method to update the SputnikGlobalScope.js
///
/// Is the destination folder path
public static void UpdateGlobals(string destination)
{
//Replace the last comma by closing curly brace and semi-colon.
File.AppendAllText(destination.Remove(destination.LastIndexOf("\\")) + globalScopeFileName, negativeTestCases.ToString());
negativeTestCases.Clear();
}
private static string GetSerializedSputnikTestScript(SputnikTestScript sputnikTestScript)
{
MemoryStream stream = new MemoryStream();
DataContractJsonSerializer ser = new DataContractJsonSerializer(typeof(SputnikTestScript));
ser.WriteObject(stream, sputnikTestScript);
stream.Position = 0;
StreamReader sr = new StreamReader(stream);
return sr.ReadToEnd();
}
private static string WrapWithEval(string s)
{
return InsertStringEscapes(s, true);
}
private static string InsertStringEscapes(string s, bool wrapWithEval = false)
{
StringReader rdr = new StringReader(s);
StringWriter wtr = new StringWriter();
int intChar;
char nextChar;
if (wrapWithEval) wtr.Write("eval(\"");
while (true)
{
intChar = rdr.Read();
if (intChar == -1) break;
nextChar = Convert.ToChar(intChar);
switch (nextChar)
{
case '\\':
case '\'':
case '"':
wtr.Write('\\');
wtr.Write(nextChar);
break;
case '\n':
wtr.Write("\\n");
break;
case '\r':
wtr.Write("\\r");
break;
case '\u2028':
wtr.Write("\\u2028");
break;
case '\u2029':
wtr.Write("\\u2029");
break;
default:
wtr.Write(nextChar);
break;
}
}
if (wrapWithEval) wtr.Write("\")");
return wtr.ToString();
}
///
/// Method to read the templates which are used to generate a ES5 format files.
///
///
private static string GetTemplateFile(string configSetting)
{
string inputTemplatePath = ConfigurationManager.AppSettings[configSetting].ToString();
return (new StreamReader(inputTemplatePath)).ReadToEnd();
}
}
}