~ubuntu-branches/ubuntu/trusty/monodevelop/trusty-proposed

« back to all changes in this revision

Viewing changes to external/nrefactory/ICSharpCode.NRefactory.ConsistencyCheck/Xml/IncrementalXmlParserTests.cs

  • Committer: Package Import Robot
  • Author(s): Jo Shields
  • Date: 2013-05-12 09:46:03 UTC
  • mto: This revision was merged to the branch mainline in revision 29.
  • Revision ID: package-import@ubuntu.com-20130512094603-mad323bzcxvmcam0
Tags: upstream-4.0.5+dfsg
ImportĀ upstreamĀ versionĀ 4.0.5+dfsg

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
ļ»æ// Copyright (c) 2010-2013 AlphaSierraPapa for the SharpDevelop Team
 
2
// 
 
3
// Permission is hereby granted, free of charge, to any person obtaining a copy of this
 
4
// software and associated documentation files (the "Software"), to deal in the Software
 
5
// without restriction, including without limitation the rights to use, copy, modify, merge,
 
6
// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
 
7
// to whom the Software is furnished to do so, subject to the following conditions:
 
8
// 
 
9
// The above copyright notice and this permission notice shall be included in all copies or
 
10
// substantial portions of the Software.
 
11
// 
 
12
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
 
13
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
 
14
// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
 
15
// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
 
16
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 
17
// DEALINGS IN THE SOFTWARE.
 
18
 
 
19
using System;
 
20
using System.Collections.Generic;
 
21
using System.Diagnostics;
 
22
using System.IO;
 
23
using System.Linq;
 
24
using System.Text;
 
25
using ICSharpCode.NRefactory.ConsistencyCheck.Xml;
 
26
using ICSharpCode.NRefactory.Editor;
 
27
using ICSharpCode.NRefactory.Xml;
 
28
 
 
29
namespace ICSharpCode.NRefactory.ConsistencyCheck
 
30
{
 
31
        /// <summary>
 
32
        /// Tests incremental tag soup parser.
 
33
        /// </summary>
 
34
        public class IncrementalXmlParserTests
 
35
        {
 
36
                static Random sharedRnd = new Random();
 
37
                
 
38
                public static void Run(string fileName)
 
39
                {
 
40
                        Run(new StringTextSource(File.ReadAllText(fileName)));
 
41
                }
 
42
                
 
43
                public static void Run(ITextSource originalXmlFile)
 
44
                {
 
45
                        int seed;
 
46
                        lock (sharedRnd) {
 
47
                                seed = sharedRnd.Next();
 
48
                        }
 
49
                        Console.WriteLine(seed);
 
50
                        Random rnd = new Random(seed);
 
51
                        
 
52
                        AXmlParser parser = new AXmlParser();
 
53
                        StringBuilder b = new StringBuilder(originalXmlFile.Text);
 
54
                        IncrementalParserState parserState = null;
 
55
                        var versionProvider = new TextSourceVersionProvider();
 
56
                        int totalCharactersParsed = 0;
 
57
                        int totalCharactersChanged = originalXmlFile.TextLength;
 
58
                        TimeSpan incrementalParseTime = TimeSpan.Zero;
 
59
                        TimeSpan nonIncrementalParseTime = TimeSpan.Zero;
 
60
                        Stopwatch w = new Stopwatch();
 
61
                        for (int iteration = 0; iteration < 100; iteration++) {
 
62
                                totalCharactersParsed += b.Length;
 
63
                                var textSource = new StringTextSource(b.ToString(), versionProvider.CurrentVersion);
 
64
                                w.Restart();
 
65
                                var incrementalResult = parser.ParseIncremental(parserState, textSource, out parserState);
 
66
                                w.Stop();
 
67
                                incrementalParseTime += w.Elapsed;
 
68
                                w.Restart();
 
69
                                var nonIncrementalResult = parser.Parse(textSource);
 
70
                                w.Stop();
 
71
                                nonIncrementalParseTime += w.Elapsed;
 
72
                                CompareResults(incrementalResult, nonIncrementalResult);
 
73
                                
 
74
                                incrementalResult.AcceptVisitor(new ValidationVisitor(textSource));
 
75
                                
 
76
                                // Randomly mutate the file:
 
77
                                
 
78
                                List<TextChangeEventArgs> changes = new List<TextChangeEventArgs>();
 
79
                                int modifications = rnd.Next(0, 25);
 
80
                                int offset = 0;
 
81
                                for (int i = 0; i < modifications; i++) {
 
82
                                        if (i == 0 || rnd.Next(0, 10) == 0)
 
83
                                                offset = rnd.Next(0, b.Length);
 
84
                                        else
 
85
                                                offset += rnd.Next(0, Math.Min(10, b.Length - offset));
 
86
                                        int originalOffset = rnd.Next(0, originalXmlFile.TextLength);
 
87
                                        int insertionLength;
 
88
                                        int removalLength;
 
89
                                        switch (rnd.Next(0, 21) / 10) {
 
90
                                                case 0:
 
91
                                                        removalLength = 0;
 
92
                                                        insertionLength = rnd.Next(0, Math.Min(50, originalXmlFile.TextLength - originalOffset));
 
93
                                                        break;
 
94
                                                case 1:
 
95
                                                        removalLength = rnd.Next(0, Math.Min(20, b.Length - offset));
 
96
                                                        insertionLength = rnd.Next(0, Math.Min(20, originalXmlFile.TextLength - originalOffset));
 
97
                                                        break;
 
98
                                                default:
 
99
                                                        removalLength = rnd.Next(0, b.Length - offset);
 
100
                                                        insertionLength = rnd.Next(0, originalXmlFile.TextLength - originalOffset);
 
101
                                                        break;
 
102
                                        }
 
103
                                        string removedText = b.ToString(offset, removalLength);
 
104
                                        b.Remove(offset, removalLength);
 
105
                                        string insertedText = originalXmlFile.GetText(originalOffset, insertionLength);
 
106
                                        b.Insert(offset, insertedText);
 
107
                                        versionProvider.AppendChange(new TextChangeEventArgs(offset, removedText, insertedText));
 
108
                                        totalCharactersChanged += insertionLength;
 
109
                                }
 
110
                        }
 
111
                        Console.WriteLine("Incremental parse time:     " + incrementalParseTime + " for " + totalCharactersChanged + " characters changed");
 
112
                        Console.WriteLine("Non-Incremental parse time: " + nonIncrementalParseTime + " for " + totalCharactersParsed + " characters");
 
113
                }
 
114
                
 
115
                static void CompareResults(IList<AXmlObject> result1, IList<AXmlObject> result2)
 
116
                {
 
117
                        for (int i = 0; i < Math.Min(result1.Count, result2.Count); i++) {
 
118
                                CompareResults(result1[i], result2[i]);
 
119
                        }
 
120
                        if (result1.Count != result2.Count)
 
121
                                throw new InvalidOperationException();
 
122
                }
 
123
                
 
124
                static void CompareResults(AXmlObject obj1, AXmlObject obj2)
 
125
                {
 
126
                        if (obj1.GetType() != obj2.GetType())
 
127
                                throw new InvalidOperationException();
 
128
                        if (obj1.StartOffset != obj2.StartOffset)
 
129
                                throw new InvalidOperationException();
 
130
                        if (obj1.EndOffset != obj2.EndOffset)
 
131
                                throw new InvalidOperationException();
 
132
                        
 
133
                        if (obj1.MySyntaxErrors.Count() != obj2.MySyntaxErrors.Count())
 
134
                                throw new InvalidOperationException();
 
135
                        foreach (var pair in obj1.MySyntaxErrors.Zip(obj2.MySyntaxErrors, (a,b) => new { a, b })) {
 
136
                                if (pair.a.StartOffset != pair.b.StartOffset)
 
137
                                        throw new InvalidOperationException();
 
138
                                if (pair.a.EndOffset != pair.b.EndOffset)
 
139
                                        throw new InvalidOperationException();
 
140
                                if (pair.a.Description != pair.b.Description)
 
141
                                        throw new InvalidOperationException();
 
142
                        }
 
143
                        
 
144
                        if (obj1 is AXmlText) {
 
145
                                var a = (AXmlText)obj1;
 
146
                                var b = (AXmlText)obj2;
 
147
                                if (a.ContainsOnlyWhitespace != b.ContainsOnlyWhitespace)
 
148
                                        throw new InvalidOperationException();
 
149
                                if (a.Value != b.Value)
 
150
                                        throw new InvalidOperationException();
 
151
                        } else if (obj1 is AXmlTag) {
 
152
                                var a = (AXmlTag)obj1;
 
153
                                var b = (AXmlTag)obj2;
 
154
                                if (a.OpeningBracket != b.OpeningBracket)
 
155
                                        throw new InvalidOperationException();
 
156
                                if (a.ClosingBracket != b.ClosingBracket)
 
157
                                        throw new InvalidOperationException();
 
158
                                if (a.Name != b.Name)
 
159
                                        throw new InvalidOperationException();
 
160
                        } else if (obj1 is AXmlAttribute) {
 
161
                                var a = (AXmlAttribute)obj1;
 
162
                                var b = (AXmlAttribute)obj2;
 
163
                                if (a.Name != b.Name)
 
164
                                        throw new InvalidOperationException();
 
165
                                if (a.Value != b.Value)
 
166
                                        throw new InvalidOperationException();
 
167
                        } else if (obj1 is AXmlElement) {
 
168
                                var a = (AXmlElement)obj1;
 
169
                                var b = (AXmlElement)obj2;
 
170
                                if (a.Name != b.Name)
 
171
                                        throw new InvalidOperationException();
 
172
                                if (a.IsProperlyNested != b.IsProperlyNested)
 
173
                                        throw new InvalidOperationException();
 
174
                                if (a.HasEndTag != b.HasEndTag)
 
175
                                        throw new InvalidOperationException();
 
176
                        } else if (obj1 is AXmlDocument) {
 
177
                                // only compare the children
 
178
                        } else {
 
179
                                throw new NotSupportedException();
 
180
                        }
 
181
                        
 
182
                        CompareResults(obj1.Children, obj2.Children);
 
183
                }
 
184
                
 
185
                sealed class ValidationVisitor : AXmlVisitor
 
186
                {
 
187
                        readonly ITextSource textSource;
 
188
                        
 
189
                        public ValidationVisitor(ITextSource textSource)
 
190
                        {
 
191
                                this.textSource = textSource;
 
192
                        }
 
193
                        
 
194
                        public override void VisitTag(AXmlTag tag)
 
195
                        {
 
196
                                if (textSource.GetText(tag.StartOffset, tag.OpeningBracket.Length) != tag.OpeningBracket)
 
197
                                        throw new InvalidOperationException();
 
198
                                if (textSource.GetText(tag.NameSegment) != tag.Name)
 
199
                                        throw new InvalidOperationException();
 
200
                                if (textSource.GetText(tag.EndOffset - tag.ClosingBracket.Length, tag.ClosingBracket.Length) != tag.ClosingBracket)
 
201
                                        throw new InvalidOperationException();
 
202
                                base.VisitTag(tag);
 
203
                        }
 
204
                        
 
205
                        public override void VisitAttribute(AXmlAttribute attribute)
 
206
                        {
 
207
                                if (textSource.GetText(attribute.NameSegment) != attribute.Name)
 
208
                                        throw new InvalidOperationException();
 
209
                                base.VisitAttribute(attribute);
 
210
                        }
 
211
                }
 
212
        }
 
213
}