Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
8f531fd
refactor tests: ParseIdentifier()
Philipp-Binder Sep 30, 2024
02538b0
refactor tests: ParseOctalByte()
Philipp-Binder Oct 20, 2024
4d007ad
refactor tests: ParseOctalChar()
Philipp-Binder Oct 20, 2024
473bbd2
refactor tests: ParseHexByte()
Philipp-Binder Oct 20, 2024
9245780
refactor tests: ParseUtf8Char()
Philipp-Binder Oct 20, 2024
53d04b8
refactor tests: ParseUtf16Char()
Philipp-Binder Oct 20, 2024
ba3c583
refactor tests: ParseUtf32Char()
Philipp-Binder Oct 20, 2024
35c355c
refactor tests: ParseEscapedChar()
Philipp-Binder Oct 20, 2024
1579e2a
refactor tests: ParseInterpolatedEnvVar()
Philipp-Binder Oct 20, 2024
120e69a
refactor tests: ParseInterpolated()
Philipp-Binder Oct 20, 2024
40a4295
refactor tests: ParseNotControlNorWhitespace()
Philipp-Binder Oct 20, 2024
0629cf6
refactor tests: ParseSpecialChar()
Philipp-Binder Oct 20, 2024
b51ba18
refactor tests: ParseComment()
Philipp-Binder Oct 20, 2024
6ce11cc
refactor tests: ParseEmpty()
Philipp-Binder Oct 20, 2024
265df50
refactor tests: ParseUnquotedValue()
Philipp-Binder Oct 20, 2024
53089bd
refactor tests: ParseDoubleQuotedValueContents()
Philipp-Binder Oct 20, 2024
7b2ef9b
refactor tests: ParseSingleQuotedValueContents()
Philipp-Binder Oct 20, 2024
010d3a2
refactor tests: ParseSingleQuotedValue()
Philipp-Binder Oct 20, 2024
f1ac796
remove unnecessary usings and unused property
Philipp-Binder Oct 20, 2024
3fd197b
refactor tests: ParseDoubleQuotedValue()
Philipp-Binder Oct 23, 2024
96d8fbb
refactor tests: TestExportExpression()
Philipp-Binder Oct 23, 2024
f1fc5e3
refactor tests: ParseValue()
Philipp-Binder Oct 23, 2024
12e7a23
refactor tests: ParseAssignment()
Philipp-Binder Oct 23, 2024
6c4f3ec
refactor tests: ParseDotenvFile
Philipp-Binder Oct 23, 2024
e5b052e
refactor ParseDotenvFileShouldParseContents using MemberData combined…
Philipp-Binder Oct 26, 2024
3b4ebac
refactor tests: LoadOptionsTests
Philipp-Binder Oct 26, 2024
eb5810a
refactor usage of tuples (use tuples only if they explain the data be…
Philipp-Binder Oct 26, 2024
c89acc4
refactor tests: ExtensionsTests
Philipp-Binder Oct 26, 2024
6d0b67f
let IndexedTheoryData inherit from generic TheoryData;
Philipp-Binder Feb 2, 2025
9a2064d
remove tuples in Theory data and add some hints as xml-doc instead; m…
Philipp-Binder Feb 2, 2025
4f62b0b
include previously dropped tests again
Philipp-Binder Mar 1, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
80 changes: 50 additions & 30 deletions test/DotNetEnv.Tests/ExtensionsTests.cs
Original file line number Diff line number Diff line change
@@ -1,42 +1,62 @@
using System;
using System.Collections.Generic;
using DotNetEnv.Extensions;
using DotNetEnv.Tests.XUnit;
using Xunit;

namespace DotNetEnv.Tests;

public class ExtensionsTests
{
[Fact]
public void ToDotEnvDictionaryTest()
private static readonly KeyValuePair<string, string> FirstValuePair = new("key", "value");
private static readonly KeyValuePair<string, string> FirstValuePairDupe = new("key", "dupe");
private static readonly KeyValuePair<string, string> SecondValuePair = new("key2", "value2");

private static readonly KeyValuePair<string, string>[] KvpSetNoDupe = { FirstValuePair, SecondValuePair };
private static readonly KeyValuePair<string, string>[] KvpSetWithDupe = { FirstValuePair, FirstValuePairDupe };

/// <summary>
/// Data: _, dictionaryOption, input, expectedValue
/// </summary>
public static readonly TheoryData<
string, CreateDictionaryOption, KeyValuePair<string, string>[], KeyValuePair<string, string>[]>
ToDotEnvDictionaryTestData =
new IndexedTheoryData<
CreateDictionaryOption, KeyValuePair<string, string>[], KeyValuePair<string, string>[]>
{
{ CreateDictionaryOption.Throw, KvpSetNoDupe, KvpSetNoDupe },
{ CreateDictionaryOption.TakeFirst, KvpSetWithDupe, new[] { FirstValuePair } },
{ CreateDictionaryOption.TakeFirst, KvpSetNoDupe, KvpSetNoDupe },
{ CreateDictionaryOption.TakeLast, KvpSetWithDupe, new[] { FirstValuePairDupe } },
{ CreateDictionaryOption.TakeLast, KvpSetNoDupe, KvpSetNoDupe },
};

[Theory]
[MemberData(nameof(ToDotEnvDictionaryTestData))]
public void ToDotEnvDictionaryWithKvpSetNoDupeShouldContainValues(string _,
CreateDictionaryOption dictionaryOption,
KeyValuePair<string, string>[] input,
KeyValuePair<string, string>[] expected)
{
var kvpSetNoDupe = new List<KeyValuePair<string, string>>()
{
new("key", "value"),
new("key2", "value2"),
};

var kvpSetWithDupe = new List<KeyValuePair<string, string>>()
{
new("key", "value"),
new("key", "value2"),
};

Assert.Throws<ArgumentException>(() => kvpSetWithDupe.ToDotEnvDictionary(CreateDictionaryOption.Throw));
var noDupeAndThrowOption = kvpSetNoDupe.ToDotEnvDictionary(CreateDictionaryOption.Throw);
Assert.Equal("value", noDupeAndThrowOption["key"]);
Assert.Equal("value2", noDupeAndThrowOption["key2"]);

var withDupeAndTakeFirstOption = kvpSetWithDupe.ToDotEnvDictionary(CreateDictionaryOption.TakeFirst);
Assert.Equal("value", withDupeAndTakeFirstOption["key"]);
var noDupeAndTakeFirstOption = kvpSetNoDupe.ToDotEnvDictionary(CreateDictionaryOption.TakeFirst);
Assert.Equal("value", noDupeAndTakeFirstOption["key"]);
Assert.Equal("value2", noDupeAndTakeFirstOption["key2"]);

var withDupeAndTakeLastOption = kvpSetWithDupe.ToDotEnvDictionary();
Assert.Equal("value2", withDupeAndTakeLastOption["key"]);
var noDupeAndTakeLastOption = kvpSetNoDupe.ToDotEnvDictionary();
Assert.Equal("value", noDupeAndTakeLastOption["key"]);
Assert.Equal("value2", noDupeAndTakeLastOption["key2"]);
var dotEnvDictionary = input.ToDotEnvDictionary(dictionaryOption);

foreach (var (key, value) in expected)
Assert.Equal(value, dotEnvDictionary[key]);
}

[Theory]
[MemberData(nameof(ToDotEnvDictionaryTestData))]
public void ToDotEnvDictionaryWithKvpSetNoDupeShouldHaveCorrectNumberOfEntries(string _,
CreateDictionaryOption dictionaryOption,
KeyValuePair<string, string>[] input,
KeyValuePair<string, string>[] expectedValues)
{
var dotEnvDictionary = input.ToDotEnvDictionary(dictionaryOption);

Assert.Equal(expectedValues.Length, dotEnvDictionary.Count);
}

[Fact]
public void ToDotEnvDictionaryWithThrowOptionShouldThrowOnDupes() =>
Assert.Throws<ArgumentException>(() => KvpSetWithDupe.ToDotEnvDictionary(CreateDictionaryOption.Throw));
}
28 changes: 28 additions & 0 deletions test/DotNetEnv.Tests/FrameworkTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
using System;
using System.Text;
using DotNetEnv.Tests.Helper;
using Xunit;

namespace DotNetEnv.Tests;

public class FrameworkTests
{
[Fact]
public void CheckUnicodeFunctionality()
{
Assert.Equal("®", Encoding.Unicode.GetString(new byte[] { 0xae, 0x00 }));
Assert.Equal(UnicodeChars.Rocket, Encoding.UTF32.GetString(new byte[] { 0x80, 0xf6, 0x01, 0x00 }));
Assert.Equal(UnicodeChars.Rocket, Encoding.UTF32.GetString(new byte[] { 0x80, 0xf6, 0x1, 0x0 }));
}

[Fact]
public void CheckEnvironmentVariableFunctionality()
{
Environment.SetEnvironmentVariable("EV_DNE", null);
Assert.Null(Environment.GetEnvironmentVariable("EV_DNE"));

// Note that dotnet returns null if the env var is empty -- even if it was set to empty!
Environment.SetEnvironmentVariable("EV_DNE", "");
Assert.Null(Environment.GetEnvironmentVariable("EV_DNE"));
}
}
10 changes: 10 additions & 0 deletions test/DotNetEnv.Tests/Helper/UnicodeChars.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
namespace DotNetEnv.Tests.Helper;

public struct UnicodeChars
{
// https://stackoverflow.com/questions/602912/how-do-you-echo-a-4-digit-unicode-character-in-bash
// printf '\xE2\x98\xA0'
// printf ☠ | hexdump # hexdump has bytes flipped per word (2 bytes, 4 hex)

public const string Rocket = "\ud83d\ude80"; // 🚀
}
122 changes: 31 additions & 91 deletions test/DotNetEnv.Tests/LoadOptionsTests.cs
Original file line number Diff line number Diff line change
@@ -1,101 +1,41 @@
using System;
using DotNetEnv.Tests.XUnit;
using Xunit;

namespace DotNetEnv.Tests
{
public class LoadOptionsTests
{
[Fact]
public void StaticEnvTest()
/// <summary>
/// Data: _, optionsUnderTest, expectedSetEnvVars, expectedClobberExistingVars, expectedOnlyExactPath
/// </summary>
public static readonly TheoryData<string, LoadOptions, bool , bool, bool>
LoadOptionTestCombinations = new IndexedTheoryData<LoadOptions, bool, bool, bool>()
{
{ Env.NoEnvVars(), false, true, true },
{ Env.NoClobber(), true, false, true },
{ Env.TraversePath(), true, true, false },
{ LoadOptions.NoEnvVars(), false, true, true },
{ LoadOptions.NoClobber(), true, false, true },
{ LoadOptions.TraversePath(), true, true, false },
{ new LoadOptions(), true, true, true },
{ new LoadOptions().NoEnvVars(), false, true, true },
{ new LoadOptions().NoClobber(), true, false, true },
{ new LoadOptions().TraversePath(), true, true, false },
{ Env.NoEnvVars().NoClobber().TraversePath(), false, false, false },
{ Env.NoClobber().TraversePath(), true, false, false },
{ Env.NoEnvVars().NoClobber(), false, false, true },
{ Env.NoEnvVars().TraversePath(), false, true, false },
};

[Theory]
[MemberData(nameof(LoadOptionTestCombinations))]
public void LoadOptionsShouldHaveCorrectPropertiesSet(string _, LoadOptions optionsUnderTest,
bool expectedSetEnvVars, bool expectedClobberExistingVars, bool expectedOnlyExactPath)
{
LoadOptions options;

options = DotNetEnv.Env.NoEnvVars();
Assert.False(options.SetEnvVars);
Assert.True(options.ClobberExistingVars);
Assert.True(options.OnlyExactPath);

options = DotNetEnv.Env.NoClobber();
Assert.True(options.SetEnvVars);
Assert.False(options.ClobberExistingVars);
Assert.True(options.OnlyExactPath);

options = DotNetEnv.Env.TraversePath();
Assert.True(options.SetEnvVars);
Assert.True(options.ClobberExistingVars);
Assert.False(options.OnlyExactPath);
}

[Fact]
public void StaticOptionsTest()
{
LoadOptions options;

options = DotNetEnv.LoadOptions.NoEnvVars();
Assert.False(options.SetEnvVars);
Assert.True(options.ClobberExistingVars);
Assert.True(options.OnlyExactPath);

options = DotNetEnv.LoadOptions.NoClobber();
Assert.True(options.SetEnvVars);
Assert.False(options.ClobberExistingVars);
Assert.True(options.OnlyExactPath);

options = DotNetEnv.LoadOptions.TraversePath();
Assert.True(options.SetEnvVars);
Assert.True(options.ClobberExistingVars);
Assert.False(options.OnlyExactPath);
}

[Fact]
public void InstanceTest()
{
LoadOptions options;

options = new DotNetEnv.LoadOptions();
Assert.True(options.SetEnvVars);
Assert.True(options.ClobberExistingVars);
Assert.True(options.OnlyExactPath);

options = new DotNetEnv.LoadOptions().NoEnvVars();
Assert.False(options.SetEnvVars);
Assert.True(options.ClobberExistingVars);
Assert.True(options.OnlyExactPath);

options = new DotNetEnv.LoadOptions().NoClobber();
Assert.True(options.SetEnvVars);
Assert.False(options.ClobberExistingVars);
Assert.True(options.OnlyExactPath);

options = new DotNetEnv.LoadOptions().TraversePath();
Assert.True(options.SetEnvVars);
Assert.True(options.ClobberExistingVars);
Assert.False(options.OnlyExactPath);
}

[Fact]
public void ComboTest()
{
LoadOptions options;

options = DotNetEnv.Env.NoEnvVars().NoClobber().TraversePath();
Assert.False(options.SetEnvVars);
Assert.False(options.ClobberExistingVars);
Assert.False(options.OnlyExactPath);

options = DotNetEnv.Env.NoClobber().TraversePath();
Assert.True(options.SetEnvVars);
Assert.False(options.ClobberExistingVars);
Assert.False(options.OnlyExactPath);

options = DotNetEnv.Env.NoEnvVars().NoClobber();
Assert.False(options.SetEnvVars);
Assert.False(options.ClobberExistingVars);
Assert.True(options.OnlyExactPath);

options = DotNetEnv.Env.NoEnvVars().TraversePath();
Assert.False(options.SetEnvVars);
Assert.True(options.ClobberExistingVars);
Assert.False(options.OnlyExactPath);
Assert.Equal(expectedSetEnvVars, optionsUnderTest.SetEnvVars);
Assert.Equal(expectedClobberExistingVars, optionsUnderTest.ClobberExistingVars);
Assert.Equal(expectedOnlyExactPath, optionsUnderTest.OnlyExactPath);
}
}
}
Loading