Skip to content

Instantly share code, notes, and snippets.

@mneedham
Created July 18, 2009 03:41
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mneedham/149395 to your computer and use it in GitHub Desktop.
Save mneedham/149395 to your computer and use it in GitHub Desktop.
Tests:
[<Test>]
let should_throw_exception_if_feed_xml_is_invalid () =
Assert.Throws<FailureException>(fun () -> FeedBurners.ProcessFeed "some broken xml" |> ignore) |> ignore
[<Test>]
let should_throw_exception_if_no_feed_found () =
let feedXml = @"<?xml version=""1.0"" encoding=""utf-8"" ?>
<rsp stat=""fail"">
<err code=""1"" msg=""Feed Not Found"" />
</rsp>"
Assert.Throws<FailureException>((fun () -> FeedBurners.ProcessFeed feedXml |> ignore),
"Failed to process feed: Feed Not Found") |> ignore
[<Test>]
let should_retrieve_circulation_and_date_if_valid_xml () =
let feedXml = @"<?xml version=""1.0"" encoding=""UTF-8""?>
<rsp stat=""ok"">
<feed id=""tdv0bg210cr731gc3nssn512cg"" uri=""MarkNeedham"">
<entry date=""2009-07-16"" circulation=""630"" hits=""1389"" reach=""629"" />
</feed>
</rsp>"
let entries = FeedBurners.ProcessFeed feedXml
let entry = entries |> Seq.hd
Assert.AreEqual(entry.Circulation, 630)
Assert.AreEqual(entry.Date, "2009-07-16")
Code:
let xName value = XName.Get value
let GetDescendants element (xDocument:XDocument) = xDocument.Descendants(xName element)
let GetAttribute element (xElement:XElement) = xElement.Attribute(xName element)
type FeedBurnerApi = { Date : string; Circulation : decimal}
let (|NoFeedFound|FeedBurnerStats|) xml =
try
let document = xml |> XDocument.Parse
let entries = document |>
GetDescendants "entry" |>
Seq.map (fun element -> GetAttribute "circulation" element, GetAttribute "date" element) |>
Seq.map (fun attribute -> { Circulation = Decimal.Parse((fst attribute).Value);
Date = (snd attribute).Value } )
match Seq.length entries with
| 0 -> NoFeedFound((document |> GetDescendants "err" |> Seq.hd |> GetAttribute "msg").Value)
| _ -> FeedBurnerStats(entries)
with
| :? System.Xml.XmlException as ex -> NoFeedFound(ex.Message)
let ProcessFeed xml =
match xml with
| NoFeedFound(error) -> failwith ("Failed to process feed: " + error)
| FeedBurnerStats(entries) -> entries
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment