private AchievementScriptInterpreter Parse(string input, bool expectedSuccess = true) { var tokenizer = Tokenizer.CreateTokenizer(input); var parser = new AchievementScriptInterpreter(); if (expectedSuccess) { if (!parser.Run(tokenizer)) { Assert.That(parser.ErrorMessage, Is.Null); Assert.Fail("AchievementScriptInterpreter.Run failed with no error message"); } } else { Assert.That(parser.Run(tokenizer), Is.False); Assert.That(parser.ErrorMessage, Is.Not.Null); } return(parser); }
private Achievement Evaluate(string input, string expectedError = null) { var tokenizer = new PositionalTokenizer(Tokenizer.CreateTokenizer(input)); var parser = new AchievementScriptInterpreter(); if (expectedError == null) { if (!parser.Run(tokenizer)) { Assert.That(parser.ErrorMessage, Is.Null); Assert.Fail("AchievementScriptInterpreter.Run failed with no error message"); } } else { Assert.That(parser.Run(tokenizer), Is.False); Assert.That(parser.ErrorMessage, Is.Not.Null.And.EqualTo(expectedError)); } return(parser.Achievements.FirstOrDefault()); }
private static string Evaluate(string input) { var script = "achievement(\"title\", \"desc\", 5,\n" + input + "\n)"; var tokenizer = Tokenizer.CreateTokenizer(script); var parser = new AchievementScriptInterpreter(); if (parser.Run(tokenizer)) { var achievement = parser.Achievements.First(); var builder = new AchievementBuilder(achievement); return(builder.RequirementsDebugString); } return(parser.Error.InnermostError.Message); }
public void TestScopedVariable() { var script = "function ItemInInventory(id) => any_of(range(0x1200, 0x1208, step=2), addr => word(addr) == id)\n" + "achievement(\"title\", \"desc\", 5, ItemInInventory(17))"; var tokenizer = Tokenizer.CreateTokenizer(script); var parser = new AchievementScriptInterpreter(); if (!parser.Run(tokenizer)) { Assert.Fail(parser.ErrorMessage); } var achievement = parser.Achievements.First(); var builder = new AchievementBuilder(achievement); Assert.That(builder.RequirementsDebugString, Is.EqualTo( "word(0x001200) == 17 || word(0x001202) == 17 || word(0x001204) == 17 || word(0x001206) == 17 || word(0x001208) == 17")); }
public void TestPredicateWithDefaultParameter() { var script = "function p(addr, id=17) => byte(addr) == id\n" + "achievement(\"title\", \"desc\", 5, any_of([1, 2, 3], p))"; var tokenizer = Tokenizer.CreateTokenizer(script); var parser = new AchievementScriptInterpreter(); if (!parser.Run(tokenizer)) { Assert.Fail(parser.ErrorMessage); } var achievement = parser.Achievements.First(); var builder = new AchievementBuilder(achievement); Assert.That(builder.RequirementsDebugString, Is.EqualTo( "byte(0x000001) == 17 || byte(0x000002) == 17 || byte(0x000003) == 17")); }
protected override void OnUpdateSyntax(ContentChangedEventArgs e) { var parser = new AchievementScriptParser(); _parsedContent = parser.Parse(Tokenizer.CreateTokenizer(e.Content)); if (e.IsAborted) { return; } var interpreter = new AchievementScriptInterpreter(); interpreter.Run(_parsedContent, out _scope); if (e.IsAborted) { return; } ServiceRepository.Instance.FindService <IBackgroundWorkerService>().InvokeOnUiThread(() => { ErrorsToolWindow.References.Clear(); foreach (var error in _parsedContent.Errors) { string message = error.Message; var innerError = error; if (innerError.InnerError != null) { do { innerError = innerError.InnerError; } while (innerError.InnerError != null); if (error.Line != innerError.Line || error.Column != innerError.Column) { message += String.Format(" (called from {0}:{1})", error.Line, error.Column); } } ErrorsToolWindow.References.Add(new CodeReferenceViewModel { StartLine = innerError.Line, StartColumn = innerError.Column, EndLine = innerError.EndLine, EndColumn = innerError.EndColumn, Message = message }); } }); if (e.IsAborted) { return; } if (e.IsWhitespaceOnlyChange) { return; } // wait a short while before updating the editor list ServiceRepository.Instance.FindService <ITimerService>().Schedule(() => { if (e.IsAborted) { return; } _owner.PopulateEditorList(interpreter); }, TimeSpan.FromMilliseconds(700)); base.OnUpdateSyntax(e); }
public void RegressionTest(string scriptFileName) { if (scriptFileName == "No scripts found.") { return; } var outputFileName = scriptFileName.Substring(0, scriptFileName.Length - 9) + ".updated.txt"; var expectedFileName = scriptFileName.Substring(0, scriptFileName.Length - 9) + ".txt"; var interpreter = new AchievementScriptInterpreter(); interpreter.Run(Tokenizer.CreateTokenizer(File.Open(scriptFileName, FileMode.Open))); Assert.IsNull(interpreter.ErrorMessage); var mockFileSystemService = new Mock <IFileSystemService>(); mockFileSystemService.Setup(s => s.CreateFile(It.IsAny <string>())).Returns((string path) => File.Create(path)); var localAchievements = new LocalAchievements(outputFileName, mockFileSystemService.Object); localAchievements.Title = Path.GetFileNameWithoutExtension(scriptFileName); foreach (var achievement in interpreter.Achievements) { localAchievements.Replace(null, achievement); } localAchievements.Commit("Author"); if (interpreter.Leaderboards.Any()) { using (var file = File.Open(outputFileName, FileMode.Append)) { using (var fileWriter = new StreamWriter(file)) { fileWriter.WriteLine("=== Leaderboards ==="); foreach (var leaderboard in interpreter.Leaderboards) { fileWriter.Write("0:"); fileWriter.Write("\"STA:"); fileWriter.Write(leaderboard.Start); fileWriter.Write("::CAN:"); fileWriter.Write(leaderboard.Cancel); fileWriter.Write("::SUB:"); fileWriter.Write(leaderboard.Submit); fileWriter.Write("::VAL:"); fileWriter.Write(leaderboard.Value); fileWriter.Write("\":"); fileWriter.Write(leaderboard.Format); fileWriter.Write(":\""); fileWriter.Write(leaderboard.Title); fileWriter.Write("\":\""); fileWriter.Write(leaderboard.Description); fileWriter.WriteLine("\""); } } } } if (!String.IsNullOrEmpty(interpreter.RichPresence)) { using (var file = File.Open(outputFileName, FileMode.Append)) { using (var fileWriter = new StreamWriter(file)) { fileWriter.WriteLine("=== Rich Presence ==="); fileWriter.WriteLine(interpreter.RichPresence); } } } Assert.IsTrue(File.Exists(expectedFileName), expectedFileName + " not found"); FileAssert.AreEqual(expectedFileName, outputFileName); File.Delete(outputFileName); }
public void RegressionTest(string scriptFileName, string scriptPath) { if (scriptFileName == NoScriptsError) { return; } var parts = scriptPath.Split('\\'); int i = 0; if (!Path.IsPathRooted(scriptPath)) { scriptPath = Path.Combine(RegressionDir, scriptPath); } else { while (parts[i] != "Regressions") { ++i; Assert.That(i < parts.Length); } ++i; Assert.That(i < parts.Length); } if (parts[i] == "scripts") { ++i; } var expectedFileName = Path.GetFileNameWithoutExtension(scriptPath); while (i < parts.Length - 1) { expectedFileName += "-" + parts[i]; ++i; } expectedFileName = Path.Combine(RegressionDir, "results", expectedFileName + ".txt"); var outputFileName = Path.ChangeExtension(expectedFileName, ".updated.txt"); var interpreter = new AchievementScriptInterpreter(); var content = File.ReadAllText(scriptPath); interpreter.Run(Tokenizer.CreateTokenizer(content)); if (!String.IsNullOrEmpty(interpreter.ErrorMessage)) { using (var file = File.Open(outputFileName, FileMode.Create)) { using (var fileWriter = new StreamWriter(file)) fileWriter.Write(interpreter.ErrorMessage); } if (!File.Exists(expectedFileName)) { Assert.IsNull(interpreter.ErrorMessage); } } else { var mockFileSystemService = new Mock <IFileSystemService>(); mockFileSystemService.Setup(s => s.CreateFile(It.IsAny <string>())).Returns((string path) => File.Create(path)); var localAchievements = new LocalAssets(outputFileName, mockFileSystemService.Object); localAchievements.Title = Path.GetFileNameWithoutExtension(scriptFileName); foreach (var achievement in interpreter.Achievements) { localAchievements.Replace(null, achievement); } foreach (var leaderboard in interpreter.Leaderboards) { localAchievements.Replace(null, leaderboard); } localAchievements.Commit("Author", null, null); if (!String.IsNullOrEmpty(interpreter.RichPresence)) { using (var file = File.Open(outputFileName, FileMode.Append)) { using (var fileWriter = new StreamWriter(file)) { fileWriter.WriteLine("=== Rich Presence ==="); var minimumVersion = Double.Parse(localAchievements.Version, System.Globalization.NumberFormatInfo.InvariantInfo); if (minimumVersion < 0.80) { interpreter.RichPresenceBuilder.DisableBuiltInMacros = true; if (minimumVersion < 0.79) { interpreter.RichPresenceBuilder.DisableLookupCollapsing = true; } fileWriter.WriteLine(interpreter.RichPresenceBuilder.ToString()); } else { fileWriter.WriteLine(interpreter.RichPresence); } } } } Assert.IsTrue(File.Exists(expectedFileName), expectedFileName + " not found"); } var expectedFileContents = File.ReadAllText(expectedFileName); var outputFileContents = File.ReadAllText(outputFileName); // file didn't match, report first difference if (expectedFileContents != outputFileContents) { var expectedFileTokenizer = Tokenizer.CreateTokenizer(expectedFileContents); var outputFileTokenizer = Tokenizer.CreateTokenizer(outputFileContents); var line = 1; do { var expectedFileLine = expectedFileTokenizer.ReadTo('\n').TrimRight(); var outputFileLine = outputFileTokenizer.ReadTo('\n').TrimRight(); if (expectedFileLine != outputFileLine) { Assert.AreEqual(expectedFileLine.ToString(), outputFileLine.ToString(), "Line " + line); } expectedFileTokenizer.Advance(); outputFileTokenizer.Advance(); ++line; } while (expectedFileTokenizer.NextChar != '\0' || outputFileTokenizer.NextChar != '\0'); // failed to find differing line, fallback to nunit assertion FileAssert.AreEqual(expectedFileName, outputFileName); } // file matched, delete temporary file File.Delete(outputFileName); }
protected override void OnUpdateSyntax(ContentChangedEventArgs e) { bool needsUpdate = false; // parse immediately so we can update the syntax highlighting var tokenizer = Tokenizer.CreateTokenizer(e.Content); if (_parsedContent == null || e.Type == ContentChangeType.Refresh) { _parsedContent = new ExpressionGroupCollection(); _parsedContent.Scope = new InterpreterScope(AchievementScriptInterpreter.GetGlobalScope()); _parsedContent.Scope.Context = new AchievementScriptContext(); lock (_parsedContent) { _parsedContent.Parse(tokenizer); needsUpdate = true; } } else if (e.Type == ContentChangeType.Update) { lock (_parsedContent) { needsUpdate = _parsedContent.Update(tokenizer, e.AffectedLines); } if (!needsUpdate && !e.IsAborted) { UpdateErrorList(); } } if (needsUpdate && !e.IsAborted) { // running the script can take a lot of time, push that work onto a background thread and show progress bar UpdateProgress(1, 0); // make sure to at least show the script file in the editor list if (!_owner.Editors.Any()) { _owner.PopulateEditorList(null); } ServiceRepository.Instance.FindService <IBackgroundWorkerService>().RunAsync(() => { if (!e.IsAborted) { // run the script var callback = new ScriptInterpreterCallback(this, e); var interpreter = new AchievementScriptInterpreter(); bool hadErrors, hasErrors; lock (_parsedContent) { hadErrors = _parsedContent.HasEvaluationErrors; hasErrors = !interpreter.Run(_parsedContent, callback); } if (!e.IsAborted) { UpdateProgress(100, 0); // if any errors were added or removed, update the highlighting if (hasErrors != hadErrors) { UpdateSyntaxHighlighting(e); } // report any errors UpdateErrorList(); if (!e.IsAborted) { // update the editor list _owner.PopulateEditorList(interpreter); } } } // make sure the progress bar is hidden UpdateProgress(0, 0); }); } base.OnUpdateSyntax(e); }