Merge pull request #41 from blackducksw/ubuntu_14
[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_DTX, "foo.dtx");
123   ASSERT_DETECT(LANG_TEX, "foo.tex");
124   ASSERT_DETECT(LANG_XSLT, "example.xsl");
125   ASSERT_DETECT(LANG_LOGTALK, "foo.lgt");
126   ASSERT_DETECT(LANG_LISP, "core.lisp");
127   ASSERT_DETECT(LANG_DMD, "foo.d");
128   ASSERT_DETECT(LANG_VIM, "foo.vim");
129   ASSERT_DETECT(LANG_EC, "foo.ec");
130   ASSERT_DETECT(LANG_EC, "foo.eh");
131   ASSERT_DETECT(LANG_EBUILD, "foo.ebuild");
132   ASSERT_DETECT(LANG_EBUILD, "foo.eclass");
133   ASSERT_DETECT(LANG_EXHERES, "foo.exheres-0");
134   ASSERT_DETECT(LANG_EXHERES, "foo.exlib");
135   ASSERT_DETECT(LANG_EIFFEL, "eiffel.e");
136   ASSERT_DETECT(LANG_OCAML, "ocaml.ml");
137   ASSERT_DETECT(LANG_AUGEAS, "augeas.aug");
138   ASSERT_DETECT(LANG_STRATEGO, "stratego.str");
139   ASSERT_DETECT(LANG_GLSL, "foo.glsl");
140   ASSERT_DETECT(LANG_GLSL, "foo_glsl.vert");
141   ASSERT_DETECT(LANG_GLSL, "foo_glsl.frag");
142   ASSERT_DETECT(LANG_IDL_PVWAVE, "foo.pro");
143   ASSERT_DETECT(LANG_ASSEMBLER, "foo.z80");
144   ASSERT_DETECT(LANG_PHP, "php.inc");
145   ASSERT_DETECT(LANG_FORTH, "forth.4th");
146   ASSERT_DETECT(LANG_FORTH, "forth.fr");
147   ASSERT_DETECT(LANG_FSHARP, "fs1.fs");
148   ASSERT_DETECT(LANG_AUTOCONF, "m4.m4");
149   ASSERT_DETECT(LANG_NSIS, "foo.nsi");
150   ASSERT_DETECT(LANG_NSIS, "foo.nsh");
151   ASSERT_DETECT(LANG_COFFEESCRIPT, "foo.coffee");
152   ASSERT_DETECT(LANG_QML, "foo.qml");
153   ASSERT_DETECT(LANG_COQ, "coq.v");
154   ASSERT_NODETECT("empty.inc");
155 }
156
157 void test_detector_upper_case_extensions() {
158   ASSERT_DETECT(LANG_CPP, "foo_upper_case.C");
159   ASSERT_DETECT(LANG_RUBY, "foo_upper_case.RB");
160 }
161
162 void test_detector_no_extensions() {
163   ASSERT_DETECT(LANG_PYTHON, "py_script");
164   ASSERT_DETECT(LANG_RUBY, "ruby_script");
165   ASSERT_DETECT(LANG_SHELL, "bourne_again_script");
166   ASSERT_DETECT(LANG_SHELL, "bash_script");
167   ASSERT_DETECT(LANG_PERL, "perl_w");
168   ASSERT_DETECT(LANG_DMD, "d_script");
169   ASSERT_DETECT(LANG_TCL, "tcl_script");
170   ASSERT_DETECT(LANG_PYTHON, "python.data");
171   ASSERT_DETECT(LANG_PYTHON, "python2.data");
172   ASSERT_DETECT(LANG_CPP, "uses_cpp_modeline");
173 }
174
175 void test_detector_csharp_or_clearsilver() {
176   ASSERT_DETECT(LANG_CSHARP, "cs1.cs");
177   ASSERT_DETECT(LANG_CLEARSILVER_TEMPLATE, "clearsilver_template1.cs");
178 }
179
180 void test_detector_basic() {
181   ASSERT_DETECT(LANG_VISUALBASIC, "visual_basic.bas");
182   ASSERT_DETECT(LANG_CLASSIC_BASIC, "classic_basic.b");
183   assert(system("mv ../detect_files/frx1.frx ../detect_files/frx1.frx2") == 0);
184   ASSERT_DETECT(LANG_STRUCTURED_BASIC, "visual_basic.bas");
185   ASSERT_DETECT(LANG_STRUCTURED_BASIC, "structured_basic.b");
186   assert(system("mv ../detect_files/frx1.frx2 ../detect_files/frx1.frx") == 0);
187 }
188
189 void test_detector_xml_with_custom_extension() {
190   ASSERT_DETECT(LANG_XML, "xml.custom_ext");
191 }
192
193 void test_detector_brainfuck() {
194   ASSERT_DETECT(LANG_BRAINFUCK, "foo.bf");
195   ASSERT_DETECT(LANG_BFPP, "foo.bfpp");
196 }
197
198 void test_detector_emacs_mode() {
199         ASSERT_DETECT(LANG_C, "emacs_mode_c");
200 }
201
202 void test_detector_emacs_with_extension() {
203   ASSERT_DETECT(LANG_RUBY, "java_emac.rb");
204   ASSERT_DETECT(LANG_JAVASCRIPT, "javascript_emac.js");
205 }
206
207 void test_detector_puppet(){
208   ASSERT_DETECT(LANG_PUPPET, "puppet_import.pp");
209   ASSERT_DETECT(LANG_PUPPET, "puppet_test.pp");
210 }
211
212 void test_detector_genie(){
213   ASSERT_DETECT(LANG_GENIE, "client-osx.gs");
214 }
215
216 void test_detector_rust(){
217   ASSERT_DETECT(LANG_RUST, "rust.rs");
218   // When RenderScript is implemented, this will, of course, need to be removed.
219   ASSERT_NODETECT("renderscript.rs");
220 }
221
222 void test_non_existent_file(){
223   ASSERT_NODETECT("xxx_non_exists_xxxi.pp");  
224 }
225
226 void all_detector_tests() {
227   test_detector_smalltalk();
228   test_detector_disambiguate_asx();
229   test_detector_disambiguate_def();
230   test_detector_disambiguate_m();
231   test_detector_disambiguate_in();
232   test_detector_disambiguate_pl();
233   test_detector_disambiguate_pro();
234   test_detector_disambiguate_r();
235   test_detector_fortran_fixedfree();
236   test_detector_detect_polyglot();
237   test_detector_upper_case_extensions();
238   test_detector_no_extensions();
239   test_detector_csharp_or_clearsilver();
240   test_detector_basic();
241   test_detector_xml_with_custom_extension();
242   test_detector_brainfuck();
243   test_detector_emacs_mode();
244   test_detector_emacs_with_extension();
245   test_detector_puppet();
246   test_detector_genie();
247   test_detector_rust();
248   test_non_existent_file();
249 }