Skip to content

Commit b008d68

Browse files
add dotnet framework tests (#104)
* 1. moved tests execution out of docker 2. added dotnet framework (legacy) end2end tests * move example projects to examples/ directory comment out codegen tests (requires refactor)
1 parent 060a99d commit b008d68

File tree

85 files changed

+3310
-638
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

85 files changed

+3310
-638
lines changed

.env

+3-4
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
SOURCE_WASM_FILE_UBUNTU="WasmRunner/obj/release/net8.0/wasi-wasm/wasm/for-publish/WasmRunner.wasm"
22
SOURCE_WASM_FILE="WasmRunner/bin/Release/net8.0/wasi-wasm/AppBundle/WasmRunner.wasm"
3-
TESTS_CONTAINER_NAME="plugin-tests"
4-
MYSQL_CONNECTION_STRING="server=mysqldb;database=tests;user=root"
5-
POSTGRES_CONNECTION_STRING="host=postgresdb;database=tests;username=user;password=pass"
6-
SQLITE_CONNECTION_STRING="Data Source=/app/plugin.db;Mode=ReadWrite"
3+
MYSQL_CONNECTION_STRING="server=localhost;database=tests;user=root"
4+
POSTGRES_CONNECTION_STRING="host=localhost;database=tests;username=postgres;password=pass"
5+
SQLITE_CONNECTION_STRING="Data Source=tests.db;Mode=ReadWriteCreate"
76
SQLC_CI_FILE="sqlc.ci.yaml"

.github/workflows/ci.yml

+108-68
Original file line numberDiff line numberDiff line change
@@ -33,45 +33,11 @@ jobs:
3333
workspace: sqlc-gen-csharp.sln
3434
exclude: |
3535
GeneratedProtobuf
36-
MySqlConnectorExample
37-
MySqlConnectorDapperExample
38-
NpgsqlExample
39-
NpgsqlDapperExample
40-
SqliteExample
41-
SqliteDapperExample
42-
43-
- name: Verify pushed Dockerfile is synced
44-
run: |
45-
./scripts/generate_dockerfile.sh /tmp/Dockerfile
46-
diff /tmp/Dockerfile Dockerfile
47-
48-
build:
49-
name: Build
50-
runs-on: ${{ matrix.os }}
51-
needs: [lint]
52-
strategy:
53-
matrix:
54-
os: [ 'ubuntu-latest', 'windows-latest', 'macos-latest' ]
55-
architecture: [ 'x64', 'arm64' ]
56-
57-
steps:
58-
- uses: actions/checkout@v4
59-
- name: Load .env file
60-
uses: xom9ikk/[email protected]
61-
with:
62-
load-mode: strict
63-
64-
- name: Setup Dotnet
65-
uses: actions/setup-dotnet@v4
66-
with:
67-
dotnet-version: '8.0.x'
36+
examples
6837
69-
- name: Dotnet Build
70-
run: dotnet build
71-
72-
publish:
73-
name: Publish WASM
74-
needs: [build]
38+
build-wasm:
39+
name: Build (WASM)
40+
needs: [lint]
7541
runs-on: ubuntu-latest
7642

7743
steps:
@@ -108,43 +74,71 @@ jobs:
10874
name: wasm-file
10975
path: dist/plugin.wasm
11076

111-
codegen-tests:
112-
name: Codegen Tests
77+
# codegen-tests:
78+
# name: Codegen Tests
79+
# runs-on: ubuntu-latest
80+
# needs: [build-wasm]
81+
#
82+
# steps:
83+
# - uses: actions/checkout@v4
84+
#
85+
# - uses: actions/download-artifact@v4
86+
# with:
87+
# name: wasm-file
88+
# path: dist
89+
#
90+
# - name: Load .env file
91+
# uses: xom9ikk/[email protected]
92+
# with:
93+
# load-mode: strict
94+
#
95+
# - uses: sqlc-dev/setup-sqlc@v4
96+
# with:
97+
# sqlc-version: '1.25.0'
98+
#
99+
# - name: Updating plugin sha
100+
# run: ./scripts/wasm/update_sha.sh ${SQLC_CI_FILE}
101+
#
102+
# - name: Verify pushed generated code is synced
103+
# run: |
104+
# ./scripts/wasm/update_sha.sh ${SQLC_CI_FILE}
105+
# sqlc -f ${SQLC_CI_FILE} diff
106+
#
107+
# - name: Codegen Tests against matrix of configurations
108+
# run: ./scripts/tests/run_codegen_matrix.sh ${SQLC_CI_FILE}
109+
110+
end2end-tests:
111+
name: End-to-End Tests
113112
runs-on: ubuntu-latest
114-
needs: [publish]
113+
needs: [build-wasm]
115114

116115
steps:
117116
- uses: actions/checkout@v4
118-
119117
- uses: actions/download-artifact@v4
120118
with:
121119
name: wasm-file
122120
path: dist
123-
124-
- name: Load .env file
125-
uses: xom9ikk/[email protected]
126-
with:
127-
load-mode: strict
128121

129122
- uses: sqlc-dev/setup-sqlc@v4
130123
with:
131124
sqlc-version: '1.25.0'
132125

133-
- name: Updating plugin sha
134-
run: ./scripts/wasm/update_sha.sh ${SQLC_CI_FILE}
126+
- name: Load .env file
127+
uses: xom9ikk/[email protected]
128+
with:
129+
load-mode: strict
130+
131+
- name: Docker compose
132+
uses: hoverkraft-tech/[email protected]
135133

136-
- name: Verify pushed generated code is synced
137-
run: |
138-
./scripts/wasm/update_sha.sh ${SQLC_CI_FILE}
139-
sqlc -f ${SQLC_CI_FILE} diff
140-
141-
- name: Codegen Tests against matrix of configurations
142-
run: ./scripts/tests/run_codegen_matrix.sh ${SQLC_CI_FILE}
134+
- name: End-to-End Tests
135+
run: ./scripts/tests/run_end2end.sh
143136

144-
end2end-tests:
145-
name: End-to-End Tests
146-
runs-on: ubuntu-latest
147-
needs: [codegen-tests]
137+
legacy-end2end-tests:
138+
# As this can run only on Windows machines, this implementation should only run in the CI
139+
name: End-to-End Tests (Legacy)
140+
runs-on: windows-latest
141+
needs: [build-wasm]
148142

149143
steps:
150144
- uses: actions/checkout@v4
@@ -161,14 +155,60 @@ jobs:
161155
uses: xom9ikk/[email protected]
162156
with:
163157
load-mode: strict
164-
165-
- name: Docker compose
166-
uses: hoverkraft-tech/[email protected]
158+
159+
- name: Install Chocolatey
160+
shell: powershell
161+
run: |
162+
Set-ExecutionPolicy Bypass -Scope Process -Force
163+
[System.Net.ServicePointManager]::SecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol -bor 3072
164+
iex ((New-Object System.Net.WebClient).DownloadString('https://community.chocolatey.org/install.ps1'))
165+
166+
- name: Install & Start MySQL
167+
shell: powershell
168+
run: choco install mysql --no-progress --version=8.0.31 -y --params "/serviceName:MySQL"
169+
170+
- name: Init MySQL Schema
171+
shell: powershell
172+
run: |
173+
$env:Path += ";C:\Program Files\MySQL\MySQL Server 8.0\bin"
174+
[Environment]::SetEnvironmentVariable("Path", $env:Path, "Machine")
175+
mysql -u root -e "CREATE DATABASE tests;"
176+
mysql -u root tests --execute="source examples/authors/mysql/schema.sql"
177+
178+
- name: Install & Start PostgreSQL
179+
shell: powershell
180+
run: choco install postgresql17 --no-progress --version=17.2.0 -y --params "/Password:pass" --params-global
181+
182+
- name: Init PostgresSQL Schema
183+
shell: powershell
184+
run: |
185+
$env:Path += ";C:\Program Files\PostgreSQL\17\bin"
186+
$env:PGPASSWORD = "pass"
187+
psql -U postgres -c "CREATE DATABASE tests;"
188+
psql -U postgres -d tests -f "examples/authors/postgresql/schema.sql"
189+
190+
- name: Setup Visual Studio for .NET Framework
191+
uses: microsoft/setup-msbuild@v1
167192
with:
168-
services: |
169-
mysqldb
170-
postgresdb
171-
plugin-tests
193+
vs-version: 'latest'
172194

195+
- name: Setup NuGet
196+
uses: NuGet/[email protected]
197+
198+
- name: Restore test projects
199+
shell: powershell
200+
run: |
201+
Get-ChildItem -Path examples -Recurse -Filter *.csproj |
202+
Where-Object { $_.FullName -like '*Legacy*' } |
203+
ForEach-Object { nuget restore $_.FullName }
204+
nuget restore ./LegacyEndToEndTests/LegacyEndToEndTests.csproj
205+
206+
- name: Build .NET Framework Test Project
207+
run: msbuild.exe ./LegacyEndToEndTests/LegacyEndToEndTests.csproj -p:Configuration=Release -p:FrameworkVersion=v4.7.2
208+
173209
- name: End-to-End Tests
174-
run: ./scripts/tests/run_end2end.sh
210+
shell: powershell
211+
run: |
212+
$path = vswhere -latest -products * -requires Microsoft.VisualStudio.Workload.ManagedDesktop Microsoft.VisualStudio.Workload.Web -requiresAny -property installationPath
213+
$path = join-path $path 'Common7\IDE\CommonExtensions\Microsoft\TestWindow\vstest.console.exe'
214+
& $path ./LegacyEndToEndTests/bin/Release/net472/LegacyEndToEndTests.dll

.github/workflows/docs.yml

-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ on:
1414
- "sqlc.ci.yaml"
1515
- "examples/**"
1616
- "*Tests/**"
17-
- "*Example/**"
1817
- "Drivers/**"
1918

2019
jobs:

CodeGenerator/CodeGenerator.cs

+10-10
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@ public class CodeGenerator
1717
{
1818
private static readonly string[] ResharperDisables =
1919
[
20-
"InconsistentNaming",
2120
"UnusedAutoPropertyAccessor.Global",
2221
"NotAccessedPositionalProperty.Global"
2322
];
@@ -32,13 +31,14 @@ public class CodeGenerator
3231

3332
private void InitGenerators(GenerateRequest generateRequest)
3433
{
35-
var projectName = new DirectoryInfo(generateRequest.Settings.Codegen.Out).Name;
34+
var outputDirectory = generateRequest.Settings.Codegen.Out;
35+
var projectName = new DirectoryInfo(outputDirectory).Name;
3636
Options = new Options(generateRequest);
3737
NamespaceName = Options.NamespaceName == string.Empty ? projectName : Options.NamespaceName;
3838
DbDriver = InstantiateDriver();
3939

4040
// initialize file generators
41-
CsprojGen = new CsprojGen(projectName, NamespaceName, Options);
41+
CsprojGen = new CsprojGen(outputDirectory, projectName, NamespaceName, Options);
4242
RootGen = new RootGen(Options);
4343
UtilsGen = new UtilsGen(NamespaceName, Options);
4444
DataClassesGen = new DataClassesGen(DbDriver);
@@ -120,8 +120,8 @@ Dictionary<string, Query[]> GetFileQueries()
120120
string QueryFilenameToClassName(string filenameWithExtension)
121121
{
122122
return string.Concat(
123-
Path.GetFileNameWithoutExtension(filenameWithExtension).FirstCharToUpper(),
124-
Path.GetExtension(filenameWithExtension)[1..].FirstCharToUpper());
123+
Path.GetFileNameWithoutExtension(filenameWithExtension).ToPascalCase(),
124+
Path.GetExtension(filenameWithExtension)[1..].ToPascalCase());
125125
}
126126
}
127127

@@ -166,7 +166,7 @@ private ClassDeclarationSyntax GetClassDeclaration(string className,
166166
MemberDeclarationSyntax GetWithPrimaryConstructor()
167167
{
168168
return ParseMemberDeclaration(
169-
$"class {className}(string {Variable.ConnectionString.Name()})" + "{}")!
169+
$"class {className}(string {Variable.ConnectionString.AsVarName()})" + "{}")!
170170
.AddModifiers(Token(SyntaxKind.PublicKeyword));
171171
}
172172

@@ -176,11 +176,11 @@ MemberDeclarationSyntax GetWithRegularConstructor()
176176
$$"""
177177
class {{className}}
178178
{
179-
public {{className}}(string {{Variable.ConnectionString.Name()}})
179+
public {{className}}(string {{Variable.ConnectionString.AsVarName()}})
180180
{
181-
this.{{Variable.ConnectionString.Name()}} = {{Variable.ConnectionString.Name()}};
181+
this.{{Variable.ConnectionString.AsPropertyName()}} = {{Variable.ConnectionString.AsVarName()}};
182182
}
183-
private string {{Variable.ConnectionString.Name()}} { get; }
183+
private string {{Variable.ConnectionString.AsPropertyName()}} { get; }
184184
}
185185
""")!
186186
.AddModifiers(Token(SyntaxKind.PublicKeyword));
@@ -206,7 +206,7 @@ private IEnumerable<MemberDeclarationSyntax> GetMembersForSingleQuery(Query quer
206206
private MemberDeclarationSyntax? GetQueryParamsDataclass(Query query)
207207
{
208208
if (query.Params.Count <= 0) return null;
209-
var columns = query.Params.Select(p => p.Column);
209+
var columns = query.Params.Select(p => p.Column).ToList();
210210
return DataClassesGen.Generate(query.Name, ClassMember.Args, columns, Options);
211211
}
212212

CodeGenerator/Generators/CsprojGen.cs

+6-6
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55

66
namespace SqlcGenCsharp.Generators;
77

8-
internal class CsprojGen(string projectName, string namespaceName, Options options)
8+
internal class CsprojGen(string outputDirectory, string projectName, string namespaceName, Options options)
99
{
1010
public File GenerateFile()
1111
{
@@ -19,27 +19,27 @@ public File GenerateFile()
1919

2020
private string GetFileContents()
2121
{
22-
var optinalNullableProperty = options.DotnetFramework.LatestDotnetSupported() ? Environment.NewLine + " <Nullable>enable</Nullable>" : "";
22+
var optionalNullableProperty = options.DotnetFramework.LatestDotnetSupported() ? Environment.NewLine + " <Nullable>enable</Nullable>" : "";
2323

2424
return $"""
2525
<!--{Consts.AutoGeneratedComment}-->
2626
<!--Run the following to add the project to the solution:
27-
dotnet sln add {projectName}/{projectName}.csproj
27+
dotnet sln add {outputDirectory}/{projectName}.csproj
2828
-->
2929
<Project Sdk="Microsoft.NET.Sdk">
3030
3131
<PropertyGroup>
3232
<TargetFramework>{options.DotnetFramework.ToName()}</TargetFramework>
3333
<RootNamespace>{namespaceName}</RootNamespace>
34-
<OutputType>Library</OutputType>{optinalNullableProperty}
34+
<OutputType>Library</OutputType>{optionalNullableProperty}
3535
</PropertyGroup>
3636
37-
{getItemGroup()}
37+
{GetItemGroup()}
3838
3939
</Project>
4040
""";
4141

42-
string getItemGroup()
42+
string GetItemGroup()
4343
{
4444
if (options.UseDapper)
4545
{

CodeGenerator/Generators/DataClassesGen.cs

+7-9
Original file line numberDiff line numberDiff line change
@@ -10,16 +10,14 @@ namespace SqlcGenCsharp.Generators;
1010

1111
internal class DataClassesGen(DbDriver dbDriver)
1212
{
13-
public MemberDeclarationSyntax Generate(string name, ClassMember classMember, IEnumerable<Column> columns,
14-
Options options)
13+
public MemberDeclarationSyntax Generate(string name, ClassMember classMember, IList<Column> columns, Options options)
1514
{
1615
if (options.DotnetFramework.LatestDotnetSupported() && !options.UseDapper)
1716
return GenerateAsRecord(name, classMember, columns);
1817
return GenerateAsCLass(name, classMember, columns);
1918
}
2019

21-
private RecordDeclarationSyntax GenerateAsRecord(string name, ClassMember classMember,
22-
IEnumerable<Column> columns)
20+
private RecordDeclarationSyntax GenerateAsRecord(string name, ClassMember classMember, IList<Column> columns)
2321
{
2422
return RecordDeclaration(
2523
Token(SyntaxKind.StructKeyword),
@@ -35,16 +33,16 @@ private RecordDeclarationSyntax GenerateAsRecord(string name, ClassMember classM
3533
ParameterListSyntax ColumnsToParameterList()
3634
{
3735
return ParameterList(SeparatedList(columns
38-
.Select(column => Parameter(Identifier(column.Name.FirstCharToUpper()))
36+
.Select(column => Parameter(Identifier(column.Name.ToPascalCase()))
3937
.WithType(ParseTypeName(dbDriver.GetColumnType(column)))
4038
)));
4139
}
4240
}
4341

44-
private ClassDeclarationSyntax GenerateAsCLass(string name, ClassMember classMember,
45-
IEnumerable<Column> columns)
42+
private ClassDeclarationSyntax GenerateAsCLass(string name, ClassMember classMember, IList<Column> columns)
4643
{
47-
return ClassDeclaration($"{name}{classMember.Name()}")
44+
var className = $"{name}{classMember.Name()}";
45+
return ClassDeclaration(className)
4846
.AddModifiers(Token(SyntaxKind.PublicKeyword))
4947
.AddMembers(ColumnsToProperties())
5048
.WithSemicolonToken(Token(SyntaxKind.SemicolonToken));
@@ -55,7 +53,7 @@ MemberDeclarationSyntax[] ColumnsToProperties()
5553
{
5654
var propertyType = dbDriver.GetColumnType(column);
5755
return ParseMemberDeclaration(
58-
$"public {propertyType} {column.Name.FirstCharToUpper()} {{ get; set; }}");
56+
$"public {propertyType} {column.Name.ToPascalCase()} {{ get; set; }}");
5957
})
6058
.Cast<MemberDeclarationSyntax>()
6159
.ToArray();

0 commit comments

Comments
 (0)