From e06b5dcb3567e15f232a1921fc29db44c63800c7 Mon Sep 17 00:00:00 2001 From: dacharyc Date: Fri, 27 Jun 2025 18:01:55 -0400 Subject: [PATCH 1/6] Add PoC C# test suite --- .gitignore | 9 ++ .../driver/Examples/Aggregation/GroupTotal.cs | 109 ++++++++++++++++++ .../Examples/Aggregation/GroupTotalOutput.txt | 3 + .../driver/Examples/Aggregation/Order.cs | 13 +++ .../csharp/driver/Examples/Examples.csproj | 14 +++ .../csharp/driver/Examples/Program.cs | 1 + .../csharp/driver/Tests/GroupTotalTest.cs | 28 +++++ .../csharp/driver/Tests/TestUtils.cs | 20 ++++ .../csharp/driver/Tests/Tests.csproj | 27 +++++ usage-examples/csharp/driver/driver.sln | 22 ++++ 10 files changed, 246 insertions(+) create mode 100644 usage-examples/csharp/driver/Examples/Aggregation/GroupTotal.cs create mode 100644 usage-examples/csharp/driver/Examples/Aggregation/GroupTotalOutput.txt create mode 100644 usage-examples/csharp/driver/Examples/Aggregation/Order.cs create mode 100644 usage-examples/csharp/driver/Examples/Examples.csproj create mode 100644 usage-examples/csharp/driver/Examples/Program.cs create mode 100644 usage-examples/csharp/driver/Tests/GroupTotalTest.cs create mode 100644 usage-examples/csharp/driver/Tests/TestUtils.cs create mode 100644 usage-examples/csharp/driver/Tests/Tests.csproj create mode 100644 usage-examples/csharp/driver/driver.sln diff --git a/.gitignore b/.gitignore index 086c1e4..d597805 100644 --- a/.gitignore +++ b/.gitignore @@ -28,3 +28,12 @@ node_modules # Mongosh temporary files temp + +# C# Debug files +Debug/ + +# NuGet generated artifact files +obj/ + +# User-specific settings files from JetBrains Rider and ReSharper +*.DotSettings.user diff --git a/usage-examples/csharp/driver/Examples/Aggregation/GroupTotal.cs b/usage-examples/csharp/driver/Examples/Aggregation/GroupTotal.cs new file mode 100644 index 0000000..fa73a43 --- /dev/null +++ b/usage-examples/csharp/driver/Examples/Aggregation/GroupTotal.cs @@ -0,0 +1,109 @@ +namespace Examples.Aggregation; + +using MongoDB.Driver; +using MongoDB.Bson; + +public class GroupTotal +{ + private IMongoDatabase _aggDB; + private IMongoCollection _orders; + + public void SeedData() + { + var uri = "mongodb://localhost:27017"; + var client = new MongoClient(uri); + _aggDB = client.GetDatabase("agg_tutorials_db"); + _orders = _aggDB.GetCollection("orders"); + _orders.DeleteMany(Builders.Filter.Empty); + + _orders.InsertMany(new List + { + new Order + { + CustomerId = "elise_smith@myemail.com", + OrderDate = DateTime.Parse("2020-05-30T08:35:52Z"), + Value = 231 + }, + new Order + { + CustomerId = "elise_smith@myemail.com", + OrderDate = DateTime.Parse("2020-01-13T09:32:07Z"), + Value = 99 + }, + new Order + { + CustomerId = "oranieri@warmmail.com", + OrderDate = DateTime.Parse("2020-01-01T08:25:37Z"), + Value = 63 + }, + new Order + { + CustomerId = "tj@wheresmyemail.com", + OrderDate = DateTime.Parse("2019-05-28T19:13:32Z"), + Value = 2 + }, + new Order + { + CustomerId = "tj@wheresmyemail.com", + OrderDate = DateTime.Parse("2020-11-23T22:56:53Z"), + Value = 187 + }, + new Order + { + CustomerId = "tj@wheresmyemail.com", + OrderDate = DateTime.Parse("2020-08-18T23:04:48Z"), + Value = 4 + }, + new Order + { + CustomerId = "elise_smith@myemail.com", + OrderDate = DateTime.Parse("2020-12-26T08:55:46Z"), + Value = 4 + }, + new Order + { + CustomerId = "tj@wheresmyemail.com", + OrderDate = DateTime.Parse("2021-02-28T07:49:32Z"), + Value = 1024 + }, + new Order + { + CustomerId = "elise_smith@myemail.com", + OrderDate = DateTime.Parse("2020-10-03T13:49:44Z"), + Value = 102 + } + }); + } + + public List PerformAggregation() + { + var uri = "mongodb://localhost:27017"; + var client = new MongoClient(uri); + _aggDB = client.GetDatabase("agg_tutorials_db"); + _orders = _aggDB.GetCollection("orders"); + + var results = _orders.Aggregate() + .Match(o => o.OrderDate >= DateTime.Parse("2020-01-01T00:00:00Z") && o.OrderDate < DateTime.Parse("2021-01-01T00:00:00Z")) + .SortBy(o => o.OrderDate) + .Group( + o => o.CustomerId, + g => new + { + CustomerId = g.Key, + FirstPurchaseDate = g.First().OrderDate, + TotalValue = g.Sum(i => i.Value), + TotalOrders = g.Count(), + Orders = g.Select(i => new { i.OrderDate, i.Value }).ToList() + } + ) + .SortBy(c => c.FirstPurchaseDate) + .As(); + + foreach (var result in results.ToList()) + { + Console.WriteLine(result); + } + + return results.ToList(); + } +} \ No newline at end of file diff --git a/usage-examples/csharp/driver/Examples/Aggregation/GroupTotalOutput.txt b/usage-examples/csharp/driver/Examples/Aggregation/GroupTotalOutput.txt new file mode 100644 index 0000000..6670eb1 --- /dev/null +++ b/usage-examples/csharp/driver/Examples/Aggregation/GroupTotalOutput.txt @@ -0,0 +1,3 @@ +{ "CustomerId" : "oranieri@warmmail.com", "FirstPurchaseDate" : { "$date" : "2020-01-01T08:25:37Z" }, "TotalValue" : 63, "TotalOrders" : 1, "Orders" : [{ "OrderDate" : { "$date" : "2020-01-01T08:25:37Z" }, "Value" : 63 }] } +{ "CustomerId" : "elise_smith@myemail.com", "FirstPurchaseDate" : { "$date" : "2020-01-13T09:32:07Z" }, "TotalValue" : 436, "TotalOrders" : 4, "Orders" : [{ "OrderDate" : { "$date" : "2020-01-13T09:32:07Z" }, "Value" : 99 }, { "OrderDate" : { "$date" : "2020-05-30T08:35:52Z" }, "Value" : 231 }, { "OrderDate" : { "$date" : "2020-10-03T13:49:44Z" }, "Value" : 102 }, { "OrderDate" : { "$date" : "2020-12-26T08:55:46Z" }, "Value" : 4 }] } +{ "CustomerId" : "tj@wheresmyemail.com", "FirstPurchaseDate" : { "$date" : "2020-08-18T23:04:48Z" }, "TotalValue" : 191, "TotalOrders" : 2, "Orders" : [{ "OrderDate" : { "$date" : "2020-08-18T23:04:48Z" }, "Value" : 4 }, { "OrderDate" : { "$date" : "2020-11-23T22:56:53Z" }, "Value" : 187 }] } \ No newline at end of file diff --git a/usage-examples/csharp/driver/Examples/Aggregation/Order.cs b/usage-examples/csharp/driver/Examples/Aggregation/Order.cs new file mode 100644 index 0000000..90ea168 --- /dev/null +++ b/usage-examples/csharp/driver/Examples/Aggregation/Order.cs @@ -0,0 +1,13 @@ +using MongoDB.Bson; +using MongoDB.Bson.Serialization.Attributes; + +namespace Examples.Aggregation; + +public class Order +{ + [BsonId] + public ObjectId Id { get; set; } + public string CustomerId { get; set; } + public DateTime OrderDate { get; set; } + public int Value { get; set; } +} \ No newline at end of file diff --git a/usage-examples/csharp/driver/Examples/Examples.csproj b/usage-examples/csharp/driver/Examples/Examples.csproj new file mode 100644 index 0000000..c0772c3 --- /dev/null +++ b/usage-examples/csharp/driver/Examples/Examples.csproj @@ -0,0 +1,14 @@ + + + + Exe + net9.0 + enable + enable + + + + + + + diff --git a/usage-examples/csharp/driver/Examples/Program.cs b/usage-examples/csharp/driver/Examples/Program.cs new file mode 100644 index 0000000..5156ea5 --- /dev/null +++ b/usage-examples/csharp/driver/Examples/Program.cs @@ -0,0 +1 @@ +Console.WriteLine("This project is not intended to be run as a console application. Run the tests using the 'Tests' solution."); \ No newline at end of file diff --git a/usage-examples/csharp/driver/Tests/GroupTotalTest.cs b/usage-examples/csharp/driver/Tests/GroupTotalTest.cs new file mode 100644 index 0000000..0f068b2 --- /dev/null +++ b/usage-examples/csharp/driver/Tests/GroupTotalTest.cs @@ -0,0 +1,28 @@ +using Examples.Aggregation; + +namespace Tests; + +public class GroupTotalTest +{ + [SetUp] + public void Setup() + { + var obj = new GroupTotal(); + obj.SeedData(); + } + + [Test] + public void Test1() + { + var obj = new GroupTotal(); + var results = obj.PerformAggregation(); + + string outputfilePath = "/Users/dachary.carey/workspace/docs-code-examples/usage-examples/csharp/driver/Examples/Aggregation/GroupTotalOutput.txt"; + var fileData = TestUtils.ReadBsonDocumentsFromFile(outputfilePath); + Assert.That(results.Count, Is.EqualTo(fileData.Length), "Result count does not match output example length."); + for (int i = 0; i < fileData.Length; i++) + { + Assert.That(fileData[i], Is.EqualTo(results[i]), $"Mismatch at index {i}: expected {fileData[i]}, got {results[i]}."); + } + } +} \ No newline at end of file diff --git a/usage-examples/csharp/driver/Tests/TestUtils.cs b/usage-examples/csharp/driver/Tests/TestUtils.cs new file mode 100644 index 0000000..f94bccc --- /dev/null +++ b/usage-examples/csharp/driver/Tests/TestUtils.cs @@ -0,0 +1,20 @@ +using MongoDB.Bson; + +public static class TestUtils +{ + public static BsonDocument[] ReadBsonDocumentsFromFile(string filePath) + { + var bsonDocuments = new List(); + + foreach (var line in File.ReadLines(filePath)) + { + if (!string.IsNullOrWhiteSpace(line)) + { + var bsonDoc = BsonDocument.Parse(line); + bsonDocuments.Add(bsonDoc); + } + } + + return bsonDocuments.ToArray(); + } +} diff --git a/usage-examples/csharp/driver/Tests/Tests.csproj b/usage-examples/csharp/driver/Tests/Tests.csproj new file mode 100644 index 0000000..9e71565 --- /dev/null +++ b/usage-examples/csharp/driver/Tests/Tests.csproj @@ -0,0 +1,27 @@ + + + + net9.0 + latest + enable + enable + false + + + + + + + + + + + + + + + + + + + diff --git a/usage-examples/csharp/driver/driver.sln b/usage-examples/csharp/driver/driver.sln new file mode 100644 index 0000000..8973cbc --- /dev/null +++ b/usage-examples/csharp/driver/driver.sln @@ -0,0 +1,22 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Examples", "Examples\Examples.csproj", "{D1D4ACA8-520F-4B09-983D-132861CC8AEB}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Tests", "Tests\Tests.csproj", "{E1F6E308-2D95-4FBB-8F39-214C70889A3D}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {D1D4ACA8-520F-4B09-983D-132861CC8AEB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {D1D4ACA8-520F-4B09-983D-132861CC8AEB}.Debug|Any CPU.Build.0 = Debug|Any CPU + {D1D4ACA8-520F-4B09-983D-132861CC8AEB}.Release|Any CPU.ActiveCfg = Release|Any CPU + {D1D4ACA8-520F-4B09-983D-132861CC8AEB}.Release|Any CPU.Build.0 = Release|Any CPU + {E1F6E308-2D95-4FBB-8F39-214C70889A3D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {E1F6E308-2D95-4FBB-8F39-214C70889A3D}.Debug|Any CPU.Build.0 = Debug|Any CPU + {E1F6E308-2D95-4FBB-8F39-214C70889A3D}.Release|Any CPU.ActiveCfg = Release|Any CPU + {E1F6E308-2D95-4FBB-8F39-214C70889A3D}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection +EndGlobal From ce6c4b66eeb56ef0b0fc66b9fb163adfd528ef70 Mon Sep 17 00:00:00 2001 From: dacharyc Date: Mon, 30 Jun 2025 13:01:43 -0400 Subject: [PATCH 2/6] Add handling for .env variable connection strings --- .../driver/Examples/Aggregation/GroupTotal.cs | 14 ++++++++++---- .../csharp/driver/Examples/Examples.csproj | 1 + 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/usage-examples/csharp/driver/Examples/Aggregation/GroupTotal.cs b/usage-examples/csharp/driver/Examples/Aggregation/GroupTotal.cs index fa73a43..a5781af 100644 --- a/usage-examples/csharp/driver/Examples/Aggregation/GroupTotal.cs +++ b/usage-examples/csharp/driver/Examples/Aggregation/GroupTotal.cs @@ -5,12 +5,16 @@ namespace Examples.Aggregation; public class GroupTotal { - private IMongoDatabase _aggDB; - private IMongoCollection _orders; + private IMongoDatabase _aggDB; + private IMongoCollection _orders; + private string _appDir; + private string _envRelPath; public void SeedData() { - var uri = "mongodb://localhost:27017"; + DotNetEnv.Env.TraversePath().Load(); + string uri = DotNetEnv.Env.GetString("CONNECTION_STRING", "Env variable not found. Verify you have a .env file with a valid connection string."); + //var uri = "mongodb://localhost:27017"; var client = new MongoClient(uri); _aggDB = client.GetDatabase("agg_tutorials_db"); _orders = _aggDB.GetCollection("orders"); @@ -77,7 +81,9 @@ public void SeedData() public List PerformAggregation() { - var uri = "mongodb://localhost:27017"; + DotNetEnv.Env.TraversePath().Load(); + string uri = DotNetEnv.Env.GetString("CONNECTION_STRING", "Env variable not found. Verify you have a .env file with a valid connection string."); + //var uri = "mongodb://localhost:27017"; var client = new MongoClient(uri); _aggDB = client.GetDatabase("agg_tutorials_db"); _orders = _aggDB.GetCollection("orders"); diff --git a/usage-examples/csharp/driver/Examples/Examples.csproj b/usage-examples/csharp/driver/Examples/Examples.csproj index c0772c3..c1efe6c 100644 --- a/usage-examples/csharp/driver/Examples/Examples.csproj +++ b/usage-examples/csharp/driver/Examples/Examples.csproj @@ -8,6 +8,7 @@ + From d25aa4cc15db61201a945c7c177c17c8ab9f61eb Mon Sep 17 00:00:00 2001 From: dacharyc Date: Mon, 30 Jun 2025 13:44:51 -0400 Subject: [PATCH 3/6] Load output file from path relative to solution root --- usage-examples/csharp/driver/Tests/GroupTotalTest.cs | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/usage-examples/csharp/driver/Tests/GroupTotalTest.cs b/usage-examples/csharp/driver/Tests/GroupTotalTest.cs index 0f068b2..39d33e5 100644 --- a/usage-examples/csharp/driver/Tests/GroupTotalTest.cs +++ b/usage-examples/csharp/driver/Tests/GroupTotalTest.cs @@ -12,13 +12,17 @@ public void Setup() } [Test] - public void Test1() + public void Test() { var obj = new GroupTotal(); var results = obj.PerformAggregation(); - string outputfilePath = "/Users/dachary.carey/workspace/docs-code-examples/usage-examples/csharp/driver/Examples/Aggregation/GroupTotalOutput.txt"; - var fileData = TestUtils.ReadBsonDocumentsFromFile(outputfilePath); + DotNetEnv.Env.TraversePath().Load(); + string solutionRoot = DotNetEnv.Env.GetString("SOLUTION_ROOT", "Env variable not found. Verify you have a .env file with a valid connection string."); + string outputLocation = "Examples/Aggregation/GroupTotalOutput.txt"; + string fullPath = Path.Combine(solutionRoot, outputLocation); + var fileData = TestUtils.ReadBsonDocumentsFromFile(fullPath); + Assert.That(results.Count, Is.EqualTo(fileData.Length), "Result count does not match output example length."); for (int i = 0; i < fileData.Length; i++) { From e7026c3984fc46944512d5db15edd371511302e8 Mon Sep 17 00:00:00 2001 From: dacharyc Date: Mon, 30 Jun 2025 15:18:30 -0400 Subject: [PATCH 4/6] Add README --- usage-examples/csharp/driver/README.md | 105 ++++++++++++++++++ .../csharp/driver/Tests/GroupTotalTest.cs | 2 +- 2 files changed, 106 insertions(+), 1 deletion(-) create mode 100644 usage-examples/csharp/driver/README.md diff --git a/usage-examples/csharp/driver/README.md b/usage-examples/csharp/driver/README.md new file mode 100644 index 0000000..1d1a13f --- /dev/null +++ b/usage-examples/csharp/driver/README.md @@ -0,0 +1,105 @@ +# C# Driver Code Example Test PoC + +This is a PoC to explore testing C# Driver code examples for MongoDB documentation. + +The structure of this C# project is as follows: + +- `driver.sln`: This solution contains the following projects: + - `Examples`: This project contains example code and output to validate. + - `Tests`: This project contains the test infrastructure to actually run + the tests by invoking the example code. + +## To run the tests locally + +### Create a MongoDB Docker Deployment + +To run these tests locally, you need a MongoDB Docker deployment. Make sure Docker is +running, and then: + +1. Pull the MongoDB image from Docker Hub: + + ```shell + docker pull mongo + ``` +2. Run the container: + + ```shell + docker run --name mongodb-test -d -p 27017:27017 mongo + ``` + +3. Verify the container is running: + + ```shell + docker ps + ``` + + The output resembles: + + ```text + CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES + ef70cce38f26 mongo "/usr/local/bin/runn…" 29 hours ago Up 29 hours (healthy) 127.0.0.1:63201->27017/tcp mongodb-test + ``` + + You may note the actual port is different than `27017`, if something else is already running on + `27017` on your machine. Note the port next to the IP address for running the tests. Alternately, you can get just + the port info for your container using the following command: + + ```shell + docker port mongodb-test + ``` + + The output resembles: + + ```text + 27017/tcp -> 0.0.0.0:27017 + 27017/tcp -> [::]:27017 + ``` + +### Create a .env file + +Create a file named `.env` at the root of the `/driver` directory. +Add the following values to your .env file, similar to the following example: + +``` +CONNECTION_STRING="mongodb://localhost:27017" +SOLUTION_ROOT="/Users/dachary.carey/workspace/docs-code-examples/usage-examples/csharp/driver/" +``` + +- `CONNECTION_STRING`: replace the port with the port where your local deployment is running. +- `SOLUTION_ROOT`: insert the path to the `driver` directory on your filesystem. + +### Install the dependencies + +This test suite requires you to have `.NET` v9.0 installed. If you +do not yet have .NET installed, refer to +[the .NET installation page](https://learn.microsoft.com/en-us/dotnet/core/install/macos) +for details. + +From the root of each project directory, run the following command to install +dependencies: + +``` +dotnet restore +``` + +### Run the tests + +You can run tests from the command line or through your IDE. + +#### Run All Tests from the command line + +From the `/drivers` directory, run: + +``` +dotnet test +``` + +#### Run Individual Tests from the command line + +You can run a single test within a given test suite (file). + +From the `/drivers` directory, run: + +``` +dotnet test --filter "FullyQualifiedName=YourNamespace.YourTestClass.YourTestMethod" +``` diff --git a/usage-examples/csharp/driver/Tests/GroupTotalTest.cs b/usage-examples/csharp/driver/Tests/GroupTotalTest.cs index 39d33e5..46b4c95 100644 --- a/usage-examples/csharp/driver/Tests/GroupTotalTest.cs +++ b/usage-examples/csharp/driver/Tests/GroupTotalTest.cs @@ -12,7 +12,7 @@ public void Setup() } [Test] - public void Test() + public void TestOutputMatchesDocs() { var obj = new GroupTotal(); var results = obj.PerformAggregation(); From 250229d90e1212bdf75a5d81f84608b490cec76a Mon Sep 17 00:00:00 2001 From: dacharyc Date: Mon, 30 Jun 2025 15:28:24 -0400 Subject: [PATCH 5/6] Add Bluehawk markup --- .../driver/Examples/Aggregation/GroupTotal.cs | 27 ++++++++++++++++--- .../driver/Examples/Aggregation/Order.cs | 4 ++- 2 files changed, 26 insertions(+), 5 deletions(-) diff --git a/usage-examples/csharp/driver/Examples/Aggregation/GroupTotal.cs b/usage-examples/csharp/driver/Examples/Aggregation/GroupTotal.cs index a5781af..0246289 100644 --- a/usage-examples/csharp/driver/Examples/Aggregation/GroupTotal.cs +++ b/usage-examples/csharp/driver/Examples/Aggregation/GroupTotal.cs @@ -1,3 +1,9 @@ +// :replace-start: { +// "terms": { +// "_order": "order", +// "_aggDb": "aggDb" +// } +// } namespace Examples.Aggregation; using MongoDB.Driver; @@ -7,16 +13,19 @@ public class GroupTotal { private IMongoDatabase _aggDB; private IMongoCollection _orders; - private string _appDir; - private string _envRelPath; public void SeedData() { DotNetEnv.Env.TraversePath().Load(); string uri = DotNetEnv.Env.GetString("CONNECTION_STRING", "Env variable not found. Verify you have a .env file with a valid connection string."); - //var uri = "mongodb://localhost:27017"; + // :snippet-start: connection-string + // :uncomment-start: + //var uri = "mongodb+srv://mongodb-example:27017"; + // :uncomment-end: + // :snippet-end: var client = new MongoClient(uri); _aggDB = client.GetDatabase("agg_tutorials_db"); + // :snippet-start: add-sample-data _orders = _aggDB.GetCollection("orders"); _orders.DeleteMany(Builders.Filter.Empty); @@ -77,6 +86,7 @@ public void SeedData() Value = 102 } }); + // :snippet-end: } public List PerformAggregation() @@ -88,9 +98,14 @@ public List PerformAggregation() _aggDB = client.GetDatabase("agg_tutorials_db"); _orders = _aggDB.GetCollection("orders"); + // :snippet-start: match var results = _orders.Aggregate() .Match(o => o.OrderDate >= DateTime.Parse("2020-01-01T00:00:00Z") && o.OrderDate < DateTime.Parse("2021-01-01T00:00:00Z")) + // :snippet-end: + // :snippet-start: sort-order-date .SortBy(o => o.OrderDate) + // :snippet-end: + // :snippet-start: group .Group( o => o.CustomerId, g => new @@ -102,8 +117,11 @@ public List PerformAggregation() Orders = g.Select(i => new { i.OrderDate, i.Value }).ToList() } ) + // :snippet-end: + // :snippet-start: sort-first-order .SortBy(c => c.FirstPurchaseDate) .As(); + // :snippet-end: foreach (var result in results.ToList()) { @@ -112,4 +130,5 @@ public List PerformAggregation() return results.ToList(); } -} \ No newline at end of file +} +// :replace-end: \ No newline at end of file diff --git a/usage-examples/csharp/driver/Examples/Aggregation/Order.cs b/usage-examples/csharp/driver/Examples/Aggregation/Order.cs index 90ea168..ba55e79 100644 --- a/usage-examples/csharp/driver/Examples/Aggregation/Order.cs +++ b/usage-examples/csharp/driver/Examples/Aggregation/Order.cs @@ -3,6 +3,7 @@ namespace Examples.Aggregation; +// :snippet-start: class-declaration public class Order { [BsonId] @@ -10,4 +11,5 @@ public class Order public string CustomerId { get; set; } public DateTime OrderDate { get; set; } public int Value { get; set; } -} \ No newline at end of file +} +// :snippet-end: \ No newline at end of file From 1c77041c93dac453e1b77f9d6e9d8e4162237f6e Mon Sep 17 00:00:00 2001 From: dacharyc Date: Tue, 1 Jul 2025 11:44:52 -0400 Subject: [PATCH 6/6] Apply review suggestions --- .../driver/Examples/Aggregation/GroupTotal.cs | 20 +++++++++---------- .../csharp/driver/Tests/GroupTotalTest.cs | 19 +++++++++--------- .../csharp/driver/Tests/TestSuiteSetup.cs | 13 ++++++++++++ 3 files changed, 31 insertions(+), 21 deletions(-) create mode 100644 usage-examples/csharp/driver/Tests/TestSuiteSetup.cs diff --git a/usage-examples/csharp/driver/Examples/Aggregation/GroupTotal.cs b/usage-examples/csharp/driver/Examples/Aggregation/GroupTotal.cs index 0246289..ee906c1 100644 --- a/usage-examples/csharp/driver/Examples/Aggregation/GroupTotal.cs +++ b/usage-examples/csharp/driver/Examples/Aggregation/GroupTotal.cs @@ -4,6 +4,7 @@ // "_aggDb": "aggDb" // } // } + namespace Examples.Aggregation; using MongoDB.Driver; @@ -11,13 +12,12 @@ namespace Examples.Aggregation; public class GroupTotal { - private IMongoDatabase _aggDB; - private IMongoCollection _orders; + private IMongoDatabase? _aggDB; + private IMongoCollection? _orders; - public void SeedData() + public void LoadSampleData() { - DotNetEnv.Env.TraversePath().Load(); - string uri = DotNetEnv.Env.GetString("CONNECTION_STRING", "Env variable not found. Verify you have a .env file with a valid connection string."); + var uri = DotNetEnv.Env.GetString("CONNECTION_STRING", "Env variable not found. Verify you have a .env file with a valid connection string."); // :snippet-start: connection-string // :uncomment-start: //var uri = "mongodb+srv://mongodb-example:27017"; @@ -91,12 +91,10 @@ public void SeedData() public List PerformAggregation() { - DotNetEnv.Env.TraversePath().Load(); - string uri = DotNetEnv.Env.GetString("CONNECTION_STRING", "Env variable not found. Verify you have a .env file with a valid connection string."); - //var uri = "mongodb://localhost:27017"; - var client = new MongoClient(uri); - _aggDB = client.GetDatabase("agg_tutorials_db"); - _orders = _aggDB.GetCollection("orders"); + if (_aggDB == null || _orders == null) + { + throw new InvalidOperationException("You must call LoadSampleData before performing aggregation."); + } // :snippet-start: match var results = _orders.Aggregate() diff --git a/usage-examples/csharp/driver/Tests/GroupTotalTest.cs b/usage-examples/csharp/driver/Tests/GroupTotalTest.cs index 46b4c95..6d8f02d 100644 --- a/usage-examples/csharp/driver/Tests/GroupTotalTest.cs +++ b/usage-examples/csharp/driver/Tests/GroupTotalTest.cs @@ -4,27 +4,26 @@ namespace Tests; public class GroupTotalTest { + private GroupTotal _example; [SetUp] public void Setup() { - var obj = new GroupTotal(); - obj.SeedData(); + _example = new GroupTotal(); + _example.LoadSampleData(); } [Test] public void TestOutputMatchesDocs() { - var obj = new GroupTotal(); - var results = obj.PerformAggregation(); + var results = _example.PerformAggregation(); - DotNetEnv.Env.TraversePath().Load(); - string solutionRoot = DotNetEnv.Env.GetString("SOLUTION_ROOT", "Env variable not found. Verify you have a .env file with a valid connection string."); - string outputLocation = "Examples/Aggregation/GroupTotalOutput.txt"; - string fullPath = Path.Combine(solutionRoot, outputLocation); + var solutionRoot = DotNetEnv.Env.GetString("SOLUTION_ROOT", "Env variable not found. Verify you have a .env file with a valid connection string."); + var outputLocation = "Examples/Aggregation/GroupTotalOutput.txt"; + var fullPath = Path.Combine(solutionRoot, outputLocation); var fileData = TestUtils.ReadBsonDocumentsFromFile(fullPath); - Assert.That(results.Count, Is.EqualTo(fileData.Length), "Result count does not match output example length."); - for (int i = 0; i < fileData.Length; i++) + Assert.That(results.Count, Is.EqualTo(fileData.Length), $"Result count {results.Count} does not match output example length {fileData.Length}."); + for (var i = 0; i < fileData.Length; i++) { Assert.That(fileData[i], Is.EqualTo(results[i]), $"Mismatch at index {i}: expected {fileData[i]}, got {results[i]}."); } diff --git a/usage-examples/csharp/driver/Tests/TestSuiteSetup.cs b/usage-examples/csharp/driver/Tests/TestSuiteSetup.cs new file mode 100644 index 0000000..29e4166 --- /dev/null +++ b/usage-examples/csharp/driver/Tests/TestSuiteSetup.cs @@ -0,0 +1,13 @@ +namespace Tests; + +using DotNetEnv; + +[SetUpFixture] +public class TestSuiteSetup +{ + [OneTimeSetUp] + public void GlobalSetup() + { + Env.TraversePath().Load(); + } +}