VERSION 1.0 CLASS
BEGIN
  MultiUse = -1  'True
END
Attribute VB_Name = "s_InfoDocument"
Attribute VB_GlobalNameSpace = False
Attribute VB_Creatable = False
Attribute VB_PredeclaredId = False
Attribute VB_Exposed = False
Option Explicit

' TODO:
' Public Function UpdateFormatFilter(docsFilter As Scripting.Dictionary, theDB As InfoDatabase)
' Public Function UpdateFormat(theDB As InfoDatabase) As Long
  ' Check first link should not be formatted

Private wordApp_ As API_WordWrapper
Private iDoc_ As InfoDocument
Private fso_ As Scripting.FileSystemObject

Public Function Setup()
  ' Mandatory setup function
  Set iDoc_ = New InfoDocument
  Set fso_ = New Scripting.FileSystemObject
  
  On Error Resume Next
  Call fso_.DeleteFolder(Dev_GetTestFolder)
  Call EnsureFolderExists(Dev_GetTestFolder)
  
  Set wordApp_ = New API_WordWrapper
  Call wordApp_.SetApplication(ThisDocument.Application)
End Function

Public Function Teardown()
  ' Mandatory teardown function
  Call wordApp_.ReleaseDocument
  Call fso_.DeleteFolder(Dev_GetTestFolder)
End Function

Public Function t_Init()
  On Error GoTo PROPAGATE_ERROR
  
  Dim doc As Word.Document: Set doc = wordApp_.NewDocument
  
  Call Dev_ExpectFalse(iDoc_.Init(doc), "Empty document")
    
  Call doc.Range.InsertAfter("test1" & vbNewLine)
  Call doc.Range.InsertAfter("test2" & vbNewLine)
  Call Dev_ExpectFalse(iDoc_.Init(doc), "No hyperlinks")
  
  Call Dev_NewCase("Second paragraph link")
  Call doc.Hyperlinks.Add(doc.Paragraphs.Last.Range, "http://mobileonline.garant.ru/document/redirect/1337/0")
  Call Dev_ExpectFalse(iDoc_.Init(doc))
  
  Call Dev_NewCase("Mobile garant")
  Call doc.Hyperlinks.Add(doc.Paragraphs.First.Range, "http://mobileonline.garant.ru/document/redirect/1337/0")
  Call Dev_ExpectTrue(iDoc_.Init(doc))
  Call Dev_ExpectEQ(doc.Name, iDoc_.doc_.Name)
  Call Dev_ExpectEQ(1337, iDoc_.gid_)
  Call Dev_ExpectEQ(PT_MOBILE, iDoc_.linkSystem_)
  
  Call Dev_NewCase("Local garant")
  doc.Hyperlinks(1).Address = "garantf1://1338.0/"
  Set iDoc_ = New InfoDocument
  Call Dev_ExpectTrue(iDoc_.Init(doc))
  Call Dev_ExpectEQ(doc.Name, iDoc_.doc_.Name)
  Call Dev_ExpectEQ(1338, iDoc_.gid_)
  Call Dev_ExpectEQ(PT_LOCAL, iDoc_.linkSystem_)
  
  Call Dev_NewCase("IVO garant")
  doc.Hyperlinks(1).Address = "http://internet.garant.ru/document/redirect/1339/0"
  Set iDoc_ = New InfoDocument
  Call Dev_ExpectTrue(iDoc_.Init(doc))
  Call Dev_ExpectEQ(doc.Name, iDoc_.doc_.Name)
  Call Dev_ExpectEQ(1339, iDoc_.gid_)
  Call Dev_ExpectEQ(PT_INTERNET, iDoc_.linkSystem_)
  
  Exit Function
PROPAGATE_ERROR:
  Call Dev_LogError(Err.Number, Err.Description)
End Function

Public Function t_GetSelection()
  On Error GoTo PROPAGATE_ERROR
  
  Dim doc As Word.Document: Set doc = wordApp_.NewDocument
  Call doc.Range.InsertAfter("test1" & vbNewLine)
  Set iDoc_.doc_ = doc
  
  Call Dev_ExpectEQ(vbNullString, iDoc_.GetSelection.Text, "Empty selection")
  Call doc.Range.Words(1).Select
  Call Dev_ExpectEQ(doc.Range.Words(1).Text, iDoc_.GetSelection.Text, "Empty selection")
  
  Exit Function
PROPAGATE_ERROR:
  Call Dev_LogError(Err.Number, Err.Description)
End Function

Public Function t_UpdateStyles()
  On Error GoTo PROPAGATE_ERROR
  
  Set iDoc_.doc_ = wordApp_.NewDocument
  Call iDoc_.UpdateStyles(ThisDocument.FullName)
  Dim sStyle As Variant
  For Each sStyle In GetAllLinkStyles()
    Call Dev_ExpectTrue(WordStyleExists(iDoc_.doc_, CStr(sStyle)), "Test style " & sStyle)
  Next sStyle

  Exit Function
PROPAGATE_ERROR:
  Call Dev_LogError(Err.Number, Err.Description)
End Function

Public Function t_CreateTitleLink()
  On Error GoTo PROPAGATE_ERROR
  
  Dim doc As Word.Document: Set doc = wordApp_.NewDocument
  Call doc.Range.InsertAfter("test1" & vbNewLine)
  Set iDoc_.doc_ = doc
  iDoc_.gid_ = 123
  
  Call iDoc_.CreateTitleLink
  Dim sAddr$: sAddr = "http://internet.garant.ru/document/redirect/123/0"
  Call Dev_AssertEQ(1, doc.Hyperlinks.Count, "Hyperlink count")
  Call Dev_ExpectEQ("test1", doc.Hyperlinks(1).Range.Text, "Hyperlink range")
  Call Dev_ExpectEQ(sAddr, doc.Hyperlinks(1).Address, "Hyperlink address")
  
  Exit Function
PROPAGATE_ERROR:
  Call Dev_LogError(Err.Number, Err.Description)
End Function

Public Function t_AddHyperlink()
  On Error GoTo PROPAGATE_ERROR
  
  Dim doc As Word.Document: Set doc = wordApp_.NewDocument
  Call doc.Range.InsertAfter("test1 link test2" & vbNewLine)
  Set iDoc_.doc_ = doc
  iDoc_.linkSystem_ = PT_LOCAL
  Call iDoc_.UpdateStyles(ThisDocument.FullName)
  
  Dim tRange As Word.Range: Set tRange = doc.Range(6, 10)
  Dim iLink As New ItemLink: Call iLink.Init(123, "lnk_2", 1337, "sub_1", T_LINK_ASPECT)
  
  Call Dev_ExpectFalse(iDoc_.AddHyperlink(doc.Range(tRange.End, tRange.End), iLink, Style13), "Empty range")
  Call Dev_ExpectTrue(iDoc_.AddHyperlink(tRange, iLink, Style13), "Valid add hyperlink")
  Call Dev_ExpectEQ("link", tRange.Text, "Do not edit text")
  Call Dev_AssertEQ(1, tRange.Hyperlinks.Count, "Hyperlinks count")
  Call Dev_ExpectEQ("garantf1://1337.1/", tRange.Hyperlinks(1).Address, "Hyperlink address")
  Call Dev_AssertEQ(1, tRange.Bookmarks.Count, "Bookmarks count")
  Call Dev_ExpectEQ("lnk_2", tRange.Bookmarks(1).Name, "Bookmarks name")
  tRange.Start = tRange.End - Len(tRange.Text)
  Call Dev_ExpectEQ(Style13, tRange.Style, "Apply formatting Style")
    
  Call doc.Range.InsertAfter("test2" & vbNewLine)
  Call Dev_ExpectFalse(iDoc_.AddHyperlink(doc.Paragraphs.Last.Range, iLink, Style13), "Bookmark taken")

  Exit Function
PROPAGATE_ERROR:
  Call Dev_LogError(Err.Number, Err.Description)
End Function

Public Function t_FormatLink()
  On Error GoTo PROPAGATE_ERROR
  
  Dim doc As Word.Document: Set doc = wordApp_.NewDocument
  Call doc.Range.InsertAfter("test1" & vbNewLine)
  Set iDoc_.doc_ = doc
  iDoc_.gid_ = 123
  Call iDoc_.UpdateStyles(ThisDocument.FullName)
  Call iDoc_.CreateTitleLink
  
  Dim hLink As Word.Hyperlink: Set hLink = doc.Hyperlinks(1)
  Call iDoc_.FormatLink(hLink, T_LINK_DEFINITION, T_LINKS_IGNORE, T_LAWS_FULL, T_LAWS_FULL)
  Call Dev_ExpectEQ(Style13, hLink.Range.Style, "Change style")
  Call Dev_ExpectTrue(hLink.Range.Font.StrikeThrough, "Change StrikeThrough")
  
  Exit Function
PROPAGATE_ERROR:
  Call Dev_LogError(Err.Number, Err.Description)
End Function

Public Function t_ApplyLinkStatus()
  On Error GoTo PROPAGATE_ERROR
  
  Dim doc As Word.Document: Set doc = wordApp_.NewDocument
  Call doc.Range.InsertAfter("test1" & vbNewLine)
  Call doc.Hyperlinks.Add(doc.Paragraphs.First.Range, "http://mobileonline.garant.ru/document/redirect/1337/0")
  Call iDoc_.Init(doc)
  
  Call Dev_NewCase("Status Ignore")
  Call iDoc_.ApplyLinkStatus(doc.Hyperlinks(1), T_LINKS_IGNORE)
  Call Dev_ExpectTrue(doc.Hyperlinks(1).Range.Font.StrikeThrough)
  
  Call Dev_NewCase("Status Add")
  Call iDoc_.ApplyLinkStatus(doc.Hyperlinks(1), T_LINKS_ADD)
  Call Dev_ExpectFalse(doc.Hyperlinks(1).Range.Font.StrikeThrough)

  Exit Function
PROPAGATE_ERROR:
  Call Dev_LogError(Err.Number, Err.Description)
End Function

Public Function t_CountLinksIn()
  On Error GoTo PROPAGATE_ERROR
  
  Dim doc As Word.Document: Set doc = wordApp_.NewDocument
  Set iDoc_.doc_ = doc
  Call Dev_ExpectEQ(0, iDoc_.CountLinksIn(doc.Range), "Empty Document")
  
  Call Dev_SetupThreeLinks(iDoc_)
  Dim testRange As Word.Range: Set testRange = doc.Range
  Call Dev_ExpectEQ(3, iDoc_.CountLinksIn(testRange), "Full range")
  
  testRange.End = doc.Hyperlinks(3).Range.Start
  Call Dev_ExpectEQ(2, iDoc_.CountLinksIn(testRange), "Ends on link")
  
  testRange.End = doc.Hyperlinks(3).Range.Start + 1
  Call Dev_ExpectEQ(3, iDoc_.CountLinksIn(testRange), "Partial intersection")
  
  doc.Hyperlinks(2).Address = "invalid"
  Call Dev_ExpectEQ(2, iDoc_.CountLinksIn(testRange), "Do not count invalid link")

  Exit Function
PROPAGATE_ERROR:
  Call Dev_LogError(Err.Number, Err.Description)
End Function

Public Function t_CountLinksBefore()
  On Error GoTo PROPAGATE_ERROR
  
  Dim doc As Word.Document: Set doc = wordApp_.NewDocument
  Set iDoc_.doc_ = doc
  Call Dev_ExpectEQ(0, iDoc_.CountLinksBefore(1), "Empty Document")
  
  Call Dev_SetupThreeLinks(iDoc_)
  
  Call Dev_ExpectEQ(0, iDoc_.CountLinksBefore(0), "Start of the document")
  Call Dev_ExpectEQ(0, iDoc_.CountLinksBefore(-1), "Negative start")
  Call Dev_ExpectEQ(doc.Hyperlinks.Count, iDoc_.CountLinksBefore(doc.Range.End), "End of the document")
  Call Dev_ExpectEQ(doc.Hyperlinks.Count, iDoc_.CountLinksBefore(doc.Range.End + 100), "Past end of the document")
  
  Call Dev_ExpectEQ(1, iDoc_.CountLinksBefore(doc.Hyperlinks(1).Range.End), "End of hlink 1")
  Call Dev_ExpectEQ(2, iDoc_.CountLinksBefore(doc.Hyperlinks(2).Range.End), "End of hlink 2")
  Call Dev_ExpectEQ(3, iDoc_.CountLinksBefore(doc.Hyperlinks(3).Range.End), "End of hlink 3")
  
  Call Dev_ExpectEQ(0, iDoc_.CountLinksBefore(doc.Hyperlinks(1).Range.Start), "Start of hlink 1")
  Call Dev_ExpectEQ(1, iDoc_.CountLinksBefore(doc.Hyperlinks(2).Range.Start), "Start of hlink 2")
  Call Dev_ExpectEQ(2, iDoc_.CountLinksBefore(doc.Hyperlinks(3).Range.Start), "Start of hlink 3")
  
  Call Dev_ExpectEQ(1, iDoc_.CountLinksBefore(doc.Hyperlinks(1).Range.Start + 2), "Mid of hlink 1")
  Call Dev_ExpectEQ(2, iDoc_.CountLinksBefore(doc.Hyperlinks(2).Range.Start + 2), "Mid of hlink 2")
  Call Dev_ExpectEQ(3, iDoc_.CountLinksBefore(doc.Hyperlinks(3).Range.Start + 2), "Mid of hlink 3")

  Exit Function
PROPAGATE_ERROR:
  Call Dev_LogError(Err.Number, Err.Description)
End Function

Public Function t_FindNextUnresolved()
  On Error GoTo PROPAGATE_ERROR
  
  Dim doc As Word.Document: Set doc = wordApp_.NewDocument
  Set iDoc_.doc_ = doc
  Call Dev_ExpectNothing(iDoc_.FindNextUnresolved(0), "Empty Document")
  
  Call Dev_SetupThreeLinks(iDoc_)
  
  Dim sLink1$: sLink1 = doc.Hyperlinks(1).Address
  Dim sLink2$: sLink2 = doc.Hyperlinks(2).Address
  Dim sLink3$: sLink3 = doc.Hyperlinks(3).Address
  
  Call Dev_ExpectEQ(sLink1, iDoc_.FindNextUnresolved(0).Address, "Start of the document")
  Call Dev_ExpectEQ(sLink1, iDoc_.FindNextUnresolved(-1).Address, "Negative start")
  Call Dev_ExpectNothing(iDoc_.FindNextUnresolved(doc.Range.End), "End of the document")
  Call Dev_ExpectNothing(iDoc_.FindNextUnresolved(doc.Range.End + 100), "Past end of the document")
  
  Call Dev_ExpectEQ(sLink2, iDoc_.FindNextUnresolved(doc.Hyperlinks(1).Range.End).Address, "End of hlink 1")
  Call Dev_ExpectEQ(sLink3, iDoc_.FindNextUnresolved(doc.Hyperlinks(2).Range.End).Address, "End of hlink 2")
  Call Dev_ExpectEQ(sLink1, iDoc_.FindNextUnresolved(doc.Hyperlinks(3).Range.End).Address, "End of hlink 3")
  
  Call Dev_ExpectEQ(sLink1, iDoc_.FindNextUnresolved(doc.Hyperlinks(1).Range.Start).Address, "Start of hlink 1")
  Call Dev_ExpectEQ(sLink2, iDoc_.FindNextUnresolved(doc.Hyperlinks(2).Range.Start).Address, "Start of hlink 2")
  Call Dev_ExpectEQ(sLink3, iDoc_.FindNextUnresolved(doc.Hyperlinks(3).Range.Start).Address, "Start of hlink 3")
  
  Call Dev_ExpectEQ(sLink1, iDoc_.FindNextUnresolved(doc.Hyperlinks(1).Range.Start + 2).Address, "Mid of hlink 1")
  Call Dev_ExpectEQ(sLink2, iDoc_.FindNextUnresolved(doc.Hyperlinks(2).Range.Start + 2).Address, "Mid of hlink 2")
  Call Dev_ExpectEQ(sLink3, iDoc_.FindNextUnresolved(doc.Hyperlinks(3).Range.Start + 2).Address, "Mid of hlink 3")
  
  Call Dev_NewCase("Skip ignored")
  doc.Hyperlinks(2).Range.Style = Style4A
  Call Dev_ExpectEQ(sLink3, iDoc_.FindNextUnresolved(doc.Hyperlinks(1).Range.End).Address)
  Call Dev_ExpectEQ(sLink3, iDoc_.FindNextUnresolved(doc.Hyperlinks(2).Range.End).Address)
  Call Dev_ExpectEQ(sLink1, iDoc_.FindNextUnresolved(doc.Hyperlinks(3).Range.End).Address)
  
  Call Dev_NewCase("Skip accepted")
  doc.Hyperlinks(2).Range.Style = Style11
  Call Dev_ExpectEQ(sLink3, iDoc_.FindNextUnresolved(doc.Hyperlinks(1).Range.End).Address)
  Call Dev_ExpectEQ(sLink3, iDoc_.FindNextUnresolved(doc.Hyperlinks(2).Range.End).Address)
  Call Dev_ExpectEQ(sLink1, iDoc_.FindNextUnresolved(doc.Hyperlinks(3).Range.End).Address)
  
  Call Dev_NewCase("Skip declined")
  doc.Hyperlinks(2).Range.Style = Style10
  doc.Hyperlinks(2).Range.Font.StrikeThrough = True
  Call Dev_ExpectEQ(sLink3, iDoc_.FindNextUnresolved(doc.Hyperlinks(1).Range.End).Address)
  Call Dev_ExpectEQ(sLink3, iDoc_.FindNextUnresolved(doc.Hyperlinks(2).Range.End).Address)
  Call Dev_ExpectEQ(sLink1, iDoc_.FindNextUnresolved(doc.Hyperlinks(3).Range.End).Address)
  
  Exit Function
PROPAGATE_ERROR:
  Call Dev_LogError(Err.Number, Err.Description)
End Function

Public Function t_IgnoreLawLinks()
  On Error GoTo PROPAGATE_ERROR
  
  Dim doc As Word.Document: Set doc = wordApp_.NewDocument
  Set iDoc_.doc_ = doc
  Dim docsToIgnore As New Scripting.Dictionary
  
  On Error Resume Next
  Call iDoc_.IgnoreLawLinks(docsToIgnore)
  Call Dev_ExpectNoError("Empty Document")
  On Error GoTo PROPAGATE_ERROR
  
  Call Dev_SetupThreeLinks(iDoc_)
  
  On Error Resume Next
  Call iDoc_.IgnoreLawLinks(docsToIgnore)
  Call Dev_ExpectNoError("Empty ignorelist")
  On Error GoTo PROPAGATE_ERROR
  
  Dim gid1&: gid1 = ParseHyperlink(doc.Hyperlinks(1)).DocumentID
  Dim gid2&: gid2 = ParseHyperlink(doc.Hyperlinks(2)).DocumentID
  Dim gid3&: gid3 = ParseHyperlink(doc.Hyperlinks(3)).DocumentID
  Dim rng1 As Word.Range: Set rng1 = doc.Hyperlinks(1).Range.Words.Last
  Dim rng2 As Word.Range: Set rng2 = doc.Hyperlinks(2).Range.Words.Last
  Dim rng3 As Word.Range: Set rng3 = doc.Hyperlinks(3).Range.Words.Last
  
  Call Dev_NewCase("Valid ignore")
  Call docsToIgnore.Add(gid2, "")
  Call docsToIgnore.Add(gid3, "")
  Call iDoc_.IgnoreLawLinks(docsToIgnore)
  Call Dev_ExpectEQ(Style10, rng1.Style)
  Call Dev_ExpectEQ(Style4A, rng2.Style)
  Call Dev_ExpectEQ(Style4A, rng3.Style)
  
  Call Dev_NewCase("Keep declined status")
  doc.Hyperlinks(2).Range.Style = Style10
  doc.Hyperlinks(2).Range.Font.StrikeThrough = True
  doc.Hyperlinks(3).Range.Style = Style10
  Call iDoc_.IgnoreLawLinks(docsToIgnore)
  Call Dev_ExpectEQ(Style10, rng1.Style)
  Call Dev_ExpectTrue(rng2.Font.StrikeThrough)
  Call Dev_ExpectEQ(Style4A, rng2.Style)
  Call Dev_ExpectEQ(Style4A, rng3.Style)
  
  Exit Function
PROPAGATE_ERROR:
  Call Dev_LogError(Err.Number, Err.Description)
End Function

Public Function t_RemoveLinksFrom()
  On Error GoTo PROPAGATE_ERROR
  
  Dim doc As Word.Document: Set doc = wordApp_.NewDocument
  Set iDoc_.doc_ = doc
  Dim docsToIgnore As New Scripting.Dictionary
  
  On Error Resume Next
  Call iDoc_.RemoveLinksFrom(doc.Range)
  Call Dev_ExpectNoError("Empty Document")
  On Error GoTo PROPAGATE_ERROR
  
  Call Dev_NewCase("Remove all links")
  Call Dev_SetupThreeLinks(iDoc_)
  Call iDoc_.RemoveLinksFrom(doc.Range)
  Call Dev_ExpectEQ(0, doc.Hyperlinks.Count)
  
  Call Dev_NewCase("Remove link precise")
  Call Dev_SetupThreeLinks(iDoc_)
  Dim rLink As Word.Range: Set rLink = doc.Hyperlinks(2).Range
  Call iDoc_.RemoveLinksFrom(rLink)
  Call Dev_ExpectEQ(2, doc.Hyperlinks.Count)
  Call Dev_ExpectEQ(0, rLink.Hyperlinks.Count)
  Call Dev_ExpectNE(Style10, rLink.Style)
  
  Call Dev_NewCase("Remove partial hit")
  Call Dev_SetupThreeLinks(iDoc_)
  Set rLink = doc.Hyperlinks(2).Range
  rLink.Start = rLink.Start - 5
  rLink.End = rLink.End + 5
  Call iDoc_.RemoveLinksFrom(rLink)
  Call Dev_ExpectEQ(2, doc.Hyperlinks.Count)
  Call Dev_ExpectEQ(0, rLink.Hyperlinks.Count)
  Call Dev_ExpectNE(Style10, rLink.Style)
  
  Exit Function
PROPAGATE_ERROR:
  Call Dev_LogError(Err.Number, Err.Description)
End Function

Public Function t_UpdateLinkTip()
  On Error GoTo PROPAGATE_ERROR
  
  Dim dbWrap As API_XLWrapper: Set dbWrap = Dev_GetDatabase
  Dim oDatabase As New InfoDatabase: Call oDatabase.Init(dbWrap.Document)
  
  Dim iData As ItemLaw: Set iData = GetDummyData
  Call oDatabase.SetItem(iData.Clone)
  
  Dim doc As Word.Document: Set doc = wordApp_.NewDocument
  Set iDoc_.doc_ = doc
  Call doc.Range.InsertAfter("test" & vbNewLine)
  Dim hLink As Word.Hyperlink: Set hLink = doc.Hyperlinks.Add(doc.Paragraphs.First.Range, "garantf1://123.0/")
  
  Call Dev_NewCase("Empty title")
  iData.title_ = vbNullString
  Call oDatabase.SetItem(iData.Clone)
  Call iDoc_.UpdateLinkTip(hLink, iData.gid_, oDatabase)
  Call Dev_ExpectEQ(vbNullString, hLink.ScreenTip)
  
  Call Dev_NewCase("Real title")
  iData.title_ = "Some title law"
  Call oDatabase.SetItem(iData.Clone)
  Call iDoc_.UpdateLinkTip(hLink, iData.gid_, oDatabase)
  Call Dev_ExpectEQ(iData.title_, hLink.ScreenTip)
  
  Call dbWrap.ReleaseDocument
  
  Exit Function
PROPAGATE_ERROR:
  Call Dev_LogError(Err.Number, Err.Description)
End Function

Public Function t_GetParagraphLink()
  On Error GoTo PROPAGATE_ERROR
  
  Dim doc As Word.Document: Set doc = wordApp_.NewDocument
  Set iDoc_.doc_ = doc
  iDoc_.gid_ = 1337
  Call Dev_ExpectEQ(vbNullString, iDoc_.GetParagraphLink(doc.Range), "Empty document")
  
  Call doc.Range.InsertAfter("test1" & vbNewLine & "test2" & vbNewLine)
  Call Dev_ExpectEQ(vbNullString, iDoc_.GetParagraphLink(doc.Range), "No bookmarks")
  
  Call Dev_NewCase("Valid bookmark link")
  Dim bmRange As Word.Range: Set bmRange = doc.Paragraphs(1).Range
  Call bmRange.Bookmarks.Add("sub_12")
  Call Dev_ExpectEQ("1337#sub_12", iDoc_.GetParagraphLink(bmRange))
  
  Exit Function
PROPAGATE_ERROR:
  Call Dev_LogError(Err.Number, Err.Description)
End Function

Public Function t_GetLawDescription()
  On Error GoTo PROPAGATE_ERROR
  
  Dim doc As Word.Document: Set doc = wordApp_.NewDocument
  Set iDoc_.doc_ = doc
  iDoc_.gid_ = 1337
  Dim iLaw As ItemLaw
  
  Call Dev_NewCase("Empty document")
  Set iLaw = iDoc_.GetLawDescription
  Call Dev_AssertNotNothing(iLaw)
  Call Dev_ExpectEQ(iDoc_.gid_, iLaw.gid_, "law id")
  Call Dev_ExpectEQ(doc.Name, iLaw.fileName_, "File name")
  Call Dev_ExpectEQ(vbNullString, iLaw.title_, "default title")
  Call Dev_ExpectFalse(iLaw.isDummy_, "Is Dummy")
  
  Call Dev_NewCase("Invalid title")
  doc.Range.Text = " Invalid title "
  Set iLaw = iDoc_.GetLawDescription
  Call Dev_ExpectEQ(iDoc_.gid_, iLaw.gid_, "law id")
  Call Dev_ExpectEQ(doc.Name, iLaw.fileName_, "File name")
  Call Dev_ExpectEQ("Invalid title", iLaw.title_, "trimmed title")
  Call Dev_ExpectFalse(iLaw.isDummy_, "Is Dummy")
  
  Call Dev_NewCase("Parsable title")
  Dim sTitle$: sTitle = "Приказ Минрегиона РФ от 23 марта 2012 г. N 126 " & _
                    """Об утверждении Порядка обжалования заключений ... инженерных изысканий"""
  doc.Range.Text = sTitle
  Set iLaw = iDoc_.GetLawDescription
  Call Dev_ExpectEQ(iDoc_.gid_, iLaw.gid_, "law id")
  Call Dev_ExpectEQ(doc.Name, iLaw.fileName_, "File name")
  Call Dev_ExpectEQ("Порядка обжалования заключений ... инженерных изысканий", iLaw.attach_, "parsed attach")
  Call Dev_ExpectEQ("Минрегиона РФ", iLaw.creator_, "parsed creator")
  Call Dev_ExpectEQ("23.03.2012", iLaw.date_, "parsed date")
  Call Dev_ExpectEQ("Об утверждении Порядка обжалования заключений ... инженерных изысканий", iLaw.header_, "parsed header")
  Call Dev_ExpectFalse(iLaw.isDummy_, "Is Dummy")
  Call Dev_ExpectFalse(iLaw.isScoped_, "Is Scoped")
  Call Dev_ExpectEQ("N 126", iLaw.number_, "parsed number")
  Call Dev_ExpectEQ(T_LAW_11_MINISTRY, iLaw.type_, "parsed type")
  Call Dev_ExpectEQ(sTitle, iLaw.title_, "parsed title")

  Exit Function
PROPAGATE_ERROR:
  Call Dev_LogError(Err.Number, Err.Description)
End Function
