Fixes recursion bug in disambiguate_in().
[ohcount] / test / unit / detector_test.h
1 // detector_test.h written by Mitchell Foral. mitchell<att>caladbolg.net.
2 // See COPYING for license information.
3
4 #include <assert.h>
5 #include <dirent.h>
6 #include <stdlib.h>
7 #include <string.h>
8
9 #include "../../src/detector.h"
10 #include "../../src/languages.h"
11 #include "../../src/sourcefile.h"
12
13 char **get_filenames(SourceFile *sourcefile) {
14         if (sourcefile->filenames == NULL) {
15                 char dirpath[FILENAME_MAX];
16                 strncpy(dirpath, sourcefile->filepath, sourcefile->dirpath);
17                 dirpath[sourcefile->dirpath] = '\0';
18                 struct dirent *file;
19                 DIR *d = opendir((const char *)dirpath);
20                 if (d) {
21                         int length = 0;
22                         while ((file = readdir(d))) length++;
23                         closedir(d);
24
25                         char **filenames = calloc(length + 1, sizeof(char *));
26                         int i = 0;
27                         d = opendir((const char *)dirpath);
28                         while ((file = readdir(d))) {
29                                 int len = strlen(file->d_name);
30                                 char *filename = malloc(len + 1);
31                                 strncpy(filename, file->d_name, len);
32                                 filename[len] = '\0';
33                                 filenames[i++] = filename;
34                         }
35                         closedir(d);
36                         sourcefile->filenames = filenames;
37                 }
38         }
39         return sourcefile->filenames;
40 }
41
42 #define ASSERT_DETECT(x, y) { \
43   SourceFile *sf = ohcount_sourcefile_new("../detect_files/" y); \
44         get_filenames(sf); \
45   const char *lang = ohcount_detect_language(sf); \
46   assert(lang); \
47   assert(strcmp(x, lang) == 0); \
48   ohcount_sourcefile_free(sf); \
49 }
50 #define ASSERT_NODETECT(x) { \
51   SourceFile *sf = ohcount_sourcefile_new("../detect_files/" x); \
52         get_filenames(sf); \
53   assert(ohcount_detect_language(sf) == NULL); \
54   ohcount_sourcefile_free(sf); \
55 }
56
57 void test_detector_smalltalk() {
58   ASSERT_DETECT(LANG_SMALLTALK, "example.st");
59   ASSERT_NODETECT("english.st");
60 }
61
62 void test_detector_disambiguate_asx() {
63   ASSERT_DETECT(LANG_ASSEMBLER, "assembler6502.asx");
64   ASSERT_NODETECT("AdvancedStreamRedirector.asx");
65 }
66
67 void test_detector_disambiguate_def() {
68   ASSERT_DETECT(LANG_MODULA2, "sampleDef.def");
69   ASSERT_NODETECT("module-definition.def");
70 }
71
72 void test_detector_disambiguate_m() {
73   ASSERT_DETECT(LANG_OBJECTIVE_C, "t1.m");
74   ASSERT_DETECT(LANG_OBJECTIVE_C, "t2.m");
75   ASSERT_DETECT(LANG_OBJECTIVE_C, "TCPSocket.m");
76   ASSERT_DETECT(LANG_OBJECTIVE_C, "foo_objective_c.m");
77   ASSERT_DETECT(LANG_MATLAB, "foo_matlab.m");
78   ASSERT_DETECT(LANG_OCTAVE, "foo_octave.m");
79 }
80
81 void test_detector_disambiguate_in() {
82   ASSERT_NODETECT("empty.in");
83   ASSERT_NODETECT("foo.in.in");
84 }
85
86 void test_detector_disambiguate_pl() {
87   ASSERT_DETECT(LANG_PERL, "foo_perl1.pl");
88   ASSERT_DETECT(LANG_PERL, "foo_perl2.pl");
89   ASSERT_DETECT(LANG_PROLOG, "foo_prolog1.pl");
90   ASSERT_DETECT(LANG_PERL, "perl_with_smiley.pl");
91   ASSERT_DETECT(LANG_PERL, "perl_shebang_prolog_body.pl");
92 }
93
94 void test_detector_disambiguate_pro() {
95   ASSERT_DETECT(LANG_IDL_PVWAVE, "foo.pro");
96   ASSERT_DETECT(LANG_MAKE, "qmake.pro");
97 }
98
99 void test_detector_disambiguate_r() {
100   ASSERT_DETECT(LANG_R, "foo_r.R");
101   ASSERT_DETECT(LANG_REBOL, "foo_rebol_lower.r");
102   ASSERT_DETECT(LANG_REBOL, "foo_rebol_upper.r");
103 }
104
105 void test_detector_fortran_fixedfree() {
106   ASSERT_DETECT(LANG_FORTRANFIXED, "fortranfixed.f");
107   ASSERT_DETECT(LANG_FORTRANFREE, "fortranfree.f");
108 }
109
110 void test_detector_detect_polyglot() {
111   ASSERT_DETECT(LANG_C, "foo.c");
112   ASSERT_DETECT(LANG_C, "uses_no_cpp.h");
113   ASSERT_DETECT(LANG_CPP, "uses_cpp_headers.h");
114   ASSERT_DETECT(LANG_CPP, "uses_cpp_stdlib_headers.h");
115   ASSERT_DETECT(LANG_CPP, "uses_cpp_keywords.h");
116   ASSERT_DETECT(LANG_RUBY, "foo.rb");
117   ASSERT_DETECT(LANG_MAKE, "foo.mk");
118   ASSERT_DETECT(LANG_OBJECTIVE_C, "foo_objective_c.h");
119   ASSERT_DETECT(LANG_PHP, "upper_case_php");
120   ASSERT_DETECT(LANG_SMALLTALK, "example.st");
121   ASSERT_DETECT(LANG_VALA, "foo.vala");
122   ASSERT_DETECT(LANG_TEX, "foo.tex");
123   ASSERT_DETECT(LANG_XSLT, "example.xsl");
124   ASSERT_DETECT(LANG_LOGTALK, "foo.lgt");
125   ASSERT_DETECT(LANG_LISP, "core.lisp");
126   ASSERT_DETECT(LANG_DMD, "foo.d");
127   ASSERT_DETECT(LANG_VIM, "foo.vim");
128   ASSERT_DETECT(LANG_EC, "foo.ec");
129   ASSERT_DETECT(LANG_EC, "foo.eh");
130   ASSERT_DETECT(LANG_EBUILD, "foo.ebuild");
131   ASSERT_DETECT(LANG_EBUILD, "foo.eclass");
132   ASSERT_DETECT(LANG_EXHERES, "foo.exheres-0");
133   ASSERT_DETECT(LANG_EXHERES, "foo.exlib");
134   ASSERT_DETECT(LANG_EIFFEL, "eiffel.e");
135   ASSERT_DETECT(LANG_OCAML, "ocaml.ml");
136   ASSERT_DETECT(LANG_STRATEGO, "stratego.str");
137   ASSERT_DETECT(LANG_GLSL, "foo.glsl");
138   ASSERT_DETECT(LANG_GLSL, "foo_glsl.vert");
139   ASSERT_DETECT(LANG_GLSL, "foo_glsl.frag");
140   ASSERT_DETECT(LANG_IDL_PVWAVE, "foo.pro");
141   ASSERT_DETECT(LANG_ASSEMBLER, "foo.z80");
142   ASSERT_DETECT(LANG_PHP, "php.inc");
143   ASSERT_DETECT(LANG_FORTH, "forth.4th");
144   ASSERT_DETECT(LANG_FORTH, "forth.fr");
145   ASSERT_DETECT(LANG_FSHARP, "fs1.fs");
146   ASSERT_DETECT(LANG_AUTOCONF, "m4.m4");
147   ASSERT_DETECT(LANG_NSIS, "foo.nsi");
148   ASSERT_DETECT(LANG_NSIS, "foo.nsh");
149   ASSERT_DETECT(LANG_COFFEESCRIPT, "foo.coffee");
150   ASSERT_DETECT(LANG_QML, "foo.qml");
151   ASSERT_NODETECT("empty.inc");
152 }
153
154 void test_detector_upper_case_extensions() {
155   ASSERT_DETECT(LANG_CPP, "foo_upper_case.C");
156   ASSERT_DETECT(LANG_RUBY, "foo_upper_case.RB");
157 }
158
159 void test_detector_no_extensions() {
160   ASSERT_DETECT(LANG_PYTHON, "py_script");
161   ASSERT_DETECT(LANG_RUBY, "ruby_script");
162   ASSERT_DETECT(LANG_SHELL, "bourne_again_script");
163   ASSERT_DETECT(LANG_SHELL, "bash_script");
164   ASSERT_DETECT(LANG_PERL, "perl_w");
165   ASSERT_DETECT(LANG_DMD, "d_script");
166   ASSERT_DETECT(LANG_TCL, "tcl_script");
167   ASSERT_DETECT(LANG_PYTHON, "python.data");
168   ASSERT_DETECT(LANG_PYTHON, "python2.data");
169   ASSERT_DETECT(LANG_CPP, "uses_cpp_modeline");
170 }
171
172 void test_detector_csharp_or_clearsilver() {
173   ASSERT_DETECT(LANG_CSHARP, "cs1.cs");
174   ASSERT_DETECT(LANG_CLEARSILVER_TEMPLATE, "clearsilver_template1.cs");
175 }
176
177 void test_detector_basic() {
178   ASSERT_DETECT(LANG_VISUALBASIC, "visual_basic.bas");
179   ASSERT_DETECT(LANG_CLASSIC_BASIC, "classic_basic.b");
180   assert(system("mv ../detect_files/frx1.frx ../detect_files/frx1.frx2") == 0);
181   ASSERT_DETECT(LANG_STRUCTURED_BASIC, "visual_basic.bas");
182   ASSERT_DETECT(LANG_STRUCTURED_BASIC, "structured_basic.b");
183   assert(system("mv ../detect_files/frx1.frx2 ../detect_files/frx1.frx") == 0);
184 }
185
186 void test_detector_xml_with_custom_extension() {
187   ASSERT_DETECT(LANG_XML, "xml.custom_ext");
188 }
189
190 void test_detector_brainfuck() {
191   ASSERT_DETECT(LANG_BRAINFUCK, "foo.bf");
192   ASSERT_DETECT(LANG_BFPP, "foo.bfpp");
193 }
194
195 void test_detector_emacs_mode() {
196         ASSERT_DETECT(LANG_C, "emacs_mode.c");
197 }
198
199 void all_detector_tests() {
200   test_detector_smalltalk();
201   test_detector_disambiguate_asx();
202   test_detector_disambiguate_def();
203   test_detector_disambiguate_m();
204   test_detector_disambiguate_in();
205   test_detector_disambiguate_pl();
206   test_detector_disambiguate_pro();
207   test_detector_disambiguate_r();
208   test_detector_fortran_fixedfree();
209   test_detector_detect_polyglot();
210   test_detector_upper_case_extensions();
211   test_detector_no_extensions();
212   test_detector_csharp_or_clearsilver();
213   test_detector_basic();
214   test_detector_xml_with_custom_extension();
215   test_detector_brainfuck();
216   test_detector_emacs_mode();
217 }