• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

b1f6c1c4 / ProfessionalAccounting / 327

28 Apr 2025 05:37PM UTC coverage: 51.346% (-3.0%) from 54.325%
327

push

appveyor

b1f6c1c4
ci buildx

6620 of 12893 relevant lines covered (51.35%)

126.37 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

92.42
/AccountingServer.Test/IntegrationTest/VoucherTest/QueryTest.cs
1
/* Copyright (C) 2020-2025 b1f6c1c4
2
 *
3
 * This file is part of ProfessionalAccounting.
4
 *
5
 * ProfessionalAccounting is free software: you can redistribute it and/or
6
 * modify it under the terms of the GNU Affero General Public License as
7
 * published by the Free Software Foundation, version 3.
8
 *
9
 * ProfessionalAccounting is distributed in the hope that it will be useful, but
10
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Affero General Public License
12
 * for more details.
13
 *
14
 * You should have received a copy of the GNU Affero General Public License
15
 * along with ProfessionalAccounting.  If not, see
16
 * <https://www.gnu.org/licenses/>.
17
 */
18

19
using System;
20
using System.Collections;
21
using System.Collections.Generic;
22
using System.Diagnostics.CodeAnalysis;
23
using System.Linq;
24
using System.Threading.Tasks;
25
using AccountingServer.BLL;
26
using AccountingServer.DAL;
27
using AccountingServer.Entities;
28
using AccountingServer.Entities.Util;
29
using Xunit;
30
using static AccountingServer.BLL.Parsing.FacadeF;
31
using static AccountingServer.BLL.Parsing.Synthesizer;
32

33
namespace AccountingServer.Test.IntegrationTest.VoucherTest;
34

35
public abstract class QueryTestBase
36
{
37
    protected abstract Client Client { get; }
38

39
    protected abstract ValueTask PrepareVoucher(Voucher voucher);
40
    protected abstract ValueTask<bool> RunQuery(IQueryCompounded<IVoucherQueryAtom> query);
41
    protected abstract ValueTask ResetVouchers();
42

43
    public virtual async Task RunTestA(bool expected, string query)
44
    {
180✔
45
        var voucher = new Voucher
180✔
46
            {
47
                ID = null,
48
                Date = null,
49
                Type = VoucherType.Uncertain,
50
                Remark = "rmk1",
51
                Details = new()
52
                    {
53
                        new()
54
                            {
55
                                User = "b1",
56
                                Currency = "JPY",
57
                                Title = 1001,
58
                                SubTitle = 05,
59
                                Content = "cont1",
60
                                Fund = 123.45,
61
                            },
62
                        new()
63
                            {
64
                                User = "b1",
65
                                Currency = "JPY",
66
                                Title = 1234,
67
                                Remark = "remk2",
68
                                Fund = -123.45,
69
                            },
70
                        new()
71
                            {
72
                                User = "b1",
73
                                Currency = "USD",
74
                                Title = 2345,
75
                                Content = "cont3",
76
                                Fund = -77.66,
77
                            },
78
                        new()
79
                            {
80
                                User = "b1",
81
                                Currency = "USD",
82
                                Title = 3456,
83
                                SubTitle = 05,
84
                                Content = "cont4",
85
                                Remark = "remk4",
86
                                Fund = 77.66,
87
                            },
88
                        new()
89
                            {
90
                                User = "b1&b2",
91
                                Currency = "eur#",
92
                                Title = 1111,
93
                                SubTitle = 22,
94
                                Fund = 114514,
95
                            },
96
                    },
97
            };
98

99
        await ResetVouchers();
180✔
100
        await PrepareVoucher(voucher);
180✔
101
        Assert.Equal(expected, await RunQuery(ParsingF.VoucherQuery(query, Client)));
180✔
102
        await ResetVouchers();
180✔
103
    }
180✔
104

105
    internal protected class DataProvider : IEnumerable<object[]>
106
    {
107
        private static readonly List<object[]> Data = new()
1✔
108
            {
109
                new object[] { true, "" },
110
                new object[] { false, "[null]%rmk%Uncertain" },
111
                new object[] { false, "[null]%rMk1%Uncertain" },
112
                new object[] { true, "[null]%rMk%.*Uncertain" },
113
                new object[] { false, "[null]Uncertain%rmk%" },
114
                new object[] { false, "[null]Uncertain%rMk1%" },
115
                new object[] { true, "[null]Uncertain%rMk%.*" },
116
                new object[] { true, "{}-{null}*{{Devalue}+{Amortization}}" },
117
                new object[] { true, "-{%rrr%}+{20170101}" },
118
                new object[] { false, "{^59278b516c2f021e80f51911^}+{G}*{%asdf%}" },
119
                new object[] { true, "@JPY T100105'cont1'>" },
120
                new object[] { true, "@JPY T123400\"remk2\"=-123.45" },
121
                new object[] { true, "@JPY T123400\"remk2\"=123.45" },
122
                new object[] { false, "@JPY T123400\"remk2\"=+123.45" },
123
                new object[] { true, "@USD T2345'cont3'<" },
124
                new object[] { true, "@USD T3456'cont4'\"remk4\"=77.66" },
125
                new object[] { true, "@USD T3456'cont4'\"remk4\"=+77.66" },
126
                new object[] { true, "{(T1234+T345605)*(''+'cont3')}-{Depreciation}-{Carry}" },
127
                new object[] { false, "T1002+'  '''+\" rmk\"+=77.66001" },
128
                new object[] { true, "(@USD+@JPY)*(=-123.45+>)+T2345+Ub1&b2@#eur# A" },
129
                new object[] { false, "(@USD+@JPY)*=-123.45+T2345+Ub1&b2@#eur# A" },
130
                new object[] { true, "{T1001+(T1234+(T2345)+T3456)+Ub1&b2@#eur# A}-{AnnualCarry}" },
131
                new object[] { true, "+(T1001+(T1234+T2345))+T3456+Ub1&b2@#eur# A" },
132
                new object[] { true, "{((<+>)*())+=1*=2+Ub1&b2@#eur# A}-{Ordinary}" },
133
                new object[] { true, "U-=1*=2 A" },
134
                new object[] { true, "-=1*=2 A" },
135
                new object[] { true, "{T1001 null Uncertain}*{T2345 G}-{T3456 A}" },
136
                new object[] { false, "{20170101~20180101}+{~~20160101}" },
137
                new object[] { true, "{20170101~~20180101}*{~20160101}" },
138
                new object[] { true, "U-" },
139
                new object[] { true, "-" },
140
                new object[] { false, "U- A" },
141
                new object[] { false, "- A" },
142
                new object[] { true, "U@#eur#\"\"" },
143
                new object[] { true, "U'b1&b2'" },
144
                new object[] { true, "Ub1+Ub1&b2 A" },
145
                new object[] { true, "U A" },
146
                new object[] { true, "@JPY Asset" },
147
                new object[] { true, "Liability cont3" },
148
                new object[] { true, "U @USD - U Asset - U Equity - U Revenue - U Expense" },
149
                new object[] { false, "%%" },
150
                new object[] { true, "U 'ConT'.**U\"rEMk\".*" },
151
                new object[] { false, "U 'cont\\'.*+U\"remk#\".*" },
152
                new object[] { true, "Ub1&b2 @#@" },
153
                new object[] { false, "Ub1&b2 @##@" },
154
            };
155

156
        public IEnumerator<object[]> GetEnumerator() => Data.GetEnumerator();
5✔
157
        IEnumerator IEnumerable.GetEnumerator() => Data.GetEnumerator();
×
158
    }
159
}
160

161
public class SynthTest
162
{
163
    [Theory]
164
    [ClassData(typeof(QueryTestBase.DataProvider))]
165
    public void Matches(bool _, string query)
166
    {
45✔
167
        var client = new Client { User = "uuu", Today = DateTime.UtcNow.Date };
45✔
168
        var q1 = ParsingF.VoucherQuery(query, client);
45✔
169
        var s1 = Synth(q1);
45✔
170
        var q2 = ParsingF.VoucherQuery(s1, client);
45✔
171
        var s2 = Synth(q2);
45✔
172
        Assert.Equal(s1, s2);
45✔
173
    }
45✔
174
}
175

176
[SuppressMessage("ReSharper", "InvokeAsExtensionMethod")]
177
public class MatchTest : QueryTestBase
178
{
179
    private Voucher m_Voucher;
180
    protected override Client Client { get; } = new() { User = "b1", Today = DateTime.UtcNow.Date };
45✔
181

182
    protected override ValueTask PrepareVoucher(Voucher voucher)
183
    {
45✔
184
        m_Voucher = voucher;
45✔
185
        return new();
45✔
186
    }
45✔
187

188
    protected override ValueTask<bool> RunQuery(IQueryCompounded<IVoucherQueryAtom> query)
189
        => ValueTask.FromResult(MatchHelper.IsMatch(m_Voucher, query));
45✔
190

191
    protected override ValueTask ResetVouchers()
192
    {
90✔
193
        m_Voucher = null;
90✔
194
        return new();
90✔
195
    }
90✔
196

197
    [Theory]
198
    [ClassData(typeof(DataProvider))]
199
    public override Task RunTestA(bool expected, string query) => base.RunTestA(expected, query);
45✔
200
}
201

202
[Collection("DbTestCollection")]
203
[SuppressMessage("ReSharper", "InvokeAsExtensionMethod")]
204
public class DbQueryTest : QueryTestBase, IDisposable
205
{
206
    private readonly IDbAdapter m_Adapter;
207

208
    public DbQueryTest()
45✔
209
    {
45✔
210
        m_Adapter = Facade.Create(db: "accounting-test");
45✔
211

212
        m_Adapter.DeleteVouchers(VoucherQueryUnconstrained.Instance).AsTask().Wait();
45✔
213
    }
45✔
214

215
    protected override Client Client { get; } = new() { User = "b1", Today = DateTime.UtcNow.Date };
45✔
216

217
    public void Dispose() => m_Adapter.DeleteVouchers(VoucherQueryUnconstrained.Instance).AsTask().Wait();
45✔
218

219
    protected override async ValueTask PrepareVoucher(Voucher voucher) => await m_Adapter.Upsert(voucher);
45✔
220

221
    protected override async ValueTask<bool> RunQuery(IQueryCompounded<IVoucherQueryAtom> query)
222
        => await m_Adapter.SelectVouchers(query).SingleOrDefaultAsync() != null;
45✔
223

224
    protected override async ValueTask ResetVouchers()
225
        => await m_Adapter.DeleteVouchers(VoucherQueryUnconstrained.Instance);
90✔
226

227
    [Theory]
228
    [ClassData(typeof(DataProvider))]
229
    public override Task RunTestA(bool expected, string query) => base.RunTestA(expected, query);
45✔
230
}
231

232
[Collection("DbTestCollection")]
233
[SuppressMessage("ReSharper", "InvokeAsExtensionMethod")]
234
public class BLLQueryTest : QueryTestBase, IDisposable
235
{
236
    private readonly Accountant m_Accountant;
237

238
    public BLLQueryTest()
45✔
239
    {
45✔
240
        m_Accountant = new(new(db: "accounting-test"), "b1", DateTime.UtcNow.Date);
45✔
241

242
        m_Accountant.DeleteVouchersAsync(VoucherQueryUnconstrained.Instance).AsTask().Wait();
45✔
243
    }
45✔
244

245
    protected override Client Client => m_Accountant.Client;
45✔
246

247
    public void Dispose() => m_Accountant.DeleteVouchersAsync(VoucherQueryUnconstrained.Instance).AsTask().Wait();
45✔
248

249
    protected override async ValueTask PrepareVoucher(Voucher voucher) => await m_Accountant.UpsertAsync(voucher);
45✔
250

251
    protected override async ValueTask<bool> RunQuery(IQueryCompounded<IVoucherQueryAtom> query)
252
        => await m_Accountant.SelectVouchersAsync(query).SingleOrDefaultAsync() != null;
45✔
253

254
    protected override async ValueTask ResetVouchers()
255
        => await m_Accountant.DeleteVouchersAsync(VoucherQueryUnconstrained.Instance);
90✔
256

257
    [Theory]
258
    [ClassData(typeof(DataProvider))]
259
    public override Task RunTestA(bool expected, string query) => base.RunTestA(expected, query);
45✔
260
}
261

262
[Collection("DbTestCollection")]
263
[SuppressMessage("ReSharper", "InvokeAsExtensionMethod")]
264
public class VirtualizedQueryTest : QueryTestBase, IAsyncDisposable
265
{
266
    private readonly Accountant m_Accountant;
267
    private readonly Accountant.VirtualizeLock m_Lock;
268

269
    public VirtualizedQueryTest()
45✔
270
    {
45✔
271
        m_Accountant = new(new(db: "accounting-test"), "b1", DateTime.UtcNow.Date);
45✔
272

273
        m_Accountant.DeleteVouchersAsync(VoucherQueryUnconstrained.Instance).AsTask().Wait();
45✔
274
        m_Lock = m_Accountant.Virtualize();
45✔
275
    }
45✔
276

277
    protected override Client Client => m_Accountant.Client;
45✔
278

279
    public async ValueTask DisposeAsync()
280
    {
×
281
        await m_Lock.DisposeAsync();
×
282
        await m_Accountant.DeleteVouchersAsync(VoucherQueryUnconstrained.Instance);
×
283
    }
×
284

285
    protected override async ValueTask PrepareVoucher(Voucher voucher) => await m_Accountant.UpsertAsync(voucher);
45✔
286

287
    protected override async ValueTask<bool> RunQuery(IQueryCompounded<IVoucherQueryAtom> query)
288
        => await m_Accountant.SelectVouchersAsync(query).SingleOrDefaultAsync() != null;
45✔
289

290
    protected override async ValueTask ResetVouchers()
291
        => await m_Accountant.DeleteVouchersAsync(VoucherQueryUnconstrained.Instance);
90✔
292

293
    [Theory]
294
    [ClassData(typeof(DataProvider))]
295
    public override Task RunTestA(bool expected, string query) => base.RunTestA(expected, query);
45✔
296
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc