diff options
author | Sverker Eriksson <[email protected]> | 2017-08-30 20:55:08 +0200 |
---|---|---|
committer | Sverker Eriksson <[email protected]> | 2017-08-30 20:55:08 +0200 |
commit | 7c67bbddb53c364086f66260701bc54a61c9659c (patch) | |
tree | 92ab0d4b91d5e2f6e7a3f9d61ea25089e8a71fe0 /lib/wx/test | |
parent | 97dc5e7f396129222419811c173edc7fa767b0f8 (diff) | |
parent | 3b7a6ffddc819bf305353a593904cea9e932e7dc (diff) | |
download | otp-7c67bbddb53c364086f66260701bc54a61c9659c.tar.gz otp-7c67bbddb53c364086f66260701bc54a61c9659c.tar.bz2 otp-7c67bbddb53c364086f66260701bc54a61c9659c.zip |
Merge tag 'OTP-19.0' into sverker/19/binary_to_atom-utf8-crash/ERL-474/OTP-14590
Diffstat (limited to 'lib/wx/test')
-rw-r--r-- | lib/wx/test/Makefile | 21 | ||||
-rw-r--r-- | lib/wx/test/wx_app_SUITE.erl | 40 | ||||
-rw-r--r-- | lib/wx/test/wx_basic_SUITE.erl | 143 | ||||
-rw-r--r-- | lib/wx/test/wx_class_SUITE.erl | 259 | ||||
-rw-r--r-- | lib/wx/test/wx_event_SUITE.erl | 287 | ||||
-rw-r--r-- | lib/wx/test/wx_obj_test.erl | 100 | ||||
-rw-r--r-- | lib/wx/test/wx_opengl_SUITE.erl | 25 | ||||
-rw-r--r-- | lib/wx/test/wx_test_lib.erl | 41 | ||||
-rw-r--r-- | lib/wx/test/wx_test_lib.hrl | 23 | ||||
-rw-r--r-- | lib/wx/test/wx_xtra_SUITE.erl | 37 | ||||
-rwxr-xr-x | lib/wx/test/wxt | 25 | ||||
-rw-r--r-- | lib/wx/test/wxt.erl | 33 |
12 files changed, 757 insertions, 277 deletions
diff --git a/lib/wx/test/Makefile b/lib/wx/test/Makefile index 836885a308..9a78307be1 100644 --- a/lib/wx/test/Makefile +++ b/lib/wx/test/Makefile @@ -1,18 +1,19 @@ # # %CopyrightBegin% # -# Copyright Ericsson AB 2008-2012. All Rights Reserved. +# Copyright Ericsson AB 2008-2016. All Rights Reserved. # -# The contents of this file are subject to the Erlang Public License, -# Version 1.1, (the "License"); you may not use this file except in -# compliance with the License. You should have received a copy of the -# Erlang Public License along with this software. If not, it can be -# retrieved online at http://www.erlang.org/. +# 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 # -# Software distributed under the License is distributed on an "AS IS" -# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See -# the License for the specific language governing rights and limitations -# under the License. +# 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% # diff --git a/lib/wx/test/wx_app_SUITE.erl b/lib/wx/test/wx_app_SUITE.erl index 162923eaa3..3fd5bf689d 100644 --- a/lib/wx/test/wx_app_SUITE.erl +++ b/lib/wx/test/wx_app_SUITE.erl @@ -1,18 +1,19 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2010-2011. All Rights Reserved. +%% Copyright Ericsson AB 2010-2016. All Rights Reserved. %% -%% The contents of this file are subject to the Erlang Public License, -%% Version 1.1, (the "License"); you may not use this file except in -%% compliance with the License. You should have received a copy of the -%% Erlang Public License along with this software. If not, it can be -%% retrieved online at http://www.erlang.org/. +%% 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 %% -%% Software distributed under the License is distributed on an "AS IS" -%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See -%% the License for the specific language governing rights and limitations -%% under the License. +%% 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% %% @@ -26,6 +27,7 @@ -compile(export_all). -include("wx_test_lib.hrl"). +-include_lib("common_test/include/ct.hrl"). t() -> wx_test_lib:t(?MODULE). @@ -47,10 +49,10 @@ end_per_testcase(Func,Config) -> %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -suite() -> [{ct_hooks,[ts_install_cth]}]. +suite() -> [{ct_hooks,[ts_install_cth]}, {timetrap,{minutes,5}}]. all() -> - [fields, modules, exportall, app_depend, undef_funcs]. + [fields, modules, exportall, app_depend, undef_funcs, appup]. groups() -> []. @@ -219,12 +221,10 @@ check_apps([App|Apps]) -> %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -undef_funcs(suite) -> - []; -undef_funcs(doc) -> - []; +undef_funcs() -> + [{timetrap,{minutes,10}}]. + undef_funcs(Config) when is_list(Config) -> - catch test_server:timetrap(timer:minutes(10)), App = wx, AppFile = key1search(app_file, Config), Mods = key1search(modules, AppFile), @@ -281,3 +281,9 @@ key1search(Key, L) -> {value, {Key, Value}} -> Value end. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +%% Test that the wx appup file is ok +appup(Config) when is_list(Config) -> + ok = ?t:appup_test(wx). diff --git a/lib/wx/test/wx_basic_SUITE.erl b/lib/wx/test/wx_basic_SUITE.erl index d55a037599..6a2528780e 100644 --- a/lib/wx/test/wx_basic_SUITE.erl +++ b/lib/wx/test/wx_basic_SUITE.erl @@ -1,19 +1,19 @@ -%% -*- coding: utf-8 -*- %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2008-2013. All Rights Reserved. +%% Copyright Ericsson AB 2008-2016. All Rights Reserved. %% -%% The contents of this file are subject to the Erlang Public License, -%% Version 1.1, (the "License"); you may not use this file except in -%% compliance with the License. You should have received a copy of the -%% Erlang Public License along with this software. If not, it can be -%% retrieved online at http://www.erlang.org/. -%% -%% Software distributed under the License is distributed on an "AS IS" -%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See -%% the License for the specific language governing rights and limitations -%% under the License. +%% 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% %%%------------------------------------------------------------------- @@ -45,7 +45,7 @@ end_per_testcase(Func,Config) -> wx_test_lib:end_per_testcase(Func,Config). %% SUITE specification -suite() -> [{ct_hooks,[ts_install_cth]}]. +suite() -> [{ct_hooks,[ts_install_cth]}, {timetrap,{minutes,2}}]. all() -> [silent_start, create_window, several_apps, wx_api, wx_misc, @@ -99,8 +99,23 @@ several_apps(Config) -> Pids = [spawn_link(fun() -> several_apps(Parent, N, Config) end) || N <- lists:seq(1,4)], process_flag(trap_exit,true), - ?m_multi_receive([{complete,Pid} || Pid <- Pids]), + Wait = fun(Pid,Acc) -> + receive {complete, Pid} -> Acc + after 20000 -> [Pid|Acc] + end + end, + Res = lists:foldl(Wait, [], Pids), [Pid ! quit || Pid <- Pids], + + Dbg = fun(Pid) -> + io:format("Stack ~p~n",[erlang:process_info(Pid, current_stacktrace)]), + io:format("Stack ~p~n",[erlang:process_info(Pid)]) + end, + case Res of + [] -> ok; + Failed -> + [Dbg(Pid)|| Pid <- Failed] + end, case wx_test_lib:user_available(Config) of true -> receive {'EXIT',_,foo} -> ok end; @@ -177,7 +192,9 @@ wx_api(Config) -> ?m(ok,wxButton:setLabel(Temp, "Testing")), ?m(ok,wxButton:destroy(Temp)), ?m({'EXIT',_},wxButton:getLabel(Temp)), - + ?m(ok,wxButton:setLabel(Temp, "Testing")), %% Should generate an error report + ?m({'EXIT',_},wxButton:getLabel(Temp)), + case wx_test_lib:user_available(Config) of true -> %% Hmm popup doesn't return until mouse is pressed. @@ -217,7 +234,7 @@ create_menus(Frame) -> %% Test the wx_misc.erl api functionality. wx_misc(TestInfo) when is_atom(TestInfo) -> wx_test_lib:tc_info(TestInfo); -wx_misc(Config) -> +wx_misc(_Config) -> wx:new([{debug, trace}]), put(wx_test_verbose, true), ?m(ok, wx_misc:bell()), @@ -242,21 +259,6 @@ wx_misc(Config) -> %% wx:shutdown() %% How do you test this? - case os:type() of - {win32, _} -> %% These hangs when running automatic tests - skip; %% through ssh on windows. Works otherwise - _ -> - wx_misc:shell([{command,"echo TESTING close the popup shell"}]) - end, - - case wx_test_lib:user_available(Config) of - true -> - wx_misc:shell(); - false -> - %% Don't want to spawn a shell if no user - skip %% is available - end, - ?m(false, wx_misc:isBusy()), ?m(ok, wx_misc:beginBusyCursor([])), ?m(true, wx_misc:isBusy()), @@ -272,13 +274,19 @@ wx_misc(Config) -> wx:destroy(). -%% Check that all the data_types works in communication +%% Check that all the data_types works in communication %% between erlang and c++ thread. data_types(TestInfo) when is_atom(TestInfo) -> wx_test_lib:tc_info(TestInfo); data_types(_Config) -> Wx = ?mr(wx_ref, wx:new()), - + Frame = wxFrame:new(Wx, 1, "Data Types"), + wxFrame:connect(Frame, show), + wxFrame:show(Frame), + receive #wx{event=#wxShow{}} -> ok + after 1000 -> exit(show_timeout) + end, + CDC = wxClientDC:new(Frame), %% From wx.erl @@ -293,16 +301,31 @@ data_types(_Config) -> ?m(ok, wxDC:setUserScale(CDC, 123.45, 234.67)), ?m({123.45,234.67}, wxDC:getUserScale(CDC)), + %% Array of doubles + try wxGraphicsContext:create(CDC) of + GC -> + wxGraphicsContext:setFont(GC, ?wxITALIC_FONT, {0, 0, 50}), + Ws = wxGraphicsContext:getPartialTextExtents(GC, "a String With More Than 16 Characters"), + _ = lists:foldl(fun(Width, {Index, Acc}) -> + if Width >= Acc, Width < 500 -> {Index+1, Width}; + true -> throw({bad_float, Width, Index, Acc}) + end + end, {0,0.0}, Ws), + ok + catch _:_ -> %% GC not supported on this platform + ok + end, + %% Colors input is 3 or 4 tuple, returns are 4 tuples ?m(ok, wxDC:setTextForeground(CDC, {100,10,1})), ?m({100,10,1,255}, wxDC:getTextForeground(CDC)), ?m(ok, wxDC:setTextForeground(CDC, {100,10,1,43})), ?m({100,10,1,43}, wxDC:getTextForeground(CDC)), - %% Bool + %% Bool ?m(ok, wxDC:setAxisOrientation(CDC, true, false)), ?m(true, is_boolean(wxDC:isOk(CDC))), - + %% wxCoord ?m(true, is_integer(wxDC:maxX(CDC))), @@ -310,13 +333,27 @@ data_types(_Config) -> ?m({_,_}, wxWindow:getSize(Frame)), %% DateTime - DateTime = {Date, _Time} = calendar:now_to_datetime(erlang:now()), + DateTime = {Date, _Time} = calendar:now_to_datetime(os:timestamp()), io:format("DateTime ~p ~n",[DateTime]), Cal = ?mt(wxCalendarCtrl, wxCalendarCtrl:new(Frame, ?wxID_ANY, [{date,DateTime}])), ?m({Date,_}, wxCalendarCtrl:getDate(Cal)), ?m(true, is_boolean(wxCalendarCtrl:setDate(Cal,DateTime))), ?m({Date,_}, wxCalendarCtrl:getDate(Cal)), + %% Images, test sending and reading binaries + Colors = << <<200:8, 199:8, 198:8 >> || _ <- lists:seq(1, 128*64) >>, + Alpha = << <<255:8>> || _ <- lists:seq(1, 128*64) >>, + ImgRGB = ?mt(wxImage, wxImage:new(128, 64, Colors)), + ?m(true, wxImage:ok(ImgRGB)), + ?m(false, wxImage:hasAlpha(ImgRGB)), + ?m(ok, case wxImage:getData(ImgRGB) of Colors -> ok; Other -> Other end), + + ImgRGBA = ?mt(wxImage, wxImage:new(128, 64, Colors, Alpha)), + ?m(true, wxImage:ok(ImgRGBA)), + ?m(true, wxImage:hasAlpha(ImgRGBA)), + ?m(ok, case wxImage:getData(ImgRGBA) of Colors -> ok; Other -> Other end), + ?m(ok, case wxImage:getAlpha(ImgRGBA) of Alpha -> ok; Other -> Other end), + wxClientDC:destroy(CDC), %%wx_test_lib:wx_destroy(Frame,Config). wx:destroy(). @@ -324,29 +361,47 @@ data_types(_Config) -> wx_object(TestInfo) when is_atom(TestInfo) -> wx_test_lib:tc_info(TestInfo); wx_object(Config) -> wx:new(), - Frame = ?mt(wxFrame, wx_obj_test:start([])), + Me = self(), + Init = fun() -> + Frame0 = wxFrame:new(wx:null(), ?wxID_ANY, "Test wx_object", [{size, {500, 400}}]), + Frame = wx_object:set_pid(Frame0, self()), + Sz = wxBoxSizer:new(?wxHORIZONTAL), + Panel = wxPanel:new(Frame), + wxSizer:add(Sz, Panel, [{flag, ?wxEXPAND}, {proportion, 1}]), + wxPanel:connect(Panel, size, [{skip, true}]), + wxPanel:connect(Panel, paint, [callback, {userData, Me}]), + wxWindow:show(Frame), + {Frame, {Frame, Panel}} + end, + Frame = ?mt(wxFrame, wx_obj_test:start([{init, Init}])), + timer:sleep(500), ?m(ok, check_events(flush())), Me = self(), ?m({call, foobar, {Me, _}}, wx_object:call(Frame, foobar)), ?m(ok, wx_object:cast(Frame, foobar2)), - ?m([{cast, foobar2}], flush()), + ?m([{cast, foobar2}|_], flush()), + + ?m(Frame, wx_obj_test:who_are_you(Frame)), + {call, {Frame,Panel}, _} = wx_object:call(Frame, fun(US) -> US end), + ?m(false, wxWindow:getParent(Panel) =:= Frame), + ?m(true, wx:equal(wxWindow:getParent(Panel),Frame)), FramePid = wx_object:get_pid(Frame), io:format("wx_object pid ~p~n",[FramePid]), FramePid ! foo3, - ?m([{info, foo3}], flush()), + ?m([{info, foo3}|_], flush()), ?m(ok, wx_object:cast(Frame, fun(_) -> hehe end)), - ?m([{cast, hehe}], flush()), + ?m([{cast, hehe}|_], flush()), wxWindow:refresh(Frame), - ?m([{sync_event, #wx{event=#wxPaint{}}, _}], flush()), + ?m([{sync_event, #wx{event=#wxPaint{}}, _}|_], flush()), ?m(ok, wx_object:cast(Frame, fun(_) -> timer:sleep(200), slept end)), %% The sleep above should not hinder the Paint event below %% Which it did in my buggy handling of the sync_callback wxWindow:refresh(Frame), - ?m([{sync_event, #wx{event=#wxPaint{}}, _}], flush()), - ?m([{cast, slept}], flush()), + timer:sleep(500), + ?m([{sync_event, #wx{event=#wxPaint{}}, _}, {cast, slept}|_], flush()), Monitor = erlang:monitor(process, FramePid), case proplists:get_value(user, Config, false) of @@ -386,7 +441,7 @@ check_events([], Async, Sync) -> end. flush() -> - flush([], 500). + flush([], 1500). flush(Acc, Wait) -> receive diff --git a/lib/wx/test/wx_class_SUITE.erl b/lib/wx/test/wx_class_SUITE.erl index 7c3eda0be1..0a3c4659bf 100644 --- a/lib/wx/test/wx_class_SUITE.erl +++ b/lib/wx/test/wx_class_SUITE.erl @@ -1,18 +1,19 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2008-2013. All Rights Reserved. +%% Copyright Ericsson AB 2008-2016. All Rights Reserved. %% -%% The contents of this file are subject to the Erlang Public License, -%% Version 1.1, (the "License"); you may not use this file except in -%% compliance with the License. You should have received a copy of the -%% Erlang Public License along with this software. If not, it can be -%% retrieved online at http://www.erlang.org/. +%% 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 %% -%% Software distributed under the License is distributed on an "AS IS" -%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See -%% the License for the specific language governing rights and limitations -%% under the License. +%% 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% %%%------------------------------------------------------------------- @@ -45,12 +46,12 @@ end_per_testcase(Func,Config) -> wx_test_lib:end_per_testcase(Func,Config). %% SUITE specification -suite() -> [{ct_hooks,[ts_install_cth]}]. +suite() -> [{ct_hooks,[ts_install_cth]}, {timetrap,{minutes,2}}]. all() -> [calendarCtrl, treeCtrl, notebook, staticBoxSizer, clipboard, helpFrame, htmlWindow, listCtrlSort, listCtrlVirtual, - radioBox, systemSettings, taskBarIcon]. + radioBox, systemSettings, taskBarIcon, toolbar, popup, modal]. groups() -> []. @@ -71,7 +72,7 @@ calendarCtrl(Config) -> Panel = wxPanel:new(Frame), Sz = wxBoxSizer:new(?wxVERTICAL), - {YMD={_,_,Day},_} = DateTime = calendar:now_to_datetime(erlang:now()), + {YMD={_,_,Day},_} = DateTime = calendar:now_to_datetime(os:timestamp()), Cal = ?mt(wxCalendarCtrl, wxCalendarCtrl:new(Panel, ?wxID_ANY, [{date,DateTime} ])), @@ -231,8 +232,15 @@ staticBoxSizer(Config) -> clipboard(TestInfo) when is_atom(TestInfo) -> wx_test_lib:tc_info(TestInfo); -clipboard(_Config) -> - wx:new(), +clipboard(Config) -> + Wx = wx:new(), + Frame = wxFrame:new(Wx, ?wxID_ANY, "Main Frame"), + Ctrl = wxTextCtrl:new(Frame, ?wxID_ANY, [{size, {600,400}}, {style, ?wxTE_MULTILINE}]), + wxTextCtrl:connect(Ctrl, command_text_copy, [{skip, true}]), + wxTextCtrl:connect(Ctrl, command_text_cut, [{skip, true}]), + wxTextCtrl:connect(Ctrl, command_text_paste, [{skip, true}]), + wxWindow:show(Frame), + CB = ?mt(wxClipboard, wxClipboard:get()), wxClipboard:usePrimarySelection(CB), ?m(false, wx:is_null(CB)), @@ -271,7 +279,8 @@ clipboard(_Config) -> ?log("Flushing ~n",[]), wxClipboard:flush(CB), ?log("Stopping ~n",[]), - ok. + wx_test_lib:wx_destroy(Frame,Config). + helpFrame(TestInfo) when is_atom(TestInfo) -> wx_test_lib:tc_info(TestInfo); helpFrame(Config) -> @@ -279,10 +288,13 @@ helpFrame(Config) -> MFrame = wx:batch(fun() -> MFrame = wxFrame:new(Wx, ?wxID_ANY, "Main Frame"), wxPanel:new(MFrame, [{size, {600,400}}]), + wxFrame:connect(MFrame, show), wxWindow:show(MFrame), MFrame end), - timer:sleep(9), + receive #wx{event=#wxShow{}} -> ok + after 1000 -> exit(show_timeout) + end, {X0, Y0} = wxWindow:getScreenPosition(MFrame), {X, Y, W,H} = wxWindow:getScreenRect(MFrame), @@ -344,21 +356,21 @@ listCtrlSort(Config) -> Wx = wx:new(), Frame = wxFrame:new(Wx, ?wxID_ANY, "Frame"), - LC = wxListCtrl:new(Frame, [{style, ?wxLC_REPORT bor ?wxLC_SORT_ASCENDING}]), + LC = wxListCtrl:new(Frame, [{style, ?wxLC_REPORT}]), %% must be done crashes in wxwidgets otherwise. wxListCtrl:insertColumn(LC, 0, "Column"), Add = fun(Int) -> - wxListCtrl:insertItem(LC, Int, integer_to_list(Int)), + wxListCtrl:insertItem(LC, Int, "ABC " ++ integer_to_list(Int)), %% ItemData Can only be integers currently - wxListCtrl:setItemData(LC, Int, abs(2500-Int)) + wxListCtrl:setItemData(LC, Int, abs(50-Int)) end, - wx:foreach(Add, lists:seq(0,5000)), + wx:foreach(Add, lists:seq(0,50)), wxWindow:show(Frame), - timer:sleep(200), + timer:sleep(2000), Sort = fun() -> wxListCtrl:sortItems(LC, fun(A, B) -> @@ -374,12 +386,26 @@ listCtrlSort(Config) -> io:format("Sorted ~p ~n",[Time]), Item = wxListItem:new(), + + %% Test that wx-asserts are sent to error logger + %% Force an assert on 3.0 (when debug compiled which it is by default) + wxListItem:setId(Item, 200), + case os:type() of + {win32, _} -> + wxListItem:setColumn(Item, 3), + io:format("Got ~p ~n", [wxListCtrl:insertItem(LC, Item)]), + wxListItem:setColumn(Item, 0); + _ -> %% Uses generic listctrl + %% we can't use the code above on linux with wx-2.8.8 because it segfaults. + io:format("Got ~p ~n", [wxListCtrl:getItem(LC, Item)]) + end, + + wxListItem:setMask(Item, ?wxLIST_MASK_TEXT), _List = wx:map(fun(Int) -> wxListItem:setId(Item, Int), ?m(true, wxListCtrl:getItem(LC, Item)), - io:format("~s~n",[wxListItem:getText(Item)]) - end, lists:seq(0,100)), - wxListItem:destroy(Item), + io:format("~p: ~s~n",[Int, wxListItem:getText(Item)]) + end, lists:seq(0,10)), wx_test_lib:wx_destroy(Frame,Config). @@ -432,15 +458,16 @@ radioBox(Config) -> Frame = wxFrame:new(Wx, ?wxID_ANY, "Frame"), TrSortRadioBox = wxRadioBox:new(Frame, ?wxID_ANY, "Sort by:", - {100, 100},{100, 100}, ["Timestamp"]), + {100, 100},{100, 100}, + ["Timestamp", "Session", "FooBar"]), io:format("TrSortRadioBox ~p ~n", [TrSortRadioBox]), - %% If I uncomment any of these lines, it will crash - - io:format("~p~n", [catch wxControlWithItems:setClientData(TrSortRadioBox, 0, timestamp)]), - %?m(_, wxListBox:append(TrSortRadioBox, "Session Id", session_id)), - %?m(_, wxListBox:insert(TrSortRadioBox, "Session Id", 0, session_id)), - + wxRadioBox:setSelection(TrSortRadioBox, 2), + wxRadioBox:setItemToolTip(TrSortRadioBox, 2, "Test"), + TT0 = ?mt(wxToolTip,wxRadioBox:getItemToolTip(TrSortRadioBox, 0)), + TT1 = ?mt(wxToolTip,wxRadioBox:getItemToolTip(TrSortRadioBox, 2)), + ?m(true, wx:is_null(TT0)), + ?m("Test", wxToolTip:getTip(TT1)), wxWindow:show(Frame), wx_test_lib:wx_destroy(Frame,Config). @@ -493,3 +520,171 @@ taskBarIcon(Config) -> wxTaskBarIcon:connect(TBI, taskbar_left_down, [{callback, fun(Ev,_) -> io:format("Left clicked: ~p~n",[Ev]) end}]), wxTaskBarIcon:connect(TBI, taskbar_right_down, [{callback,fun(Ev,_) -> io:format("Right clicked: ~p~n",[Ev]) end}]), wx_test_lib:wx_destroy(Frame,Config). + +toolbar(TestInfo) when is_atom(TestInfo) -> wx_test_lib:tc_info(TestInfo); +toolbar(Config) -> + Wx = wx:new(), + Frame = wxFrame:new(Wx, ?wxID_ANY, "Frame"), + TB = wxFrame:createToolBar(Frame), + BM1 = wxArtProvider:getBitmap("wxART_COPY", [{size, {16,16}}, {client, "wxART_TOOLBAR"}]), + BM2 = wxArtProvider:getBitmap("wxART_TICK_MARK", [{size, {16,16}}, {client, "wxART_TOOLBAR"}]), + wxToolBar:addTool(TB, 747, "PressMe", BM1, + [{shortHelp, "Press Me"}]), + catch wxToolBar:addStretchableSpace(TB), %% wxWidgets 3.0 only + Add = fun(#wx{}, _) -> + wxToolBar:addTool(TB, -1, "Added", BM2, + [{shortHelp, "Test 2 popup text"}]), + catch wxToolBar:addStretchableSpace(TB), %% wxWidgets 3.0 only + wxToolBar:realize(TB) + end, + + wxToolBar:realize(TB), + wxFrame:connect(Frame, command_menu_selected, [{callback, Add}, {id, 747}]), + wxFrame:show(Frame), + wx_test_lib:wx_destroy(Frame,Config). + +popup(TestInfo) when is_atom(TestInfo) -> wx_test_lib:tc_info(TestInfo); +popup(Config) -> + Wx = wx:new(), + Frame = wxFrame:new(Wx, ?wxID_ANY, "Frame"), + TB = wxFrame:createToolBar(Frame), + wxToolBar:addTool(TB, 747, "PressMe", wxArtProvider:getBitmap("wxART_COPY", [{size, {16,16}}]), + [{shortHelp, "Press Me"}]), + + Log = fun(#wx{id=Id, event=Ev}, Obj) -> + io:format("Got ~p from ~p~n", [Ev, Id]), + wxEvent:skip(Obj) + end, + CreatePopup = fun() -> + Pop = wxPopupTransientWindow:new(Frame), + Panel = wxPanel:new(Pop), + Sz = wxBoxSizer:new(?wxVERTICAL), + wxSizer:add(Sz, wxButton:new(Panel, 42, [{label, "A button"}])), + wxSizer:add(Sz, Txt = wxStaticText:new(Panel, 43, "Some static text")), + wxSizer:add(Sz, wxButton:new(Panel, 44, [{label, "B button"}])), + wxPanel:setSizerAndFit(Panel, Sz), + wxSizer:setSizeHints(Sz, Pop), + wxWindow:connect(Pop, command_button_clicked, [{callback, Log}]), + wxWindow:connect(Txt, left_up, [{callback, Log}]), + wxWindow:connect(Txt, middle_up, [{callback, Log}]), + wxWindow:connect(Txt, right_up, [{callback, Log}]), + wxWindow:connect(Pop, show, [{callback, Log}]), + Pos = wx_misc:getMousePosition(), + wxPopupTransientWindow:position(Pop, Pos, {-1, -1}), + wxPopupTransientWindow:popup(Pop), + Pop + end, + wxFrame:connect(Frame, command_menu_selected, [{id, 747}]), + wxFrame:connect(Frame, show), + wxFrame:show(Frame), + receive #wx{event=#wxShow{}} -> ok + after 1000 -> exit(show_timeout) + end, + + Pop = CreatePopup(), + Scale = case wx_test_lib:user_available(Config) of + true -> 25; + false -> 1 + end, + receive + #wx{} -> CreatePopup() + after 200*Scale -> + wxPopupTransientWindow:dismiss(Pop) + end, + wx_test_lib:wx_destroy(Frame,Config). + +locale(TestInfo) when is_atom(TestInfo) -> wx_test_lib:tc_info(TestInfo); +locale(_Config) -> + wx:new(), + io:format("SystemEncoding: ~p~n",[wxLocale:getSystemEncoding()]), + io:format("SystemEncodingName: ~ts~n",[wxLocale:getSystemEncodingName()]), + io:format("SystemLanguage: ~p~n",[wxLocale:getSystemLanguage()]), + io:format("SystemLanguageName: ~p~n",[wxLocale:getLanguageName(wxLocale:getSystemLanguage())]), + lang_env(), + LC = wxLocale:new(), + %% wxLocale:addCatalog(LC, "wxstd"), + io:format("Swedish: ~p~n",[wxLocale:getLanguageName(?wxLANGUAGE_SWEDISH)]), + R0 = wxLocale:init(LC, [{language, ?wxLANGUAGE_SWEDISH}, {flags, 0}]), + io:format("initiated ~p~n",[R0]), + lang_env(), + ok. +%% wx_test_lib:wx_destroy(Frame,Config). + +lang_env() -> + Env0 = os:getenv(), + Env = [[R,"\n"]||R <- Env0], + %%io:format("~p~n",[lists:sort(Env)]), + Opts = [global, multiline, {capture, all, list}], + format_env(re:run(Env, "LC_ALL.*", Opts)), + format_env(re:run(Env, "^LANG.*=.*$", Opts)), + ok. +format_env({match, List}) -> + [io:format(" ~ts~n",[L]) || L <- List]; +format_env(nomatch) -> ok. + +%% Add a testcase that tests that we can recurse in showModal +%% because it hangs in observer if object are not destroyed correctly +%% when popping the stack + +modal(Config) -> + Wx = wx:new(), + case {?wxMAJOR_VERSION, ?wxMINOR_VERSION, ?wxRELEASE_NUMBER} of + {2, Min, Rel} when Min < 8 orelse (Min =:= 8 andalso Rel < 11) -> + {skip, "old wxWidgets version"}; + _ -> + Frame = wxFrame:new(Wx, -1, "Test Modal windows"), + wxFrame:show(Frame), + Env = wx:get_env(), + Tester = self(), + ets:new(test_state, [named_table, public]), + Upd = wxUpdateUIEvent:getUpdateInterval(), + wxUpdateUIEvent:setUpdateInterval(500), + _Pid = spawn(fun() -> + wx:set_env(Env), + modal_dialog(Frame, 1, Tester) + end), + %% need to sleep so we know that the window is stuck in + %% the ShowModal event loop and not in an earlier event loop + %% wx2.8 invokes the event loop from more calls than wx-3 + M1 = receive {dialog, W1, 1} -> timer:sleep(1200), ets:insert(test_state, {W1, ready}), W1 end, + M2 = receive {dialog, W2, 2} -> timer:sleep(1200), ets:insert(test_state, {W2, ready}), W2 end, + + receive done -> ok end, + receive {dialog_done, M2, 2} -> M2 end, + receive {dialog_done, M1, 1} -> M1 end, + + wxUpdateUIEvent:setUpdateInterval(Upd), + wx_test_lib:wx_destroy(Frame,Config) + end. + +modal_dialog(Parent, Level, Tester) when Level < 3 -> + M1 = wxTextEntryDialog:new(Parent, "Dialog " ++ integer_to_list(Level)), + io:format("Creating dialog ~p ~p~n",[Level, M1]), + wxDialog:connect(M1, show, [{callback, fun(#wx{event=Ev},_) -> + case Ev of + #wxShow{show=true} -> + Tester ! {dialog, M1, Level}; + _ -> ignore + end + end}]), + DoOnce = fun(_,_) -> + case ets:take(test_state, M1) of + [] -> ignore; + [_] -> modal_dialog(M1, Level+1, Tester) + end + end, + wxDialog:connect(M1, update_ui, [{callback, DoOnce}]), + ?wxID_OK = wxDialog:showModal(M1), + wxDialog:destroy(M1), + case Level > 1 of + true -> + io:format("~p: End dialog ~p ~p~n",[?LINE, Level-1, Parent]), + wxDialog:endModal(Parent, ?wxID_OK); + false -> ok + end, + Tester ! {dialog_done, M1, Level}, + ok; +modal_dialog(Parent, Level, Tester) -> + io:format("~p: End dialog ~p ~p~n",[?LINE, Level-1, Parent]), + wxDialog:endModal(Parent, ?wxID_OK), + Tester ! done. diff --git a/lib/wx/test/wx_event_SUITE.erl b/lib/wx/test/wx_event_SUITE.erl index 53a2ee7d7b..6512cedaf2 100644 --- a/lib/wx/test/wx_event_SUITE.erl +++ b/lib/wx/test/wx_event_SUITE.erl @@ -1,18 +1,19 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2008-2012. All Rights Reserved. +%% Copyright Ericsson AB 2008-2016. All Rights Reserved. %% -%% The contents of this file are subject to the Erlang Public License, -%% Version 1.1, (the "License"); you may not use this file except in -%% compliance with the License. You should have received a copy of the -%% Erlang Public License along with this software. If not, it can be -%% retrieved online at http://www.erlang.org/. -%% -%% Software distributed under the License is distributed on an "AS IS" -%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See -%% the License for the specific language governing rights and limitations -%% under the License. +%% 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% %%%------------------------------------------------------------------- @@ -43,11 +44,13 @@ end_per_testcase(Func,Config) -> wx_test_lib:end_per_testcase(Func,Config). %% SUITE specification -suite() -> [{ct_hooks,[ts_install_cth]}]. +suite() -> [{ct_hooks,[ts_install_cth]}, {timetrap,{minutes,2}}]. -all() -> - [connect, disconnect, connect_msg_20, connect_cb_20, - mouse_on_grid, spin_event, connect_in_callback, recursive]. +all() -> + [connect, disconnect, disconnect_cb, connect_msg_20, connect_cb_20, + mouse_on_grid, spin_event, connect_in_callback, recursive, + dialog, char_events, callback_clean + ]. groups() -> []. @@ -75,7 +78,6 @@ connect(Config) -> Tester ! {got_size, UserD} end, - ?m(ok, wxFrame:connect(Frame, size)), ?m(ok, wxEvtHandler:connect(Panel, size,[{skip, true},{userData, panel}])), ?m(ok, wxEvtHandler:connect(Panel, size,[{callback,CB},{userData, panel}])), @@ -88,12 +90,16 @@ connect(Config) -> ?m(ok, wxWindow:connect(Window, size,[{callback,CB},{userData, window}])), ?m(ok, wxWindow:connect(Window, size,[{skip,true},{userData, window}])), + %% For trivial side effect free callbacks, can deadlock easily otherwise + CB1 = fun(_,_) -> Tester ! {got_size, nospawn_cb} end, + ?m(ok, wxWindow:connect(Frame, size, [{callback,{nospawn, CB1}}])), + ?m(ok, wxFrame:connect(Frame, size, [{skip, true}])), ?m(true, wxFrame:show(Frame)), wxWindow:setSize(Panel, {200,100}), wxWindow:setSize(Window, {200,100}), - get_size_messages(Frame, [frame, panel_cb, window_cb, window]), + get_size_messages(Frame, [frame, panel_cb, window_cb, window, nospawn_cb]), wx_test_lib:wx_destroy(Frame, Config). @@ -112,7 +118,9 @@ get_size_messages(Frame, Msgs) -> ?m(false, lists:member(window, Msgs)), get_size_messages(Frame, lists:delete(window_cb, Msgs)); {got_size,panel} -> - get_size_messages(Frame, lists:delete(panel_cb, Msgs)); + get_size_messages(Frame, lists:delete(panel_cb, Msgs)); + {got_size,nospawn_cb} -> + get_size_messages(Frame, lists:delete(nospawn_cb, Msgs)); Other -> ?error("Got unexpected msg ~p ~p~n", [Other,Msgs]) after 1000 -> @@ -147,16 +155,40 @@ disconnect(Config) -> timer:sleep(1000), wx_test_lib:flush(), - ?m({'EXIT', {{badarg,_},_}}, wxEvtHandler:disconnect(Panel, non_existing_event_type)), + ?m(false, wxEvtHandler:disconnect(Panel, non_existing_event_type)), ?m(true, wxEvtHandler:disconnect(Panel, size)), ?m(ok, wxWindow:setSize(Panel, {200,102})), timer:sleep(1000), ?m([], wx_test_lib:flush()), wx_test_lib:wx_destroy(Frame, Config). - + +disconnect_cb(TestInfo) when is_atom(TestInfo) -> wx_test_lib:tc_info(TestInfo); +disconnect_cb(Config) -> + ?mr(wx_ref, wx:new()), + Frame = ?mt(wxFrame, wxFrame:new(wx:null(), 1, "Event Testing")), + Panel = ?mt(wxPanel, wxPanel:new(Frame)), + + Tester = self(), + CB = fun(#wx{event=#wxSize{},userData=UserD}, SizeEvent) -> + ?mt(wxSizeEvent, SizeEvent), + wxEvtHandler:disconnect(Frame, close_window), + Tester ! {got_size, UserD} + end, + ?m(ok, wxFrame:connect(Frame, close_window)), + ?m(ok, wxFrame:connect(Frame, size)), + ?m(ok, wxEvtHandler:connect(Panel, size, [{callback,CB},{userData, panel}])), + + ?m(true, wxFrame:show(Frame)), + + wxWindow:setSize(Panel, {200,100}), + get_size_messages(Frame, [frame, panel_cb]), + wx_test_lib:flush(), + + wx_test_lib:wx_destroy(Frame, Config). + %% Test that the msg events are forwarded as supposed to connect_msg_20(TestInfo) when is_atom(TestInfo) -> wx_test_lib:tc_info(TestInfo); @@ -334,12 +366,14 @@ connect_in_callback(Config) -> end}]), wxWindow:show(F1), receive - {continue, F1} -> Tester ! {continue, F1} + {continue, F1} -> + true = wxFrame:disconnect(F1, size), + Tester ! {continue, F1} end end, - wxFrame:connect(Frame,size, + wxFrame:connect(Frame,show, [{callback, - fun(#wx{event=#wxSize{}},_SizeEv) -> + fun(#wx{event=#wxShow{}},_SizeEv) -> io:format("Frame got size~n",[]), spawn(TestWindow) end}]), @@ -375,26 +409,195 @@ recursive(Config) -> Frame = wxFrame:new(Wx, ?wxID_ANY, "Connect in callback"), Panel = wxPanel:new(Frame, []), Sz = wxBoxSizer:new(?wxVERTICAL), - ListBox = wxListBox:new(Panel, ?wxID_ANY, [{choices, ["foo", "bar", "baz"]}]), - wxSizer:add(Sz, ListBox, [{proportion, 1},{flag, ?wxEXPAND}]), - wxWindow:setSizer(Panel, Sz), - wxListBox:connect(ListBox, command_listbox_selected, - [{callback, - fun(#wx{event=#wxCommand{commandInt=Id}}, _) -> - io:format("Selected ~p~n",[Id]) - end}]), - wxListBox:setSelection(ListBox, 0), - wxListBox:connect(ListBox, size, - [{callback, - fun(#wx{event=#wxSize{}}, _) -> - io:format("Size init ~n",[]), - case wxListBox:getCount(ListBox) > 0 of - true -> wxListBox:delete(ListBox, 0); - false -> ok - end, - io:format("Size done ~n",[]) - end}]), + Ctrl1 = wxTextCtrl:new(Panel, ?wxID_ANY, [{size, {300, -1}}]), + Ctrl2 = wxTextCtrl:new(Panel, ?wxID_ANY, [{size, {300, -1}}]), + wxSizer:add(Sz, Ctrl1, [{proportion, 1},{flag, ?wxEXPAND}]), + wxSizer:add(Sz, Ctrl2, [{proportion, 1},{flag, ?wxEXPAND}]), + wxWindow:setSizerAndFit(Panel, Sz), + + CB1 = fun(#wx{event=#wxCommand{cmdString=String}}, _) -> + io:format(" CB1: ~s~n",[String]), + wxTextCtrl:setValue(Ctrl2, io_lib:format("from CB1 ~s", [String])) + end, + CB2 = fun(#wx{event=#wxCommand{cmdString=String}}, _) -> + io:format(" CB2: ~s~n",[String]), + ok + end, + wxTextCtrl:connect(Ctrl1, command_text_updated, [{callback,CB1}]), + wxTextCtrl:connect(Ctrl2, command_text_updated, [{callback,CB2}]), + wxFrame:connect(Frame, size, + [{callback, + fun(#wx{event=#wxSize{size=Size}}, _) -> + io:format("Size init: ~s ~n",[wxTextCtrl:getValue(Ctrl2)]), + wxTextCtrl:setValue(Ctrl1, io_lib:format("Size ~p", [Size])), + io:format("Size done: ~s ~n",[wxTextCtrl:getValue(Ctrl2)]) + end}]), + wxFrame:show(Frame), + wx_test_lib:flush(), + + wx_test_lib:wx_destroy(Frame, Config). + + +dialog(TestInfo) when is_atom(TestInfo) -> wx_test_lib:tc_info(TestInfo); +dialog(Config) -> + Wx = wx:new(), + Frame = wxFrame:new(Wx, ?wxID_ANY, "Testing"), + wxFrame:show(Frame), + Env = wx:get_env(), + Tester = self(), + PD = wxProgressDialog:new("Dialog","Testing", + [%%{parent, Frame}, + {maximum,101}, + {style, ?wxPD_SMOOTH bor ?wxPD_AUTO_HIDE}]), + Forward = fun(#wx{event=#wxInitDialog{}}, Ev) -> + ?mt(wxInitDialogEvent, Ev), + io:format("Heyhoo~n", []), + wxEvent:skip(Ev), + Tester ! {progress_dialog,PD} + end, + wxDialog:connect(PD, init_dialog, [{callback, Forward}]), + Recurse = fun(Recurse, N) -> + true = wxProgressDialog:update(PD, min(N,100)), + timer:sleep(5), + Recurse(Recurse,N+1) + end, + Run = fun() -> + wx:set_env(Env), + Recurse(Recurse, 0) + end, + Worker = spawn_link(Run), + timer:sleep(500), + io:format("Got ~p~n", [wx_test_lib:flush()]), + unlink(Worker), + wxProgressDialog:destroy(PD), + wx_test_lib:wx_destroy(Frame, Config). + + + +char_events(TestInfo) when is_atom(TestInfo) -> wx_test_lib:tc_info(TestInfo); +char_events(Config) -> + Wx = wx:new(), + Frame = wxFrame:new(Wx, ?wxID_ANY, "Press any key"), + Panel = wxPanel:new(Frame, []), + wxFrame:connect(Frame, enter_window, [{callback, fun(_,_) -> + io:format("Set focus~n"), + wxWindow:setFocus(Panel) + end}]), + KeyEvent = fun(Ev,Obj) -> io:format("Got ~p~n",[Ev]), wxEvent:skip(Obj) end, + [wxWindow:connect(Panel, Types, [{callback,KeyEvent}]) + || Types <- [key_down, key_up, char]], + wxWindow:connect(Frame, char_hook, [{callback,KeyEvent}]), + wxFrame:show(Frame), wx_test_lib:flush(), wx_test_lib:wx_destroy(Frame, Config). + +callback_clean(TestInfo) when is_atom(TestInfo) -> wx_test_lib:tc_info(TestInfo); +callback_clean(Config) -> + %% Be sure that event handling are cleanup up correctly and don't keep references to old + %% fun's and event listeners + Wx = wx:new(), + Frame = wxFrame:new(Wx, ?wxID_ANY, "Frame Window"), + wxFrame:show(Frame), + + %% wx:debug([verbose,driver]), + Dlg = wxDialog:new(Frame, ?wxID_ANY, "Testing"), + Panel = wxPanel:new(Dlg, []), + Sizer = wxBoxSizer:new(?wxVERTICAL), + Button = wxButton:new(Panel, 600, [{label, "Foobar"}]), + wxSizer:add(Sizer, Button, [{proportion,1}, {flag, ?wxEXPAND}]), + wxSizer:add(Sizer, wxDialog:createStdDialogButtonSizer(Dlg,?wxOK bor ?wxCANCEL)), + wxDialog:setSizerAndFit(Dlg, Sizer), + + Env = wx:get_env(), + SetupEventHandlers = + fun() -> + wx:set_env(Env), + Me = self(), + Print = fun(#wx{id=ID, event=#wxCommand{}},Ev) -> + io:format("~p Clicked ~p~n", [self(), ID]), + Me ! #wx{event=#wxClose{}}, + wxEvent:skip(Ev, [{skip, true}]); + (#wx{id=ID, event=#wxClose{}},Ev) -> + io:format("~p Closed ~p~n", [self(), ID]), + wxEvent:skip(Ev, [{skip, true}]) + end, + + wxDialog:connect(Dlg, command_button_clicked,[{callback,Print}]), + wxDialog:connect(Dlg, close_window, [{skip, true}]) + end, + ?m({[],[],[]}, white_box_check_event_handlers()), + Pid = spawn_link(fun() -> + SetupEventHandlers(), + receive #wx{event=#wxClose{}} -> ok; + remove -> ok + end + end), + timer:sleep(500), %% Give it time to remove it + ?m({[{Pid,_}],[_],[_]}, white_box_check_event_handlers()), + + Pid ! remove, + timer:sleep(500), %% Give it time to remove it + ?m({[],[],[]}, white_box_check_event_handlers()), + + SetupEventHandlers(), + ?m({[{_,_}],[_],[_]}, white_box_check_event_handlers()), + + wxDialog:show(Dlg), + wx_test_lib:wx_close(Dlg, Config), + wxDialog:destroy(Dlg), + timer:sleep(500), %% Give it time to remove it + ?m({[],[],[]}, white_box_check_event_handlers()), + + wx_test_lib:flush(), + io:format("**Deleting Frame**~n",[]), + wx_test_lib:wx_destroy(Frame, Config). + %% timer:sleep(infinity), + %% ok. + + +white_box_check_event_handlers() -> + {_,_,Server,_} = wx:get_env(), + {status, _, _, [Env, _, _, _, Data]} = sys:get_status(Server), + [_H, _data, {data, [{_, Record}]}] = Data, + {state, _Port1, _Port2, Users, [], CBs, _Next} = Record, + {[{Pid, Evs} || + {Pid, {user, Evs}} <- gb_trees:to_list(Users), + Evs =/= []], %% Ignore empty + gb_trees:to_list(CBs), + [Funs || Funs = {Id, {Fun,_}} <- Env, is_integer(Id), is_function(Fun)] + }. + +handler_clean(TestInfo) when is_atom(TestInfo) -> + wx_test_lib:tc_info(TestInfo); +handler_clean(_Config) -> + wx:new(), + Init = fun() -> create_window() end, + Frame1 = wx_obj_test:start([{init, Init}]), + ?mt(wxFrame, Frame1), + wxWindow:show(Frame1), + ?m([_|_], lists:sort(wx_test_lib:flush())), + ?m(ok, wx_obj_test:stop(Frame1)), + ?m([{terminate,normal}], lists:sort(wx_test_lib:flush())), + + Terminate = fun({Frame,_}) -> wxWindow:destroy(Frame) end, + Frame2 = wx_obj_test:start([{init, Init}, {terminate, Terminate}]), + wxWindow:show(Frame2), + ?m([_|_], lists:sort(wx_test_lib:flush())), + ?m(ok, wx_obj_test:stop(Frame2)), + ?m([{terminate,normal}], lists:sort(wx_test_lib:flush())), + timer:sleep(104), + ?m({[],[],[]}, white_box_check_event_handlers()), + ?m(ok, wx:destroy()), + ok. + +create_window() -> + Frame = wxFrame:new(wx:null(), ?wxID_ANY, "Test wx_object", [{size, {500, 400}}]), + Sz = wxBoxSizer:new(?wxHORIZONTAL), + Panel = wxPanel:new(Frame), + wxSizer:add(Sz, Panel, [{flag, ?wxEXPAND}, {proportion, 1}]), + wxWindow:connect(Frame, show), + %% wxPanel:connect(Panel, paint, [callback, {userData, foobar}]), + wxWindow:connect(Panel, size, [callback]), + {Frame, {Frame, Panel}}. diff --git a/lib/wx/test/wx_obj_test.erl b/lib/wx/test/wx_obj_test.erl index b4d7640c7e..23142e28b2 100644 --- a/lib/wx/test/wx_obj_test.erl +++ b/lib/wx/test/wx_obj_test.erl @@ -1,86 +1,98 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2011. All Rights Reserved. +%% Copyright Ericsson AB 2011-2016. All Rights Reserved. %% -%% The contents of this file are subject to the Erlang Public License, -%% Version 1.1, (the "License"); you may not use this file except in -%% compliance with the License. You should have received a copy of the -%% Erlang Public License along with this software. If not, it can be -%% retrieved online at http://www.erlang.org/. +%% 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 %% -%% Software distributed under the License is distributed on an "AS IS" -%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See -%% the License for the specific language governing rights and limitations -%% under the License. +%% 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(wx_obj_test). -include_lib("wx/include/wx.hrl"). --export([start/1]). +-export([start/1, stop/1, who_are_you/1]). %% wx_object callbacks -export([init/1, handle_info/2, terminate/2, code_change/3, handle_call/3, handle_sync_event/3, handle_event/2, handle_cast/2]). --record(state, {frame, panel, opts}). +-record(state, {parent, me, opts, user_state}). start(Opts) -> - wx_object:start_link(?MODULE, [{parent, self()}, Opts], []). + wx_object:start_link(?MODULE, [{parent, self()}| Opts], []). + +stop(Object) -> + wx_object:stop(Object). + +who_are_you(Object) -> + wx_object:call(Object, who_are_you). init(Opts) -> - put(parent_pid, proplists:get_value(parent, Opts)), - Frame = wxFrame:new(wx:null(), ?wxID_ANY, "Test wx_object", [{size, {500, 400}}]), - Sz = wxBoxSizer:new(?wxHORIZONTAL), - Panel = wxPanel:new(Frame), - wxSizer:add(Sz, Panel, [{flag, ?wxEXPAND}, {proportion, 1}]), - wxPanel:connect(Panel, size, [{skip, true}]), - wxPanel:connect(Panel, paint, [callback, {userData, proplists:get_value(parent, Opts)}]), - wxWindow:show(Frame), - {Frame, #state{frame=Frame, panel=Panel, opts=Opts}}. + Parent = proplists:get_value(parent, Opts), + put(parent_pid, Parent), + Init = proplists:get_value(init, Opts), + {Obj, UserState} = Init(), + {Obj, #state{me=Obj, parent=Parent, opts=Opts, user_state=UserState}}. -handle_sync_event(Event = #wx{obj=Panel}, WxEvent, #state{opts=Opts}) -> - DC=wxPaintDC:new(Panel), %% We must create & destroy paintDC, or call wxEvent:skip(WxEvent)) - wxPaintDC:destroy(DC), %% in sync_event. Otherwise wx on windows keeps sending the events. - Pid = proplists:get_value(parent, Opts), - true = is_pid(Pid), - Pid ! {sync_event, Event, WxEvent}, +handle_sync_event(Event = #wx{obj=Panel, event=#wxPaint{}}, + WxEvent, #state{parent=Parent, user_state=US, opts=Opts}) -> + case proplists:get_value(redraw, Opts) of + undefined -> + DC=wxPaintDC:new(Panel), %% We must create & destroy paintDC, or call wxEvent:skip(WxEvent)) + wxPaintDC:destroy(DC), %% in sync_event. Otherwise wx on windows keeps sending the events. + Parent ! {sync_event, Event, WxEvent}; + Redraw -> + Redraw(Event, WxEvent, US) + end, + ok; +handle_sync_event(Event, WxEvent, #state{parent=Parent}) -> + Parent ! {sync_event, Event, WxEvent}, ok. -handle_event(Event, State = #state{opts=Opts}) -> - Pid = proplists:get_value(parent, Opts), - Pid ! {event, Event}, +handle_event(Event, State = #state{parent=Parent}) -> + Parent ! {event, Event}, {noreply, State}. -handle_call(What, From, State) when is_function(What) -> - Result = What(State), +handle_call(who_are_you, _From, State = #state{me=Me}) -> + {reply, Me, State}; +handle_call(What, From, State = #state{user_state=US}) when is_function(What) -> + Result = What(US), {reply, {call, Result, From}, State}; handle_call(What, From, State) -> {reply, {call, What, From}, State}. -handle_cast(What, State = #state{opts=Opts}) when is_function(What) -> - Result = What(State), - Pid = proplists:get_value(parent, Opts), +handle_cast(What, State = #state{parent=Pid, user_state=US}) when is_function(What) -> + Result = What(US), Pid ! {cast, Result}, {noreply, State}; -handle_cast(What, State = #state{opts=Opts}) -> - Pid = proplists:get_value(parent, Opts), +handle_cast(What, State = #state{parent=Pid}) -> Pid ! {cast, What}, {noreply, State}. -handle_info(What, State = #state{opts=Opts}) -> - Pid = proplists:get_value(parent, Opts), +handle_info(What, State = #state{parent=Pid}) -> Pid ! {info, What}, {noreply, State}. -terminate(What, #state{opts=Opts}) -> - Pid = proplists:get_value(parent, Opts), +terminate(What, #state{parent=Pid, opts=Opts, user_state=US}) -> + case proplists:get_value(terminate, Opts) of + undefined -> + ok; + Terminate -> + Terminate(US) + end, Pid ! {terminate, What}, ok. -code_change(Ver1, Ver2, State = #state{opts=Opts}) -> - Pid = proplists:get_value(parent, Opts), +code_change(Ver1, Ver2, State = #state{parent=Pid}) -> Pid ! {code_change, Ver1, Ver2}, State. diff --git a/lib/wx/test/wx_opengl_SUITE.erl b/lib/wx/test/wx_opengl_SUITE.erl index f351bc93ed..643a0df6a3 100644 --- a/lib/wx/test/wx_opengl_SUITE.erl +++ b/lib/wx/test/wx_opengl_SUITE.erl @@ -1,18 +1,19 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2008-2012. All Rights Reserved. +%% Copyright Ericsson AB 2008-2016. All Rights Reserved. %% -%% The contents of this file are subject to the Erlang Public License, -%% Version 1.1, (the "License"); you may not use this file except in -%% compliance with the License. You should have received a copy of the -%% Erlang Public License along with this software. If not, it can be -%% retrieved online at http://www.erlang.org/. -%% -%% Software distributed under the License is distributed on an "AS IS" -%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See -%% the License for the specific language governing rights and limitations -%% under the License. +%% 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% %%%------------------------------------------------------------------- @@ -51,7 +52,7 @@ end_per_testcase(Func,Config) -> wx_test_lib:end_per_testcase(Func,Config). %% SUITE specification -suite() -> [{ct_hooks,[ts_install_cth]}]. +suite() -> [{ct_hooks,[ts_install_cth]}, {timetrap,{minutes,2}}]. all() -> [canvas, glu_tesselation]. diff --git a/lib/wx/test/wx_test_lib.erl b/lib/wx/test/wx_test_lib.erl index 8509d6be6f..9f26b8cb9d 100644 --- a/lib/wx/test/wx_test_lib.erl +++ b/lib/wx/test/wx_test_lib.erl @@ -1,18 +1,19 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2008-2010. All Rights Reserved. +%% Copyright Ericsson AB 2008-2016. All Rights Reserved. %% -%% The contents of this file are subject to the Erlang Public License, -%% Version 1.1, (the "License"); you may not use this file except in -%% compliance with the License. You should have received a copy of the -%% Erlang Public License along with this software. If not, it can be -%% retrieved online at http://www.erlang.org/. -%% -%% Software distributed under the License is distributed on an "AS IS" -%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See -%% the License for the specific language governing rights and limitations -%% under the License. +%% 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% %%%------------------------------------------------------------------- @@ -129,28 +130,30 @@ pick_msg() -> user_available(Config) -> false /= proplists:get_value(user, Config, false). - wx_destroy(Frame, Config) -> + wx_close(Frame, Config), + ?m(ok, wx:destroy()). + +wx_close(Frame, Config) -> case proplists:get_value(user, Config, false) of false -> timer:sleep(100), - ?m(ok, wxFrame:destroy(Frame)), - ?m(ok, wx:destroy()); + ?m(ok, wxWindow:destroy(Frame)); true -> timer:sleep(500), - ?m(ok, wxFrame:destroy(Frame)), - ?m(ok, wx:destroy()); + ?m(ok, wxWindow:destroy(Frame)); step -> %% Wait for user to close window ?m(ok, wxEvtHandler:connect(Frame, close_window, [{skip,true}])), - wait_for_close() + wait_for_close(), + catch wxEvtHandler:disconnect(Frame, close_window), + ok end. wait_for_close() -> receive #wx{event=#wxClose{}} -> - ?log("Got close~n",[]), - ?m(ok, wx:destroy()); + ?log("Got close~n",[]); #wx{obj=Obj, event=Event} -> try Name = wxTopLevelWindow:getTitle(Obj), diff --git a/lib/wx/test/wx_test_lib.hrl b/lib/wx/test/wx_test_lib.hrl index 820e8f0050..68fdcf54e2 100644 --- a/lib/wx/test/wx_test_lib.hrl +++ b/lib/wx/test/wx_test_lib.hrl @@ -1,18 +1,19 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2008-2011. All Rights Reserved. +%% Copyright Ericsson AB 2008-2016. All Rights Reserved. %% -%% The contents of this file are subject to the Erlang Public License, -%% Version 1.1, (the "License"); you may not use this file except in -%% compliance with the License. You should have received a copy of the -%% Erlang Public License along with this software. If not, it can be -%% retrieved online at http://www.erlang.org/. -%% -%% Software distributed under the License is distributed on an "AS IS" -%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See -%% the License for the specific language governing rights and limitations -%% under the License. +%% 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% %%%------------------------------------------------------------------- diff --git a/lib/wx/test/wx_xtra_SUITE.erl b/lib/wx/test/wx_xtra_SUITE.erl index a2d4c26319..c6268a7f46 100644 --- a/lib/wx/test/wx_xtra_SUITE.erl +++ b/lib/wx/test/wx_xtra_SUITE.erl @@ -1,18 +1,19 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2009-2012. All Rights Reserved. +%% Copyright Ericsson AB 2009-2016. All Rights Reserved. %% -%% The contents of this file are subject to the Erlang Public License, -%% Version 1.1, (the "License"); you may not use this file except in -%% compliance with the License. You should have received a copy of the -%% Erlang Public License along with this software. If not, it can be -%% retrieved online at http://www.erlang.org/. +%% 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 %% -%% Software distributed under the License is distributed on an "AS IS" -%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See -%% the License for the specific language governing rights and limitations -%% under the License. +%% 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% %%%------------------------------------------------------------------- @@ -44,7 +45,7 @@ end_per_testcase(Func,Config) -> wx_test_lib:end_per_testcase(Func,Config). %% SUITE specification -suite() -> [{ct_hooks,[ts_install_cth]}]. +suite() -> [{ct_hooks,[ts_install_cth]}, {timetrap,{minutes,2}}]. all() -> [destroy_app, multiple_add_in_sizer, app_dies, @@ -129,15 +130,19 @@ app_dies(_Config) -> app_dies2(Test, N) -> spawn_link(fun() -> Test(N) end), - receive - {'EXIT', _, {oops, last}} -> ok; - {'EXIT', _, {oops, _}} -> app_dies2(Test, N+1) + receive + {'EXIT', _, {oops, Server, What}} -> + Ref = erlang:monitor(process, Server), + receive {'DOWN', Ref, _, _, _} -> ok end, + timer:sleep(100), + What =/= last andalso app_dies2(Test, N+1) end. oops(Die, Line) when (Die =:= last) orelse (Die =< Line) -> - timer:sleep(300), + timer:sleep(200), ?log(" Exits at line ~p~n",[Line]), - exit({oops, Die}); + Server = element(3, wx:get_env()), + exit({oops, Server, Die}); oops(_,_) -> ok. diff --git a/lib/wx/test/wxt b/lib/wx/test/wxt index f94350e47b..e720ed94f4 100755 --- a/lib/wx/test/wxt +++ b/lib/wx/test/wxt @@ -2,18 +2,19 @@ # # %CopyrightBegin% # -# Copyright Ericsson AB 2008-2009. All Rights Reserved. +# Copyright Ericsson AB 2008-2016. All Rights Reserved. # -# The contents of this file are subject to the Erlang Public License, -# Version 1.1, (the "License"); you may not use this file except in -# compliance with the License. You should have received a copy of the -# Erlang Public License along with this software. If not, it can be -# retrieved online at http://www.erlang.org/. -# -# Software distributed under the License is distributed on an "AS IS" -# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See -# the License for the specific language governing rights and limitations -# under the License. +# 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% # @@ -38,4 +39,4 @@ if [ "$ostype" = "SunOS" ] ; then else xterm -T Testing -e script -f -c "$erlcmd" "$log" & fi -tail -f "$log" | egrep 'Eval|<ERROR>|NYI'
\ No newline at end of file +tail -f "$log" | egrep 'Eval|<ERROR>|NYI' diff --git a/lib/wx/test/wxt.erl b/lib/wx/test/wxt.erl index c14d3f8647..265cd5c981 100644 --- a/lib/wx/test/wxt.erl +++ b/lib/wx/test/wxt.erl @@ -1,27 +1,24 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2008-2011. All Rights Reserved. +%% Copyright Ericsson AB 2008-2016. All Rights Reserved. %% -%% The contents of this file are subject to the Erlang Public License, -%% Version 1.1, (the "License"); you may not use this file except in -%% compliance with the License. You should have received a copy of the -%% Erlang Public License along with this software. If not, it can be -%% retrieved online at http://www.erlang.org/. +%% 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 %% -%% Software distributed under the License is distributed on an "AS IS" -%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See -%% the License for the specific language governing rights and limitations -%% under the License. +%% 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% -%%%------------------------------------------------------------------- -%%% File : wxt.erl -%%% Author : Dan Gudmundsson <[email protected]> -%%% Description : Shortcuts for starting test with wx internal test_server -%%% -%%% Created : 4 Nov 2008 by Dan Gudmundsson <[email protected]> -%%%------------------------------------------------------------------- +%% +%% Description : Shortcuts for running tests with wx internal test_server +%%------------------------------------------------------------------- -module(wxt). -compile(export_all). @@ -39,7 +36,7 @@ t(Mod, TC) when is_atom(Mod), is_atom(TC) -> t({Mod,TC}, []); t(all, Config) when is_list(Config) -> Fs = filelib:wildcard("wx_*_SUITE.erl"), - t([list_to_atom(filename:rootname(File)) || File <- Fs], Config); + t([list_to_atom(filename:rootname(File)) || File <- Fs, File =/= "wx_app_SUITE.erl"], Config); t(Test,Config) when is_list(Config) -> Tests = resolve(Test), write_test_case(Test), |