%%
%% %CopyrightBegin%
%%
%% Copyright Ericsson AB 1997-2016. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
%%
%% http://www.apache.org/licenses/LICENSE-2.0
%%
%% Unless required by applicable law or agreed to in writing, software
%% distributed under the License is distributed on an "AS IS" BASIS,
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
%%
%% %CopyrightEnd%
%%
%%
-module(erl_match_SUITE).
-include_lib("common_test/include/ct.hrl").
-include("erl_match_SUITE_data/match_test_cases.hrl").
-export([all/0, suite/0,
atoms/1, lists/1, tuples/1, references/1, pids/1, ports/1,
bind/1, integers/1, floats/1, binaries/1, strings/1]).
%% For interactive running of matcher.
-export([start_matcher/1, erl_match/3]).
%% This test suite tests the erl_match() function.
suite() ->
[{ct_hooks,[ts_install_cth]}].
all() ->
[atoms, lists, tuples, references, pids, ports, bind,
integers, floats, binaries, strings].
atoms(Config) when is_list(Config) ->
P = start_matcher(Config),
eq(P, '', ''),
eq(P, a, a),
ne(P, a, b),
ne(P, a, aa),
eq(P, kalle, kalle),
ne(P, kalle, arne),
ne(P, kalle, 42),
ne(P, 42, kalle),
runner:finish(P),
ok.
lists(Config) when is_list(Config) ->
P = start_matcher(Config),
eq(P, [], []),
ne(P, [], [a]),
ne(P, [a], []),
eq(P, [a], [a]),
ne(P, [a], [b]),
eq(P, [a|b], [a|b]),
ne(P, [a|b], [a|x]),
eq(P, [a, b], [a, b]),
ne(P, [a, b], [a, x]),
eq(P, [a, b, c], [a, b, c]),
ne(P, [a, b|c], [a, b|x]),
ne(P, [a, b, c], [a, b, x]),
ne(P, [a, b|c], [a, b|x]),
ne(P, [a, x|c], [a, b|c]),
ne(P, [a, b, c], [a, x, c]),
runner:finish(P),
ok.
tuples(Config) when is_list(Config) ->
P = start_matcher(Config),
ne(P, {}, {a, b}),
ne(P, {a, b}, {}),
ne(P, {a}, {a, b}),
ne(P, {a, b}, {a}),
eq(P, {}, {}),
eq(P, {a}, {a}),
ne(P, {a}, {b}),
eq(P, {1}, {1}),
ne(P, {1}, {2}),
eq(P, {a, b}, {a, b}),
ne(P, {x, b}, {a, b}),
ne(P, {error, x}, {error, y}),
ne(P, {error, {undefined, {subscriber, last}}},
{error, {undefined, {subscriber, name}}}),
runner:finish(P),
ok.
references(Config) when is_list(Config) ->
P = start_matcher(Config),
Ref1 = make_ref(),
Ref2 = make_ref(),
eq(P, Ref1, Ref1),
eq(P, Ref2, Ref2),
ne(P, Ref1, Ref2),
ne(P, Ref2, Ref1),
runner:finish(P),
ok.
pids(Config) when is_list(Config) ->
P = start_matcher(Config),
Pid1 = c:pid(0,1,2),
Pid2 = c:pid(0,1,3),
eq(P, self(), self()),
eq(P, Pid1, Pid1),
ne(P, Pid1, self()),
ne(P, Pid2, Pid1),
runner:finish(P),
ok.
ports(Config) when is_list(Config) ->
case os:type() of
vxworks ->
{skipped,"not on vxworks, pucko"};
_ ->
P = start_matcher(Config),
P2 = start_matcher(Config),
eq(P, P, P),
ne(P, P, P2),
runner:finish(P),
runner:finish(P2),
ok
end.
integers(Config) when is_list(Config) ->
P = start_matcher(Config),
I1 = 123,
I2 = 12345,
I3 = -123,
I4 = 2234,
eq(P, I1, I1),
eq(P, I2, I2),
ne(P, I1, I2),
ne(P, I1, I3),
eq(P, I4, I4),
runner:finish(P),
ok.
floats(Config) when is_list(Config) ->
P = start_matcher(Config),
F1 = 3.1414,
F2 = 3.1415,
F3 = 3.1416,
S1 = "string",
S2 = "string2",
eq(P, F1, F1),
eq(P, F2, F2),
ne(P, F1, F2),
ne(P, F3, F2),
eq(P, S2, S2),
ne(P, S1, S2),
runner:finish(P),
ok.
binaries(Config) when is_list(Config) ->
P = start_matcher(Config),
Bin1 = term_to_binary({kalle, 146015, {kungsgatan, 23}}),
Bin2 = term_to_binary(sune),
Bin3 = list_to_binary("sune"),
eq(P, Bin1, Bin1),
eq(P, Bin2, Bin2),
eq(P, Bin3, Bin3),
ne(P, Bin1, Bin2),
ne(P, Bin1, Bin3),
ne(P, Bin2, Bin3),
runner:finish(P),
ok.
strings(Config) when is_list(Config) ->
P = start_matcher(Config),
S1 = "string",
S2 = "streng",
S3 = "String",
eq(P, S1, S1),
ne(P, S1, S2),
ne(P, S1, S3),
runner:finish(P),
ok.
bind(Config) when is_list(Config) ->
P = start_bind(Config),
S = "[X,Y,Z]",
L1 = [301,302,302],
L2 = [65,66,67],
bind_ok(P, S, L1),
bind_ok(P, S, L2),
runner:finish(P),
ok.
start_bind(Config) ->
runner:start(?erl_match_bind).
bind_ok(Port, Bind, Term) ->
true = erl_bind(Port, Bind, Term).
%bind_nok(Port, Bind, Term) ->
% false = erl_bind(Port, Bind, Term).
erl_bind(Port, Pattern, Term) ->
Port ! {self(), {command, [$b, Pattern, 0]}},
runner:send_term(Port, Term),
case runner:get_term(Port) of
{term, 0} -> false;
{term, 1} -> true
end.
start_matcher(Config) ->
runner:start(?erl_match_server).
eq(Port, Pattern, Term) ->
true = erl_match(Port, Pattern, Term).
ne(Port, Pattern, Term) ->
false = erl_match(Port, Pattern, Term).
erl_match(Port, Pattern, Term) ->
runner:send_term(Port, Pattern),
runner:send_term(Port, Term),
case runner:get_term(Port) of
{term, 0} -> false;
{term, 1} -> true
end.