1+ module FSharp.Data.Tests.BaseTypesHtmlGenerics
2+
3+ open NUnit.Framework
4+ open FsUnit
5+ open System
6+ open System.Reflection
7+ open System.IO
8+ open FSharp.Data
9+ open FSharp.Data .Runtime .BaseTypes
10+
11+ // ============================================
12+ // BaseTypes.HtmlDocument Coverage Tests
13+ // ============================================
14+
15+ // Use reflection to create HtmlDocument since Create is for generated code only
16+ let private createHtmlDocumentFromString ( html : string ) =
17+ use reader = new StringReader( html)
18+ let createMethod = typeof< HtmlDocument>. GetMethod( " Create" , [| typeof< bool>; typeof< System.IO.TextReader> |])
19+ createMethod.Invoke( null , [| false ; reader |]) :?> HtmlDocument
20+
21+ [<Test>]
22+ let ``HtmlDocument Create should work using reflection`` () =
23+ let html = """ <html><body><table id="test"><tr><td>Test</td></tr></table></body></html>"""
24+ let doc = createHtmlDocumentFromString html
25+
26+ doc |> should not' ( be null )
27+ doc.Html |> should not' ( be null )
28+
29+ [<Test>]
30+ let ``HtmlDocument GetTable should handle reflection calls`` () =
31+ let html = """ <html><body><table id="testTable"><tr><td>Test</td></tr></table></body></html>"""
32+ let doc = createHtmlDocumentFromString html
33+
34+ let getTableMethod = doc.GetType() .GetMethod( " GetTable" )
35+ // Even if the table is not found, the method should exist and be callable
36+ getTableMethod |> should not' ( be null )
37+
38+ [<Test>]
39+ let ``HtmlDocument GetList should handle reflection calls`` () =
40+ let html = """ <html><body><ul id="testList"><li>Item</li></ul></body></html>"""
41+ let doc = createHtmlDocumentFromString html
42+
43+ let getListMethod = doc.GetType() .GetMethod( " GetList" )
44+ // Even if the list is not found, the method should exist and be callable
45+ getListMethod |> should not' ( be null )
46+
47+ [<Test>]
48+ let ``HtmlDocument GetDefinitionList should handle reflection calls`` () =
49+ let html = """ <html><body><dl id="testDefList"><dt>Term</dt><dd>Definition</dd></dl></body></html>"""
50+ let doc = createHtmlDocumentFromString html
51+
52+ let getDefListMethod = doc.GetType() .GetMethod( " GetDefinitionList" )
53+ // Even if the definition list is not found, the method should exist and be callable
54+ getDefListMethod |> should not' ( be null )
55+
56+ // ============================================
57+ // BaseTypes.HtmlTable<T> Coverage Tests
58+ // ============================================
59+
60+ [<Test>]
61+ let ``HtmlTable < T > Create with headers should work using reflection`` () =
62+ let html = """ <html><body><table id="testTable"><tr><th>Name</th><th>Age</th></tr><tr><td>John</td><td>30</td></tr></table></body></html>"""
63+ let doc = createHtmlDocumentFromString html
64+ let converter = Func< string[], string>( fun row -> String.Join( " ," , row))
65+ let createMethod = typeof< HtmlTable< string>>. GetMethod( " Create" , [| typeof< Func< string[], string>>; typeof< HtmlDocument>; typeof< string>; typeof< bool> |])
66+
67+ let table = createMethod.Invoke( null , [| converter; doc; " testTable" ; true |]) :?> HtmlTable< string>
68+
69+ table.Name |> should equal " testTable"
70+ table.Headers |> should not' ( be null )
71+ table.Rows.Length |> should be ( greaterThan 0 )
72+ table.Html |> should not' ( be null )
73+
74+ [<Test>]
75+ let ``HtmlTable < T > Create without headers should work using reflection`` () =
76+ let html = """ <html><body><table id="testTable"><tr><td>John</td><td>30</td></tr><tr><td>Jane</td><td>25</td></tr></table></body></html>"""
77+ let doc = createHtmlDocumentFromString html
78+ let converter = Func< string[], string>( fun row -> String.Join( " |" , row))
79+ let createMethod = typeof< HtmlTable< string>>. GetMethod( " Create" , [| typeof< Func< string[], string>>; typeof< HtmlDocument>; typeof< string>; typeof< bool> |])
80+
81+ let table = createMethod.Invoke( null , [| converter; doc; " testTable" ; false |]) :?> HtmlTable< string>
82+
83+ table.Name |> should equal " testTable"
84+ table.Headers |> should be null
85+ table.Rows.Length |> should be ( greaterThan 0 )
86+ table.Html |> should not' ( be null )
87+
88+ [<Test>]
89+ let ``HtmlTable < T > properties should be accessible`` () =
90+ let html = """ <html><body><table id="testTable"><tr><th>Col1</th><th>Col2</th></tr><tr><td>A</td><td>B</td></tr></table></body></html>"""
91+ let doc = createHtmlDocumentFromString html
92+ let converter = Func< string[], int>( fun row -> row.Length)
93+ let createMethod = typeof< HtmlTable< int>>. GetMethod( " Create" , [| typeof< Func< string[], int>>; typeof< HtmlDocument>; typeof< string>; typeof< bool> |])
94+
95+ let table = createMethod.Invoke( null , [| converter; doc; " testTable" ; true |]) :?> HtmlTable< int>
96+
97+ table.Name |> should equal " testTable"
98+ table.Headers.Value |> should haveLength 2
99+ table.Rows |> should haveLength 1
100+ table.Rows.[ 0 ] |> should equal 2
101+ table.Html |> should not' ( be null )
102+
103+ // ============================================
104+ // BaseTypes.HtmlList<T> Coverage Tests
105+ // ============================================
106+
107+ [<Test>]
108+ let ``HtmlList < T > Create should work using reflection`` () =
109+ let html = """ <html><body><ul id="testList"><li>Item 1</li><li>Item 2</li><li>Item 3</li></ul></body></html>"""
110+ let doc = createHtmlDocumentFromString html
111+ let converter = Func< string, int>( fun item -> item.Length)
112+ let createMethod = typeof< HtmlList< int>>. GetMethod( " Create" , [| typeof< Func< string, int>>; typeof< HtmlDocument>; typeof< string> |])
113+
114+ let list = createMethod.Invoke( null , [| converter; doc; " testList" |]) :?> HtmlList< int>
115+
116+ list.Name |> should equal " testList"
117+ list.Values.Length |> should be ( greaterThan 0 )
118+ list.Html |> should not' ( be null )
119+
120+ [<Test>]
121+ let ``HtmlList < T > CreateNested should work using reflection`` () =
122+ let html = """ <html><body><dl id="testDefList"><dt>Term 1</dt><dd>Definition 1</dd><dd>Another definition</dd><dt>Term 2</dt><dd>Definition 2</dd></dl></body></html>"""
123+ let doc = createHtmlDocumentFromString html
124+ let converter = Func< string, string>( fun item -> item.ToUpper())
125+ let createMethod = typeof< HtmlList< string>>. GetMethod( " CreateNested" , [| typeof< Func< string, string>>; typeof< HtmlDocument>; typeof< string>; typeof< int> |])
126+
127+ let list = createMethod.Invoke( null , [| converter; doc; " testDefList" ; 0 |]) :?> HtmlList< string>
128+
129+ list.Name |> should not' ( be null )
130+ list.Values.Length |> should be ( greaterThan 0 )
131+ list.Html |> should not' ( be null )
132+
133+ [<Test>]
134+ let ``HtmlList < T > properties should be accessible`` () =
135+ let html = """ <html><body><ul id="testList"><li>Item 1</li><li>Item 2</li></ul></body></html>"""
136+ let doc = createHtmlDocumentFromString html
137+ let converter = Func< string, string>( fun item -> item.Replace( " Item" , " Element" ))
138+ let createMethod = typeof< HtmlList< string>>. GetMethod( " Create" , [| typeof< Func< string, string>>; typeof< HtmlDocument>; typeof< string> |])
139+
140+ let list = createMethod.Invoke( null , [| converter; doc; " testList" |]) :?> HtmlList< string>
141+
142+ list.Name |> should equal " testList"
143+ list.Values.Length |> should be ( greaterThan 0 )
144+ list.Html |> should not' ( be null )
145+
146+ [<Test>]
147+ let ``HtmlList < T > with complex converter should work using reflection`` () =
148+ let html = """ <html><body><ul id="testList"><li>Item 1</li><li>Item 2</li></ul></body></html>"""
149+ let doc = createHtmlDocumentFromString html
150+
151+ // Complex converter that creates a tuple
152+ let converter = Func< string, string * int>( fun item -> ( item.Trim(), item.Length))
153+ let createMethod = typeof< HtmlList< string * int>>. GetMethod( " Create" , [| typeof< Func< string, string * int>>; typeof< HtmlDocument>; typeof< string> |])
154+
155+ let list = createMethod.Invoke( null , [| converter; doc; " testList" |]) :?> HtmlList< string * int>
156+
157+ list.Name |> should equal " testList"
158+ list.Values.Length |> should be ( greaterThan 0 )
159+ let ( text , length ) = list.Values.[ 0 ]
160+ text |> should not' ( be null )
161+ length |> should be ( greaterThan 0 )
0 commit comments