11 changed files with 40 additions and 375 deletions
@ -1,223 +0,0 @@ |
|||||||
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
|
|
||||||
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
|
|
||||||
|
|
||||||
using System; |
|
||||||
using System.Collections.Generic; |
|
||||||
using System.Linq; |
|
||||||
using System.Diagnostics; |
|
||||||
using System.IO; |
|
||||||
using System.Text; |
|
||||||
|
|
||||||
using ICSharpCode.AvalonEdit.Xml; |
|
||||||
using ICSharpCode.SharpZipLib.Zip; |
|
||||||
using NUnit.Framework; |
|
||||||
|
|
||||||
namespace ICSharpCode.AvalonEdit.Xml |
|
||||||
{ |
|
||||||
class TestFile |
|
||||||
{ |
|
||||||
public string Name { get; set; } |
|
||||||
public string Content { get; set; } |
|
||||||
public string Canonical { get; set; } |
|
||||||
public string Description { get; set; } |
|
||||||
} |
|
||||||
|
|
||||||
[TestFixture] |
|
||||||
public class ParserTests |
|
||||||
{ |
|
||||||
readonly string zipFileName = @"XmlParser\W3C.zip"; |
|
||||||
|
|
||||||
List<TestFile> xmlFiles = new List<TestFile>(); |
|
||||||
|
|
||||||
[TestFixtureSetUp] |
|
||||||
public void OpenZipFile() |
|
||||||
{ |
|
||||||
ZipFile zipFile = new ZipFile(zipFileName); |
|
||||||
|
|
||||||
Dictionary<string, TestFile> xmlFiles = new Dictionary<string, TestFile>(); |
|
||||||
|
|
||||||
// Decompress XML files
|
|
||||||
foreach(ZipEntry zipEntry in zipFile.Cast<ZipEntry>().Where(zip => zip.IsFile && zip.Name.EndsWith(".xml"))) { |
|
||||||
Stream stream = zipFile.GetInputStream(zipEntry); |
|
||||||
string content = new StreamReader(stream).ReadToEnd(); |
|
||||||
xmlFiles.Add(zipEntry.Name, new TestFile { Name = zipEntry.Name, Content = content }); |
|
||||||
} |
|
||||||
// Add descriptions
|
|
||||||
foreach(TestFile metaData in xmlFiles.Values.Where(f => f.Name.StartsWith("ibm/ibm_oasis"))) { |
|
||||||
var doc = System.Xml.Linq.XDocument.Parse(metaData.Content); |
|
||||||
foreach(var testElem in doc.Descendants("TEST")) { |
|
||||||
string uri = "ibm/" + testElem.Attribute("URI").Value; |
|
||||||
string description = testElem.Value.Replace("\n ", "\n").TrimStart('\n'); |
|
||||||
if (xmlFiles.ContainsKey(uri)) |
|
||||||
xmlFiles[uri].Description = description; |
|
||||||
} |
|
||||||
} |
|
||||||
// Copy canonical forms
|
|
||||||
foreach(TestFile canonical in xmlFiles.Values.Where(f => f.Name.Contains("/out/"))) { |
|
||||||
string uri = canonical.Name.Replace("/out/", "/"); |
|
||||||
if (xmlFiles.ContainsKey(uri)) |
|
||||||
xmlFiles[uri].Canonical = canonical.Content; |
|
||||||
} |
|
||||||
// Copy resuts to field
|
|
||||||
this.xmlFiles.AddRange(xmlFiles.Values.Where(f => !f.Name.Contains("/out/"))); |
|
||||||
} |
|
||||||
|
|
||||||
IEnumerable<TestFile> GetXmlFilesStartingWith(string directory) |
|
||||||
{ |
|
||||||
return xmlFiles.Where(f => f.Name.StartsWith(directory)); |
|
||||||
} |
|
||||||
|
|
||||||
[Test] |
|
||||||
public void W3C_Valid() |
|
||||||
{ |
|
||||||
string[] exclude = { |
|
||||||
// NAME in DTD infoset
|
|
||||||
"ibm02v01", "ibm03v01", "ibm85v01", "ibm86v01", "ibm87v01", "ibm88v01", "ibm89v01", |
|
||||||
}; |
|
||||||
TestFiles(GetXmlFilesStartingWith("ibm/valid/"), true, exclude); |
|
||||||
} |
|
||||||
|
|
||||||
[Test] |
|
||||||
public void W3C_Invalid() |
|
||||||
{ |
|
||||||
string[] exclude = { |
|
||||||
// Default attribute value
|
|
||||||
"ibm56i03", |
|
||||||
}; |
|
||||||
TestFiles(GetXmlFilesStartingWith("ibm/invalid/"), true, exclude); |
|
||||||
} |
|
||||||
|
|
||||||
[Test] |
|
||||||
public void W3C_NotWellformed() |
|
||||||
{ |
|
||||||
string[] exclude = { |
|
||||||
// XML declaration well formed
|
|
||||||
"ibm23n", "ibm24n", "ibm26n01", "ibm32n", "ibm80n06", "ibm81n01", "ibm81n02", "ibm81n03", "ibm81n04", "ibm81n05", "ibm81n06", "ibm81n07", "ibm81n08", "ibm81n09", |
|
||||||
// Invalid chars in a comment - do we care?
|
|
||||||
"ibm02n", |
|
||||||
// Invalid char ref - do we care?
|
|
||||||
"ibm66n12", "ibm66n13", "ibm66n14", "ibm66n15", |
|
||||||
// DTD in wrong location
|
|
||||||
"ibm27n01", "ibm43n", |
|
||||||
// Entity refs depending on DTD
|
|
||||||
"ibm41n10", "ibm41n11", "ibm41n12", "ibm41n13", "ibm41n14", "ibm68n04", "ibm68n06", "ibm68n07", "ibm68n08", "ibm68n09", "ibm68n10", |
|
||||||
// DTD Related tests
|
|
||||||
"ibm09n01", "ibm09n02", "ibm13n01", "ibm13n02", "ibm13n03", "ibm28n01", "ibm28n02", "ibm28n03", "ibm29n01", "ibm29n03", "ibm29n04", "ibm29n07", "ibm30n01", "ibm31n01", "ibm45n01", "ibm45n02", "ibm45n03", "ibm45n04", "ibm45n05", "ibm45n06", "ibm46n01", "ibm46n02", "ibm46n03", "ibm46n04", |
|
||||||
"ibm46n05", "ibm47n01", "ibm47n02", "ibm47n03", "ibm47n04", "ibm47n05", "ibm47n06", "ibm48n01", "ibm48n02", "ibm48n03", "ibm48n04", "ibm48n05", "ibm48n06", "ibm48n07", "ibm49n01", "ibm49n02", "ibm49n03", "ibm49n04", "ibm49n05", "ibm49n06", "ibm50n01", "ibm50n02", "ibm50n03", "ibm50n04", |
|
||||||
"ibm50n05", "ibm50n06", "ibm50n07", "ibm51n01", "ibm51n02", "ibm51n03", "ibm51n04", "ibm51n05", "ibm51n06", "ibm51n07", "ibm52n01", "ibm52n02", "ibm52n03", "ibm53n01", "ibm53n02", "ibm53n03", "ibm53n04", "ibm53n05", "ibm53n06", "ibm53n07", "ibm53n08", "ibm54n01", "ibm54n02", "ibm55n01", |
|
||||||
"ibm55n02", "ibm55n03", "ibm56n01", "ibm56n02", "ibm56n03", "ibm56n04", "ibm56n05", "ibm56n06", "ibm56n07", "ibm57n01", "ibm58n01", "ibm58n02", "ibm58n03", "ibm58n04", "ibm58n05", "ibm58n06", "ibm58n07", "ibm58n08", "ibm59n01", "ibm59n02", "ibm59n03", "ibm59n04", "ibm59n05", "ibm59n06", |
|
||||||
"ibm60n01", "ibm60n02", "ibm60n03", "ibm60n04", "ibm60n05", "ibm60n06", "ibm60n07", "ibm60n08", "ibm61n01", "ibm62n01", "ibm62n02", "ibm62n03", "ibm62n04", "ibm62n05", "ibm62n06", "ibm62n07", "ibm62n08", "ibm63n01", "ibm63n02", "ibm63n03", "ibm63n04", "ibm63n05", "ibm63n06", "ibm63n07", |
|
||||||
"ibm64n01", "ibm64n02", "ibm64n03", "ibm65n01", "ibm65n02", "ibm66n01", "ibm66n03", "ibm66n05", "ibm66n07", "ibm66n09", "ibm66n11", "ibm69n01", "ibm69n02", "ibm69n03", "ibm69n04", "ibm69n05", "ibm69n06", "ibm69n07", "ibm70n01", "ibm71n01", "ibm71n02", "ibm71n03", "ibm71n04", "ibm71n05", |
|
||||||
"ibm72n01", "ibm72n02", "ibm72n03", "ibm72n04", "ibm72n05", "ibm72n06", "ibm72n09", "ibm73n01", "ibm73n03", "ibm74n01", "ibm75n01", "ibm75n02", "ibm75n03", "ibm75n04", "ibm75n05", "ibm75n06", "ibm75n07", "ibm75n08", "ibm75n09", "ibm75n10", "ibm75n11", "ibm75n12", "ibm75n13", "ibm76n01", |
|
||||||
"ibm76n02", "ibm76n03", "ibm76n04", "ibm76n05", "ibm76n06", "ibm76n07", "ibm77n01", "ibm77n02", "ibm77n03", "ibm77n04", "ibm78n01", "ibm78n02", "ibm79n01", "ibm79n02", "ibm82n01", "ibm82n02", "ibm82n03", "ibm82n04", "ibm82n08", "ibm83n01", "ibm83n03", "ibm83n04", "ibm83n05", "ibm83n06", |
|
||||||
// No idea what this is
|
|
||||||
"misc/432gewf", "ibm28an01", |
|
||||||
}; |
|
||||||
TestFiles(GetXmlFilesStartingWith("ibm/not-wf/"), false, exclude); |
|
||||||
} |
|
||||||
|
|
||||||
StringBuilder errorOutput; |
|
||||||
|
|
||||||
void TestFiles(IEnumerable<TestFile> files, bool areWellFormed, string[] exclude) |
|
||||||
{ |
|
||||||
errorOutput = new StringBuilder(); |
|
||||||
int testsRun = 0; |
|
||||||
int ignored = 0; |
|
||||||
foreach (TestFile file in files) { |
|
||||||
if (exclude.Any(exc => file.Name.Contains(exc))) { |
|
||||||
ignored++; |
|
||||||
} else { |
|
||||||
testsRun++; |
|
||||||
TestFile(file, areWellFormed); |
|
||||||
} |
|
||||||
} |
|
||||||
if (testsRun == 0) { |
|
||||||
Assert.Fail("Test files not found"); |
|
||||||
} |
|
||||||
if (errorOutput.Length > 0) { |
|
||||||
// Can not output ]]> otherwise nuint will crash
|
|
||||||
Assert.Fail(errorOutput.Replace("]]>", "]]~NUNIT~>").ToString()); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
/// <remarks>
|
|
||||||
/// If using DTD, canonical representation is not checked
|
|
||||||
/// If using DTD, uknown entiry references are not error
|
|
||||||
/// </remarks>
|
|
||||||
bool TestFile(TestFile testFile, bool isWellFormed) |
|
||||||
{ |
|
||||||
bool passed = true; |
|
||||||
|
|
||||||
string content = testFile.Content; |
|
||||||
Debug.WriteLine("Testing " + testFile.Name + "..."); |
|
||||||
AXmlParser parser = new AXmlParser(); |
|
||||||
|
|
||||||
bool usingDTD = content.Contains("<!DOCTYPE") && (content.Contains("<!ENTITY") || content.Contains(" SYSTEM ")); |
|
||||||
if (usingDTD) |
|
||||||
parser.UnknownEntityReferenceIsError = false; |
|
||||||
|
|
||||||
AXmlDocument document; |
|
||||||
|
|
||||||
parser.Lock.EnterWriteLock(); |
|
||||||
try { |
|
||||||
document = parser.Parse(content, null); |
|
||||||
} finally { |
|
||||||
parser.Lock.ExitWriteLock(); |
|
||||||
} |
|
||||||
|
|
||||||
string printed = PrettyPrintAXmlVisitor.PrettyPrint(document); |
|
||||||
if (content != printed) { |
|
||||||
errorOutput.AppendFormat("Output of pretty printed XML for \"{0}\" does not match the original.\n", testFile.Name); |
|
||||||
errorOutput.AppendFormat("Pretty printed:\n{0}\n", Indent(printed)); |
|
||||||
passed = false; |
|
||||||
} |
|
||||||
|
|
||||||
if (isWellFormed && !usingDTD) { |
|
||||||
string canonicalPrint = CanonicalPrintAXmlVisitor.Print(document); |
|
||||||
if (testFile.Canonical != null) { |
|
||||||
if (testFile.Canonical != canonicalPrint) { |
|
||||||
errorOutput.AppendFormat("Canonical XML for \"{0}\" does not match the excpected.\n", testFile.Name); |
|
||||||
errorOutput.AppendFormat("Expected:\n{0}\n", Indent(testFile.Canonical)); |
|
||||||
errorOutput.AppendFormat("Seen:\n{0}\n", Indent(canonicalPrint)); |
|
||||||
passed = false; |
|
||||||
} |
|
||||||
} else { |
|
||||||
errorOutput.AppendFormat("Can not find canonical output for \"{0}\"", testFile.Name); |
|
||||||
errorOutput.AppendFormat("Suggested canonical output:\n{0}\n", Indent(canonicalPrint)); |
|
||||||
passed = false; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
bool hasErrors = document.SyntaxErrors.FirstOrDefault() != null; |
|
||||||
if (isWellFormed && hasErrors) { |
|
||||||
errorOutput.AppendFormat("Syntax error(s) in well formed file \"{0}\":\n", testFile.Name); |
|
||||||
foreach (var error in document.SyntaxErrors) { |
|
||||||
string followingText = content.Substring(error.StartOffset, Math.Min(10, content.Length - error.StartOffset)); |
|
||||||
errorOutput.AppendFormat("Error ({0}-{1}): {2} (followed by \"{3}\")\n", error.StartOffset, error.EndOffset, error.Message, followingText); |
|
||||||
} |
|
||||||
passed = false; |
|
||||||
} |
|
||||||
|
|
||||||
if (!isWellFormed && !hasErrors) { |
|
||||||
errorOutput.AppendFormat("No syntax errors reported for mallformed file \"{0}\"\n", testFile.Name); |
|
||||||
passed = false; |
|
||||||
} |
|
||||||
|
|
||||||
// Epilog
|
|
||||||
if (!passed) { |
|
||||||
if (testFile.Description != null) { |
|
||||||
errorOutput.AppendFormat("Test description:\n{0}\n", Indent(testFile.Description)); |
|
||||||
} |
|
||||||
errorOutput.AppendFormat("File content:\n{0}\n", Indent(content)); |
|
||||||
errorOutput.AppendLine(); |
|
||||||
} |
|
||||||
|
|
||||||
return passed; |
|
||||||
} |
|
||||||
|
|
||||||
string Indent(string text) |
|
||||||
{ |
|
||||||
return " " + text.TrimEnd().Replace("\n", "\n "); |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
@ -1,115 +0,0 @@ |
|||||||
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
|
|
||||||
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
|
|
||||||
|
|
||||||
using System; |
|
||||||
using System.Collections.Generic; |
|
||||||
using ICSharpCode.AvalonEdit.Document; |
|
||||||
using ICSharpCode.AvalonEdit.Xml; |
|
||||||
using NUnit.Framework; |
|
||||||
|
|
||||||
namespace ICSharpCode.AvalonEdit.Xml |
|
||||||
{ |
|
||||||
[TestFixture] |
|
||||||
public class TextReplacementTests |
|
||||||
{ |
|
||||||
#region Test Data
|
|
||||||
string initialDocumentText = @"<UserControl x:Class='ICSharpCode.Profiler.Controls.TimeLineCell'
|
|
||||||
xmlns='http://schemas.microsoft.com/winfx/2006/xaml/presentation'
|
|
||||||
xmlns:x='http://schemas.microsoft.com/winfx/2006/xaml'>
|
|
||||||
<Grid> |
|
||||||
|
|
||||||
</Grid> |
|
||||||
</UserControl>";
|
|
||||||
|
|
||||||
string finalDocumentText = @"<UserControl x:Class='ICSharpCode.Profiler.Controls.TimeLineCell'
|
|
||||||
xmlns='http://schemas.microsoft.com/winfx/2006/xaml/presentation'
|
|
||||||
xmlns:x='http://schemas.microsoft.com/winfx/2006/xaml'>
|
|
||||||
<Grid> |
|
||||||
<Grid.RowDefinitions> |
|
||||||
<RowDefinition Height='20' /> |
|
||||||
<RowDefinition Height='20' /> |
|
||||||
<RowDefinition Height='Auto' /> |
|
||||||
</Grid.RowDefinitions> |
|
||||||
<StackPanel Orientation='Horizontal'> |
|
||||||
<TextBlock Text='Test' /> |
|
||||||
</StackPanel> |
|
||||||
<local:TimeLineControl x:Name='t1' Grid.Row='1' /> |
|
||||||
<TextBlock Grid.Row='2' Text='Test' /> |
|
||||||
</Grid> |
|
||||||
</UserControl>";
|
|
||||||
|
|
||||||
int offset = @"<UserControl x:Class='ICSharpCode.Profiler.Controls.TimeLineCell'
|
|
||||||
xmlns='http://schemas.microsoft.com/winfx/2006/xaml/presentation'
|
|
||||||
xmlns:x='http://schemas.microsoft.com/winfx/2006/xaml'>
|
|
||||||
".Length;
|
|
||||||
|
|
||||||
string original = @" <Grid>
|
|
||||||
|
|
||||||
</Grid>";
|
|
||||||
|
|
||||||
string replacement = @" <Grid>
|
|
||||||
<Grid.RowDefinitions> |
|
||||||
<RowDefinition Height='20' /> |
|
||||||
<RowDefinition Height='20' /> |
|
||||||
<RowDefinition Height='Auto' /> |
|
||||||
</Grid.RowDefinitions> |
|
||||||
<StackPanel Orientation='Horizontal'> |
|
||||||
<TextBlock Text='Test' /> |
|
||||||
</StackPanel> |
|
||||||
<local:TimeLineControl x:Name='t1' Grid.Row='1' /> |
|
||||||
<TextBlock Grid.Row='2' Text='Test' /> |
|
||||||
</Grid>";
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
[Test] |
|
||||||
public void ReplacementTest1() |
|
||||||
{ |
|
||||||
/* |
|
||||||
* REPRODUCTION STEPS |
|
||||||
* |
|
||||||
* 1. Run XmlDOM project |
|
||||||
* 2. paste text from initialDocumentText (see Test Data region) |
|
||||||
* 3. select lines 4 to 6 |
|
||||||
* 4. replace with replacement (see Test Data region) |
|
||||||
* 5. exception thrown: |
|
||||||
* ICSharpCode.AvalonEdit.Xml.InternalException : Assertion failed: cached elements must not have zero length |
|
||||||
* at ICSharpCode.AvalonEdit.Xml.AXmlParser.Assert(Boolean condition, String message) |
|
||||||
* in c:\Projects\SharpDevelop\4.0\SharpDevelop\src\Libraries\AvalonEdit\ICSharpCode.AvalonEdit\Xml\AXmlParser.cs:line 121 |
|
||||||
* at ICSharpCode.AvalonEdit.Xml.TagReader.TryReadFromCacheOrNew[T](T& res, Predicate`1 condition) |
|
||||||
* in c:\Projects\SharpDevelop\4.0\SharpDevelop\src\Libraries\AvalonEdit\ICSharpCode.AvalonEdit\Xml\TagReader.cs:line 39 |
|
||||||
* at ICSharpCode.AvalonEdit.Xml.TagReader.<ReadText>d__12.MoveNext() |
|
||||||
* in c:\Projects\SharpDevelop\4.0\SharpDevelop\src\Libraries\AvalonEdit\ICSharpCode.AvalonEdit\Xml\TagReader.cs:line 456 |
|
||||||
* at System.Collections.Generic.List`1.InsertRange(Int32 index, IEnumerable`1 collection) |
|
||||||
* at System.Collections.Generic.List`1.AddRange(IEnumerable`1 collection) |
|
||||||
* at ICSharpCode.AvalonEdit.Xml.TagReader.ReadAllTags() |
|
||||||
* in c:\Projects\SharpDevelop\4.0\SharpDevelop\src\Libraries\AvalonEdit\ICSharpCode.AvalonEdit\Xml\TagReader.cs:line 73 |
|
||||||
* at ICSharpCode.AvalonEdit.Xml.AXmlParser.Parse(String input, IEnumerable`1 changesSinceLastParse) |
|
||||||
* in c:\Projects\SharpDevelop\4.0\SharpDevelop\src\Libraries\AvalonEdit\ICSharpCode.AvalonEdit\Xml\AXmlParser.cs:line 161 |
|
||||||
* at ICSharpCode.AvalonEdit.Tests.XmlParser.TextReplacementTests.RunTest() |
|
||||||
* in c:\Projects\SharpDevelop\4.0\SharpDevelop\src\Libraries\AvalonEdit\ICSharpCode.AvalonEdit.Tests\XmlParser\TextReplacementTests.cs:line 114 |
|
||||||
* at ICSharpCode.AvalonEdit.Tests.XmlParser.TextReplacementTests.TestMethod( |
|
||||||
* ) in c:\Projects\SharpDevelop\4.0\SharpDevelop\src\Libraries\AvalonEdit\ICSharpCode.AvalonEdit.Tests\XmlParser\TextReplacementTests.cs:line 97 |
|
||||||
* */ |
|
||||||
Assert.DoesNotThrow(RunTest1); |
|
||||||
} |
|
||||||
|
|
||||||
void RunTest1() |
|
||||||
{ |
|
||||||
AXmlParser parser = new AXmlParser(); |
|
||||||
|
|
||||||
try { |
|
||||||
parser.Lock.EnterWriteLock(); |
|
||||||
|
|
||||||
parser.Parse(initialDocumentText, null); // full reparse
|
|
||||||
|
|
||||||
IList<DocumentChangeEventArgs> changes = new List<DocumentChangeEventArgs>(); |
|
||||||
|
|
||||||
changes.Add(new DocumentChangeEventArgs(offset, original, replacement)); |
|
||||||
|
|
||||||
parser.Parse(finalDocumentText, changes); |
|
||||||
} finally { |
|
||||||
parser.Lock.ExitWriteLock(); |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
Binary file not shown.
Loading…
Reference in new issue