public static async Task WaitsForBuildCompletion() { var botName = Guid.NewGuid().ToString(); var count = 0; var timestamps = new DateTimeOffset[3]; var mockClient = CreateLexTrainClientMock(); mockClient.Setup(lex => lex.GetBotAsync( It.Is <GetBotRequest>(request => request.Name == botName), It.IsAny <CancellationToken>())) .Returns(() => Task.FromResult(new GetBotResponse { AbortStatement = new Statement { Messages = { new Message() } }, ClarificationPrompt = new Prompt { Messages = { new Message() } }, Status = ++count < 3 ? Status.BUILDING : Status.READY, })) .Callback(() => timestamps[count - 1] = DateTimeOffset.Now); using (var lex = new LexNLUTrainClient(botName, string.Empty, new JObject(), mockClient.Object)) { var utterance = new LabeledUtterance(string.Empty, string.Empty, null); await lex.TrainAsync(new[] { utterance }).ConfigureAwait(false); var difference = timestamps[2] - timestamps[1]; difference.Should().BeGreaterThan(TimeSpan.FromSeconds(2) - Epsilon); } }
public static async Task ReplacesCorrectTokensInSampleUtterances( string text, string entityMatch, string entityTypeName, int matchIndex, string sampleUtterance) { var intent = Guid.NewGuid().ToString(); var payload = default(JObject); var mockClient = CreateLexTrainClientMock(); mockClient.Setup(lex => lex.StartImportAsync( It.IsAny <StartImportRequest>(), It.IsAny <CancellationToken>())) .Callback <StartImportRequest, CancellationToken>((request, cancellationToken) => payload = GetPayloadJson(request.Payload)); var slot = CreateSlot(entityTypeName, entityTypeName); using (var lex = new LexNLUTrainClient(string.Empty, string.Empty, new JObject(), mockClient.Object)) { var entity = new Entity(entityTypeName, null, entityMatch, matchIndex); var utterance = new LabeledUtterance(text, intent, new[] { entity }); await lex.TrainAsync(new[] { utterance }).ConfigureAwait(false); // assert template utterance is set payload.Should().NotBeNull(); payload.SelectToken(".resource.intents[0].sampleUtterances").Count().Should().Be(1); payload.SelectToken(".resource.intents[0].sampleUtterances[0]").Value <string>().Should().Be(sampleUtterance); } }
private static TestCase CreateTestCase( string utteranceId, ConfusionMatrixResultKind resultKind, ComparisonTargetKind targetKind, LabeledUtterance expectedUtterance, LabeledUtterance actualUtterance, double score, string group, string[] args, string because, IEnumerable <string> categories) { var testLabel = TestLabel != null ? $"[{TestLabel}] " : string.Empty; var categoriesWithGroup = categories; if (group != null) { categoriesWithGroup.Append(group); } return(new TestCase( utteranceId, resultKind, targetKind, expectedUtterance, actualUtterance, score, group, $"{testLabel}{resultKind}{targetKind}('{string.Join("', '", args)}')", because, categoriesWithGroup)); }
public static void ReturnsNullPropertyValues() { var utterance = new LabeledUtterance(null, null, null); utterance.GetScore().Should().BeNull(); utterance.GetTextScore().Should().BeNull(); utterance.GetTimestamp().Should().BeNull(); }
public LabeledUtterancePair( string utteranceId, LabeledUtterance expected, LabeledUtterance actual) { this.UtteranceId = utteranceId; this.Expected = expected; this.Actual = actual; }
public LabeledUtteranceTestInput( string utteranceId, LabeledUtterance expected, LabeledUtterance actual, TestSettings testSettings) { this.UtteranceId = utteranceId; this.Expected = expected; this.Actual = actual; this.TestSettings = testSettings; }
public static void UsesIndexAsUtteranceId() { var expectedUtterance = new LabeledUtterance(null, "Greeting", null); var actualUtterance = new LabeledUtterance(null, "Greeting", null); var compareResults = TestCaseSource.GetNLUCompareResults( new[] { expectedUtterance, expectedUtterance }, new[] { actualUtterance, actualUtterance }); compareResults.TestCases.Count.Should().Be(4); compareResults.TestCases.Where(t => t.UtteranceId == "0").Count().Should().Be(2); compareResults.TestCases.Where(t => t.UtteranceId == "1").Count().Should().Be(2); }
public static void GlobalLocalStrictIgnoreEntities( string expected, string actual, string value, bool unitTestMode, int truePositive, int trueNegative, int falsePositive, int falseNegative) { var globalSettingsFile = Guid.NewGuid().ToString(); var globalSettings = new JObject { { "strictEntities", new JArray { "c", "e" } }, { "ignoreEntities", new JArray { "d", "f" } }, }; File.WriteAllText(globalSettingsFile, globalSettings.ToString()); try { var expectedEntity = new Entity(expected, null, string.Empty, 0); var actualEntity = new Entity(actual, null, value, 0); var expectedUtterance = new LabeledUtterance(null, null, new[] { expectedEntity }) .WithProperty("strictEntities", new JArray { "a", "f" }) .WithProperty("ignoreEntities", new JArray { "b", "e" }); var actualUtterance = new LabeledUtterance(null, null, new[] { actualEntity }); var testSettings = new TestSettings(globalSettingsFile, unitTestMode); var compareResults = TestCaseSource.GetNLUCompareResults( new[] { expectedUtterance }, new[] { actualUtterance }, testSettings); compareResults.Statistics.Entity.TruePositive.Should().Be(truePositive); compareResults.Statistics.Entity.TrueNegative.Should().Be(trueNegative); compareResults.Statistics.Entity.FalsePositive.Should().Be(falsePositive); compareResults.Statistics.Entity.FalseNegative.Should().Be(falseNegative); } finally { File.Delete(globalSettingsFile); } }
public static void UsesInputUtteranceId() { var utteranceId = Guid.NewGuid().ToString(); var expectedUtterance = new CompareLabeledUtterance(utteranceId, null, "Greeting", null); var actualUtterance = new LabeledUtterance(null, "Greeting", null); var compareResults = TestCaseSource.GetNLUCompareResults( new[] { expectedUtterance }, new[] { actualUtterance }, false); compareResults.TestCases.Count.Should().Be(2); compareResults.TestCases.Where(t => t.UtteranceId == utteranceId).Count().Should().Be(2); }
public static void MissingEntityMatchInTextThrowsInvalidOperation() { var text = "foo"; var match = "bar"; using (var service = new LexNLUService(string.Empty, string.Empty, new LexSettings(), new MockLexClient())) { var entity = new Entity(string.Empty, string.Empty, match, 0); var utterance = new LabeledUtterance(text, string.Empty, new[] { entity }); var invalidEntityMatch = new Func <Task>(() => service.TrainAsync(new[] { utterance })); invalidEntityMatch.Should().Throw <InvalidOperationException>(); } }
public static void ConvertsUtteranceWithNoEntities() { var text = Guid.NewGuid().ToString(); var intent = Guid.NewGuid().ToString(); var expected = new LabeledUtterance(text, intent, null); var serializer = CreateSerializer(); var json = JObject.FromObject(expected); var actual = json.ToObject <LabeledUtterance>(serializer); actual.Text.Should().Be(expected.Text); actual.Intent.Should().Be(actual.Intent); actual.Entities.Should().BeNull(); }
public static void UtteranceRoundtrip() { var utterance = new LabeledUtterance(null, null, null) .WithScore(0.42) .WithTextScore(0.5) .WithTimestamp(DateTimeOffset.Now.Date) .WithProperty("foo", new[] { 42 }); var roundtrip = JToken.FromObject(utterance).ToObject <JsonLabeledUtterance>(); roundtrip.GetScore().Should().BeApproximately(utterance.GetScore(), Epsilon); roundtrip.GetTextScore().Should().BeApproximately(utterance.GetTextScore(), Epsilon); roundtrip.GetTimestamp().Should().Be(utterance.GetTimestamp()); roundtrip.GetProperty <JArray>("foo").Should().BeEquivalentTo(new[] { 42 }); }
public static void MissingEntityMatchInTextThrowsInvalidOperation() { var text = "foo"; var match = "bar"; var mockClient = CreateLexTrainClientMock(); using (var lex = new LexNLUTrainClient(string.Empty, string.Empty, new LexSettings(), mockClient.Object)) { var entity = new Entity(null, null, match, 0); var utterance = new LabeledUtterance(text, null, new[] { entity }); var invalidEntityMatch = new Func <Task>(() => lex.TrainAsync(new[] { utterance })); invalidEntityMatch.Should().Throw <InvalidOperationException>(); } }
public static void GetNLUCompareResultsNullScores() { var entityType = Guid.NewGuid().ToString(); var matchText = Guid.NewGuid().ToString(); var expectedEntity = new[] { new Entity(entityType, null, matchText, 0) }; var actualEntity = new[] { new Entity(entityType, null, matchText, 0) }; var expectedUtterance = new LabeledUtterance(null, null, expectedEntity); var actualUtterance = new LabeledUtterance(null, null, actualEntity); var compareResults = TestCaseSource.GetNLUCompareResults( new[] { expectedUtterance }, new[] { actualUtterance }); compareResults.TestCases.Select(t => t.Score).Any(score => score != null).Should().BeFalse(); }
public static void UsesInputUtteranceId() { var utteranceId = Guid.NewGuid().ToString(); var expectedUtterance = new JsonLabeledUtterance(null, "Greeting", null); expectedUtterance.AdditionalProperties.Add("utteranceId", utteranceId); var actualUtterance = new LabeledUtterance(null, "Greeting", null); var compareResults = TestCaseSource.GetNLUCompareResults( new[] { expectedUtterance }, new[] { actualUtterance }); compareResults.TestCases.Count.Should().Be(2); compareResults.TestCases.Where(t => t.UtteranceId == utteranceId).Count().Should().Be(2); }
public static void GetNLUCompareResultsExtractsFalsePositiveEntityScore() { var entityType = Guid.NewGuid().ToString(); var matchText = Guid.NewGuid().ToString(); var actualEntity = new[] { new Entity(entityType, null, matchText, 0).WithScore(0.5) }; var expectedUtterance = new LabeledUtterance(null, null, null); var actualUtterance = new LabeledUtterance(null, null, actualEntity); var compareResults = TestCaseSource.GetNLUCompareResults( new[] { expectedUtterance }, new[] { actualUtterance }); var testCase = compareResults.TestCases.FirstOrDefault(t => t.TargetKind == ComparisonTargetKind.Entity); testCase.Should().NotBeNull(); testCase.Score.Should().Be(0.5); }
public static void GetNLUCompareResultsDefaultScores() { var entityType = Guid.NewGuid().ToString(); var matchText = Guid.NewGuid().ToString(); var expectedEntity = new[] { new Entity(entityType, null, matchText, 0) }; var actualEntity = new[] { new Entity(entityType, null, matchText, 0) }; var expectedUtterance = new LabeledUtterance(null, null, expectedEntity); var actualUtterance = new LabeledUtterance(null, null, actualEntity); var compareResults = TestCaseSource.GetNLUCompareResults( new[] { expectedUtterance }, new[] { actualUtterance }, false); compareResults.TestCases.Select(t => t.Score).Should().AllBeEquivalentTo(0); }
public static async Task CreatesBot() { var text = "hello world"; var intent = Guid.NewGuid().ToString(); var entityTypeName = "Planet"; var botName = Guid.NewGuid().ToString(); var payload = default(JObject); var mockClient = CreateLexTrainClientMock(); mockClient.Setup(lex => lex.StartImportAsync( It.IsAny <StartImportRequest>(), It.IsAny <CancellationToken>())) .Callback <StartImportRequest, CancellationToken>((request, cancellationToken) => payload = GetPayloadJson(request.Payload)); var slot = CreateSlot(entityTypeName, entityTypeName); var lexSettings = new LexSettings(new JArray { slot }); using (var lex = new LexNLUTrainClient(botName, string.Empty, lexSettings, mockClient.Object)) { var entity = new Entity(entityTypeName, "Earth", "world", 0); var utterance = new LabeledUtterance(text, intent, new[] { entity }); await lex.TrainAsync(new[] { utterance }).ConfigureAwait(false); // assert payload payload.Should().NotBeNull(); // assert name is set payload.SelectToken(".resource.name").Value <string>().Should().Be(botName); // assert intent is created payload.SelectToken(".resource.intents").Count().Should().Be(1); payload.SelectToken(".resource.intents[0].name").Value <string>().Should().Be(intent); // assert template utterance is set payload.SelectToken(".resource.intents[0].sampleUtterances").Count().Should().Be(1); payload.SelectToken(".resource.intents[0].sampleUtterances[0]").Value <string>().Should().Be("hello {Planet}"); // assert slot is created in intent payload.SelectToken(".resource.intents[0].slots").Count().Should().Be(1); payload.SelectToken(".resource.intents[0].slots[0].name").Value <string>().Should().Be(entityTypeName); payload.SelectToken(".resource.intents[0].slots[0].slotType").Value <string>().Should().Be(entityTypeName); } }
public static void GetNLUCompareResultsExtractsIntentAndTextScore() { var expectedUtterance = new LabeledUtterance(null, null, null).WithProperty("speechFile", "speechFile"); var actualUtterance = new LabeledUtterance(null, null, null).WithScore(0.5).WithTextScore(0.1); var compareResults = TestCaseSource.GetNLUCompareResults( new[] { expectedUtterance }, new[] { actualUtterance }); var intentTestCase = compareResults.TestCases.FirstOrDefault(t => t.TargetKind == ComparisonTargetKind.Intent); intentTestCase.Should().NotBeNull(); intentTestCase.Score.Should().Be(0.5); var textTestCase = compareResults.TestCases.FirstOrDefault(t => t.TargetKind == ComparisonTargetKind.Text); textTestCase.Should().NotBeNull(); textTestCase.Score.Should().Be(0.1); }
public static void NoFalsePositiveIntentsUnitTestMode() { var expectedUtterance = new JsonLabeledUtterance(new JsonEntities(Array.Empty <Entity>())); var actualUtterance = new LabeledUtterance(null, "foo", null); var testSettings = new TestSettings(default(string), true); var compareResults = TestCaseSource.GetNLUCompareResults( new[] { expectedUtterance }, new[] { actualUtterance }, testSettings); compareResults.Statistics.Intent.TruePositive.Should().Be(0); compareResults.Statistics.Intent.TrueNegative.Should().Be(0); compareResults.Statistics.Intent.FalsePositive.Should().Be(0); compareResults.Statistics.Intent.FalseNegative.Should().Be(0); }
public static async Task WaitsForImportCompletion() { var importId = Guid.NewGuid().ToString(); var mockClient = new MockLexClient(); mockClient.Get <StartImportResponse>().ImportId = importId; mockClient.Get <StartImportResponse>().ImportStatus = ImportStatus.IN_PROGRESS; mockClient.Get <GetImportResponse>().ImportId = importId; mockClient.Get <GetImportResponse>().ImportStatus = ImportStatus.IN_PROGRESS; // Wait for the second GetImport action to set status to complete var count = 0; void onRequest(object request) { if (request is GetImportRequest && ++count == 2) { mockClient.Get <GetImportResponse>().ImportStatus = ImportStatus.COMPLETE; } } mockClient.OnRequest = onRequest; using (var lex = new LexNLUService(string.Empty, string.Empty, new LexSettings(), mockClient)) { var utterance = new LabeledUtterance(string.Empty, string.Empty, null); await lex.TrainAsync(new[] { utterance }).ConfigureAwait(false); // Assert two GetImport actions occur mockClient.Requests.OfType <GetImportRequest>().Count().Should().Be(2); // Assert that the time difference is at least two seconds var requests = mockClient.TimestampedRequests .Where(tuple => tuple.Item1 is GetImportRequest) .Select(tuple => new { Request = (GetImportRequest)tuple.Item1, Timestamp = tuple.Item2 }) .ToArray(); var difference = requests[1].Timestamp - requests[0].Timestamp; difference.Should().BeGreaterThan(TimeSpan.FromSeconds(2) - Epsilon); } }
public static async Task CreatesBot() { var text = "hello world"; var intent = Guid.NewGuid().ToString(); var entityTypeName = "Planet"; var botName = Guid.NewGuid().ToString(); var mockClient = new MockLexClient(); var slot = CreateSlot(entityTypeName, entityTypeName); var lexSettings = new LexSettings(new JArray { slot }); using (var lex = new LexNLUService(botName, string.Empty, lexSettings, mockClient)) { var entity = new Entity(entityTypeName, "Earth", "world", 0); var utterance = new LabeledUtterance(text, intent, new[] { entity }); await lex.TrainAsync(new[] { utterance }).ConfigureAwait(false); // get StartImport request var startImportRequest = mockClient.Requests.OfType <StartImportRequest>().FirstOrDefault(); startImportRequest.Should().NotBeNull(); // get payload var payloadJson = GetPayloadJson(startImportRequest.Payload); payloadJson.Should().NotBeNull().And.NotBeEmpty(); var payload = JObject.Parse(payloadJson); // assert name is set payload.SelectToken(".resource.name").Value <string>().Should().Be(botName); // assert intent is created payload.SelectToken(".resource.intents").Count().Should().Be(1); payload.SelectToken(".resource.intents[0].name").Value <string>().Should().Be(intent); // assert template utterance is set payload.SelectToken(".resource.intents[0].sampleUtterances").Count().Should().Be(1); payload.SelectToken(".resource.intents[0].sampleUtterances[0]").Value <string>().Should().Be("hello {Planet}"); // assert slot is created in intent payload.SelectToken(".resource.intents[0].slots").Count().Should().Be(1); payload.SelectToken(".resource.intents[0].slots[0].name").Value <string>().Should().Be(entityTypeName); payload.SelectToken(".resource.intents[0].slots[0].slotType").Value <string>().Should().Be(entityTypeName); } }
private static string CreateSampleUtterance(LabeledUtterance utterance) { var text = utterance.Text; if (utterance.Entities != null) { foreach (var entity in utterance.Entities) { // Match in original text var index = entity.StartCharIndexInText(utterance.Text); // Replace the matching token with the slot indicator text = new Regex(entity.MatchText) .Replace(text, $"{{{entity.EntityType}}}", 1, index); } } return text; }
public static void GetNLUCompareResultsTextStatistics( string expected, string actual, int truePositive, int trueNegative, int falsePositive, int falseNegative) { var expectedUtterance = new LabeledUtterance(expected, null, null).WithProperty("speechFile", "speechFile"); var actualUtterance = new LabeledUtterance(actual, null, null); var compareResults = TestCaseSource.GetNLUCompareResults( new[] { expectedUtterance }, new[] { actualUtterance }); compareResults.Statistics.Text.TruePositive.Should().Be(truePositive); compareResults.Statistics.Text.TrueNegative.Should().Be(trueNegative); compareResults.Statistics.Text.FalsePositive.Should().Be(falsePositive); compareResults.Statistics.Text.FalseNegative.Should().Be(falseNegative); }
public static async Task TestOutputTruncatesExistingFile() { var outputPath = Path.GetRandomFileName(); File.WriteAllText(outputPath, string.Join(string.Empty, Enumerable.Repeat("!", 1000))); var testResult = new LabeledUtterance("foo", "foo", null); var options = new TestOptions { UtterancesPath = "testdata/utterances.json", OutputPath = outputPath, }; var testCommand = new TestCommandWithMockResult(testResult, options); await testCommand.RunAsync().ConfigureAwait(false); var content = File.ReadAllText(outputPath); var json = JToken.Parse(content); json.As <JArray>().Count.Should().Be(7); }
public static async Task WaitsForBuildCompletion() { var mockClient = new MockLexClient(); mockClient.Get <GetBotResponse>().Status = Status.BUILDING; // Wait for the third GetBot action to set status to complete var count = 0; void onRequest(object request) { if (request is GetBotRequest && ++count == 3) { mockClient.Get <GetBotResponse>().Status = Status.READY; } } mockClient.OnRequest = onRequest; using (var lex = new LexNLUService(string.Empty, string.Empty, new LexSettings(), mockClient)) { var utterance = new LabeledUtterance(string.Empty, string.Empty, null); await lex.TrainAsync(new[] { utterance }).ConfigureAwait(false); // Assert three GetBot actions occur mockClient.Requests.OfType <GetBotRequest>().Count().Should().Be(3); // Assert that the time difference is at least two seconds var requests = mockClient.TimestampedRequests .Where(tuple => tuple.Item1 is GetBotRequest) .Select(tuple => new { Request = (GetBotRequest)tuple.Item1, Timestamp = tuple.Item2 }) .ToArray(); var difference = requests[2].Timestamp - requests[1].Timestamp; difference.Should().BeGreaterThan(TimeSpan.FromSeconds(2) - Epsilon); } }
public static void ConvertsUtteranceWithGenericEntity() { var entityType = Guid.NewGuid().ToString(); var matchText = Guid.NewGuid().ToString(); var matchIndex = 42; var expected = new Entity(entityType, null, matchText, matchIndex); var expectedUtterance = new LabeledUtterance(null, null, new[] { expected }); var serializer = CreateSerializer(); var json = JObject.FromObject(expectedUtterance, serializer); var actualUtterance = json.ToObject <LabeledUtterance>(serializer); actualUtterance.Text.Should().BeNull(); actualUtterance.Intent.Should().BeNull(); actualUtterance.Entities.Count.Should().Be(1); var actual = actualUtterance.Entities.Single(); actual.EntityType.Should().Be(expected.EntityType); actual.MatchText.Should().Be(expected.MatchText); actual.MatchIndex.Should().Be(expected.MatchIndex); actual.EntityValue.Should().BeNull(); }
/// <summary> /// Initializes a new instance of the <see cref="TestCase"/> class. /// </summary> /// <param name="resultKind">Confusion matrix result kind.</param> /// <param name="targetKind">Comparison target kind.</param> /// <param name="expectedUtterance">Expected utterance.</param> /// <param name="actualUtterance">Actual utterance.</param> /// <param name="score">Confidence score for test case result.</param> /// <param name="group">Test case group name.</param> /// <param name="testName">Test name.</param> /// <param name="because">Because.</param> /// <param name="categories">Categories.</param> public TestCase( ConfusionMatrixResultKind resultKind, ComparisonTargetKind targetKind, LabeledUtterance expectedUtterance, LabeledUtterance actualUtterance, double score, string group, string testName, string because, IEnumerable <string> categories) { this.ResultKind = resultKind; this.TargetKind = targetKind; this.ExpectedUtterance = expectedUtterance; this.ActualUtterance = actualUtterance; this.Score = score; this.Group = group; this.TestName = testName; this.Because = because; this.Categories = categories.ToList(); }
private static TestCase FalseNegative( ComparisonTargetKind targetKind, LabeledUtterance expectedUtterance, LabeledUtterance actualUtterance, double score, string group, string[] args, string because, params string[] categories) { return(CreateTestCase( ConfusionMatrixResultKind.FalseNegative, targetKind, expectedUtterance, actualUtterance, score, group, args, because, categories.Append("FalseNegative"))); }
public static void CustomTrueNegativeIntent( string expected, string actual, int truePositive, int trueNegative, int falsePositive, int falseNegative) { var expectedUtterance = new LabeledUtterance(null, expected, null); var actualUtterance = new LabeledUtterance(null, actual, null); var configuration = new ConfigurationBuilder() .AddInMemoryCollection(new Dictionary <string, string> { { "trueNegativeIntent", "foo" }, }) .Build(); var testSettings = new TestSettings(configuration, false); var compareResults = TestCaseSource.GetNLUCompareResults( new[] { expectedUtterance }, new[] { actualUtterance }, testSettings); compareResults.Statistics.Intent.TruePositive.Should().Be(truePositive); compareResults.Statistics.Intent.TrueNegative.Should().Be(trueNegative); compareResults.Statistics.Intent.FalsePositive.Should().Be(falsePositive); compareResults.Statistics.Intent.FalseNegative.Should().Be(falseNegative); if (expected != null && expected != "foo") { compareResults.Statistics.ByIntent[expected].TruePositive.Should().Be(truePositive); compareResults.Statistics.ByIntent[expected].FalseNegative.Should().Be(falseNegative); } else if (actual != null && actual != "foo") { compareResults.Statistics.ByIntent[actual].FalsePositive.Should().Be(falsePositive); } }