-
-
Notifications
You must be signed in to change notification settings - Fork 292
Expand file tree
/
Copy pathLibVLCAPICoverage.cs
More file actions
108 lines (88 loc) · 3.92 KB
/
LibVLCAPICoverage.cs
File metadata and controls
108 lines (88 loc) · 3.92 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
using NUnit.Framework;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Net.Http;
using System.Reflection;
using System.Threading.Tasks;
namespace LibVLCSharp.Tests
{
[TestFixture]
public class LibVLCAPICoverage
{
const string LibVLCSymURL = "https://code.videolan.org/videolan/vlc/-/raw/master/lib/libvlc.sym";
[Test]
public async Task CheckLibVLCCoverage()
{
string[] libvlcSymbols;
using (var httpClient = new HttpClient())
{
libvlcSymbols = (await httpClient.GetStringAsync(LibVLCSymURL)).Split(new[] { '\r', '\n' }).Where(s => !string.IsNullOrEmpty(s)).ToArray();
}
var dllImports = new List<string>();
// retrieving EventManager using reflection because the type is internal
var eventManager = typeof(MediaPlayer).GetRuntimeProperties()
.First(n => n.Name.Equals("EventManager"))
.PropertyType
.BaseType!;
var libvlcTypes = new List<Type>
{
typeof(LibVLC),
typeof(MediaPlayer),
typeof(Media),
typeof(MediaDiscoverer),
typeof(RendererDiscoverer),
typeof(RendererItem),
typeof(Dialog),
typeof(MediaList),
typeof(Equalizer),
typeof(Picture),
typeof(PictureList),
typeof(MediaTrack),
typeof(MediaTrackList),
typeof(ProgramList),
eventManager
};
var implementedButHidden = new List<string>
{
"libvlc_media_player_set_android_context", // android build only
"libvlc_free" // hidden in internal type
};
// not implemented symbols for lack of use case or user interest
var notImplementedOnPurpose = new List<string>
{
"libvlc_media_list_player", "libvlc_dialog_get_context", "libvlc_dialog_set_context", "libvlc_log_get_object", "libvlc_media_player_lock", "libvlc_media_player_signal", "libvlc_media_player_unlock", "libvlc_media_player_wait"
};
var exclude = new List<string>();
exclude.AddRange(implementedButHidden);
exclude.AddRange(notImplementedOnPurpose);
foreach (var libvlcType in libvlcTypes)
{
var r = libvlcType.GetNestedType("Native", BindingFlags.NonPublic);
if (r == null) continue;
foreach (var method in r.GetRuntimeMethods())
{
foreach (var attr in method.CustomAttributes)
{
if (attr.AttributeType.Name.Equals("DllImportAttribute"))
{
var arg = attr.NamedArguments.FirstOrDefault(a => a.MemberName.Equals("EntryPoint"));
if (arg == default) continue;
var sym = (string)arg.TypedValue.Value!;
dllImports.Add(sym);
}
}
}
}
var unusedDllImports = dllImports.Except(libvlcSymbols);
var missingApis = libvlcSymbols
.Where(symbol => !exclude.Any(excludeSymbol => symbol.StartsWith(excludeSymbol))) // Filters out excluded symbols
.Except(dllImports);
var missingApisCount = missingApis.Count();
Debug.WriteLine($"we have {dllImports.Count} dll import statements");
Assert.Zero(missingApis.Count(), string.Concat("missing APIs are: ", string.Join(", ", missingApis)));
Assert.Zero(unusedDllImports.Count(), string.Concat("unused dll imports are: ", string.Join(", ", unusedDllImports)));
}
}
}