diff --git a/DEPLOYMENT.md b/DEPLOYMENT.md index 76864c0..8e20101 100644 --- a/DEPLOYMENT.md +++ b/DEPLOYMENT.md @@ -8,12 +8,12 @@ are passing, and you're happy with the state of things... 1. Create a branch named `release` 1. Update [`ReleaseNotes.md`](ReleaseNotes.md), following the existing format -1. Bump the version number in [`SolutionInfo.cs`](SolutionInfo.cs) and the `.nuspec` and `appveyor.yml` files (if required) +1. Bump the version number in [`Directory.build.props`](Directory.build.props) and [`appveyor.yml`](appveyor.yml) 1. Push the branch to GitHub and create a pull request -1. Run `.\build CreatePackages` to create the NuGet packages (locally) for the new version +1. If the build succeeds, accept the pull request +1. Create and push a tag from the new HEAD `git tag v#.#.#` and `git push --tags` +1. Create the NuGet packages (in the local solution root) for the new version: `dotnet pack --output ..\` 1. Test the NuGet packages! [How to install NuGet package locally](http://stackoverflow.com/questions/10240029/how-to-install-a-nuget-package-nupkg-file-locally) -1. If satisfied with the release, push the new packages up to NuGet -1. Accept the pull request -1. Create a tag `git tag v#.#.#`. For example, to create a tag for 1.0.0 `git tag v1.0.0` 1. [Create a new release](https://help.github.com/articles/creating-releases) using the tag you just created and pasting in the release notes you just wrote up. Attach a copy of the latest `.nupkg` files generated above. +1. Push the new packages up to NuGet `dotnet nuget push` diff --git a/Directory.build.props b/Directory.build.props new file mode 100644 index 0000000..bb9a026 --- /dev/null +++ b/Directory.build.props @@ -0,0 +1,11 @@ + + + City of Santa Monica, CA + City of Santa Monica, CA + Copyright 2019 City of Santa Monica, CA + SODA + https://github.com/CityofSantaMonica/SODA.NET + MIT + 0.9.0 + + \ No newline at end of file diff --git a/Net45.SODA.Tests/Net45.SODA.Tests.csproj b/Net45.SODA.Tests/Net45.SODA.Tests.csproj new file mode 100644 index 0000000..c08b6f0 --- /dev/null +++ b/Net45.SODA.Tests/Net45.SODA.Tests.csproj @@ -0,0 +1,23 @@ + + + + net45 + + false + + Net45.SODA.Tests + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Net45.Utilities.Tests/Net45.Utilities.Tests.csproj b/Net45.Utilities.Tests/Net45.Utilities.Tests.csproj new file mode 100644 index 0000000..667409d --- /dev/null +++ b/Net45.Utilities.Tests/Net45.Utilities.Tests.csproj @@ -0,0 +1,24 @@ + + + + net45 + + false + + Net45.SODA.Utilities.Tests + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/NetCore22.SODA.Tests/NetCore22.SODA.Tests.csproj b/NetCore22.SODA.Tests/NetCore22.SODA.Tests.csproj new file mode 100644 index 0000000..a2a2e0d --- /dev/null +++ b/NetCore22.SODA.Tests/NetCore22.SODA.Tests.csproj @@ -0,0 +1,23 @@ + + + + netcoreapp2.2 + + false + + NetCore22.SODA.Tests + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/NetCore22.Utilities.Tests/NetCore22.Utilities.Tests.csproj b/NetCore22.Utilities.Tests/NetCore22.Utilities.Tests.csproj new file mode 100644 index 0000000..748c959 --- /dev/null +++ b/NetCore22.Utilities.Tests/NetCore22.Utilities.Tests.csproj @@ -0,0 +1,25 @@ + + + + netcoreapp2.2 + + false + + NetCore22.SODA.Utilities.Tests + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/ReleaseNotes.md b/ReleaseNotes.md index 768926e..c7b6dcf 100644 --- a/ReleaseNotes.md +++ b/ReleaseNotes.md @@ -1,3 +1,9 @@ +### New in 0.9.0 (Released 2019/07/24) + +New features + + - Support for .NET Core 2.2 + ### New in 0.8.0 (Released 2017/12/06) Bug fixes diff --git a/SODA.Tests/HumanAddressTests.cs b/SODA.Tests/HumanAddressTests.cs index 1e6a862..0acecab 100644 --- a/SODA.Tests/HumanAddressTests.cs +++ b/SODA.Tests/HumanAddressTests.cs @@ -28,11 +28,10 @@ public void New_Deserializes_Valid_HumanAddress_Json() [TestCase("not json")] [TestCase(@"{""not"":""a"",""human"":""address""}")] - [ExpectedException(typeof(ArgumentOutOfRangeException))] [Category("HumanAddress")] public void New_Throws_ArgumentOutOfRangeException_For_Invalid_HumanAddress_Json(string input) { - new HumanAddress(input); + Assert.That(() => new HumanAddress(input), Throws.TypeOf()); } [Test] diff --git a/SODA.Tests/PhoneColumnTest.cs b/SODA.Tests/PhoneColumnTest.cs index 5b284a8..7344380 100644 --- a/SODA.Tests/PhoneColumnTest.cs +++ b/SODA.Tests/PhoneColumnTest.cs @@ -88,11 +88,10 @@ public void New_Deserializes_PhoneColumn_For_No_Type_Json() [TestCase("not json")] [TestCase(@"{""not"":""a"",""valid"":""phone""}")] - [ExpectedException(typeof(ArgumentOutOfRangeException))] [Category("PhoneColumn")] public void New_Throws_ArgumentOutOfRangeException_For_Invalid_PhoneColumn_Json(string input) { - new PhoneColumn(input); + Assert.That(() => new PhoneColumn(input), Throws.TypeOf()); } } } diff --git a/SODA.Tests/Properties/AssemblyInfo.cs b/SODA.Tests/Properties/AssemblyInfo.cs deleted file mode 100644 index 7bd4013..0000000 --- a/SODA.Tests/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,36 +0,0 @@ -using System.Reflection; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; - -// General Information about an assembly is controlled through the following -// set of attributes. Change these attribute values to modify the information -// associated with an assembly. -[assembly: AssemblyTitle("SODA.Tests")] -[assembly: AssemblyDescription("Test project for the SODA library.")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("City of Santa Monica")] -[assembly: AssemblyProduct("SODA.Tests")] -[assembly: AssemblyCopyright("Copyright © City of Santa Monica 2014")] -[assembly: AssemblyTrademark("")] -[assembly: AssemblyCulture("")] - -// Setting ComVisible to false makes the types in this assembly not visible -// to COM components. If you need to access a type in this assembly from -// COM, set the ComVisible attribute to true on that type. -[assembly: ComVisible(false)] - -// The following GUID is for the ID of the typelib if this project is exposed to COM -[assembly: Guid("7f9cf47c-8168-48eb-82b3-a82249c0346e")] - -// Version information for an assembly consists of the following four values: -// -// Major Version -// Minor Version -// Build Number -// Revision -// -// You can specify all the values or you can default the Build and Revision Numbers -// by using the '*' as shown below: -// [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("1.0.0.0")] -[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/SODA.Tests/ResourceTests.cs b/SODA.Tests/ResourceTests.cs index 8989ad1..c7496d1 100644 --- a/SODA.Tests/ResourceTests.cs +++ b/SODA.Tests/ResourceTests.cs @@ -70,11 +70,10 @@ public void New_Gets_Metadata_Identifier() [TestCase(StringMocks.EmptyInput)] [TestCase(StringMocks.NullInput)] - [ExpectedException(typeof(ArgumentException))] [Category("Resource")] public void GetRow_With_Invalid_RowId_Throws_ArugmentException(string input) { - new Resource(mockMetadata).GetRow(input); + Assert.That(() => new Resource(mockMetadata).GetRow(input), Throws.TypeOf()); } } } diff --git a/SODA.Tests/SODA.Tests.csproj b/SODA.Tests/SODA.Tests.csproj deleted file mode 100644 index a82370c..0000000 --- a/SODA.Tests/SODA.Tests.csproj +++ /dev/null @@ -1,122 +0,0 @@ - - - - Debug - AnyCPU - {6872AC23-29E5-4EDB-A826-A3FC35AAFDA0} - Library - Properties - SODA.Tests - SODA.Tests - v4.5 - 512 - {3AC096D0-A1C2-E12C-1390-A8335801FDAB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} - 10.0 - $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) - $(ProgramFiles)\Common Files\microsoft shared\VSTT\$(VisualStudioVersion)\UITestExtensionPackages - False - UnitTest - SAK - SAK - SAK - SAK - - ..\ - - - true - full - false - bin\Debug\ - DEBUG;TRACE - prompt - 4 - false - - - pdbonly - true - bin\Release\ - TRACE - prompt - 4 - false - - - - - False - ..\packages\NUnit.2.6.4\lib\nunit.framework.dll - - - - 3.5 - - - - - - - - - - - - - - - - Code - - - - - - - - - Code - - - - - - - - - - {837ebdd7-eb58-44f8-834b-f2903a05a16e} - SODA - - - - - - - - - - False - - - False - - - False - - - False - - - - - - - - \ No newline at end of file diff --git a/SODA.Tests/SODA.Tests.projitems b/SODA.Tests/SODA.Tests.projitems new file mode 100644 index 0000000..b90e2eb --- /dev/null +++ b/SODA.Tests/SODA.Tests.projitems @@ -0,0 +1,28 @@ + + + + $(MSBuildAllProjects);$(MSBuildThisFileFullPath) + true + 1112171d-6a3f-49f6-818a-fb44195ac837 + + + SODA.Tests + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/SODA.Tests/SODA.Tests.shproj b/SODA.Tests/SODA.Tests.shproj new file mode 100644 index 0000000..61ec44e --- /dev/null +++ b/SODA.Tests/SODA.Tests.shproj @@ -0,0 +1,13 @@ + + + + 1112171d-6a3f-49f6-818a-fb44195ac837 + 14.0 + + + + + + + + diff --git a/SODA.Tests/SodaClientTests.cs b/SODA.Tests/SodaClientTests.cs index ad7a289..1f569f9 100644 --- a/SODA.Tests/SodaClientTests.cs +++ b/SODA.Tests/SodaClientTests.cs @@ -22,14 +22,13 @@ public void TestSetup() exampleUri = new Uri(exampleUrl); mockClient = new SodaClient(StringMocks.Host, StringMocks.NonEmptyInput); } - + [TestCase(StringMocks.NullInput)] [TestCase(StringMocks.EmptyInput)] - [ExpectedException(typeof(ArgumentException))] [Category("SodaClient")] public void New_With_Empty_Host_Throws_ArgumentException(string input) { - new SodaClient(input, StringMocks.Host); + Assert.That(() => new SodaClient(input, StringMocks.Host), Throws.TypeOf()); } [TestCase("host.com")] @@ -69,42 +68,38 @@ public void New_With_Username_Gets_Username() [TestCase(StringMocks.NullInput)] [TestCase(StringMocks.EmptyInput)] [TestCase(StringMocks.NonEmptyInput)] - [ExpectedException(typeof(ArgumentOutOfRangeException))] [Category("SodaClient")] public void GetMetadata_With_Invalid_ResourceId_Throws_ArgumentOutOfRangeException(string input) { - mockClient.GetMetadata(input); + Assert.That(() => mockClient.GetMetadata(input), Throws.TypeOf()); } [TestCase(-100)] [TestCase(-1)] [TestCase(0)] - [ExpectedException(typeof(ArgumentOutOfRangeException))] [Category("SodaClient")] public void GetMetadataPage_With_NonPositive_Page_Throws_ArgumentOutOfRangeException(int input) { //the call to ToList ensures the IEnumerable is evaluated - mockClient.GetMetadataPage(input).ToList(); + Assert.That(() => mockClient.GetMetadataPage(input).ToList(), Throws.TypeOf()); } [TestCase(StringMocks.NullInput)] [TestCase(StringMocks.EmptyInput)] [TestCase(StringMocks.NonEmptyInput)] - [ExpectedException(typeof(ArgumentOutOfRangeException))] [Category("SodaClient")] public void GetResource_With_Invalid_ResourceId_Throws_ArgumentOutOfRangeException(string input) { - mockClient.GetResource(input); + Assert.That(() => mockClient.GetResource(input), Throws.TypeOf()); } [TestCase(StringMocks.NullInput)] [TestCase(StringMocks.EmptyInput)] [TestCase(StringMocks.NonEmptyInput)] - [ExpectedException(typeof(ArgumentOutOfRangeException))] [Category("SodaClient")] public void Query_With_Invalid_ResourceId_Throws_ArgumentOutOfRangeException(string input) { - mockClient.Query(new SoqlQuery(), input); + Assert.That(() => mockClient.Query(new SoqlQuery(), input), Throws.TypeOf()); } [Test] @@ -118,7 +113,7 @@ public void Query_With_UndefinedLimit_UsesMaximum() { mockClient.Query(query, StringMocks.ResourceId); } - catch (WebException) + catch (InvalidOperationException) { //pass } @@ -128,47 +123,42 @@ public void Query_With_UndefinedLimit_UsesMaximum() } [Test] - [ExpectedException(typeof(ArgumentOutOfRangeException))] [Category("SodaClient")] public void Upsert_With_String_And_SodaDataFormat_XML_Throws_ArgumentOutOfRangeException() { - mockClient.Upsert(String.Empty, SodaDataFormat.XML, StringMocks.ResourceId); + Assert.That(() => mockClient.Upsert(String.Empty, SodaDataFormat.XML, StringMocks.ResourceId), Throws.TypeOf()); } [Test] - [ExpectedException(typeof(InvalidOperationException))] [Category("SodaClient")] public void Upsert_With_String_And_SodaDataFormat_Using_Anonymous_Client_Throws_InvalidOperationException() { - mockClient.Upsert(String.Empty, SodaDataFormat.JSON, StringMocks.ResourceId); + Assert.That(() => mockClient.Upsert(String.Empty, SodaDataFormat.JSON, StringMocks.ResourceId), Throws.TypeOf()); } [TestCase(StringMocks.NullInput)] [TestCase(StringMocks.EmptyInput)] [TestCase(StringMocks.NonEmptyInput)] - [ExpectedException(typeof(ArgumentOutOfRangeException))] [Category("SodaClient")] public void Upsert_With_Entities_And_Invalid_ResourceId_Throws_ArgumentOutOfRangeException(string input) { IEnumerable payload = Enumerable.Empty(); - mockClient.Upsert(payload, input); + Assert.That(() => mockClient.Upsert(payload, input), Throws.TypeOf()); } [Test] - [ExpectedException(typeof(InvalidOperationException))] [Category("SodaClient")] public void Upsert_With_Entities_Using_Anonymous_Client_Throws_InvalidOperationException() { IEnumerable payload = Enumerable.Empty(); - mockClient.Upsert(payload, StringMocks.ResourceId); + Assert.That(() => mockClient.Upsert(payload, StringMocks.ResourceId), Throws.TypeOf()); } [TestCase(StringMocks.NullInput)] [TestCase(StringMocks.EmptyInput)] [TestCase(StringMocks.NonEmptyInput)] - [ExpectedException(typeof(ArgumentOutOfRangeException))] [Category("SodaClient")] public void BatchUpsert_With_Entities_And_BatchSize_And_BreakFunction_And_Invalid_ResourceId_Throws_ArgumentOutOfRangeException(string input) { @@ -176,11 +166,10 @@ public void BatchUpsert_With_Entities_And_BatchSize_And_BreakFunction_And_Invali Func, object, bool> breakFunc = (l, s) => false; //call ToList to ensure the IEnumerable is executed - mockClient.BatchUpsert(payload, 1, breakFunc, input).ToList(); + Assert.That(() => mockClient.BatchUpsert(payload, 1, breakFunc, input).ToList(), Throws.TypeOf()); } [Test] - [ExpectedException(typeof(InvalidOperationException))] [Category("SodaClient")] public void BatchUpsert_With_Entities_And_BatchSize_And_BreakFunction_Using_Anonymous_Client_Throws_InvalidOperationException() { @@ -188,104 +177,94 @@ public void BatchUpsert_With_Entities_And_BatchSize_And_BreakFunction_Using_Anon Func, object, bool> breakFunc = (l, s) => false; //call ToList to ensure the IEnumerable is executed - mockClient.BatchUpsert(payload, 1, breakFunc, StringMocks.ResourceId).ToList(); + Assert.That(() => mockClient.BatchUpsert(payload, 1, breakFunc, StringMocks.ResourceId).ToList(), Throws.TypeOf()); } [TestCase(StringMocks.NullInput)] [TestCase(StringMocks.EmptyInput)] [TestCase(StringMocks.NonEmptyInput)] - [ExpectedException(typeof(ArgumentOutOfRangeException))] [Category("SodaClient")] public void BatchUpsert_With_Entities_And_BatchSize_And_Invalid_ResourceId_Throws_ArgumentOutOfRangeException(string input) { IEnumerable payload = Enumerable.Empty(); - mockClient.BatchUpsert(payload, 1, input); + Assert.That(() => mockClient.BatchUpsert(payload, 1, input), Throws.TypeOf()); } [Test] - [ExpectedException(typeof(InvalidOperationException))] [Category("SodaClient")] public void BatchUpsert_With_Entities_And_BatchSize_Using_Anonymous_Client_Throws_InvalidOperationException() { IEnumerable payload = Enumerable.Empty(); - mockClient.BatchUpsert(payload, 1, StringMocks.ResourceId); + Assert.That(() => mockClient.BatchUpsert(payload, 1, StringMocks.ResourceId), Throws.TypeOf()); } [Test] - [ExpectedException(typeof(ArgumentOutOfRangeException))] [Category("SodaClient")] public void Replace_With_String_And_DataFormat_XML_And_ResourceId_Throws_ArgumentOutOfRangeException() { - mockClient.Replace(String.Empty, SodaDataFormat.XML, StringMocks.ResourceId); + Assert.That(() => mockClient.Replace(String.Empty, SodaDataFormat.XML, StringMocks.ResourceId), Throws.TypeOf()); } [TestCase(StringMocks.NullInput)] [TestCase(StringMocks.EmptyInput)] [TestCase(StringMocks.NonEmptyInput)] - [ExpectedException(typeof(ArgumentOutOfRangeException))] [Category("SodaClient")] public void Replace_With_String_And_DataFormat_And_Invalid_ResourceId_Throws_ArgumentOutOfRangeException(string input) { - mockClient.Replace(String.Empty, SodaDataFormat.JSON, input); + Assert.That(() => mockClient.Replace(String.Empty, SodaDataFormat.JSON, input), Throws.TypeOf()); } [Test] - [ExpectedException(typeof(InvalidOperationException))] [Category("SodaClient")] public void Replace_With_String_And_DataFormat_Using_Anonymous_Client_Throws_InvalidOperationException() { - mockClient.Replace(String.Empty, SodaDataFormat.JSON, StringMocks.ResourceId); + Assert.That(() => mockClient.Replace(String.Empty, SodaDataFormat.JSON, StringMocks.ResourceId), Throws.TypeOf()); } [TestCase(StringMocks.NullInput)] [TestCase(StringMocks.EmptyInput)] [TestCase(StringMocks.NonEmptyInput)] - [ExpectedException(typeof(ArgumentOutOfRangeException))] [Category("SodaClient")] public void Replace_With_Entities_And_Invalid_ResourceId_Throws_ArgumentOutOfRangeException(string input) { IEnumerable payload = Enumerable.Empty(); - mockClient.Replace(payload, input); + Assert.That(() => mockClient.Replace(payload, input), Throws.TypeOf()); } [Test] - [ExpectedException(typeof(InvalidOperationException))] [Category("SodaClient")] public void Replace_With_Entities_Using_Anonymous_Client_Throws_InvalidOperationException() { IEnumerable payload = Enumerable.Empty(); - mockClient.Replace(payload, StringMocks.ResourceId); + Assert.That(() => mockClient.Replace(payload, StringMocks.ResourceId), Throws.TypeOf()); } [TestCase(StringMocks.NullInput)] [TestCase(StringMocks.EmptyInput)] - [ExpectedException(typeof(ArgumentException))] [Category("SodaClient")] public void DeleteRow_With_Empty_RowId_Throws_ArgumentException(string input) { - mockClient.DeleteRow(input, StringMocks.ResourceId); + Assert.That(() => mockClient.DeleteRow(input, StringMocks.ResourceId), Throws.TypeOf()); } [TestCase(StringMocks.NullInput)] [TestCase(StringMocks.EmptyInput)] [TestCase(StringMocks.NonEmptyInput)] - [ExpectedException(typeof(ArgumentOutOfRangeException))] [Category("SodaClient")] public void DeleteRow_With_Invalid_ResourceId_Throws_ArgumentOutOfRangeException(string input) { - mockClient.DeleteRow(StringMocks.NonEmptyInput, input); + Assert.That(() => mockClient.DeleteRow(StringMocks.NonEmptyInput, input), Throws.TypeOf()); } [Test] - [ExpectedException(typeof(InvalidOperationException))] [Category("SodaClient")] public void DeleteRow_Using_Anonymous_Client_Throws_InvalidOperationException() { - mockClient.DeleteRow(StringMocks.NonEmptyInput, StringMocks.ResourceId); + Assert.That(() => mockClient.DeleteRow(StringMocks.NonEmptyInput, StringMocks.ResourceId), Throws.TypeOf()); } } } \ No newline at end of file diff --git a/SODA.Tests/SodaRequestTests.cs b/SODA.Tests/SodaRequestTests.cs index ceb5538..3aa8085 100644 --- a/SODA.Tests/SodaRequestTests.cs +++ b/SODA.Tests/SodaRequestTests.cs @@ -2,6 +2,8 @@ using SODA.Tests.Mocks; using System; using System.Net; +using System.Net.Http; +using System.Net.Http.Headers; using System.Text; namespace SODA.Tests @@ -33,8 +35,11 @@ public void New_Disables_Unsupported_Protocols() [Category("SodaRequest")] public void New_Enables_Minimum_Protocol() { +#if NETCOREAPP + ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls; +#else ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3 | SecurityProtocolType.Tls; - +#endif var request = new SodaRequest(exampleUri, "GET", null, null, null); Assert.True((ServicePointManager.SecurityProtocol & SecurityProtocolType.Tls11) == SecurityProtocolType.Tls11); @@ -58,7 +63,7 @@ public void New_Returns_Request_With_Specified_Uri() { var request = new SodaRequest(exampleUri, "GET", null, null, null); - Assert.AreEqual(exampleUri, request.webRequest.RequestUri); + Assert.AreEqual(exampleUri, request.RequestMessage.RequestUri); } [TestCase("GET")] @@ -70,16 +75,16 @@ public void New_Returns_Request_With_Specified_Method(string input) { var request = new SodaRequest(exampleUri, input, null, null, null); - StringAssert.AreEqualIgnoringCase(input, request.webRequest.Method); + StringAssert.AreEqualIgnoringCase(input, request.RequestMessage.Method.Method); } [Test] [Category("SodaRequest")] - public void New_Returns_Request_Using_HTTP_1_1() + public void New_Returns_Request_Using_HTTP_1_1_Or_Greater() { var request = new SodaRequest(exampleUri, "GET", null, null, null); - Assert.AreEqual(new Version("1.1"), request.webRequest.ProtocolVersion); + Assert.GreaterOrEqual(request.RequestMessage.Version, new Version("1.1")); } [TestCase("appToken1234")] @@ -88,7 +93,7 @@ public void New_Returns_Request_With_Specified_X_App_Token_Header(string input) { var request = new SodaRequest(exampleUri, "GET", input, null, null); - Assert.AreEqual(input, request.webRequest.Headers["X-App-Token"]); + Assert.IsTrue(System.Linq.Enumerable.Contains(request.Client.DefaultRequestHeaders.GetValues("X-App-Token"), input)); } [Test] @@ -97,7 +102,7 @@ public void New_Returns_Request_With_No_Authorization_Header_When_No_Credentials { var request = new SodaRequest(exampleUri, "GET", null, null, null); - Assert.IsNull(request.webRequest.Headers["Authorization"]); + Assert.IsFalse(request.Client.DefaultRequestHeaders.Contains("Authorization")); } [Test] @@ -106,11 +111,11 @@ public void New_Returns_Request_With_Basic_Authorization_Header_From_Specified_C { string username = "username"; string password = "password"; - string expected = String.Format("Basic {0}", Convert.ToBase64String(Encoding.UTF8.GetBytes(String.Format("{0}:{1}", username, password)))); + var expected = new AuthenticationHeaderValue("Basic", Convert.ToBase64String(Encoding.UTF8.GetBytes(String.Format("{0}:{1}", username, password)))); var request = new SodaRequest(exampleUri, "GET", null, username, password); - Assert.AreEqual(expected, request.webRequest.Headers["Authorization"]); + Assert.AreEqual(expected, request.Client.DefaultRequestHeaders.Authorization); } [TestCase("GET")] @@ -122,7 +127,7 @@ public void New_With_JSON_DataFormat_Sets_Accept_Header(string input) { var request = new SodaRequest(exampleUri, input, null, null, null, SodaDataFormat.JSON); - Assert.AreEqual("application/json", request.webRequest.Accept); + Assert.IsTrue(request.Client.DefaultRequestHeaders.Accept.Contains(new MediaTypeWithQualityHeaderValue("application/json"))); } [TestCase("POST")] @@ -131,9 +136,9 @@ public void New_With_JSON_DataFormat_Sets_Accept_Header(string input) [Category("SodaRequest")] public void New_Non_GET_With_JSON_DataFormat_Sets_ContentType_Header(string input) { - var request = new SodaRequest(exampleUri, input, null, null, null, SodaDataFormat.JSON); + var request = new SodaRequest(exampleUri, input, null, null, null, SodaDataFormat.JSON, "{}"); - Assert.AreEqual("application/json", request.webRequest.ContentType); + Assert.AreEqual("application/json", request.RequestMessage.Content.Headers.ContentType.MediaType); } [Test] @@ -142,7 +147,7 @@ public void New_GET_With_CSV_DataFormat_Sets_Accept_Header() { var request = new SodaRequest(exampleUri, "GET", null, null, null, SodaDataFormat.CSV); - Assert.AreEqual("text/csv", request.webRequest.Accept); + Assert.IsTrue(request.Client.DefaultRequestHeaders.Accept.Contains(new MediaTypeWithQualityHeaderValue("text/csv"))); } [TestCase("POST")] @@ -150,9 +155,9 @@ public void New_GET_With_CSV_DataFormat_Sets_Accept_Header() [Category("SodaRequest")] public void New_POST_PUT_With_CSV_DataFormat_Sets_ContentType_Header(string input) { - var request = new SodaRequest(exampleUri, input, null, null, null, SodaDataFormat.CSV); + var request = new SodaRequest(exampleUri, input, null, null, null, SodaDataFormat.CSV, "1,1"); - Assert.AreEqual("text/csv", request.webRequest.ContentType); + Assert.AreEqual("text/csv", request.RequestMessage.Content.Headers.ContentType.MediaType); } [Test] @@ -161,18 +166,16 @@ public void New_GET_With_XML_DataFormat_Sets_Accept_Header() { var request = new SodaRequest(exampleUri, "GET", null, null, null, SodaDataFormat.XML); - Assert.AreEqual("application/rdf+xml", request.webRequest.Accept); + Assert.IsTrue(request.Client.DefaultRequestHeaders.Accept.Contains(new MediaTypeWithQualityHeaderValue("application/rdf+xml"))); } [Test] [Category("SodaRequest")] - public void New_Returns_Request_With_Unset_ContentLength_For_Empty_Payload() + public void New_Returns_Request_With_Unset_Content_For_Empty_Payload() { var request = new SodaRequest(exampleUri, "POST", null, null, null); - //The default is -1, which indicates the property has not been set and that there is no request data to send. - //http://msdn.microsoft.com/en-us/library/system.net.httpwebrequest.contentlength(v=vs.110).aspx - Assert.AreEqual(-1, request.webRequest.ContentLength); + Assert.IsNull(request.RequestMessage.Content); } [Test] @@ -184,18 +187,18 @@ public void New_Sets_ContentLength_Header_To_Payload_Bytes_Length() var request = new SodaRequest(exampleUri, "POST", null, null, null, SodaDataFormat.JSON, payload); - Assert.AreEqual(payloadBytes.Length, request.webRequest.ContentLength); + Assert.AreEqual(payloadBytes.Length, request.RequestMessage.Content.Headers.ContentLength); } [Test] [Category("SodaRequest")] public void New_Sets_Timeout_To_HttpWebRequest_Timeout_If_Not_Given() { - var newHttpRequest = WebRequest.Create(exampleUri) as HttpWebRequest; + var client = new HttpClient(); var request = new SodaRequest(exampleUri, "GET", null, null, null, SodaDataFormat.JSON, null, null); - Assert.AreEqual(newHttpRequest.Timeout, request.webRequest.Timeout); + Assert.AreEqual(client.Timeout, request.Client.Timeout); } [Test] @@ -205,12 +208,12 @@ public void New_Sets_Timeout_To_Given_Timeout() int timeout = 100; var request = new SodaRequest(exampleUri, "GET", null, null, null, SodaDataFormat.JSON, null, timeout); + var timeoutspan = new TimeSpan(0, 0, 0, 0, timeout); - Assert.AreEqual(timeout, request.webRequest.Timeout); + Assert.AreEqual(timeoutspan, request.Client.Timeout); } [Test] - [ExpectedException(typeof(InvalidOperationException))] [Category("SodaRequest")] public void ParseResponse_ReThrows_JSON_Parse_Exception_As_InvalidOperationException() { @@ -218,7 +221,7 @@ public void ParseResponse_ReThrows_JSON_Parse_Exception_As_InvalidOperationExcep var request = new SodaRequest(exampleUri, "GET", null, null, null, SodaDataFormat.JSON); //we get html5 back from example.com //it can't be parsed to a json string - request.ParseResponse().ToLower(); + Assert.That(() => request.ParseResponse().ToLower(), Throws.TypeOf()); } [Test] @@ -226,9 +229,9 @@ public void ParseResponse_ReThrows_JSON_Parse_Exception_As_InvalidOperationExcep public void ParseResponse_Can_GET_Example() { var request = new SodaRequest(exampleUri, "GET", null, null, null, SodaDataFormat.XML); - + string result = request.ParseResponse().ToLower(); - + StringAssert.Contains("", result); StringAssert.Contains("", result); @@ -242,21 +245,22 @@ public void ParseResponse_Can_GET_Example() [TestCase("PUT")] [TestCase("DELETE")] [Category("SodaRequest")] - public void ParseResponse_Non_GET_Sends_Request_To_Example_Using_Method(string input) + public void ParseResponse_Non_GET_Sends_Request_To_Example_Using_Method(string method) { - var request = new SodaRequest(exampleUri, input, null, null, null); + var request = new SodaRequest(exampleUri, method, null, null, null); string result; try { result = request.ParseResponse(); } - catch (WebException webException) + catch(InvalidOperationException) { - var webResponse = webException.Response as HttpWebResponse; - - Assert.AreEqual(exampleUri, webResponse.ResponseUri); - StringAssert.AreEqualIgnoringCase(input, webResponse.Method); + } + finally + { + Assert.AreEqual(exampleUri, request.ResponseMessage.RequestMessage.RequestUri); + StringAssert.AreEqualIgnoringCase(method, request.ResponseMessage.RequestMessage.Method.Method); } } } diff --git a/SODA.Tests/SodaUriTests.cs b/SODA.Tests/SodaUriTests.cs index e0c1372..3b32cc9 100644 --- a/SODA.Tests/SodaUriTests.cs +++ b/SODA.Tests/SodaUriTests.cs @@ -14,7 +14,7 @@ public void All_Methods_Return_Uri_With_Socrata_Domain_As_Host() { Uri uri = SodaUri.ForMetadata(StringMocks.Host, StringMocks.ResourceId); StringAssert.AreEqualIgnoringCase(StringMocks.Host, uri.Host); - + uri = null; uri = SodaUri.ForMetadataList(StringMocks.Host, 1); StringAssert.AreEqualIgnoringCase(StringMocks.Host, uri.Host); @@ -34,7 +34,7 @@ public void All_Methods_Return_Uri_With_Socrata_Domain_As_Host() uri = null; uri = SodaUri.ForQuery(StringMocks.Host, StringMocks.ResourceId, new SoqlQuery()); StringAssert.AreEqualIgnoringCase(StringMocks.Host, uri.Host); - + uri = null; uri = SodaUri.ForCategoryPage(StringMocks.Host, StringMocks.NonEmptyInput); StringAssert.AreEqualIgnoringCase(StringMocks.Host, uri.Host); @@ -50,7 +50,7 @@ public void All_Methods_Return_Uri_Using_HTTPS() uri = null; uri = SodaUri.ForMetadata("http://" + StringMocks.Host, StringMocks.ResourceId); StringAssert.AreEqualIgnoringCase(Uri.UriSchemeHttps, uri.Scheme); - + uri = null; uri = SodaUri.ForMetadataList(StringMocks.Host, 1); StringAssert.AreEqualIgnoringCase(Uri.UriSchemeHttps, uri.Scheme); @@ -90,7 +90,7 @@ public void All_Methods_Return_Uri_Using_HTTPS() uri = null; uri = SodaUri.ForQuery("http://" + StringMocks.Host, StringMocks.ResourceId, new SoqlQuery()); StringAssert.AreEqualIgnoringCase(Uri.UriSchemeHttps, uri.Scheme); - + uri = null; uri = SodaUri.ForCategoryPage(StringMocks.Host, StringMocks.NonEmptyInput); StringAssert.AreEqualIgnoringCase(Uri.UriSchemeHttps, uri.Scheme); @@ -102,21 +102,19 @@ public void All_Methods_Return_Uri_Using_HTTPS() [TestCase(StringMocks.NullInput)] [TestCase(StringMocks.EmptyInput)] - [ExpectedException(typeof(ArgumentException))] [Category("SodaUri")] public void ForMetadata_With_Empty_Host_Throws_ArgumentException(string input) { - SodaUri.ForMetadata(input, StringMocks.NonEmptyInput); + Assert.That(() => SodaUri.ForMetadata(input, StringMocks.NonEmptyInput), Throws.TypeOf()); } [TestCase(StringMocks.NullInput)] [TestCase(StringMocks.EmptyInput)] [TestCase(StringMocks.NonEmptyInput)] - [ExpectedException(typeof(ArgumentOutOfRangeException))] [Category("SodaUri")] public void ForMetadata_With_Invalid_ResourceId_Throws_ArgumentOutOfRangeException(string input) { - SodaUri.ForMetadata(StringMocks.Host, input); + Assert.That(() => SodaUri.ForMetadata(StringMocks.Host, input), Throws.TypeOf()); } [Test] @@ -130,21 +128,19 @@ public void ForMetadata_With_Valid_Arguments_Creates_Metadata_Uri() [TestCase(StringMocks.NullInput)] [TestCase(StringMocks.EmptyInput)] - [ExpectedException(typeof(ArgumentException))] [Category("SodaUri")] public void ForMetadataList_With_Empty_Host_Throws_ArgumentException(string input) { - SodaUri.ForMetadataList(input, 1); + Assert.That(() => SodaUri.ForMetadataList(input, 1), Throws.TypeOf()); } [TestCase(-100)] [TestCase(-1)] [TestCase(0)] - [ExpectedException(typeof(ArgumentOutOfRangeException))] [Category("SodaUri")] public void ForMetadataList_With_Page_Less_Than_1_Throws_ArugmentOutOfRangeException(int page) { - SodaUri.ForMetadataList(StringMocks.Host, page); + Assert.That(() => SodaUri.ForMetadataList(StringMocks.Host, page), Throws.TypeOf()); } [TestCase(1)] @@ -154,28 +150,26 @@ public void ForMetadataList_With_Page_Less_Than_1_Throws_ArugmentOutOfRangeExcep public void ForMetadataList_With_Valid_Arguments_Creates_MetadataList_Uri(int page) { var uri = SodaUri.ForMetadataList(StringMocks.Host, page); - + StringAssert.AreEqualIgnoringCase("/views", uri.LocalPath); StringAssert.AreEqualIgnoringCase(String.Format("?page={0}", page), uri.Query); } [TestCase(StringMocks.NullInput)] [TestCase(StringMocks.EmptyInput)] - [ExpectedException(typeof(ArgumentException))] [Category("SodaUri")] public void ForResourceAPI_With_Empty_Host_Throws_ArgumentException(string input) { - SodaUri.ForResourceAPI(input, StringMocks.ResourceId); + Assert.That(() => SodaUri.ForResourceAPI(input, StringMocks.ResourceId), Throws.TypeOf()); } [TestCase(StringMocks.NullInput)] [TestCase(StringMocks.EmptyInput)] [TestCase(StringMocks.NonEmptyInput)] - [ExpectedException(typeof(ArgumentOutOfRangeException))] [Category("SodaUri")] public void ForResourceAPI_With_Invalid_ResourceId_Throws_ArgumentOutOfRangeException(string input) { - SodaUri.ForResourceAPI(StringMocks.Host, input); + Assert.That(() => SodaUri.ForResourceAPI(StringMocks.Host, input), Throws.TypeOf()); } [Test] @@ -186,7 +180,7 @@ public void ForResourceAPI_With_Valid_Arguments_Creates_ResourceAPI_Uri() StringAssert.AreEqualIgnoringCase(String.Format("/resource/{0}", StringMocks.ResourceId), uri.LocalPath); uri = null; - string rowId = "rowId"; + string rowId = "rowId"; uri = SodaUri.ForResourceAPI(StringMocks.Host, StringMocks.ResourceId, rowId); StringAssert.AreEqualIgnoringCase(String.Format("/resource/{0}/{1}", StringMocks.ResourceId, rowId), uri.LocalPath); @@ -194,21 +188,19 @@ public void ForResourceAPI_With_Valid_Arguments_Creates_ResourceAPI_Uri() [TestCase(StringMocks.NullInput)] [TestCase(StringMocks.EmptyInput)] - [ExpectedException(typeof(ArgumentException))] [Category("SodaUri")] public void ForResourcePage_With_Empty_Host_Throws_ArgumentException(string input) { - SodaUri.ForResourcePage(input, StringMocks.ResourceId); + Assert.That(() => SodaUri.ForResourcePage(input, StringMocks.ResourceId), Throws.TypeOf()); } [TestCase(StringMocks.NullInput)] [TestCase(StringMocks.EmptyInput)] [TestCase(StringMocks.NonEmptyInput)] - [ExpectedException(typeof(ArgumentOutOfRangeException))] [Category("SodaUri")] public void ForResourcePage_With_Invalid_ResourceId_Throws_ArgumentOutOfRangeException(string input) { - SodaUri.ForResourcePage(StringMocks.Host, input); + Assert.That(() => SodaUri.ForResourcePage(StringMocks.Host, input), Throws.TypeOf()); } [Test] @@ -222,21 +214,19 @@ public void ForResourcePage_With_Valid_Arguments_Creates_ResourcePermalink_Uri() [TestCase(StringMocks.NullInput)] [TestCase(StringMocks.EmptyInput)] - [ExpectedException(typeof(ArgumentException))] [Category("SodaUri")] public void ForResourceAboutPage_With_Empty_Host_Throws_ArgumentException(string input) { - SodaUri.ForResourceAboutPage(input, StringMocks.ResourceId); + Assert.That(() => SodaUri.ForResourceAboutPage(input, StringMocks.ResourceId), Throws.TypeOf()); } [TestCase(StringMocks.NullInput)] [TestCase(StringMocks.EmptyInput)] [TestCase(StringMocks.NonEmptyInput)] - [ExpectedException(typeof(ArgumentOutOfRangeException))] [Category("SodaUri")] public void ForResourceAboutPage_With_Invalid_ResourceId_Throws_ArgumentOutOfRangeException(string input) { - SodaUri.ForResourceAboutPage(StringMocks.Host, input); + Assert.That(() => SodaUri.ForResourceAboutPage(StringMocks.Host, input), Throws.TypeOf()); } [Test] @@ -250,21 +240,19 @@ public void ForResourceAboutPage_With_Valid_Arguments_Creates_ResourcePermalink_ [TestCase(StringMocks.NullInput)] [TestCase(StringMocks.EmptyInput)] - [ExpectedException(typeof(ArgumentException))] [Category("SodaUri")] public void ForResourceAPIPage_With_Empty_Host_Throws_ArgumentException(string input) { - SodaUri.ForResourceAPIPage(input, StringMocks.ResourceId); + Assert.That(() => SodaUri.ForResourceAPIPage(input, StringMocks.ResourceId), Throws.TypeOf()); } [TestCase(StringMocks.NullInput)] [TestCase(StringMocks.EmptyInput)] [TestCase(StringMocks.NonEmptyInput)] - [ExpectedException(typeof(ArgumentOutOfRangeException))] [Category("SodaUri")] public void ForResourceAPIPage_With_Invalid_ResourceId_Throws_ArgumentOutOfRangeException(string input) { - SodaUri.ForResourceAPIPage(StringMocks.Host, input); + Assert.That(() => SodaUri.ForResourceAPIPage(StringMocks.Host, input), Throws.TypeOf()); } [TestCase("http://")] @@ -290,29 +278,26 @@ public void ForResourceAPIPage_With_Valid_Arguments_Creates_ResourceAPIPage_Uri( [TestCase(StringMocks.NullInput)] [TestCase(StringMocks.EmptyInput)] - [ExpectedException(typeof(ArgumentException))] [Category("SodaUri")] public void ForQuery_With_Empty_Host_Throws_ArgumentException(string input) { - SodaUri.ForQuery(input, StringMocks.ResourceId, new SoqlQuery()); + Assert.That(() => SodaUri.ForQuery(input, StringMocks.ResourceId, new SoqlQuery()), Throws.TypeOf()); } [TestCase(StringMocks.NullInput)] [TestCase(StringMocks.EmptyInput)] [TestCase(StringMocks.NonEmptyInput)] - [ExpectedException(typeof(ArgumentOutOfRangeException))] [Category("SodaUri")] public void ForQuery_With_Invalid_ResourceId_Throws_ArgumentOutOfRangeException(string input) { - SodaUri.ForQuery(StringMocks.Host, input, new SoqlQuery()); + Assert.That(() => SodaUri.ForQuery(StringMocks.Host, input, new SoqlQuery()), Throws.TypeOf()); } [Test] [Category("SodaUri")] - [ExpectedException(typeof(ArgumentNullException))] public void ForQuery_With_Null_SoqlQuery_Throws_ArgumentNullException() { - SodaUri.ForQuery(StringMocks.Host, StringMocks.ResourceId, null); + Assert.That(() => SodaUri.ForQuery(StringMocks.Host, StringMocks.ResourceId, null), Throws.TypeOf()); } [Test] @@ -329,20 +314,18 @@ public void ForQuery_With_Valid_Arguments_Creates_Query_Uri() [TestCase(StringMocks.NullInput)] [TestCase(StringMocks.EmptyInput)] - [ExpectedException(typeof(ArgumentException))] [Category("SodaUri")] public void ForCategoryPage_With_Empty_Host_Throws_ArgumentException(string input) { - SodaUri.ForCategoryPage(input, StringMocks.NonEmptyInput); + Assert.That(() => SodaUri.ForCategoryPage(input, StringMocks.NonEmptyInput), Throws.TypeOf()); } [TestCase(StringMocks.NullInput)] [TestCase(StringMocks.EmptyInput)] - [ExpectedException(typeof(ArgumentException))] [Category("SodaUri")] public void ForCategoryPage_With_Empty_Category_Throws_ArgumentException(string input) { - SodaUri.ForCategoryPage(StringMocks.Host, input); + Assert.That(() => SodaUri.ForCategoryPage(StringMocks.Host, input), Throws.TypeOf()); } [Test] @@ -350,9 +333,9 @@ public void ForCategoryPage_With_Empty_Category_Throws_ArgumentException(string public void ForCategoryPage_With_Valid_Arguments_Creates_CategoryPage_Uri() { string category = "Category"; - + var uri = SodaUri.ForCategoryPage(StringMocks.Host, category); - + StringAssert.AreEqualIgnoringCase(String.Format("/categories/{0}", category), uri.LocalPath); } diff --git a/SODA.Tests/SoqlQueryTests.cs b/SODA.Tests/SoqlQueryTests.cs index f2e58ee..f7e93e5 100644 --- a/SODA.Tests/SoqlQueryTests.cs +++ b/SODA.Tests/SoqlQueryTests.cs @@ -33,11 +33,10 @@ public void Default_Ctor_Has_No_Limit() [TestCase(null)] [TestCase("")] - [ExpectedException(typeof(ArgumentOutOfRangeException))] [Category("SoqlQuery")] public void Query_Ctor_Requires_Query(string query) { - var soql = new SoqlQuery(query); + Assert.That(() => new SoqlQuery(query), Throws.TypeOf()); } [Test] @@ -78,7 +77,7 @@ public void Last_Select_Overwrites_All_Previous() { string[] first = { "first", "second", "last" }; string[] second = { "first", "second" }; - string[] last = { "last" }; + string[] last = { "last" }; string format = String.Format("{0}={{0}}", SoqlQuery.SelectKey); string soql = new SoqlQuery().Select(first) @@ -420,11 +419,10 @@ public void Last_Having_Overwrites_All_Previous() [TestCase(-100)] [TestCase(-1)] [TestCase(0)] - [ExpectedException(typeof(ArgumentOutOfRangeException))] [Category("SoqlQuery")] public void Limit_Less_Than_One_Throws_ArgumentOutOfRangeException(int limit) { - var soql = new SoqlQuery().Limit(limit); + Assert.That(() => new SoqlQuery().Limit(limit), Throws.TypeOf()); } [TestCase(50001)] @@ -447,7 +445,7 @@ public void Last_Limit_Overwrites_All_Previous() int second = 2; int last = 3; string format = String.Format("{0}={{0}}", SoqlQuery.LimitKey); - + string soql = new SoqlQuery().Limit(first) .Limit(second) .Limit(last) @@ -460,11 +458,10 @@ public void Last_Limit_Overwrites_All_Previous() [TestCase(-999)] [TestCase(-1)] - [ExpectedException(typeof(ArgumentOutOfRangeException))] [Category("SoqlQuery")] public void Offset_Less_Than_Zero_Throws_ArgumentOutOfRangeException(int offset) { - var soql = new SoqlQuery().Offset(offset); + Assert.That(() => new SoqlQuery().Offset(offset), Throws.TypeOf()); } [Test] @@ -533,7 +530,7 @@ public void Last_FullTextSearch_Overwrites_All_Previous() string second = "second text"; string last = "last text"; string format = String.Format("{0}={{0}}", SoqlQuery.SearchKey); - + string soql = new SoqlQuery().FullTextSearch(first) .FullTextSearch(second) .FullTextSearch(last) @@ -568,4 +565,4 @@ public void All_Query_Methods_Return_The_Original_Instance() Assert.AreSame(original, search); } } -} +} \ No newline at end of file diff --git a/SODA.Tests/packages.config b/SODA.Tests/packages.config deleted file mode 100644 index c714ef3..0000000 --- a/SODA.Tests/packages.config +++ /dev/null @@ -1,4 +0,0 @@ - - - - \ No newline at end of file diff --git a/SODA.sln b/SODA.sln index da01369..d075090 100644 --- a/SODA.sln +++ b/SODA.sln @@ -1,61 +1,86 @@  Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio 15 -VisualStudioVersion = 15.0.27130.0 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.29102.190 MinimumVisualStudioVersion = 10.0.40219.1 -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SODA", "SODA\SODA.csproj", "{837EBDD7-EB58-44F8-834B-F2903A05A16E}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SODA.Tests", "SODA.Tests\SODA.Tests.csproj", "{6872AC23-29E5-4EDB-A826-A3FC35AAFDA0}" -EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{970C9034-3C0D-47ED-82F5-CCEDD67B7EB0}" ProjectSection(SolutionItems) = preProject .gitattributes = .gitattributes .gitignore = .gitignore appveyor.yml = appveyor.yml - build.cmd = build.cmd CONTRIBUTING.md = CONTRIBUTING.md DEPLOYMENT.md = DEPLOYMENT.md + Directory.build.props = Directory.build.props LICENSE.txt = LICENSE.txt README.md = README.md ReleaseNotes.md = ReleaseNotes.md - SolutionInfo.cs = SolutionInfo.cs EndProjectSection EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Utilities", "Utilities\Utilities.csproj", "{63B7FAD7-5927-417C-AD2A-608D777AD1A7}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SODA", "SODA\SODA.csproj", "{8C71D7E2-8EF0-4D7E-9EEB-06B1458D235E}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tests", "Tests", "{76D1DD9D-B476-4900-A561-18BB7CBAF54F}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Utilities", "Utilities\Utilities.csproj", "{8DA784F1-63B3-40A8-AEF4-833D813E5E54}" +EndProject +Project("{D954291E-2A0B-460D-934E-DC6B0785DB48}") = "SODA.Tests", "SODA.Tests\SODA.Tests.shproj", "{1112171D-6A3F-49F6-818A-FB44195AC837}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Utilities.Tests", "Utilities.Tests\Utilities.Tests.csproj", "{6AAB405A-D32F-4D8B-B491-BDD5088561A7}" +Project("{D954291E-2A0B-460D-934E-DC6B0785DB48}") = "Utilities.Tests", "Utilities.Tests\Utilities.Tests.shproj", "{651FB983-B00B-445A-960B-850D21D17DB0}" EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Utilities", "Utilities", "{C2E27366-ABDF-4FE3-A399-A6792C33D437}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Net45.SODA.Tests", "Net45.SODA.Tests\Net45.SODA.Tests.csproj", "{309FA03E-E032-4547-A83C-389EC450FD1A}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Net45.Utilities.Tests", "Net45.Utilities.Tests\Net45.Utilities.Tests.csproj", "{763FFFCB-49DD-4A86-B5A1-B51EA15CE764}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "NetCore22.SODA.Tests", "NetCore22.SODA.Tests\NetCore22.SODA.Tests.csproj", "{CFAEADE7-EBEA-40F8-9630-C699AA5F8274}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "NetCore22.Utilities.Tests", "NetCore22.Utilities.Tests\NetCore22.Utilities.Tests.csproj", "{02CEA30A-5D25-4F9D-B74E-7CED1EBA84BF}" EndProject Global + GlobalSection(SharedMSBuildProjectFiles) = preSolution + SODA.Tests\SODA.Tests.projitems*{1112171d-6a3f-49f6-818a-fb44195ac837}*SharedItemsImports = 13 + SODA.Tests\SODA.Tests.projitems*{309fa03e-e032-4547-a83c-389ec450fd1a}*SharedItemsImports = 4 + Utilities.Tests\Utilities.Tests.projitems*{651fb983-b00b-445a-960b-850d21d17db0}*SharedItemsImports = 13 + Utilities.Tests\Utilities.Tests.projitems*{763fffcb-49dd-4a86-b5a1-b51ea15ce764}*SharedItemsImports = 4 + EndGlobalSection GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU Release|Any CPU = Release|Any CPU EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution - {837EBDD7-EB58-44F8-834B-F2903A05A16E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {837EBDD7-EB58-44F8-834B-F2903A05A16E}.Debug|Any CPU.Build.0 = Debug|Any CPU - {837EBDD7-EB58-44F8-834B-F2903A05A16E}.Release|Any CPU.ActiveCfg = Release|Any CPU - {837EBDD7-EB58-44F8-834B-F2903A05A16E}.Release|Any CPU.Build.0 = Release|Any CPU - {6872AC23-29E5-4EDB-A826-A3FC35AAFDA0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {6872AC23-29E5-4EDB-A826-A3FC35AAFDA0}.Debug|Any CPU.Build.0 = Debug|Any CPU - {6872AC23-29E5-4EDB-A826-A3FC35AAFDA0}.Release|Any CPU.ActiveCfg = Release|Any CPU - {6872AC23-29E5-4EDB-A826-A3FC35AAFDA0}.Release|Any CPU.Build.0 = Release|Any CPU - {63B7FAD7-5927-417C-AD2A-608D777AD1A7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {63B7FAD7-5927-417C-AD2A-608D777AD1A7}.Debug|Any CPU.Build.0 = Debug|Any CPU - {63B7FAD7-5927-417C-AD2A-608D777AD1A7}.Release|Any CPU.ActiveCfg = Release|Any CPU - {63B7FAD7-5927-417C-AD2A-608D777AD1A7}.Release|Any CPU.Build.0 = Release|Any CPU - {6AAB405A-D32F-4D8B-B491-BDD5088561A7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {6AAB405A-D32F-4D8B-B491-BDD5088561A7}.Debug|Any CPU.Build.0 = Debug|Any CPU - {6AAB405A-D32F-4D8B-B491-BDD5088561A7}.Release|Any CPU.ActiveCfg = Release|Any CPU - {6AAB405A-D32F-4D8B-B491-BDD5088561A7}.Release|Any CPU.Build.0 = Release|Any CPU + {8C71D7E2-8EF0-4D7E-9EEB-06B1458D235E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {8C71D7E2-8EF0-4D7E-9EEB-06B1458D235E}.Debug|Any CPU.Build.0 = Debug|Any CPU + {8C71D7E2-8EF0-4D7E-9EEB-06B1458D235E}.Release|Any CPU.ActiveCfg = Release|Any CPU + {8C71D7E2-8EF0-4D7E-9EEB-06B1458D235E}.Release|Any CPU.Build.0 = Release|Any CPU + {8DA784F1-63B3-40A8-AEF4-833D813E5E54}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {8DA784F1-63B3-40A8-AEF4-833D813E5E54}.Debug|Any CPU.Build.0 = Debug|Any CPU + {8DA784F1-63B3-40A8-AEF4-833D813E5E54}.Release|Any CPU.ActiveCfg = Release|Any CPU + {8DA784F1-63B3-40A8-AEF4-833D813E5E54}.Release|Any CPU.Build.0 = Release|Any CPU + {309FA03E-E032-4547-A83C-389EC450FD1A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {309FA03E-E032-4547-A83C-389EC450FD1A}.Debug|Any CPU.Build.0 = Debug|Any CPU + {309FA03E-E032-4547-A83C-389EC450FD1A}.Release|Any CPU.ActiveCfg = Release|Any CPU + {309FA03E-E032-4547-A83C-389EC450FD1A}.Release|Any CPU.Build.0 = Release|Any CPU + {763FFFCB-49DD-4A86-B5A1-B51EA15CE764}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {763FFFCB-49DD-4A86-B5A1-B51EA15CE764}.Debug|Any CPU.Build.0 = Debug|Any CPU + {763FFFCB-49DD-4A86-B5A1-B51EA15CE764}.Release|Any CPU.ActiveCfg = Release|Any CPU + {763FFFCB-49DD-4A86-B5A1-B51EA15CE764}.Release|Any CPU.Build.0 = Release|Any CPU + {CFAEADE7-EBEA-40F8-9630-C699AA5F8274}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {CFAEADE7-EBEA-40F8-9630-C699AA5F8274}.Debug|Any CPU.Build.0 = Debug|Any CPU + {CFAEADE7-EBEA-40F8-9630-C699AA5F8274}.Release|Any CPU.ActiveCfg = Release|Any CPU + {CFAEADE7-EBEA-40F8-9630-C699AA5F8274}.Release|Any CPU.Build.0 = Release|Any CPU + {02CEA30A-5D25-4F9D-B74E-7CED1EBA84BF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {02CEA30A-5D25-4F9D-B74E-7CED1EBA84BF}.Debug|Any CPU.Build.0 = Debug|Any CPU + {02CEA30A-5D25-4F9D-B74E-7CED1EBA84BF}.Release|Any CPU.ActiveCfg = Release|Any CPU + {02CEA30A-5D25-4F9D-B74E-7CED1EBA84BF}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection GlobalSection(NestedProjects) = preSolution - {63B7FAD7-5927-417C-AD2A-608D777AD1A7} = {C2E27366-ABDF-4FE3-A399-A6792C33D437} - {6AAB405A-D32F-4D8B-B491-BDD5088561A7} = {C2E27366-ABDF-4FE3-A399-A6792C33D437} + {1112171D-6A3F-49F6-818A-FB44195AC837} = {76D1DD9D-B476-4900-A561-18BB7CBAF54F} + {651FB983-B00B-445A-960B-850D21D17DB0} = {76D1DD9D-B476-4900-A561-18BB7CBAF54F} + {309FA03E-E032-4547-A83C-389EC450FD1A} = {76D1DD9D-B476-4900-A561-18BB7CBAF54F} + {763FFFCB-49DD-4A86-B5A1-B51EA15CE764} = {76D1DD9D-B476-4900-A561-18BB7CBAF54F} + {CFAEADE7-EBEA-40F8-9630-C699AA5F8274} = {76D1DD9D-B476-4900-A561-18BB7CBAF54F} + {02CEA30A-5D25-4F9D-B74E-7CED1EBA84BF} = {76D1DD9D-B476-4900-A561-18BB7CBAF54F} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {17A9746D-4584-4AD5-B2FA-2A9EDFC6ED09} diff --git a/SODA/Properties/AssemblyInfo.cs b/SODA/Properties/AssemblyInfo.cs index fb4dca9..179e20d 100644 --- a/SODA/Properties/AssemblyInfo.cs +++ b/SODA/Properties/AssemblyInfo.cs @@ -1,6 +1,4 @@ -using System.Reflection; -using System.Runtime.CompilerServices; +using System.Runtime.CompilerServices; -[assembly: AssemblyTitle("SODA")] -[assembly: AssemblyDescription("Socrata Open Data API client library targeting .NET 4.5 and above.")] -[assembly: InternalsVisibleTo("SODA.Tests")] \ No newline at end of file +[assembly: InternalsVisibleTo("Net45.SODA.Tests")] +[assembly: InternalsVisibleTo("NetCore22.SODA.Tests")] diff --git a/SODA/Resource.cs b/SODA/Resource.cs index 3bcec33..d02252a 100644 --- a/SODA/Resource.cs +++ b/SODA/Resource.cs @@ -1,8 +1,10 @@ using System; using System.Collections.Generic; using System.Linq; +using System.Runtime.CompilerServices; using SODA.Utilities; - +[assembly: InternalsVisibleTo("Net45.Tests")] +[assembly: InternalsVisibleTo("NetCore22.Tests")] namespace SODA { /// diff --git a/SODA/SODA.csproj b/SODA/SODA.csproj index 86685b6..78d1060 100644 --- a/SODA/SODA.csproj +++ b/SODA/SODA.csproj @@ -1,94 +1,20 @@ - - - + + - Debug - AnyCPU - {837EBDD7-EB58-44F8-834B-F2903A05A16E} - Library - Properties - SODA + netstandard2.0;net45 SODA - v4.5 - 512 - SAK - SAK - SAK - SAK - - ..\ - - - true - full - false - bin\Debug\ - DEBUG;TRACE - prompt - 4 - bin\Debug\SODA.XML - - - pdbonly - true - bin\Release\ - TRACE - prompt - 4 - bin\Release\SODA.XML + SODA + Socrata Open Data API client library targeting .NET 4.5 and above. + true + CSM.SodaDotNet + API OpenData Socrata SODA + - - ..\packages\Newtonsoft.Json.7.0.1\lib\net45\Newtonsoft.Json.dll - True - - - - - - - - - - - - - - SolutionInfo.cs - - - - - - - - - - - - - - - - - - - - - Code - - - - - - + + + - - - \ No newline at end of file + + + diff --git a/SODA/SODA.nuspec b/SODA/SODA.nuspec deleted file mode 100644 index 6f22904..0000000 --- a/SODA/SODA.nuspec +++ /dev/null @@ -1,21 +0,0 @@ - - - - CSM.SodaDotNet - $version$ - CSM.SodaDotNet - City of Santa Monica, CA - City of Santa Monica, CA - https://github.com/CityOfSantaMonica/SODA.NET/blob/master/LICENSE.txt - https://github.com/CityOfSantaMonica/SODA.NET - http://www.smgov.net/uploadedImages/Main/colorstd-R.gif - false - $description$ - - Copyright 2017 City of Santa Monica, CA - API OpenData Socrata SODA - - - - - \ No newline at end of file diff --git a/SODA/SodaRequest.cs b/SODA/SodaRequest.cs index 5e962e5..db482cb 100644 --- a/SODA/SodaRequest.cs +++ b/SODA/SodaRequest.cs @@ -1,6 +1,8 @@ using System; using System.IO; using System.Net; +using System.Net.Http; +using System.Net.Http.Headers; using System.Text; using System.Xml; using System.Xml.Serialization; @@ -13,9 +15,19 @@ namespace SODA internal class SodaRequest { /// - /// The underlying HttpWebRequest handled by this SodaRequest + /// The underlying HttpClient handled by this SodaRequest /// - internal HttpWebRequest webRequest { get; private set; } + internal HttpClient Client { get; private set; } + + /// + /// The underlying HttpRequestMessage handled by this SodaRequest + /// + internal HttpRequestMessage RequestMessage { get; private set; } + + /// + /// The underlying HttpResponseMessage handled by this SodaRequest + /// + internal HttpResponseMessage ResponseMessage { get; private set; } /// /// The Socrata supported data-interchange formats that this SodaRequest uses @@ -38,63 +50,52 @@ internal SodaRequest(Uri uri, string method, string appToken, string username, s { this.dataFormat = dataFormat; - var request = WebRequest.Create(uri) as HttpWebRequest; - request.Method = method.ToUpper(); - request.ProtocolVersion = new System.Version("1.1"); - request.PreAuthenticate = true; - request.Timeout = timeout.HasValue ? timeout.Value : request.Timeout; + this.Client = new HttpClient(); + this.Client.Timeout = timeout.HasValue ? new TimeSpan(0, 0, 0, 0, timeout.Value) : Client.Timeout; + this.RequestMessage = new HttpRequestMessage { RequestUri = uri, Method = new HttpMethod(method) }; if (!String.IsNullOrEmpty(appToken)) { //http://dev.socrata.com/docs/app-tokens.html - request.Headers.Add("X-App-Token", appToken); + this.Client.DefaultRequestHeaders.Add("X-App-Token", appToken); } - if (!String.IsNullOrEmpty(username) && !String.IsNullOrEmpty(password)) { //Authentication using HTTP Basic Authentication //http://dev.socrata.com/docs/authentication.html string authKVP = String.Format("{0}:{1}", username, password); byte[] authBytes = Encoding.UTF8.GetBytes(authKVP); - request.Headers.Add("Authorization", String.Format("Basic {0}", Convert.ToBase64String(authBytes))); + this.Client.DefaultRequestHeaders.Add("Authorization", String.Format("Basic {0}", Convert.ToBase64String(authBytes))); } - //http://dev.socrata.com/docs/formats/index.html switch (dataFormat) { case SodaDataFormat.JSON: - request.Accept = "application/json"; - if (!request.Method.Equals("GET")) - request.ContentType = "application/json"; + Client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); break; case SodaDataFormat.CSV: - switch (request.Method) - { - case "GET": - request.Accept = "text/csv"; - break; - case "POST": - case "PUT": - request.ContentType = "text/csv"; - break; - } + this.Client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("text/csv")); break; case SodaDataFormat.XML: - request.Accept = "application/rdf+xml"; + this.Client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/rdf+xml")); break; } if (!String.IsNullOrEmpty(payload)) { - byte[] bodyBytes = Encoding.UTF8.GetBytes(payload); - - using (var stream = request.GetRequestStream()) + switch (dataFormat) { - stream.Write(bodyBytes, 0, bodyBytes.Length); + case SodaDataFormat.JSON: + this.RequestMessage.Content = new StringContent(payload, Encoding.UTF8, "application/json"); + break; + case SodaDataFormat.CSV: + this.RequestMessage.Content = new StringContent(payload, Encoding.UTF8, "text/csv"); + break; + case SodaDataFormat.XML: + this.RequestMessage.Content = new StringContent(payload, Encoding.UTF8, "application/rdf+xml"); + break; } } - - this.webRequest = request; } /// @@ -108,52 +109,49 @@ internal TResult ParseResponse() where TResult : class Exception inner = null; bool exception = false; - using (var responseStream = webRequest.GetResponse().GetResponseStream()) - { - string response = new StreamReader(responseStream).ReadToEnd(); + this.ResponseMessage = Client.SendAsync(RequestMessage).Result; - //attempt to deserialize based on the requested format - switch (dataFormat) - { - case SodaDataFormat.JSON: + //attempt to deserialize based on the requested format + switch (dataFormat) + { + case SodaDataFormat.JSON: + try + { + result = Newtonsoft.Json.JsonConvert.DeserializeObject(this.ResponseMessage.Content.ReadAsStringAsync().Result); + } + catch (Newtonsoft.Json.JsonException jex) + { + inner = jex; + exception = true; + } + break; + case SodaDataFormat.CSV: + //TODO: should we consider this an error (i.e. InvalidOperationException) if this cast returns null? + result = this.ResponseMessage.Content.ReadAsStringAsync().Result as TResult; + break; + case SodaDataFormat.XML: + //see if the caller just wanted the XML string + var ttype = typeof(TResult); + if (ttype == typeof(string)) + { + result = this.ResponseMessage.Content.ReadAsStringAsync().Result as TResult; + } + else + { + //try to deserialize the XML response try { - result = Newtonsoft.Json.JsonConvert.DeserializeObject(response); + var reader = XmlReader.Create(new StringReader(this.ResponseMessage.Content.ReadAsStringAsync().Result)); + var serializer = new XmlSerializer(ttype); + result = serializer.Deserialize(reader) as TResult; } - catch (Newtonsoft.Json.JsonException jex) + catch (Exception ex) { - inner = jex; + inner = ex; exception = true; } - break; - case SodaDataFormat.CSV: - //TODO: should we consider this an error (i.e. InvalidOperationException) if this cast returns null? - result = response as TResult; - break; - case SodaDataFormat.XML: - //see if the caller just wanted the XML string - var ttype = typeof(TResult); - if (ttype == typeof(string)) - { - result = response as TResult; - } - else - { - //try to deserialize the XML response - try - { - var reader = XmlReader.Create(new StringReader(response)); - var serializer = new XmlSerializer(ttype); - result = serializer.Deserialize(reader) as TResult; - } - catch (Exception ex) - { - inner = ex; - exception = true; - } - } - break; - } + } + break; } if (exception) diff --git a/SODA/packages.config b/SODA/packages.config index 505e588..9e775b7 100644 --- a/SODA/packages.config +++ b/SODA/packages.config @@ -1,4 +1,5 @@  - + + \ No newline at end of file diff --git a/SolutionInfo.cs b/SolutionInfo.cs deleted file mode 100644 index 06084bc..0000000 --- a/SolutionInfo.cs +++ /dev/null @@ -1,10 +0,0 @@ -using System.Reflection; -using System.Runtime.InteropServices; - -[assembly: AssemblyCompany("City of Santa Monica, CA")] -[assembly: AssemblyProduct("SODA")] -[assembly: AssemblyCopyright("Copyright © 2018 City of Santa Monica, CA")] -[assembly: AssemblyVersion("0.8.0")] -[assembly: AssemblyFileVersion("0.8.0")] -[assembly: AssemblyInformationalVersion("0.8.0")] -[assembly: ComVisible(false)] \ No newline at end of file diff --git a/Utilities.Tests/DataFileExporterTests.cs b/Utilities.Tests/DataFileExporterTests.cs index 6f55c8d..330d818 100644 --- a/Utilities.Tests/DataFileExporterTests.cs +++ b/Utilities.Tests/DataFileExporterTests.cs @@ -17,6 +17,7 @@ public class DataFileExporterTests [SetUp] public void TestInitialize() { + Environment.CurrentDirectory = TestContext.CurrentContext.TestDirectory; simpleEntities = new[] { new SimpleEntityMock(foo, bar) }; if (File.Exists(FileMocks.FileThatDoesNotExist(".csv"))) @@ -55,19 +56,17 @@ public void ExportCSV_Parameterless_Uses_DefaultFilePath() [TestCase(StringMocks.EmptyInput)] [TestCase(StringMocks.NullInput)] - [ExpectedException(typeof(ArgumentException))] [Category("DataFileExporter")] public void ExportCSV_With_Empty_File_Paths_Throws_Exception(string input) { - DataFileExporter.ExportCSV(simpleEntities, input); + Assert.That(() => DataFileExporter.ExportCSV(simpleEntities, input), Throws.TypeOf()); } [TestCase("something.notcsv")] - [ExpectedException(typeof(ArgumentException))] [Category("DataFileExporter")] public void ExportCSV_With_Incorrect_File_Extension_Throws_Exception(string input) { - DataFileExporter.ExportCSV(simpleEntities, input); + Assert.That(() => DataFileExporter.ExportCSV(simpleEntities, input), Throws.TypeOf()); } [Test] @@ -101,7 +100,7 @@ public void ExportCSV_Writes_Simple_Collection_To_File() Assert.That( File.ReadAllText(DataFileExporter.DefaultCSVPath).Trim(), - Is.StringStarting("foo,bar").And.StringEnding(String.Format(@"""{0}"",""{1}""", foo, bar)) + Does.StartWith("foo,bar").And.EndsWith(String.Format(@"""{0}"",""{1}""", foo, bar)) ); } @@ -111,7 +110,7 @@ public void ExportCSV_Writes_Complex_Collection_To_File() { var complexEntities = new[] { new ComplexEntityMock( - "complexEntity", + "complexEntity", new[] { new SimpleEntityMock(foo, bar), new SimpleEntityMock(foo, bar), @@ -125,7 +124,7 @@ public void ExportCSV_Writes_Complex_Collection_To_File() Assert.That( File.ReadAllText(DataFileExporter.DefaultCSVPath).Trim(), - Is.StringStarting("name,entities").And.StringEnding(String.Format(@"""complexEntity"",""{0}""", serializedSimpleEntities)) + Does.StartWith("name,entities").And.EndsWith(String.Format(@"""complexEntity"",""{0}""", serializedSimpleEntities)) ); } @@ -142,19 +141,17 @@ public void ExportTSV_Parameterless_Uses_DefaultFilePath() [TestCase(StringMocks.EmptyInput)] [TestCase(StringMocks.NullInput)] - [ExpectedException(typeof(ArgumentException))] [Category("DataFileExporter")] public void ExportTSV_With_Empty_File_Paths_Throws_Exception(string input) { - DataFileExporter.ExportTSV(simpleEntities, input); + Assert.That(() => DataFileExporter.ExportTSV(simpleEntities, input), Throws.TypeOf()); } [TestCase("something.nottsv")] - [ExpectedException(typeof(ArgumentException))] [Category("DataFileExporter")] public void ExportTSV_With_Incorrect_File_Extension_Throws_Exception(string input) { - DataFileExporter.ExportTSV(simpleEntities, input); + Assert.That(() => DataFileExporter.ExportTSV(simpleEntities, input), Throws.TypeOf()); } [Test] @@ -165,7 +162,7 @@ public void ExportTSV_Creates_NonExistent_File() DataFileExporter.ExportTSV(simpleEntities, FileMocks.FileThatDoesNotExist(".tsv")); Assert.True(File.Exists(FileMocks.FileThatDoesNotExist(".tsv"))); } - + [Test] [Category("DataFileExporter")] public void ExportJSON_Parameterless_Uses_DefaultFilePath() @@ -179,19 +176,17 @@ public void ExportJSON_Parameterless_Uses_DefaultFilePath() [TestCase(StringMocks.EmptyInput)] [TestCase(StringMocks.NullInput)] - [ExpectedException(typeof(ArgumentException))] [Category("DataFileExporter")] public void ExportJSON_With_Empty_File_Paths_Throws_Exception(string input) { - DataFileExporter.ExportJSON(simpleEntities, input); + Assert.That(() => DataFileExporter.ExportJSON(simpleEntities, input), Throws.TypeOf()); } [TestCase("something.notjson")] - [ExpectedException(typeof(ArgumentException))] [Category("DataFileExporter")] public void ExportJSON_With_Incorrect_File_Extension_Throws_Exception(string input) { - DataFileExporter.ExportJSON(simpleEntities, input); + Assert.That(() => DataFileExporter.ExportJSON(simpleEntities, input), Throws.TypeOf()); } [Test] @@ -235,7 +230,7 @@ public void ExportJSON_Writes_Complex_Collection_To_File() { var complexEntities = new[] { new ComplexEntityMock( - "complexEntity", + "complexEntity", new[] { new SimpleEntityMock(foo, bar), new SimpleEntityMock(foo, bar), @@ -269,4 +264,4 @@ public void ExportJSON_Respects_DataContractAttribute() ); } } -} +} \ No newline at end of file diff --git a/Utilities.Tests/ExcelDataReaderHelperTests.cs b/Utilities.Tests/ExcelDataReaderHelperTests.cs index f7e6e4e..43151ce 100644 --- a/Utilities.Tests/ExcelDataReaderHelperTests.cs +++ b/Utilities.Tests/ExcelDataReaderHelperTests.cs @@ -9,6 +9,15 @@ namespace SODA.Utilities.Tests [TestFixture] public class ExcelDataReaderHelperTests { + [SetUp] + public void TestInitialize() + { + Environment.CurrentDirectory = TestContext.CurrentContext.TestDirectory; +#if NETCOREAPP + System.Text.Encoding.RegisterProvider(System.Text.CodePagesEncodingProvider.Instance); +#endif + } + [Test] [Category("ExcelDataReaderHelper")] public void GetRowsFromDataSheets_With_Empty_Filename_Throws_ArgumentNullException() diff --git a/Utilities.Tests/FileLoggingTests.cs b/Utilities.Tests/FileLoggingTests.cs index 9826232..11192c3 100644 --- a/Utilities.Tests/FileLoggingTests.cs +++ b/Utilities.Tests/FileLoggingTests.cs @@ -9,6 +9,12 @@ namespace SODA.Utilities.Tests [TestFixture] public class FileLoggingTests { + [SetUp] + public void TestInitialize() + { + Environment.CurrentDirectory = TestContext.CurrentContext.TestDirectory; + } + [TearDown] public void TestCleanUp() { @@ -32,20 +38,18 @@ public void Default_New_Uses_DefaultLogFile_And_DefaultMaxLogSize() [TestCase(StringMocks.NullInput)] [TestCase(StringMocks.EmptyInput)] - [ExpectedException(typeof(ArgumentNullException))] [Category("SimpleFileLogger")] public void New_With_Empty_LogFilePath_Throws_ArgumentNullException(string input) { - new SimpleFileLogger(input); + Assert.That(() => new SimpleFileLogger(input), Throws.TypeOf()); } [TestCase(-1)] [TestCase(0)] - [ExpectedException(typeof(ArgumentOutOfRangeException))] [Category("SimpleFileLogger")] public void New_With_NonPositive_MaxLogBytes_Throws_ArgumentOutOfRangeException(int input) { - new SimpleFileLogger(input); + Assert.That(() => new SimpleFileLogger(input), Throws.TypeOf()); } [Test] @@ -66,7 +70,7 @@ public void New_ReThrows_Target_File_Exceptions() { //make sure the target file exists File.WriteAllText(FileMocks.FileThatDoesNotExist(), String.Empty); - + //open the target file in exclusive mode using (var exclusive = File.Open(FileMocks.FileThatDoesNotExist(), FileMode.Open, FileAccess.Read, FileShare.None)) { @@ -93,7 +97,7 @@ public void New_Writes_Log_Header() Assert.That( File.ReadAllText(FileMocks.FileThatDoesNotExist()), - Is.StringContaining("Log Start").IgnoreCase + Does.Contain("Log Start").IgnoreCase ); } @@ -115,7 +119,7 @@ public void New_Rolls_Log_After_MaximumLogSize() Assert.That( File.ReadAllText(FileMocks.FileThatDoesNotExist()), - Is.StringContaining("Log Rollover").IgnoreCase + Does.Contain("Log Rollover").IgnoreCase ); Assert.That( @@ -152,7 +156,7 @@ public void Writes_Simple_Message_To_File() Assert.That( File.ReadAllText(FileMocks.FileThatDoesNotExist()), - Is.StringContaining(message) + Does.Contain(message) ); } @@ -171,7 +175,7 @@ public void Writes_Format_Message_To_File() Assert.That( File.ReadAllText(FileMocks.FileThatDoesNotExist()), - Is.StringContaining(param1).And.StringContaining(param2) + Does.Contain(param1).And.Contains(param2) ); } @@ -197,7 +201,7 @@ public void Writes_Exception_To_File() Assert.That( File.ReadAllText(FileMocks.FileThatDoesNotExist()), - Is.StringContaining(ex.Message).And.StringContaining(ex.StackTrace) + Does.Contain(ex.Message).And.Contains(ex.StackTrace) ); } @@ -233,8 +237,8 @@ public void Writes_InnerException_To_File() Assert.That( File.ReadAllText(FileMocks.FileThatDoesNotExist()), - Is.StringContaining(inner.Message).And.StringContaining(inner.StackTrace) + Does.Contain(inner.Message).And.Contains(inner.StackTrace) ); } } -} +} \ No newline at end of file diff --git a/Utilities.Tests/Properties/AssemblyInfo.cs b/Utilities.Tests/Properties/AssemblyInfo.cs deleted file mode 100644 index 67f2772..0000000 --- a/Utilities.Tests/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,36 +0,0 @@ -using System.Reflection; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; - -// General Information about an assembly is controlled through the following -// set of attributes. Change these attribute values to modify the information -// associated with an assembly. -[assembly: AssemblyTitle("SODA.Utilities.Tests")] -[assembly: AssemblyDescription("Test project for the SODA.Utilities library")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("City of Santa Monica")] -[assembly: AssemblyProduct("SODA.Utilities.Tests")] -[assembly: AssemblyCopyright("Copyright © City of Santa Monica 2014")] -[assembly: AssemblyTrademark("")] -[assembly: AssemblyCulture("")] - -// Setting ComVisible to false makes the types in this assembly not visible -// to COM components. If you need to access a type in this assembly from -// COM, set the ComVisible attribute to true on that type. -[assembly: ComVisible(false)] - -// The following GUID is for the ID of the typelib if this project is exposed to COM -[assembly: Guid("bccf9284-9ee5-434a-a64d-b396481aac6a")] - -// Version information for an assembly consists of the following four values: -// -// Major Version -// Minor Version -// Build Number -// Revision -// -// You can specify all the values or you can default the Build and Revision Numbers -// by using the '*' as shown below: -// [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("1.0.0.0")] -[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/Utilities.Tests/SeparatedValuesSerializerTests.cs b/Utilities.Tests/SeparatedValuesSerializerTests.cs index 00710d9..1cddc7f 100644 --- a/Utilities.Tests/SeparatedValuesSerializerTests.cs +++ b/Utilities.Tests/SeparatedValuesSerializerTests.cs @@ -18,13 +18,13 @@ public class SeparatedValuesSerializerTests [SetUp] public void TestInitialize() { - simpleEntities = new[] { + simpleEntities = new[] { new SimpleEntityMock(foo, bar) }; complexEntities = new[] { new ComplexEntityMock( - "complexEntity", + "complexEntity", new[] { new SimpleEntityMock(foo, bar), new SimpleEntityMock(foo, bar), @@ -49,11 +49,10 @@ public void DelimiterString_For_Tab_Is_Tab() [TestCase(SeparatedValuesDelimiter.Comma - 1)] [TestCase(SeparatedValuesDelimiter.Tab + 1)] - [ExpectedException(typeof(ArgumentOutOfRangeException))] [Category("SeparatedValuesSerializer")] public void SerializeToString_Throws_ArgumentOutOfRangeException_For_Invalid_Delimiter(SeparatedValuesDelimiter delimiter) { - string result = SeparatedValuesSerializer.SerializeToString(simpleEntities, delimiter); + Assert.That(() => SeparatedValuesSerializer.SerializeToString(simpleEntities, delimiter), Throws.TypeOf()); } [TestCase(SeparatedValuesDelimiter.Comma)] @@ -66,7 +65,7 @@ public void SerializeToString_Writes_Header_Row_By_Default(SeparatedValuesDelimi Assert.That( SeparatedValuesSerializer.SerializeToString(entities, delimiter), - Is.StringStarting(String.Join(delimiterString, "id", "name", "number")) + Does.StartWith(String.Join(delimiterString, "id", "name", "number")) ); } @@ -80,7 +79,7 @@ public void SerializeToString_Can_Skip_Writing_Header_Row(SeparatedValuesDelimit Assert.That( SeparatedValuesSerializer.SerializeToString(entities, delimiter, false), - Is.Not.StringContaining(String.Join(delimiterString, "id", "name", "number")) + Does.Not.Contain(String.Join(delimiterString, "id", "name", "number")) ); } @@ -90,7 +89,7 @@ public void SerializeToString_Can_Skip_Writing_Header_Row(SeparatedValuesDelimit public void SerializeToString_Writes_Empty_Collection_To_String(SeparatedValuesDelimiter delimiter) { var emptyEntities = Enumerable.Empty(); - + Assert.That( SeparatedValuesSerializer.SerializeToString(emptyEntities, delimiter), Is.EqualTo(String.Format("foo{0}bar", SeparatedValuesSerializer.DelimiterString(delimiter))) @@ -106,7 +105,7 @@ public void SerializeToString_Writes_Simple_Collection_To_String(SeparatedValues Assert.That( SeparatedValuesSerializer.SerializeToString(simpleEntities, delimiter), - Is.StringEnding(String.Format(@"""{0}""{1}""{2}""", foo, delimiterString, bar)) + Does.EndWith(String.Format(@"""{0}""{1}""{2}""", foo, delimiterString, bar)) ); } @@ -120,7 +119,7 @@ public void SerializeToString_Writes_Complex_Collection_To_String(SeparatedValue Assert.That( SeparatedValuesSerializer.SerializeToString(complexEntities, delimiter), - Is.StringEnding(String.Format(@"""complexEntity""{0}""{1}""", delimiterString, serializedSimpleEntities)) + Does.EndWith(String.Format(@"""complexEntity""{0}""{1}""", delimiterString, serializedSimpleEntities)) ); } @@ -135,15 +134,15 @@ public void SerializeToString_Respects_DataContractAttribute(SeparatedValuesDeli string csvData = SeparatedValuesSerializer.SerializeToString(dataContractEntities, delimiter); Assert.That( - csvData, - Is.StringEnding(String.Format("\"{0}\"{1}\"{2}\"", foo, delimiterString, bar)) + csvData, + Does.EndWith(String.Format("\"{0}\"{1}\"{2}\"", foo, delimiterString, bar)) ); Assert.That( - csvData, - Is.Not.StringContaining("bup") + csvData, + Does.Not.Contain("bup") .And - .Not.StringContaining(bup) + .Not.Contains(bup) ); } @@ -155,15 +154,15 @@ public void SerializeToString_Serializes_LocationColumn_In_Socrata_Publish_Forma string latitude = "lat"; string longitude = "lng"; - var entities = new[] { - new { + var entities = new[] { + new { location = new LocationColumn() { Latitude = latitude, Longitude = longitude } - } + } }; Assert.That( SeparatedValuesSerializer.SerializeToString(entities, delimiter), - Is.StringEnding(String.Format("\"({0},{1})\"", latitude, longitude)) + Does.EndWith(String.Format("\"({0},{1})\"", latitude, longitude)) ); } @@ -175,20 +174,20 @@ public void SerializeToString_Writes_Empty_String_For_LocationColumn_With_Missin string latitude = "lat"; string longitude = "lng"; - var entities = new[] { - new { + var entities = new[] { + new { location = new LocationColumn() { Latitude = null, Longitude = longitude } }, - new { + new { location = new LocationColumn() { Latitude = latitude, Longitude = null } } }; Assert.That( SeparatedValuesSerializer.SerializeToString(entities, delimiter), - Is.Not.StringContaining(latitude) - .And.Not.StringContaining(longitude) + Does.Not.Contain(latitude) + .And.Not.Contain(longitude) ); } } -} +} \ No newline at end of file diff --git a/Utilities.Tests/Utilities.Tests.csproj b/Utilities.Tests/Utilities.Tests.csproj deleted file mode 100644 index 1db3721..0000000 --- a/Utilities.Tests/Utilities.Tests.csproj +++ /dev/null @@ -1,142 +0,0 @@ - - - - Debug - AnyCPU - {6AAB405A-D32F-4D8B-B491-BDD5088561A7} - Library - Properties - SODA.Utilities.Tests - SODA.Utilities.Tests - v4.5 - 512 - {3AC096D0-A1C2-E12C-1390-A8335801FDAB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} - 10.0 - $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) - $(ProgramFiles)\Common Files\microsoft shared\VSTT\$(VisualStudioVersion)\UITestExtensionPackages - False - UnitTest - - SAK - SAK - SAK - SAK - ..\ - - - true - full - false - bin\Debug\ - DEBUG;TRACE - prompt - 4 - false - - - pdbonly - true - bin\Release\ - TRACE - prompt - 4 - false - - - - ..\packages\ExcelDataReader.2.1.2.3\lib\net45\Excel.dll - True - - - ..\packages\SharpZipLib.0.86.0\lib\20\ICSharpCode.SharpZipLib.dll - True - - - ..\packages\Microsoft.Exchange.WebServices.2.2\lib\40\Microsoft.Exchange.WebServices.dll - - - ..\packages\Microsoft.Exchange.WebServices.2.2\lib\40\Microsoft.Exchange.WebServices.Auth.dll - - - False - ..\packages\NUnit.2.6.4\lib\nunit.framework.dll - - - - 3.5 - - - - - - - - - - - - - - - - Code - - - - - - - - - - - - - - - - PreserveNewest - - - PreserveNewest - - - - - - {837ebdd7-eb58-44f8-834b-f2903a05a16e} - SODA - - - {63b7fad7-5927-417c-ad2a-608d777ad1a7} - Utilities - - - - - - - False - - - False - - - False - - - False - - - - - - - - \ No newline at end of file diff --git a/Utilities.Tests/Utilities.Tests.projitems b/Utilities.Tests/Utilities.Tests.projitems new file mode 100644 index 0000000..c813eaf --- /dev/null +++ b/Utilities.Tests/Utilities.Tests.projitems @@ -0,0 +1,32 @@ + + + + $(MSBuildAllProjects);$(MSBuildThisFileFullPath) + true + 651fb983-b00b-445a-960b-850d21d17db0 + + + Utilities.Tests + + + + + + + + + + + + + + + + + PreserveNewest + + + PreserveNewest + + + \ No newline at end of file diff --git a/Utilities.Tests/Utilities.Tests.shproj b/Utilities.Tests/Utilities.Tests.shproj new file mode 100644 index 0000000..180980c --- /dev/null +++ b/Utilities.Tests/Utilities.Tests.shproj @@ -0,0 +1,13 @@ + + + + 651fb983-b00b-445a-960b-850d21d17db0 + 14.0 + + + + + + + + diff --git a/Utilities.Tests/packages.config b/Utilities.Tests/packages.config deleted file mode 100644 index 1995e28..0000000 --- a/Utilities.Tests/packages.config +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/Utilities/DataFileExporter.cs b/Utilities/DataFileExporter.cs index e2d07a5..091cb69 100644 --- a/Utilities/DataFileExporter.cs +++ b/Utilities/DataFileExporter.cs @@ -1,6 +1,10 @@ using System; using System.Collections.Generic; using System.IO; +using System.Runtime.CompilerServices; + +[assembly: InternalsVisibleTo("Utilities.Net45.Tests")] +[assembly: InternalsVisibleTo("Utilities.NetCore22.Tests")] namespace SODA.Utilities { diff --git a/Utilities/EwsClient.cs b/Utilities/EwsClient.cs index 4a5be14..9804347 100644 --- a/Utilities/EwsClient.cs +++ b/Utilities/EwsClient.cs @@ -26,8 +26,14 @@ protected Folder Inbox { get { - if(inbox == null) + if (inbox == null) + { +#if NET45 inbox = Folder.Bind(exchangeService, WellKnownFolderName.Inbox); +#elif NETSTANDARD + inbox = Folder.Bind(exchangeService, WellKnownFolderName.Inbox).Result; +#endif + } return inbox; } @@ -147,13 +153,22 @@ public virtual bool DownloadAttachment(Regex attachmentNamePattern, string targe ); //perform the search and return the results as EmailMessage objects +#if NET45 var results = Inbox.FindItems(filter, view).Cast(); +#elif NETSTANDARD + var results = Inbox.FindItems(filter, view).Result.Cast(); +#endif bool foundAttachment = false; foreach (var result in results) { //another call to EWS to actually load in this email's attachment collection +#if NET45 var email = EmailMessage.Bind(exchangeService, result.Id, new PropertySet(EmailMessageSchema.Attachments)); +#elif NETSTANDARD + var email = EmailMessage.Bind(exchangeService, result.Id, new PropertySet(EmailMessageSchema.Attachments)).Result; +#endif + foreach (var attachment in email.Attachments) { @@ -171,7 +186,7 @@ public virtual bool DownloadAttachment(Regex attachmentNamePattern, string targe //mark the email as read email.IsRead = true; email.Update(ConflictResolutionMode.AlwaysOverwrite); - + //get outta here! foundAttachment = true; break; diff --git a/Utilities/ExcelDataReaderHelper.cs b/Utilities/ExcelDataReaderHelper.cs index 5bb42a1..e53e6e2 100644 --- a/Utilities/ExcelDataReaderHelper.cs +++ b/Utilities/ExcelDataReaderHelper.cs @@ -1,4 +1,4 @@ -using Excel; +using ExcelDataReader; using System; using System.Collections.Generic; using System.Data; @@ -39,9 +39,13 @@ public static IEnumerable GetRowsFromDataSheets(string excelFileName, b using (IExcelDataReader reader = MakeExcelReader(excelFileName)) { - reader.IsFirstRowAsColumnNames = isFirstRowColumnNames; - - foreach (DataTable table in reader.AsDataSet().Tables) + foreach (DataTable table in reader.AsDataSet(new ExcelDataSetConfiguration + { + ConfigureDataTable = (tableReader) => new ExcelDataTableConfiguration + { + UseHeaderRow = isFirstRowColumnNames, + } + }).Tables) { allDataRows.AddRange(table.Rows.OfType()); } diff --git a/Utilities/Properties/AssemblyInfo.cs b/Utilities/Properties/AssemblyInfo.cs index aae2250..f81c691 100644 --- a/Utilities/Properties/AssemblyInfo.cs +++ b/Utilities/Properties/AssemblyInfo.cs @@ -1,5 +1,4 @@ -using System.Reflection; -using System.Runtime.CompilerServices; +using System.Runtime.CompilerServices; -[assembly: AssemblyTitle("SODA.Utilities")] -[assembly: AssemblyDescription("Library of helper classes and extension methods for working with Socrata Open Data portals.")] \ No newline at end of file +[assembly: InternalsVisibleTo("Net45.SODA.Utilities.Tests")] +[assembly: InternalsVisibleTo("NetCore22.SODA.Utilities.Tests")] \ No newline at end of file diff --git a/Utilities/README.md b/Utilities/README.md deleted file mode 100644 index 62bdaee..0000000 --- a/Utilities/README.md +++ /dev/null @@ -1,98 +0,0 @@ -# SODA.Utilities - -A set of helper classes and extension methods that we use alongside SODA.NET for our publishing workflow. -Note, this library is entirely optional and is not required to interact with a Socrata Open Data portal. - -## Usage examples - -**SimpleFileLogger**, a simple file logging utility (imagine that!) - -```c# -using (var logger = new SimpleFileLogger("log.txt")) -{ - //write a line of text to the log file (and the Console window), e.g. - //[2014-08-05 14:16:03] Message here - - logger.WriteLine("Message here"); -} -``` - -**DataFileExporter**, a utility for exporting data to a text-based file format - -```c# -IEnumerable payload = GetPayloadData(); - -//export as JSON -DataFileExporter.ExportJSON(payload, "data.json"); - -//export as CSV -DataFileExporter.ExportCSV(payload, "data.csv"); -``` - -**ExcelOleDbHelper**, a utility for reading -[DataRows](http://msdn.microsoft.com/en-us/library/system.data.datarow) -out of Excel documents - -```c# -//make a connection to an .xls(x) workbook -OleDbConnection connection = ExcelOleDbHelper.MakeConnection("data.xlsx"); - -//read out a collection of DataRows from all sheets in the workbook -IEnumerable rows = ExcelOleDbHelper.GetRowsFromDataSheets(connection); -``` - -**IEwsClient**, an interface that wraps some Exchange WebServices functionality - -```c# -//initialize a new client targeting Exchange Server 2007 SP1 -IEwsClient ewsClient = new Ews2007Sp1Client("username", "password", "domain.org"); - -//regex to match against attachment filenames -var regx = new Regex("file\\d{6}\\.xlsx"); - -//download an attachment -//from the first unread email containing a matching attachment -bool foundAttachment = ewsClient.DownloadAttachment(regx, "C:\\temp"); - -//send an email message to a list of recipients -ewsClient.SendMessage("Subject Line", - "Body text here", - "recipient@example.com", - "another.recipient@example.com"); -``` - -**SeparatedValuesSerializer**, a utility for serializing a collection to a "separated values" (e.g. CSV) representation -```c# -IEnumerable payload = GetPayloadData(); - -//serialize using a comma to separate fields -string payloadCSV = - SeparatedValuesSerializer.SerializeToString( - payload, - SeparatedValuesDelimiter.Comma - ); - -//serialize using a tab to separate fields -string payloadTSV = - SeparatedValuesSerializer.SerializeToString( - payload, - SeparatedValuesDelimiter.Tab - ); -``` - -## Dependencies - -SODA.Utilities has a few dependencies: - - - SODA.NET - - [Excel Data Reader](https://www.nuget.org/packages/ExcelDataReader/2.1.2.3) -(for reading data from Excel documents) - - [Microsoft Exchange WebServices 2.2](https://www.nuget.org/packages/Microsoft.Exchange.WebServices/2.2.0) -(for talking to an Exchange server) - -## Getting Started - -SODA.Utilities is available as a [NuGet package](https://www.nuget.org/packages/CSM.SodaDotNet.Utilities/). - - Install-Package CSM.SodaDotNet.Utilities - diff --git a/Utilities/SODA.Utilities.nuspec b/Utilities/SODA.Utilities.nuspec deleted file mode 100644 index 79edca3..0000000 --- a/Utilities/SODA.Utilities.nuspec +++ /dev/null @@ -1,23 +0,0 @@ - - - - CSM.SodaDotNet.Utilities - $version$ - CSM.SodaDotNet.Utilities - City of Santa Monica, CA - City of Santa Monica, CA - https://github.com/CityOfSantaMonica/SODA.NET/blob/master/LICENSE.txt - https://github.com/CityOfSantaMonica/SODA.NET - http://www.smgov.net/uploadedImages/Main/colorstd-R.gif - false - $description$ - - Copyright 2017 City of Santa Monica, CA - EWS Excel SODA - - - - - - - \ No newline at end of file diff --git a/Utilities/Utilities.csproj b/Utilities/Utilities.csproj index 16ab195..576a54c 100644 --- a/Utilities/Utilities.csproj +++ b/Utilities/Utilities.csproj @@ -1,103 +1,37 @@ - - - + + - Debug - AnyCPU - {63B7FAD7-5927-417C-AD2A-608D777AD1A7} - Library - Properties - SODA.Utilities + netstandard2.0;net45 SODA.Utilities - v4.5 - 512 - SAK - SAK - SAK - SAK - - ..\ - - - true - full - false - bin\Debug\ - DEBUG;TRACE - prompt - 4 - false - bin\Debug\SODA.Utilities.XML - - - pdbonly - true - bin\Release\ - TRACE - prompt - 4 - false - bin\Release\SODA.Utilities.XML + SODA.Utilities + Library of helper classes and extension methods for working with Socrata Open Data portals. + true + CSM.SodaDotNet.Utilities + EWS Excel SODA + - - ..\packages\ExcelDataReader.2.1.2.3\lib\net45\Excel.dll - True - - - ..\packages\SharpZipLib.0.86.0\lib\20\ICSharpCode.SharpZipLib.dll - True - - - ..\packages\Microsoft.Exchange.WebServices.2.2\lib\40\Microsoft.Exchange.WebServices.dll - - - ..\packages\Microsoft.Exchange.WebServices.2.2\lib\40\Microsoft.Exchange.WebServices.Auth.dll - - - - - - - - - + + + + - - SolutionInfo.cs - - - - - - - Code - - - - - - - - + - - - {837ebdd7-eb58-44f8-834b-f2903a05a16e} - SODA - + + + + 1.1.3 + + + 4.5.1 + - - - + + + 2.2.0 + - - - \ No newline at end of file + + diff --git a/Utilities/packages.config b/Utilities/packages.config deleted file mode 100644 index 888fbf8..0000000 --- a/Utilities/packages.config +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/appveyor.yml b/appveyor.yml index 44d56de..d7247cd 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -1,6 +1,17 @@ -version: 0.8.{build} +version: 0.9.0-{build} + +image: Visual Studio 2017 + pull_requests: do_not_increment_build_number: true + skip_tags: true + +before_build: + - dotnet restore --verbosity m + build_script: -- cmd: .\build.cmd \ No newline at end of file + - dotnet build SODA.sln + +test_script: + - dotnet test diff --git a/build.cmd b/build.cmd deleted file mode 100644 index cbc4ecc..0000000 --- a/build.cmd +++ /dev/null @@ -1,40 +0,0 @@ -@echo off - -cls - -set TARGET="Default" -if not "%1" == "" (set TARGET="%1") - -set BUILDMODE="Release" -if not "%2" == "" (set BUILDMODE="%2") - -set MSBUILDDIR="%WINDIR%\Microsoft.NET\Framework\v4.0.30319" -set SODADIR=".\SODA" -set UTILSDIR=".\SODA.Utilities" - -echo Restoring NuGet package dependencies - -call nuget restore - -echo Rebuilding solution with Configuration: %BUILDMODE% - -call %MSBUILDDIR%\msbuild.exe SODA.sln /m "/p:Configuration=%BUILDMODE%" "/p:Platform=Any CPU" /t:Clean,Build - -echo Finished solution rebuild - -if %TARGET% == "CreatePackages" ( - echo Creating NuGet packages with Configuration: %BUILDMODE% - - call xcopy %SODADIR%\bin\%BUILDMODE%\*.* %SODADIR%\lib\ /y - call xcopy %UTILSDIR%\bin\%BUILDMODE%\*.* %UTILSDIR%\lib\ /y - - call nuget pack %SODADIR%\SODA.csproj -Properties "Configuration=%BUILDMODE%;Platform=AnyCPU" - call nuget pack %UTILSDIR%\SODA.Utilities.csproj -IncludeReferencedProjects -Properties "Configuration=%BUILDMODE%;Platform=AnyCPU" - - rd /S /Q %SODADIR%\lib - rd /S /Q %UTILSDIR%\lib - - echo Finished NuGet package creation -) - -exit /B %errorlevel% \ No newline at end of file