Skip to content

Instantly share code, notes, and snippets.

@mavnn
Last active December 19, 2015 16:28
Show Gist options
  • Select an option

  • Save mavnn/5983701 to your computer and use it in GitHub Desktop.

Select an option

Save mavnn/5983701 to your computer and use it in GitHub Desktop.
module DevEd.FsCheck
open System.Xml
open System.Xml.Linq
let AddEnhancement (xDoc : XDocument) (input : string) =
xDoc.Root.Add(XElement(XName.Get "Enhancement", input))
xDoc
open FsCheck
open DevEd.FsCheck
open System.Xml.Linq
let baseDoc = "<root />"
let ``Add enhancement must be idempotent`` input =
let xml1 = XDocument.Parse baseDoc
let xml2 = XDocument.Parse baseDoc
(AddEnhancement xml1 input).ToString() =
(AddEnhancement (AddEnhancement xml2 input) input).ToString()
Check.Quick ``Add enhancement must be idempotent``
System.Console.ReadLine() |> ignore
let AddEnhancement (xDoc : XDocument) (input : string) =
if
xDoc.Root.Elements(XName.Get "Enhancement")
|> Seq.exists (fun e -> e.Value = input)
|> not then
xDoc.Root.Add(XElement(XName.Get "Enhancement", input))
xDoc
System.ArgumentException was unhandled by user code
HResult=-2147024809
Message=' ', hexadecimal value 0x18, is an invalid character.
Source=System.Xml
StackTrace:
at System.Xml.XmlEncodedRawTextWriter.InvalidXmlChar(Int32 ch, Char* pDst, Boolean entitize)
at System.Xml.XmlEncodedRawTextWriter.WriteElementTextBlock(Char* pSrc, Char* pSrcEnd)
at System.Xml.XmlEncodedRawTextWriter.WriteString(String text)
at System.Xml.XmlEncodedRawTextWriterIndent.WriteString(String text)
at System.Xml.XmlWellFormedWriter.WriteString(String text)
at System.Xml.Linq.ElementWriter.WriteElement(XElement e)
at System.Xml.Linq.XElement.WriteTo(XmlWriter writer)
at System.Xml.Linq.XContainer.WriteContentTo(XmlWriter writer)
at System.Xml.Linq.XNode.GetXmlString(SaveOptions o)
at System.Xml.Linq.XNode.ToString()
at Program.Add enhancement must be idompotent(String input) in C:\Users\michael.newton\documents\visual studio 2012\Projects\DevEd.FsCheck\TestRunner\Program.fs:line 10
at [email protected](String input) in C:\Users\michael.newton\documents\visual studio 2012\Projects\DevEd.FsCheck\TestRunner\Program.fs:line 13
at FsCheck.Testable.evaluate[a,b](FSharpFunc`2 body, a a)
InnerException:
let filterInvalidChars (input : string) =
input
|> Seq.filter (fun c -> XmlConvert.IsXmlChar c)
|> Seq.map string
|> String.concat ""
let (|ValidXml|InvalidXml|) str =
let filtered = filterInvalidChars str
if String.length filtered = String.length str then
ValidXml str
else
InvalidXml filtered
let AddEnhancement (xDoc : XDocument) (input : string) =
match input with
| ValidXml text ->
if xDoc.Root.Elements(XName.Get "Enhancement") |> Seq.exists(fun enhance -> enhance.Value = text) then
xDoc.Root.Add(XElement(XName.Get "Enhancement", text))
| InvalidXml text ->
if xDoc.Root.Elements(XName.Get "Error") |> Seq.exists(fun error -> error.Value = text) then
xDoc.Root.Add(XElement(XName.Get "Error", text))
xDoc
module FsCheck.Examples.Tests
open FsCheck
open DevEd.FsCheck
open System.Xml.Linq
let baseDocText = """<?xml version="1.0" encoding="UTF-8"?>
<root />
"""
type XmlTree =
| NodeName of string
| Container of string * List<XmlTree>
let nodeNames =
["myNode";
"myOtherNode";
"someDifferentNode"]
let tree =
let rec tree' s =
match s with
| 0 -> Gen.map NodeName (Gen.elements nodeNames)
| n when n > 0 ->
let subtrees =
Gen.sized <| fun s ->
Gen.resize (s
|> float
|> sqrt
|> int) (Gen.listOf(tree'(n / 2)))
Gen.oneof
[Gen.map NodeName (Gen.elements nodeNames);
Gen.map2 (fun name contents -> Container(name, contents))
(Gen.elements nodeNames) subtrees]
| _ -> invalidArg "s" "Size most be positive."
Gen.sized tree'
let treeToXDoc xmlTree =
let rec inner currentNode children =
let childMatch child =
match child with
| NodeName name -> XElement(XName.Get name)
| Container(name, contents) ->
let element = XElement(XName.Get name)
inner element contents
currentNode.Add(List.map childMatch children |> List.toArray)
currentNode
match xmlTree with
| NodeName name -> XDocument(XElement(XName.Get name))
| Container(name, contents) ->
let doc = XDocument(XElement(XName.Get name))
inner doc.Root contents |> ignore
doc
type XmlGenerator() =
static member XmlTree() =
{ new Arbitrary<XmlTree>() with
member x.Generator = tree
member x.Shrinker t =
match t with
| NodeName _ -> Seq.empty
| Container(name, contents) ->
match contents with
| [] -> seq { yield NodeName name }
| c ->
seq {
for n in c -> n } }
type XmlUpdaterProperties() =
static member ``AddEnhancement is idempotent``(data : string) =
((AddEnhancement <| AddEnhancement (XDocument.Parse baseDocText) data) data)
.ToString() = (AddEnhancement (XDocument.Parse baseDocText) data)
.ToString()
static member ``AddEnhancement is idempotent on different xml structures``(xmlDoc : XmlTree,
data : string) =
(AddEnhancement (treeToXDoc xmlDoc) data).ToString() = (AddEnhancement (AddEnhancement (treeToXDoc xmlDoc) data) data)
.ToString()
static member ``AddEnhancement never reduces the number of nodes`` (xmlDoc : XmlTree, data : string) =
Seq.length ((treeToXDoc xmlDoc).DescendantNodes()) = Seq.length ((AddEnhancement (treeToXDoc xmlDoc) data).DescendantNodes())
Arb.register<XmlGenerator>() |> ignore
Check.QuickAll<XmlUpdaterProperties>()
System.Console.ReadLine() |> ignore
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment