Skip to content

Commit aa3af69

Browse files
authored
Merge pull request #1 from Handlebars-Net/feature/implementation
Actual Json extension implementation
2 parents 13d3225 + 5cbf3a0 commit aa3af69

19 files changed

+1180
-51
lines changed

.github/workflows/ci.yml

Lines changed: 53 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ name: CI
22

33
on:
44
push:
5-
branches: [ master ]
5+
branches: [ main ]
66

77
jobs:
88
build:
@@ -38,7 +38,58 @@ jobs:
3838
- name: Test
3939
working-directory: ./source
4040
run: dotnet test --logger:trx --logger:GitHubActions
41+
42+
43+
sonar-ci:
44+
name: SonarCloud
45+
runs-on: windows-latest
46+
steps:
47+
- uses: actions/checkout@v2
48+
with:
49+
fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis
50+
- name: Setup dotnet 2.1
51+
uses: actions/setup-dotnet@v1
52+
with:
53+
dotnet-version: 2.1.811
54+
- name: Setup dotnet 3.1
55+
uses: actions/setup-dotnet@v1
56+
with:
57+
dotnet-version: 3.1.201
58+
- uses: actions/setup-java@v1
59+
with:
60+
java-version: '13' # The JDK version to make available on the path.
61+
- name: Cache SonarCloud packages
62+
uses: actions/cache@v1
63+
with:
64+
path: ~\sonar\cache
65+
key: ${{ runner.os }}-sonar
66+
restore-keys: ${{ runner.os }}-sonar
67+
- name: Cache SonarCloud scanner
68+
id: cache-sonar-scanner
69+
uses: actions/cache@v1
70+
with:
71+
path: .\.sonar\scanner
72+
key: ${{ runner.os }}-sonar-scanner
73+
restore-keys: ${{ runner.os }}-sonar-scanner
74+
- name: Install SonarCloud scanner
75+
if: steps.cache-sonar-scanner.outputs.cache-hit != 'true'
76+
shell: powershell
77+
run: |
78+
New-Item -Path .\.sonar\scanner -ItemType Directory
79+
dotnet tool update dotnet-sonarscanner --tool-path .\.sonar\scanner
80+
- name: Run tests
81+
run: dotnet test source/Handlebars.Extension.sln --logger:trx --collect:"XPlat Code Coverage" --settings source/Handlebars.Extension.Test/coverlet.runsettings
82+
- name: Build and analyze
83+
env:
84+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # Needed to get PR information, if any
85+
SONAR_TOKEN: 012523e2c6e40ac42f500a14a56aeec8eece71ea
86+
shell: powershell
87+
run: |
88+
.\.sonar\scanner\dotnet-sonarscanner begin /k:"Handlebars-Net_Handlebars.Net.Extension.Json" /o:"handlebars-net" /d:sonar.login="${{ env.SONAR_TOKEN }}" /d:sonar.host.url="https://sonarcloud.io" /d:sonar.cs.opencover.reportsPaths="**/*.opencover.xml" /d:sonar.cs.vstest.reportsPaths="**/*.trx" /d:sonar.coverage.exclusions="**/*.md;source/Handlebars.Extension.Benchmark/**/*.*"
89+
dotnet build source/Handlebars.Extension.sln -c Release
90+
.\.sonar\scanner\dotnet-sonarscanner end /d:sonar.login="${{ env.SONAR_TOKEN }}"
4191
92+
4293
benchmark:
4394
name: Run Benchmark.Net
4495
runs-on: ubuntu-latest
@@ -75,6 +126,7 @@ jobs:
75126
name: Benchmark
76127
path: source/Handlebars.Extension.Benchmark/BenchmarkDotNet.Artifacts/results/
77128

129+
78130
update_release_draft:
79131
name: Release Drafter
80132
runs-on: ubuntu-latest

.github/workflows/pull_request.yml

Lines changed: 53 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ name: Pull Request
22

33
on:
44
pull_request:
5-
branches: [ master ]
5+
branches: [ main ]
66

77
jobs:
88
build:
@@ -18,6 +18,7 @@ jobs:
1818
working-directory: ./source
1919
run: dotnet build -c Release
2020

21+
2122
test:
2223
name: Tests on ${{ matrix.os }}
2324
needs: [ build ]
@@ -39,6 +40,57 @@ jobs:
3940
working-directory: ./source
4041
run: dotnet test --logger:trx --logger:GitHubActions
4142

43+
44+
sonar-pr:
45+
name: SonarCloud
46+
runs-on: windows-latest
47+
steps:
48+
- uses: actions/checkout@v2
49+
with:
50+
fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis
51+
- name: Setup dotnet 2.1
52+
uses: actions/setup-dotnet@v1
53+
with:
54+
dotnet-version: 2.1.811
55+
- name: Setup dotnet 3.1
56+
uses: actions/setup-dotnet@v1
57+
with:
58+
dotnet-version: 3.1.201
59+
- uses: actions/setup-java@v1
60+
with:
61+
java-version: '13' # The JDK version to make available on the path.
62+
- name: Cache SonarCloud packages
63+
uses: actions/cache@v1
64+
with:
65+
path: ~\sonar\cache
66+
key: ${{ runner.os }}-sonar
67+
restore-keys: ${{ runner.os }}-sonar
68+
- name: Cache SonarCloud scanner
69+
id: cache-sonar-scanner
70+
uses: actions/cache@v1
71+
with:
72+
path: .\.sonar\scanner
73+
key: ${{ runner.os }}-sonar-scanner
74+
restore-keys: ${{ runner.os }}-sonar-scanner
75+
- name: Install SonarCloud scanner
76+
if: steps.cache-sonar-scanner.outputs.cache-hit != 'true'
77+
shell: powershell
78+
run: |
79+
New-Item -Path .\.sonar\scanner -ItemType Directory
80+
dotnet tool update dotnet-sonarscanner --tool-path .\.sonar\scanner
81+
- name: Run tests
82+
run: dotnet test source/Handlebars.Extension.sln --logger:trx --collect:"XPlat Code Coverage" --settings source/Handlebars.Extension.Test/coverlet.runsettings
83+
- name: Build and analyze
84+
env:
85+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # Needed to get PR information, if any
86+
SONAR_TOKEN: 012523e2c6e40ac42f500a14a56aeec8eece71ea
87+
shell: powershell
88+
run: |
89+
.\.sonar\scanner\dotnet-sonarscanner begin /k:"Handlebars-Net_Handlebars.Net.Extension.Json" /o:"handlebars-net" /d:sonar.login="${{ env.SONAR_TOKEN }}" /d:sonar.host.url="https://sonarcloud.io" /d:sonar.cs.opencover.reportsPaths="**/*.opencover.xml" /d:sonar.cs.vstest.reportsPaths="**/*.trx" /d:sonar.coverage.exclusions="**/*.md;source/Handlebars.Extension.Benchmark/**/*.*" /d:sonar.pullrequest.key=${{ github.event.number }} /d:sonar.pullrequest.branch=${{ github.event.pull_request.head.ref }} /d:sonar.pullrequest.base=${{ github.event.pull_request.base.ref }}
90+
dotnet build source/Handlebars.Extension.sln -c Release
91+
.\.sonar\scanner\dotnet-sonarscanner end /d:sonar.login="${{ env.SONAR_TOKEN }}"
92+
93+
4294
benchmark:
4395
name: Run Benchmark.Net
4496
runs-on: ubuntu-latest

.github/workflows/release.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,4 +29,4 @@ jobs:
2929

3030
- name: Publish to NuGet
3131
working-directory: ./source
32-
run: dotnet nuget push **/*.nupkg -k ${{ secrets.NUGET_PUSH_KEY }} -s https://api.nuget.org/v3/index.json
32+
run: dotnet nuget push **/*.nupkg -k ${{ secrets.NUGET_ORG_PUSH_KEY }} -s https://api.nuget.org/v3/index.json

README.md

Lines changed: 37 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,41 @@
1-
# Handlebars.Net.Extension
1+
Handlebars.Extension.Json [![Nuget](https://img.shields.io/nuget/vpre/Handlebars.Net.Extension.Json)](https://www.nuget.org/packages/Handlebars.Net.Extension.Json/)
2+
--
23

3-
Template repository for Handlebars.Net extensions
4+
## Purpose
45

5-
#### How to use:
6-
- Create new repo using template
7-
- Find all `<!-- Replace with correct value -->` and replace with valid values
8-
- Make additional changes that are required by the extensions
6+
Adds [`System.Text.Json.JsonDocument`](https://docs.microsoft.com/en-us/dotnet/api/system.text.json.jsondocument) support to [Handlebars.Net](https://github.com/Handlebars-Net/Handlebars.Net).
97

10-
Notes:
11-
- The template is designed to be used as part of Handlebars-Net organization.
12-
Usage outside of the organization may require additional changes
8+
### Install
9+
```cmd
10+
dotnet add package Handlebars.Net.Extension.Json
11+
```
12+
13+
### Usage
14+
```c#
15+
var handlebars = Handlebars.Create();
16+
handlebars.Configuration.UseJson();
17+
```
18+
19+
### Example
20+
```c#
21+
[Fact]
22+
public void JsonTestObjects()
23+
{
24+
var model = JsonDocument.Parse("{\"Key1\": \"Val1\", \"Key2\": \"Val2\"}");
25+
26+
var source = "{{#each this}}{{@key}}{{@value}}{{/each}}";
27+
28+
var handlebars = Handlebars.Create();
29+
handlebars.Configuration.UseJson();
30+
31+
var template = handlebars.Compile(source);
32+
33+
var output = template(model);
34+
35+
Assert.Equal("Key1Val1Key2Val2", output);
36+
}
37+
```
38+
39+
### History
40+
- Inspired by [rexm/Handlebars.Net/issues/304](https://github.com/rexm/Handlebars.Net/issues/304)
1341

14-
#### If you want your extension to be moved under Handlebars-Net organization:
15-
- Add [@zjklee](https://github.com/zjklee) as admin for the repo
16-
- Contact [@zjklee](https://github.com/zjklee)

source/Directory.Build.props

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,12 @@
55
</PropertyGroup>
66

77
<PropertyGroup>
8-
<Authors><!-- Replace with correct value --></Authors>
9-
<Copyright>Copyright © 2020 <!-- Replace with correct value --></Copyright>
8+
<Authors>Oleh Formaniuk</Authors>
9+
<Copyright>Copyright © 2020 Oleh Formaniuk</Copyright>
1010
<PackageLicense>LICENSE</PackageLicense>
1111
<PackageIcon>hbnet-icon.png</PackageIcon>
1212
<GenerateDocumentationFile>true</GenerateDocumentationFile>
13-
<Owner><!-- Replace with correct value --></Owner>
13+
<Owner>Oleh Formaniuk</Owner>
1414
<PublishRepositoryUrl>true</PublishRepositoryUrl>
1515
<EmbedUntrackedSources>false</EmbedUntrackedSources>
1616
<IncludeSymbols>true</IncludeSymbols>
Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
using System.Collections.Generic;
2+
using System.IO;
3+
using System.Text.Json;
4+
using BenchmarkDotNet.Attributes;
5+
using HandlebarsDotNet;
6+
using HandlebarsDotNet.Extension.Json;
7+
8+
namespace HandlebarsNet.Extension.Benchmark
9+
{
10+
public class EndToEnd
11+
{
12+
private object _data;
13+
private HandlebarsTemplate<TextWriter, object, object> _default;
14+
15+
[Params(5)]
16+
public int N { get; set; }
17+
18+
[Params("json")]
19+
public string DataType { get; set; }
20+
21+
[GlobalSetup]
22+
public void Setup()
23+
{
24+
const string template = @"
25+
childCount={{level1.Count}}
26+
{{#each level1}}
27+
id={{id}}
28+
childCount={{level2.Count}}
29+
index=[{{@../../index}}:{{@../index}}:{{@index}}]
30+
pow1=[{{pow1 @index}}]
31+
pow2=[{{pow2 @index}}]
32+
pow3=[{{pow3 @index}}]
33+
pow4=[{{pow4 @index}}]
34+
pow5=[{{#pow5 @index}}empty{{/pow5}}]
35+
{{#each level2}}
36+
id={{id}}
37+
childCount={{level3.Count}}
38+
index=[{{@../../index}}:{{@../index}}:{{@index}}]
39+
pow1=[{{pow1 @index}}]
40+
pow2=[{{pow2 @index}}]
41+
pow3=[{{pow3 @index}}]
42+
pow4=[{{pow4 @index}}]
43+
pow5=[{{#pow5 @index}}empty{{/pow5}}]
44+
{{#each level3}}
45+
id={{id}}
46+
index=[{{@../../index}}:{{@../index}}:{{@index}}]
47+
pow1=[{{pow1 @index}}]
48+
pow2=[{{pow2 @index}}]
49+
pow3=[{{pow3 @index}}]
50+
pow4=[{{pow4 @index}}]
51+
pow5=[{{#pow5 @index}}empty{{/pow5}}]
52+
{{/each}}
53+
{{/each}}
54+
{{/each}}";
55+
56+
switch (DataType)
57+
{
58+
case "json":
59+
var json = JsonSerializer.Serialize(new { level1 = ObjectLevel1Generator()});
60+
_data = JsonDocument.Parse(json);
61+
break;
62+
}
63+
64+
var handlebars = Handlebars.Create();
65+
66+
handlebars.Configuration.UseJson();
67+
68+
handlebars.RegisterHelper("pow1", (output, context, arguments) => output.WriteSafeString(((int) arguments[0] * (int) arguments[0]).ToString()));
69+
handlebars.RegisterHelper("pow2", (output, context, arguments) => output.WriteSafeString(((int) arguments[0] * (int) arguments[0]).ToString()));
70+
handlebars.RegisterHelper("pow5", (output, options, context, arguments) => output.WriteSafeString(((int) arguments[0] * (int) arguments[0]).ToString()));
71+
72+
using (var reader = new StringReader(template))
73+
{
74+
_default = handlebars.Compile(reader);
75+
}
76+
77+
handlebars.RegisterHelper("pow3", (output, context, arguments) => output.WriteSafeString(((int) arguments[0] * (int) arguments[0]).ToString()));
78+
handlebars.RegisterHelper("pow4", (output, context, arguments) => output.WriteSafeString(((int) arguments[0] * (int) arguments[0]).ToString()));
79+
80+
List<object> ObjectLevel1Generator()
81+
{
82+
var level = new List<object>();
83+
for (int i = 0; i < N; i++)
84+
{
85+
level.Add(new
86+
{
87+
id = $"{i}",
88+
level2 = ObjectLevel2Generator(i)
89+
});
90+
}
91+
92+
return level;
93+
}
94+
95+
List<object> ObjectLevel2Generator(int id1)
96+
{
97+
var level = new List<object>();
98+
for (int i = 0; i < N; i++)
99+
{
100+
level.Add(new
101+
{
102+
id = $"{id1}-{i}",
103+
level3 = ObjectLevel3Generator(id1, i)
104+
});
105+
}
106+
107+
return level;
108+
}
109+
110+
List<object> ObjectLevel3Generator(int id1, int id2)
111+
{
112+
var level = new List<object>();
113+
for (int i = 0; i < N; i++)
114+
{
115+
level.Add(new
116+
{
117+
id = $"{id1}-{id2}-{i}"
118+
});
119+
}
120+
121+
return level;
122+
}
123+
}
124+
125+
[Benchmark]
126+
public void Default() => _default(TextWriter.Null, _data);
127+
}
128+
}

0 commit comments

Comments
 (0)