Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
c8d5ede
ft: minor code compaction in the helpers
bolorundurowb Jun 14, 2025
2fd3487
ft: minor syntax cleanup for the dotenv options
bolorundurowb Jun 14, 2025
043b543
ft: first go at implementing a parser with escape support
bolorundurowb Jun 14, 2025
76d2c51
ft: update the version for the lib
bolorundurowb Jun 14, 2025
2c88bd0
ft: remove commented out code
bolorundurowb Jun 14, 2025
00b0733
ft: update dependencies
bolorundurowb Jun 14, 2025
a70a47d
ft: add reader tests
bolorundurowb Jun 14, 2025
cfd7319
ft: rework the dotenv options tests
bolorundurowb Jun 14, 2025
e568a86
ft: minor syntx cleanup in the env reader
bolorundurowb Jun 14, 2025
375e15b
ft: remove deprecated methods
bolorundurowb Jun 15, 2025
ce8caa2
ft: move helper code to the reader class
bolorundurowb Jun 15, 2025
16bd590
ft: improve the parsing logic
bolorundurowb Jun 15, 2025
73f67c2
ft: rework the env reader tests
bolorundurowb Jun 15, 2025
acea91f
ft: add parser tests
bolorundurowb Jun 15, 2025
41852bc
ft: remove multi-function methods and stick with single function methods
bolorundurowb Jun 15, 2025
4a9209d
ft: restructure the test structure
bolorundurowb Jun 16, 2025
430bf9b
ft: remove readme copy
bolorundurowb Jun 16, 2025
f52e19c
ft: add writer tests and remove netstandard1.6 support
bolorundurowb Jun 16, 2025
3a95368
ft: remove assembly and file versions
bolorundurowb Jun 16, 2025
3cacd58
ft: add dot env root class tests
bolorundurowb Jun 16, 2025
ab3cfa0
ft: improve test cases
bolorundurowb Jun 16, 2025
66b9340
ft: fix CI build
bolorundurowb Jun 16, 2025
c87b8be
ft: replace fluent assertions with shouldly and fix CI
bolorundurowb Jun 16, 2025
77b0247
ft: update to dotnet 9
bolorundurowb Jun 16, 2025
e9b33de
ft: improve test coverage
bolorundurowb Jun 16, 2025
f8be94c
ft: minor syntax cleanup
bolorundurowb Jun 16, 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
14 changes: 7 additions & 7 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,30 +4,30 @@ on:
push:
branches: [ master ]
pull_request:
workflow_dispatch: # Allows manual triggering
workflow_dispatch:

jobs:
build-and-test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3

- name: Use .NET 8 SDK
- name: Use .NET 9 SDK
uses: actions/setup-dotnet@v4
with:
dotnet-version: 8.0.x
dotnet-version: 9.x

- name: Restore dependencies
run: dotnet restore ./src/**/*.csproj
run: dotnet restore

- name: Build all projects
run: dotnet build ./src/**/*.csproj -c Release --no-restore
run: dotnet build --no-restore

- name: Run tests with code coverage
run: dotnet test dotenv.net.sln /p:CollectCoverage=true /p:CoverletOutputFormat=lcov /p:CoverletOutput=./coverage/
run: dotnet test /p:CollectCoverage=true /p:CoverletOutputFormat=lcov /p:CoverletOutput=./coverage/

- name: Upload coverage to Coveralls
uses: coverallsapp/github-action@v1.1.2
with:
github-token: ${{ github.token }}
path-to-lcov: ${{ github.workspace }}/tests/dotenv.net.Tests/coverage/coverage.info
path-to-lcov: ${{ github.workspace }}/src/dotenv.net.Tests/coverage/coverage.info
31 changes: 11 additions & 20 deletions dotenv.net.sln
Original file line number Diff line number Diff line change
@@ -1,33 +1,24 @@

Microsoft Visual Studio Solution File, Format Version 12.00
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 2013
VisualStudioVersion = 12.0.0.0
MinimumVisualStudioVersion = 10.0.0.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "dotenv.net", "src\dotenv.net/dotenv.net.csproj", "{92FD0370-AEB1-4154-8C9F-D5FF30CABCF8}"
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "dotenv.net", "src\dotenv.net\dotenv.net.csproj", "{ABC30C21-62C1-4DF5-B352-4D33BCDD9845}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "dotenv.net.Tests", "tests\dotenv.net.Tests\dotenv.net.Tests.csproj", "{A03D81EE-4F67-4521-932A-0B9B5BE50F72}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tests", "tests", "{1CEC83AC-9E34-4320-AECE-F0F52FE70538}"
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "dotenv.net.Tests", "src\dotenv.net.Tests\dotenv.net.Tests.csproj", "{FC5ED4B3-DFDC-45E9-889C-847433F08E0E}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{92FD0370-AEB1-4154-8C9F-D5FF30CABCF8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{92FD0370-AEB1-4154-8C9F-D5FF30CABCF8}.Debug|Any CPU.Build.0 = Debug|Any CPU
{92FD0370-AEB1-4154-8C9F-D5FF30CABCF8}.Release|Any CPU.ActiveCfg = Release|Any CPU
{92FD0370-AEB1-4154-8C9F-D5FF30CABCF8}.Release|Any CPU.Build.0 = Release|Any CPU
{A03D81EE-4F67-4521-932A-0B9B5BE50F72}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{A03D81EE-4F67-4521-932A-0B9B5BE50F72}.Debug|Any CPU.Build.0 = Debug|Any CPU
{A03D81EE-4F67-4521-932A-0B9B5BE50F72}.Release|Any CPU.ActiveCfg = Release|Any CPU
{A03D81EE-4F67-4521-932A-0B9B5BE50F72}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
{A03D81EE-4F67-4521-932A-0B9B5BE50F72} = {1CEC83AC-9E34-4320-AECE-F0F52FE70538}
{ABC30C21-62C1-4DF5-B352-4D33BCDD9845}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{ABC30C21-62C1-4DF5-B352-4D33BCDD9845}.Debug|Any CPU.Build.0 = Debug|Any CPU
{ABC30C21-62C1-4DF5-B352-4D33BCDD9845}.Release|Any CPU.ActiveCfg = Release|Any CPU
{ABC30C21-62C1-4DF5-B352-4D33BCDD9845}.Release|Any CPU.Build.0 = Release|Any CPU
{FC5ED4B3-DFDC-45E9-889C-847433F08E0E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{FC5ED4B3-DFDC-45E9-889C-847433F08E0E}.Debug|Any CPU.Build.0 = Debug|Any CPU
{FC5ED4B3-DFDC-45E9-889C-847433F08E0E}.Release|Any CPU.ActiveCfg = Release|Any CPU
{FC5ED4B3-DFDC-45E9-889C-847433F08E0E}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
EndGlobal
15 changes: 15 additions & 0 deletions src/dotenv.net.Tests/.env
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
lower_case_key=world
# this is a comment
DOUBLE_QUOTES="double"
SINGLE_QUOTES='single'
BOOLEAN=true
NUMERIC=34.56
DB_DATABASE= laravel
DOTTED.KEY =spaced value
=ValueWithNoKey
KeyWithNoValue=
DOUBLE_QUOTE_EVEN_MORE_LINES="this
is
\"a
multi-line
value"
160 changes: 160 additions & 0 deletions src/dotenv.net.Tests/DotEnvOptionsTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,160 @@
using System;
using System.Collections.Generic;
using System.Text;
using Shouldly;
using Xunit;

namespace dotenv.net.Tests;

public class DotEnvOptionsTests
{
[Fact]
public void Constructor_WithNullEnvFilePaths_ShouldUseDefaultPath()
{
var options = new DotEnvOptions(envFilePaths: null);
options.EnvFilePaths.ShouldBe([DotEnvOptions.DefaultEnvFileName]);
}

[Fact]
public void Constructor_WithEmptyEnvFilePaths_ShouldUseDefaultPath()
{
var emptyPaths = new List<string>();
var options = new DotEnvOptions(envFilePaths: emptyPaths);
options.EnvFilePaths.ShouldBe([DotEnvOptions.DefaultEnvFileName]);
}

[Fact]
public void Constructor_WithNullEncoding_ShouldUseUtf8()
{
var options = new DotEnvOptions(encoding: null);
options.Encoding.ShouldBe(Encoding.UTF8);
}

[Fact]
public void WithEncoding_WithNullEncoding_ShouldUseUtf8()
{
var options = new DotEnvOptions();
options.WithEncoding(null!);
options.Encoding.ShouldBe(Encoding.UTF8);
}

[Fact]
public void WithEnvFiles_WithNullParams_ShouldUseDefaultPath()
{
var options = new DotEnvOptions();
options.WithEnvFiles(null!);
options.EnvFilePaths.ShouldBe([DotEnvOptions.DefaultEnvFileName]);
}

[Fact]
public void WithEnvFiles_WithEmptyParams_ShouldUseDefaultPath()
{
var options = new DotEnvOptions();
options.WithEnvFiles(Array.Empty<string>());
options.EnvFilePaths.ShouldBe([DotEnvOptions.DefaultEnvFileName]);
}

[Fact]
public void WithProbeForEnv_WithNegativeProbeLevels_ShouldUseDefaultProbeDepth()
{
var options = new DotEnvOptions();
options.WithProbeForEnv(-1);
options.ProbeLevelsToSearch.ShouldBe(DotEnvOptions.DefaultProbeAscendLimit);
}

[Fact]
public void WithoutProbeForEnv_ShouldResetProbeLevelsToDefault()
{
var options = new DotEnvOptions().WithProbeForEnv(10);
options.WithoutProbeForEnv();
options.ProbeForEnv.ShouldBeFalse();
options.ProbeLevelsToSearch.ShouldBe(DotEnvOptions.DefaultProbeAscendLimit);
}

[Fact]
public void WithDefaultEncoding_ShouldResetToUtf8()
{
var options = new DotEnvOptions().WithEncoding(Encoding.ASCII);
options.WithDefaultEncoding();
options.Encoding.ShouldBe(Encoding.UTF8);
}

[Theory]
[InlineData(true)]
[InlineData(false)]
public void WithExceptions_ShouldSetIgnoreExceptionsCorrectly(bool initialValue)
{
var options = new DotEnvOptions(ignoreExceptions: initialValue);
options.WithExceptions();
options.IgnoreExceptions.ShouldBeFalse();
}

[Theory]
[InlineData(true)]
[InlineData(false)]
public void WithoutExceptions_ShouldSetIgnoreExceptionsCorrectly(bool initialValue)
{
var options = new DotEnvOptions(ignoreExceptions: initialValue);
options.WithoutExceptions();
options.IgnoreExceptions.ShouldBeTrue();
}

[Theory]
[InlineData(true)]
[InlineData(false)]
public void WithOverwriteExistingVars_ShouldSetOverwriteCorrectly(bool initialValue)
{
var options = new DotEnvOptions(overwriteExistingVars: initialValue);
options.WithOverwriteExistingVars();
options.OverwriteExistingVars.ShouldBeTrue();
}

[Theory]
[InlineData(true)]
[InlineData(false)]
public void WithoutOverwriteExistingVars_ShouldSetOverwriteCorrectly(bool initialValue)
{
var options = new DotEnvOptions(overwriteExistingVars: initialValue);
options.WithoutOverwriteExistingVars();
options.OverwriteExistingVars.ShouldBeFalse();
}

[Theory]
[InlineData(true)]
[InlineData(false)]
public void WithTrimValues_ShouldSetTrimValuesCorrectly(bool initialValue)
{
var options = new DotEnvOptions(trimValues: initialValue);
options.WithTrimValues();
options.TrimValues.ShouldBeTrue();
}

[Theory]
[InlineData(true)]
[InlineData(false)]
public void WithoutTrimValues_ShouldSetTrimValuesCorrectly(bool initialValue)
{
var options = new DotEnvOptions(trimValues: initialValue);
options.WithoutTrimValues();
options.TrimValues.ShouldBeFalse();
}

[Fact]
public void Read_ComplexExistingEnv_ShouldExtractValidValues()
{
var values = DotEnv.Fluent()
.WithTrimValues()
.WithProbeForEnv()
.Read();

values.ShouldContainKeyAndValue("lower_case_key", "world");
values.ShouldContainKeyAndValue("DOUBLE_QUOTES", "double");
values.ShouldContainKeyAndValue("SINGLE_QUOTES", "single");
values.ShouldContainKeyAndValue("BOOLEAN", "true");
values.ShouldContainKeyAndValue("NUMERIC", "34.56");
values.ShouldContainKeyAndValue("DOTTED.KEY", "spaced value");
values.ShouldContainKeyAndValue("KeyWithNoValue", string.Empty);
values.ShouldContainKeyAndValue("DOUBLE_QUOTE_EVEN_MORE_LINES",
$"""this{Environment.NewLine}is{Environment.NewLine}"a{Environment.NewLine}multi-line{Environment.NewLine} value""");
}
}
25 changes: 25 additions & 0 deletions src/dotenv.net.Tests/DotEnvTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
using System;
using Shouldly;
using Xunit;

namespace dotenv.net.Tests;

public class DotEnvTests
{
[Fact]
public void Read_ComplexExistingEnv_ShouldExtractValidValues()
{
var options = new DotEnvOptions(trimValues: true, probeForEnv: true, probeLevelsToSearch: 5);
var values = DotEnv.Read(options);

values.ShouldContainKeyAndValue("lower_case_key", "world");
values.ShouldContainKeyAndValue("DOUBLE_QUOTES", "double");
values.ShouldContainKeyAndValue("SINGLE_QUOTES", "single");
values.ShouldContainKeyAndValue("BOOLEAN", "true");
values.ShouldContainKeyAndValue("NUMERIC", "34.56");
values.ShouldContainKeyAndValue("DOTTED.KEY", "spaced value");
values.ShouldContainKeyAndValue("KeyWithNoValue", string.Empty);
values.ShouldContainKeyAndValue("DOUBLE_QUOTE_EVEN_MORE_LINES",
$"""this{Environment.NewLine}is{Environment.NewLine}"a{Environment.NewLine}multi-line{Environment.NewLine} value""");
}
}
Loading
Loading