Current section
Files
Jump to
Current section
Files
src/swear.erl
-module(swear).
%% API exports
-export([scan/1, scan/2]).
%%====================================================================
%% API functions
%%====================================================================
scan(Str) ->
scan_files(lang_files(all_languages()), Str).
scan(Str, [H|_T] = Langs) when is_list(H) ->
scan_files(lang_files(Langs), Str).
%%====================================================================
%% Internal functions
%%====================================================================
all_languages() ->
PrivDir = code:priv_dir(swear),
{ok, Filenames} = file:list_dir(PrivDir),
Filenames.
lang_files(Langs) ->
PrivDir = code:priv_dir(swear),
{ok, Filenames} = file:list_dir(PrivDir),
FilesPerLang = lists:map(fun(Lang) ->
lists:filter(fun(Filename) ->
nomatch =/= string:find(Filename, Lang, leading)
end, Filenames)
end, Langs),
lists:map(fun(Filename) -> PrivDir ++ "/" ++ Filename end, lists:umerge(FilesPerLang)).
scan_files([], _Str) ->
false;
scan_files([H|T], Str) ->
scan_lines(read_lines(H), Str) orelse scan_files(T, Str).
scan_lines(Lines, Str) ->
scan_lines(Lines, Str, false).
scan_lines([], _Str, Accum) ->
Accum;
scan_lines([H|T], Str, Accum) ->
CaseFold = string:casefold(Str),
nomatch =/= string:find(CaseFold, H, leading) orelse scan_lines(T, Str, Accum).
read_lines(FileName) ->
{ok, Pid} = file:open(FileName, [read, {encoding, utf8}]),
try
string:tokens(get_all_lines(Pid), "\n")
after
file:close(Pid)
end.
get_all_lines(Pid) ->
case io:get_line(Pid, "") of
eof -> [];
Line -> Line ++ get_all_lines(Pid)
end.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% Eunit Tests %%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-ifdef(TEST).
-include_lib("eunit/include/eunit.hrl").
global_swear_scan_test() ->
?assert(?MODULE:scan("shit")),
?assert(?MODULE:scan("merda")),
?assert(not ?MODULE:scan("lisbon")).
english_swear_not_detected_in_other_languages_test() ->
?assert(not ?MODULE:scan("shit", ["pt"])),
?assert(not ?MODULE:scan("shit", ["es"])),
?assert(not ?MODULE:scan("shit", ["fr"])),
?assert(not ?MODULE:scan("shit", ["ar", "es", "pt", "fr"])).
portuguese_swear_detected_in_list_of_languages_test() ->
?assert(not ?MODULE:scan("merda", ["es"])),
?assert(not ?MODULE:scan("merda", ["en"])),
?assert(?MODULE:scan("merda", ["en", "pt", "es"])),
?assert(?MODULE:scan("merda", ["pt", "en", "es"])),
?assert(?MODULE:scan("merda", ["en", "es", "pt"])),
?assert(?MODULE:scan("merda", ["en", "pt"])),
?assert(?MODULE:scan("merda", ["pt"])).
empty_language_scan_fails_test() ->
?assertError(function_clause, ?MODULE:scan("shit", [])),
?assertError(function_clause, ?MODULE:scan("shit", "")).
foreseen_incorrect_usage_fails_test() ->
?assertError(function_clause, ?MODULE:scan("shit", "en")).
-endif.