source: default/TinyLogViewer/trunk/TinyLogViewerTest/Sources/Parser/LogEntryParserTest.cs @ 1474

このファイルの 1474 以降における最終更新内容1474 で hizuya@… が 5年前 に更新しました
  • ログエントリーのパースを実装。
ファイルサイズ: 11.2 KB
 
1// ----------------------------------------------------------------------------
2// <copyright company="F.C. Soft., Inc.">
3//   Copyright(c) F.C. Soft., Inc.  All rights reserved.
4// </copyright>
5// <license>
6//   Licensed to F.C. Soft., Inc. (FCSoft) under one or more contributor
7//   license agreements.  See the NOTICE file distributed with this work for
8//   additional information regarding copyright ownership.  FCSoft licenses
9//   this file to You under the Apache License, Version 2.0 (the "License");
10//   you may not use this file except in compliance with the License.  You
11//   may obtain a copy of the License at
12//
13//     http://www.apache.org/licenses/LICENSE-2.0
14//
15//   Unless required by applicable law or agreed to in writing, software
16//   distributed under the License is distributed on an "AS IS" BASIS,
17//   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18//   See the License for the specific language governing permissions and
19//   limitations under the License.
20// </license>
21// ----------------------------------------------------------------------------
22namespace FCSoft.TinyLogViewer.Parser
23{
24    using System;
25    using System.Collections.Generic;
26    using System.Diagnostics;
27    using System.IO;
28    using System.Text;
29    using System.Text.RegularExpressions;
30    using NUnit.Framework;
31
32
33    /// <summary>
34    /// <see cref="LogEntryParser"/> をテストするクラスです。
35    /// </summary>
36    [TestFixture]
37    public class LogEntryParserTest
38    {
39        /// <summary>
40        /// デフォルトで使用するログファイルのパス。
41        /// </summary>
42        private const string DefulatLogFilePath = "path.txt";
43
44
45        /// <summary>
46        /// インスタンスを作成します。
47        /// </summary>
48        public LogEntryParserTest()
49        {
50            // AVOID
51        }
52
53
54        /// <summary>
55        /// ログエントリーの開始を検出ルテストです。
56        /// </summary>
57        [Test]
58        public void TestStartDetection()
59        {
60            List<LogEntryInfo> logEntryInfos = new List<LogEntryInfo>();
61            LogEntryParser parser
62                = new LogEntryParser(
63                    new Regex("^[^ ]+ [^:]+: [0-9]+ : ", RegexOptions.ExplicitCapture),
64                    null,
65                    delegate(LogEntry logEntry)
66                    {
67                        logEntryInfos.Add(new LogEntryInfo(logEntry));
68                    });
69
70            Execute(
71                parser,
72                @"FCosft.TinyLogViewer.Test Information: 101 : Message1.
73    ProcessId=1001
74    ThreadId=2
75    DateTime=2020-01-23T10:20:30.1234567+09:00
76FCosft.TinyLogViewer.Test Information: 102 : Message2.
77FCosft.TinyLogViewer.Test Information: 103 : Message3.
78XX yyy.
79    ProcessId=1001
80    ThreadId=2
81    DateTime=2020-01-23T10:20:32.1234567+09:00
82");
83
84            Assert.That(
85                logEntryInfos,
86                Is.EqualTo(new[]
87                {
88                    new LogEntryInfo(
89                        DefulatLogFilePath,
90                        1,
91                        4,
92                        @"FCosft.TinyLogViewer.Test Information: 101 : Message1.
93    ProcessId=1001
94    ThreadId=2
95    DateTime=2020-01-23T10:20:30.1234567+09:00
96"),
97                    new LogEntryInfo(
98                        DefulatLogFilePath,
99                        5,
100                        1,
101                        @"FCosft.TinyLogViewer.Test Information: 102 : Message2.
102"),
103                    new LogEntryInfo(
104                        DefulatLogFilePath,
105                        6,
106                        5,
107                        @"FCosft.TinyLogViewer.Test Information: 103 : Message3.
108XX yyy.
109    ProcessId=1001
110    ThreadId=2
111    DateTime=2020-01-23T10:20:32.1234567+09:00
112"),
113                }));
114        }
115
116
117        /// <summary>
118        /// 文字列をパーサに供給します。
119        /// </summary>
120        /// <param name="parser">パーサ。</param>
121        /// <param name="text">文字列。</param>
122        private static void Execute(LogEntryParser parser, string text)
123        {
124            LogFile logFile = new LogFile(DefulatLogFilePath, 0x1000, Encoding.Unicode, Encoding.Unicode, 0x1000);
125
126            using (StringReader reader = new StringReader(text))
127            {
128                long position = 0;
129                int lineNumber = 1;
130                string line;
131                while ((line = reader.ReadLine()) != null)
132                {
133                    string value = line + "\r\n";
134                    int byteCount = Encoding.Unicode.GetByteCount(value);
135
136                    parser.FeedLine(
137                        logFile,
138                        position,
139                        byteCount,
140                        lineNumber,
141                        LineEndType.CarriageReturnAndLineFeed,
142                        value.ToCharArray(),
143                        0,
144                        value.Length);
145
146                    position += byteCount;
147                    lineNumber++;
148                }
149            }
150
151            parser.Flush();
152        }
153
154
155        /// <summary>
156        /// ログエントリーの情報を表すクラスです。
157        /// </summary>
158        [DebuggerDisplay(@"\{LineNumber = {lineNumber} LineCount = {lineCount}\}")]
159        private sealed class LogEntryInfo :
160            IEquatable<LogEntryInfo>
161        {
162            /// <summary>
163            /// ファイルパス。
164            /// </summary>
165            private readonly string path;
166
167            /// <summary>
168            /// 行番号。
169            /// </summary>
170            private readonly long lineNumber;
171
172            /// <summary>
173            /// 行数。
174            /// </summary>
175            private readonly long lineCount;
176
177            /// <summary>
178            /// 値。
179            /// </summary>
180            private readonly string value;
181
182
183            /// <summary>
184            /// インスタンスを作成します。
185            /// </summary>
186            /// <param name="path">ファイルパス。</param>
187            /// <param name="lineNumber">行番号。</param>
188            /// <param name="lineCount">行数。</param>
189            /// <param name="value">値。</param>
190            internal LogEntryInfo(string path, long lineNumber, long lineCount, string value)
191            {
192                this.path = path;
193                this.lineNumber = lineNumber;
194                this.lineCount = lineCount;
195                this.value = value;
196            }
197
198            /// <summary>
199            /// インスタンスを作成します。
200            /// </summary>
201            /// <param name="logEntry">ログエントリー。</param>
202            internal LogEntryInfo(LogEntry logEntry)
203            {
204                path = logEntry.FirstLogFile.Path;
205                lineNumber = logEntry.FirstLineNumber;
206                lineCount = logEntry.LineCount;
207                value = logEntry.Value;
208            }
209
210
211            /// <summary>
212            /// 等号演算子を実装します。
213            /// </summary>
214            /// <param name="o1">比較するオブジェクト 1。</param>
215            /// <param name="o2">比較するオブジェクト 2。</param>
216            /// <returns>
217            /// <paramref name="o1"/> と <paramref name="o2"/>
218            /// が等しい場合は <see langword="true"/>、それ以外の場合は <see langword="false"/>。
219            /// </returns>
220            public static bool operator ==(
221                LogEntryInfo o1,
222                LogEntryInfo o2)
223            {
224                return ReferenceEquals(o1, null) ? ReferenceEquals(o2, null) : o1.Equals(o2);
225            }
226
227            /// <summary>
228            /// 不等号演算子を実装します。
229            /// </summary>
230            /// <param name="o1">比較するオブジェクト 1。</param>
231            /// <param name="o2">比較するオブジェクト 2。</param>
232            /// <returns>
233            /// <paramref name="o1"/> と <paramref name="o2"/>
234            /// が等しい場合は <see langword="true"/>、それ以外の場合は <see langword="false"/>。
235            /// </returns>
236            public static bool operator !=(
237                LogEntryInfo o1,
238                LogEntryInfo o2)
239            {
240                return !(o1 == o2);
241            }
242
243
244            /// <summary>
245            /// 現在の <see cref="LogEntryInfo"/> を表す <see cref="string"/> を返します。
246            /// </summary>
247            /// <returns>
248            /// 現在の <see cref="LogEntryInfo"/> を表す <see cref="string"/>。
249            /// </returns>
250            public override string ToString()
251            {
252                return @"LogEntryInfo{
253  Path=" + path + @"
254  LineNumber=" + lineNumber + @"
255  LineCount=" + lineCount + @"
256  Value=" + value + @"
257}";
258            }
259
260            /// <summary>
261            /// 特定の型のハッシュ関数として機能します。
262            /// </summary>
263            /// <returns>
264            /// 現在の <see cref="LogEntryInfo"/> のハッシュ コード。
265            /// </returns>
266            public override int GetHashCode()
267            {
268                return (path != null ? path.GetHashCode() : -0x63928471)
269                    ^ ~lineNumber.GetHashCode()
270                    ^ lineCount.GetHashCode()
271                    ^ (value != null ? value.GetHashCode() : 0x199F8DE3);
272            }
273
274            /// <summary>
275            /// 指定した <see cref="LogEntryInfo"/> が、現在の <see cref="LogEntryInfo"/> と等しいかどうかを判断します。
276            /// </summary>
277            /// <param name="obj">現在の <see cref="LogEntryInfo"/> と比較する <see cref="LogEntryInfo"/>。</param>
278            /// <returns>
279            /// 指定した <see cref="LogEntryInfo"/> が現在の <see cref="LogEntryInfo"/> と等しい場合は <see langword="true"/>。
280            /// それ以外の場合は <see langword="false"/>。
281            /// </returns>
282            public override bool Equals(object obj)
283            {
284                return Equals(obj as LogEntryInfo);
285            }
286
287            /// <summary>
288            /// 現在のオブジェクトが、同じ型の別のオブジェクトと等しいかどうかを示します。
289            /// </summary>
290            /// <param name="other">このオブジェクトと比較するオブジェクト。</param>
291            /// <returns>
292            /// 現在のオブジェクトが <paramref name="other"/> パラメータと等しい場合は <see langword="true"/>。
293            /// それ以外の場合は <see langword="false"/>。
294            /// </returns>
295            public bool Equals(LogEntryInfo other)
296            {
297                return !ReferenceEquals(other, null)
298                    && Equals(path, other.path)
299                    && lineNumber == other.lineNumber
300                    && lineCount == other.lineCount
301                    && Equals(value, other.value);
302            }
303        }
304    }
305}
詳しい使い方は TracBrowser を参照してください。