aboutsummaryrefslogtreecommitdiffstats
path: root/lib/wx/test
diff options
context:
space:
mode:
authorErlang/OTP <[email protected]>2009-11-20 14:54:40 +0000
committerErlang/OTP <[email protected]>2009-11-20 14:54:40 +0000
commit84adefa331c4159d432d22840663c38f155cd4c1 (patch)
treebff9a9c66adda4df2106dfd0e5c053ab182a12bd /lib/wx/test
downloadotp-84adefa331c4159d432d22840663c38f155cd4c1.tar.gz
otp-84adefa331c4159d432d22840663c38f155cd4c1.tar.bz2
otp-84adefa331c4159d432d22840663c38f155cd4c1.zip
The R13B03 release.OTP_R13B03
Diffstat (limited to 'lib/wx/test')
-rw-r--r--lib/wx/test/Makefile68
-rw-r--r--lib/wx/test/Readme30
-rw-r--r--lib/wx/test/wx.spec2
-rw-r--r--lib/wx/test/wx_basic_SUITE.erl296
-rw-r--r--lib/wx/test/wx_class_SUITE.erl381
-rw-r--r--lib/wx/test/wx_event_SUITE.erl331
-rw-r--r--lib/wx/test/wx_opengl_SUITE.erl182
-rw-r--r--lib/wx/test/wx_test_lib.erl234
-rw-r--r--lib/wx/test/wx_test_lib.hrl110
-rw-r--r--lib/wx/test/wx_xtra_SUITE.erl176
-rwxr-xr-xlib/wx/test/wxt41
-rw-r--r--lib/wx/test/wxt.erl160
12 files changed, 2011 insertions, 0 deletions
diff --git a/lib/wx/test/Makefile b/lib/wx/test/Makefile
new file mode 100644
index 0000000000..65d7d56650
--- /dev/null
+++ b/lib/wx/test/Makefile
@@ -0,0 +1,68 @@
+#
+# %CopyrightBegin%
+#
+# Copyright Ericsson AB 2008-2009. 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.
+#
+# %CopyrightEnd%
+#
+
+include ../vsn.mk
+include ../config.mk
+
+ESRC = .
+EBIN = .
+ERLC = erlc
+PWD = $(shell pwd)
+APPDIR = $(shell dirname $(PWD))
+ERL_COMPILE_FLAGS = -pa $(APPDIR)/ebin
+
+Mods = wxt wx_test_lib \
+ wx_basic_SUITE wx_event_SUITE \
+ wx_class_SUITE \
+ wx_xtra_SUITE \
+ wx_opengl_SUITE
+
+ErlSrc = $(Mods:%=%.erl)
+ErlTargets = $(Mods:%=$(EBIN)/%.beam)
+
+# Targets
+opt debug: $(ErlTargets)
+
+clean:
+ rm -f $(ErlTargets)
+ rm -f core erl_crash.dump
+ rm -f *~
+
+docs:
+
+
+# Rules
+ifneq ($(INSIDE_ERLSRC),true)
+
+$(EBIN)/%.beam: $(ESRC)/%.erl
+ $(ERLC) -W -bbeam $(ERL_FLAGS) $(ERL_COMPILE_FLAGS) -o$(EBIN) $<
+
+else
+RELSYSDIR = $(RELEASE_PATH)/wx_test
+include $(ERL_TOP)/make/otp_release_targets.mk
+release_spec:
+
+release_tests_spec: opt
+ $(INSTALL_DIR) $(RELSYSDIR)
+ $(INSTALL_DATA) wx.spec wx_test_lib.hrl $(ErlSrc) $(ErlTargets) $(RELSYSDIR)
+ $(INSTALL_PROGRAM) wxt $(RELSYSDIR)
+
+release_docs_spec:
+
+endif
diff --git a/lib/wx/test/Readme b/lib/wx/test/Readme
new file mode 100644
index 0000000000..09e9604491
--- /dev/null
+++ b/lib/wx/test/Readme
@@ -0,0 +1,30 @@
+
+Testing and running wxerlang tests.
+
+Testing gui api/applications can be hard, but we can at least
+test that wxerlang behaves as we expected, i.e. that the api
+is consistent and that it don't crash.
+
+The tests are structured as they are because we want you to
+be able to run them in three different ways.
+ - direct via an erlang shell
+ - via common_test application
+ - via erlang/OTP inhouse ts tool.
+
+To run all the tests compile them and on unix
+run ./wxt to create an erlang terminal.
+
+Invoke wxt:t(). in the erlang shell to run all regression tests.
+If you want to specific tests invoke wxt:t(Module)
+or wxt:t(Module, TestCase).
+
+To run all tests including the ones that require manual intervention run.
+wxt:t(all, [{user,true}]).
+
+To see every test_case window use
+wxt:t(all, [{user,step}]).
+This requires that you manually close each window to step to the
+next test_case.
+
+If you want to run specific test_cases use:
+wxt:t({Module,TestCase}, [{user,step}]).
diff --git a/lib/wx/test/wx.spec b/lib/wx/test/wx.spec
new file mode 100644
index 0000000000..a9201e5737
--- /dev/null
+++ b/lib/wx/test/wx.spec
@@ -0,0 +1,2 @@
+{topcase, {dir, "../wx_test"}}.
+
diff --git a/lib/wx/test/wx_basic_SUITE.erl b/lib/wx/test/wx_basic_SUITE.erl
new file mode 100644
index 0000000000..599aa371ba
--- /dev/null
+++ b/lib/wx/test/wx_basic_SUITE.erl
@@ -0,0 +1,296 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2008-2009. 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.
+%%
+%% %CopyrightEnd%
+%%%-------------------------------------------------------------------
+%%% File : wx_basic_SUITE.erl
+%%% Author : Dan Gudmundsson <[email protected]>
+%%% Description : Basic SUITE, some simple tests to show that the basics
+%%% are working.
+%%% Created : 3 Nov 2008 by Dan Gudmundsson <[email protected]>
+%%%-------------------------------------------------------------------
+-module(wx_basic_SUITE).
+-export([all/0, init_per_suite/1, end_per_suite/1,
+ init_per_testcase/2, fin_per_testcase/2, end_per_testcase/2]).
+
+-compile(export_all).
+
+-include("wx_test_lib.hrl").
+
+%% Initialization functions.
+init_per_suite(Config) ->
+ wx_test_lib:init_per_suite(Config).
+
+end_per_suite(Config) ->
+ wx_test_lib:end_per_suite(Config).
+
+init_per_testcase(Func,Config) ->
+ wx_test_lib:init_per_testcase(Func,Config).
+end_per_testcase(Func,Config) ->
+ wx_test_lib:end_per_testcase(Func,Config).
+fin_per_testcase(Func,Config) -> %% For test_server
+ wx_test_lib:end_per_testcase(Func,Config).
+
+%% SUITE specification
+all() ->
+ all(suite).
+all(suite) ->
+ [
+ create_window,
+ several_apps,
+ wx_api,
+ wx_misc,
+ data_types
+ ].
+
+%% The test cases
+
+%% create and test creating a window
+create_window(TestInfo) when is_atom(TestInfo) -> wx_test_lib:tc_info(TestInfo);
+create_window(Config) ->
+ Wx = ?mr(wx_ref, wx:new()),
+ Frame = ?mt(wxFrame, wxFrame:new(Wx, 1, "Hello World")),
+ timer:sleep(1000),
+ ?m(true,wxWindow:show(Frame, [])),
+ wx_test_lib:wx_destroy(Frame, Config).
+
+%% create several windows from independent processes
+%% to simulate several applications and test creating a window
+several_apps(TestInfo) when is_atom(TestInfo) -> wx_test_lib:tc_info(TestInfo);
+several_apps(Config) ->
+ Parent = self(),
+ 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]),
+ case wx_test_lib:user_available(Config) of
+ true ->
+ receive {'EXIT',_,foo} -> ok end;
+ false ->
+ ok
+ end.
+
+several_apps(Parent, N, Config) ->
+ Wx = ?mr(wx_ref, wx:new()),
+ Frame = ?mt(wxFrame, wxFrame:new(Wx, 1, "Hello World No:" ++
+ integer_to_list(N))),
+ create_menus(Frame),
+ wxFrame:connect(Frame,size),
+ ?m(true,wxWindow:show(Frame, [])),
+ receive
+ #wx{obj=Frame, event=#wxSize{}} ->
+ Parent ! {complete, self()}
+ end,
+ wx_test_lib:wx_destroy(Frame, Config),
+ exit(foo).
+
+
+%% Test the wx.erl api functionality.
+wx_api(TestInfo) when is_atom(TestInfo) -> wx_test_lib:tc_info(TestInfo);
+wx_api(Config) ->
+ Wx = ?mr(wx_ref, wx:new()),
+ ?m(true, wx:is_null(Wx)),
+ Null = ?mr(wx_ref, wx:null()),
+ ?m(true, wx:is_null(Null)),
+ Frame = ?mt(wxFrame, wxFrame:new(Wx, 1, "WX API: " ++ unicode:characters_to_list("������"))),
+ ?m(false, wx:is_null(Frame)),
+ ?m(wxFrame, wx:getObjectType(Frame)),
+ Env = ?mr(wx_env, wx:get_env()),
+ %% Test some error cases
+ erase(wx_env),
+ ?m({'EXIT', {{wxe,unknown_port},_}},wxWindow:show(Frame, [])),
+ ?m({'EXIT', {{wxe,unknown_port},_}},wx:debug(2)),
+
+ ?m(ok,wx:set_env(Env)),
+ ?m(ok,wx:debug(1)),
+ ?m(ok,wx:debug(2)),
+ ?m(ok,wx:debug(0)),
+ ?m(ok,wx:debug(none)),
+ ?m(ok,wx:debug(verbose)),
+ ?m(ok,wx:debug(trace)),
+
+ Mem = ?mr(wx_mem, wx:create_memory(10)),
+ ?m(true, is_binary(wx:get_memory_bin(Mem))),
+ ?mt(foo, wx:typeCast(Frame, foo)),
+
+ RecBatch = fun() ->
+ wx:batch(fun() -> create_menus(Frame) end)
+ end,
+ ?m(batch_ret, wx:batch(fun() -> RecBatch(), batch_ret end)),
+ ?m(ok, wx:foreach(fun(A) -> true = lists:member(A,[1,2,3,4,5]) end,
+ lists:seq(1,5))),
+ ?m([2,3,4,5,6], wx:map(fun(A) -> A+1 end, lists:seq(1,5))),
+ ?m({5,15}, wx:foldl(fun(A,{_,Acc}) -> {A,A+Acc} end, {0,0},
+ lists:seq(1,5))),
+ ?m({1,15}, wx:foldr(fun(A,{_,Acc}) -> {A,A+Acc} end, {0,0},
+ lists:seq(1,5))),
+ ?m(ok,wx:debug(none)),
+
+ ?m(ball, wx:batch(fun() -> throw(ball), batch_ret end)),
+ ?m({'EXIT', door}, wx:batch(fun() -> exit(door), batch_ret end)),
+ ?m({'EXIT',{message,_ST}},
+ wx:batch(fun() -> erlang:error(message), batch_ret end)),
+
+
+ ?m({'EXIT',_},wxWindow:show(wx:null(), [])),
+ ?m(true,wxWindow:show(Frame, [])),
+ Temp = ?mt(wxButton, wxButton:new(Frame, -1)),
+ ?m(ok,wxButton:setLabel(Temp, "Testing")),
+ ?m(ok,wxButton:destroy(Temp)),
+ ?m({'EXIT',_},wxButton:getLabel(Temp)),
+
+ case wx_test_lib:user_available(Config) of
+ true ->
+ %% Hmm popup doesn't return until mouse is pressed.
+ Menu = wxMenu:new(),
+ wxMenu:append(Menu, 0, "Press", []),
+ wxMenu:append(Menu, 1, "Me", []),
+ ?m(true, wxWindow:popupMenu(Frame, Menu)),
+ %% This didn't work for a while
+ ?m(true, wx:batch(fun() ->
+ wxMenu:append(Menu, 2, "AGAIN", []),
+ wxWindow:popupMenu(Frame, Menu)
+ end)),
+ ok;
+ _ ->
+ ignore
+ end,
+
+%% dbg:tracer(),
+%% {_, _Port, Server, _Dbg} = wx:get_env(),
+%% dbg:p(Server, [m, call]),
+%% dbg:p(new, [m, call]),
+%% dbg:tpl(wxe_server,'_', [{'_', [], [{return_trace}]}]),
+ wx_test_lib:wx_destroy(Frame,Config).
+
+create_menus(Frame) ->
+ MenuBar = ?mt(wxMenuBar, wxMenuBar:new()),
+ File = ?mt(wxMenu, wxMenu:new([])),
+ Help = ?mt(wxMenu, wxMenu:new([])),
+ ?mt(wxMenuItem, wxMenu:append(Help, ?wxID_ABOUT, "&About", [])),
+ ?mt(wxMenuItem, wxMenu:append(Help, ?wxID_HELP, "&Help", [])),
+ ?mt(wxMenuItem, wxMenu:append(File, ?wxID_EXIT, "Exit", [])),
+ ?m(ok,wxFrame:connect(Frame, command_menu_selected)),
+ ?m(true, wxMenuBar:append(MenuBar, File, "&File")),
+ ?m(true, wxMenuBar:append(MenuBar, Help, "&Help")),
+ ?m(ok, wxFrame:setMenuBar(Frame,MenuBar)).
+
+
+%% Test the wx_misc.erl api functionality.
+wx_misc(TestInfo) when is_atom(TestInfo) -> wx_test_lib:tc_info(TestInfo);
+wx_misc(Config) ->
+ wx:new([{debug, trace}]),
+ put(wx_test_verbose, true),
+ ?m(ok, wx_misc:bell()),
+ ?m(true, length(wx_misc:getUserId()) > 0),
+ ?m(true, is_list(wx_misc:getEmailAddress())),
+ Home = ?m([_|_], wx_misc:getHomeDir()),
+ ?m(true, filelib:is_dir(Home)),
+ ?m(true, length(wx_misc:getOsDescription()) > 0),
+ IsLitte = case <<1:32/native>> of
+ <<1:8, 0:24>> -> true;
+ <<0:24,1:16>> -> false
+ end,
+ ?m(IsLitte, wx_misc:isPlatformLittleEndian()),
+ ?m(true, is_boolean(wx_misc:isPlatform64Bit())),
+
+ ?mr(wxMouseState, wx_misc:getMouseState()),
+ ?m({_,_}, wx_misc:getMousePosition()),
+
+ %% Don't hold home down when testing :-)
+ ?m(false, wx_misc:getKeyState(?WXK_HOME)),
+
+
+ %% 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()),
+ ?m(ok, wx_misc:endBusyCursor()),
+
+ %%?m(true, is_boolean(wx_misc:setDetectableAutoRepeat(true)),
+ Curr = wx_misc:getCurrentId(),
+ ?m(true, is_integer(Curr)),
+ NewId = wx_misc:newId(),
+ ?m(ok, wx_misc:registerId(NewId+1)),
+ ?m(true, (NewId+1) /= wx_misc:newId()),
+
+ wx:destroy().
+
+
+%% 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"),
+ CDC = wxClientDC:new(Frame),
+
+ %% From wx.erl
+ %% The following classes are implemented directly as erlang types: <br />
+ %% wxPoint={x,y},wxSize={w,h},wxRect={x,y,w,h},wxColour={r,g,b [,a]},wxString=[integer],
+ %% wxGBPosition={r,c},wxGBSpan={rs,cs},wxGridCellCoords={r,c}.
+
+ %% Strings
+ ?m("Data Types", wxFrame:getTitle(Frame)),
+
+ %% Doubles
+ ?m(ok, wxDC:setUserScale(CDC, 123.45, 234.67)),
+ ?m({123.45,234.67}, wxDC:getUserScale(CDC)),
+
+ %% 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
+ ?m(ok, wxDC:setAxisOrientation(CDC, true, false)),
+ ?m(true, is_boolean(wxDC:isOk(CDC))),
+
+ %% wxCoord
+ ?m(true, is_integer(wxDC:maxX(CDC))),
+
+ %% wxSize
+ ?m({_,_}, wxWindow:getSize(Frame)),
+
+ %% DateTime
+ DateTime = calendar:now_to_datetime(erlang:now()),
+ io:format("DateTime ~p ~n",[DateTime]),
+ Cal = ?mt(wxCalendarCtrl, wxCalendarCtrl:new(Frame, ?wxID_ANY, [{date,DateTime}])),
+ ?m(DateTime, wxCalendarCtrl:getDate(Cal)),
+ ?m(true, is_boolean(wxCalendarCtrl:setDate(Cal,DateTime))),
+ ?m(DateTime, wxCalendarCtrl:getDate(Cal)),
+
+ wxClientDC:destroy(CDC),
+ %%wx_test_lib:wx_destroy(Frame,Config).
+ wx:destroy().
diff --git a/lib/wx/test/wx_class_SUITE.erl b/lib/wx/test/wx_class_SUITE.erl
new file mode 100644
index 0000000000..cedbd1ef19
--- /dev/null
+++ b/lib/wx/test/wx_class_SUITE.erl
@@ -0,0 +1,381 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2008-2009. 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.
+%%
+%% %CopyrightEnd%
+%%%-------------------------------------------------------------------
+%%% File : wx_class_SUITE.erl
+%%% Author : Dan Gudmundsson <[email protected]>
+%%% Description :
+%%%
+%%% Created : 13 Nov 2008 by Dan Gudmundsson <[email protected]>
+%%%-------------------------------------------------------------------
+-module(wx_class_SUITE).
+
+-export([all/0, init_per_suite/1, end_per_suite/1,
+ init_per_testcase/2, fin_per_testcase/2, end_per_testcase/2]).
+
+-compile(export_all).
+
+-include("wx_test_lib.hrl").
+
+%% Initialization functions.
+init_per_suite(Config) ->
+ wx_test_lib:init_per_suite(Config).
+
+end_per_suite(Config) ->
+ wx_test_lib:end_per_suite(Config).
+
+init_per_testcase(Func,Config) ->
+ wx_test_lib:init_per_testcase(Func,Config).
+end_per_testcase(Func,Config) ->
+ wx_test_lib:end_per_testcase(Func,Config).
+fin_per_testcase(Func,Config) -> %% For test_server
+ wx_test_lib:end_per_testcase(Func,Config).
+
+%% SUITE specification
+all() ->
+ all(suite).
+all(suite) ->
+ [
+ calendarCtrl,
+ treeCtrl,
+ notebook,
+ staticBoxSizer,
+ clipboard,
+ helpFrame,
+ htmlWindow,
+ listCtrlSort,
+ radioBox
+ ].
+
+%% The test cases
+
+%% create and test a calendar, especially the DateAttr no-deletition.
+calendarCtrl(TestInfo) when is_atom(TestInfo) -> wx_test_lib:tc_info(TestInfo);
+calendarCtrl(Config) ->
+ Wx = ?mr(wx_ref, wx:new()),
+ Frame = ?mt(wxFrame, wxFrame:new(Wx, 1, "Calendar", [])),
+ Panel = wxPanel:new(Frame),
+ Sz = wxBoxSizer:new(?wxVERTICAL),
+
+ {YMD={_,_,Day},_} = DateTime = calendar:now_to_datetime(erlang:now()),
+ Cal = ?mt(wxCalendarCtrl, wxCalendarCtrl:new(Panel, ?wxID_ANY,
+ [{date,DateTime}
+ ])),
+ wxSizer:add(Sz,Cal),
+
+ DateAttr0 = ?mt(wxCalendarDateAttr, wxCalendarCtrl:getAttr(Cal,Day)),
+ case wx:is_null(DateAttr0) of
+ true ->
+ ?log("DateAttr is null~n",[]);
+ false ->
+ ?log("DateAttr is useable~n",[])
+ end,
+ DateAttr = ?mt(wxCalendarDateAttr, wxCalendarDateAttr:new()),
+ wxCalendarDateAttr:setBackgroundColour(DateAttr, {0,243,0}),
+ wxCalendarCtrl:setAttr(Cal, Day, DateAttr),
+ DateAttr1 = ?mt(wxCalendarDateAttr, wxCalendarCtrl:getAttr(Cal,Day)),
+ ?m({0,243,0,255}, wxCalendarDateAttr:getBackgroundColour(DateAttr1)),
+
+ ?m({YMD, _},wxCalendarCtrl:getDate(Cal)),
+
+ wxCalendarCtrl:connect(Cal, calendar_weekday_clicked),
+ wxCalendarCtrl:connect(Cal, calendar_day_changed),
+ wxCalendarCtrl:connect(Cal, calendar_month_changed),
+ wxCalendarCtrl:connect(Cal, calendar_year_changed),
+ wxCalendarCtrl:connect(Cal, calendar_doubleclicked),
+ wxCalendarCtrl:connect(Cal, calendar_sel_changed),
+
+ wxWindow:setSizer(Panel,Sz),
+ wxSizer:setSizeHints(Sz,Frame),
+ wxWindow:show(Frame),
+
+ wx_test_lib:wx_destroy(Frame,Config).
+
+
+treeCtrl(TestInfo) when is_atom(TestInfo) -> wx_test_lib:tc_info(TestInfo);
+treeCtrl(Config) ->
+ Wx = wx:new(),
+
+ Frame = wxFrame:new(Wx, ?wxID_ANY, "Frame"),
+ Panel = wxPanel:new(Frame, []),
+ Tree = ?mt(wxTreeCtrl,wxTreeCtrl:new(Panel, [{style , ?wxTR_HAS_BUTTONS}])),
+ Root = ?mt(wxTreeItemId, wxTreeCtrl:addRoot(Tree, "Root", [])),
+ Item1 = ?mt(wxTreeItemId, wxTreeCtrl:appendItem(Tree, Root, "Item1", [])),
+ ?m(ok, wxTreeCtrl:setItemData(Tree, Item1, {data, item1})),
+ Item2 = ?mt(wxTreeItemId, wxTreeCtrl:appendItem(Tree, Root, "Item2", [])),
+ ?m(ok, wxTreeCtrl:setItemData(Tree, Item2, {data, item2})),
+ Item3 = ?mt(wxTreeItemId, wxTreeCtrl:appendItem(Tree, Root, "Item3", [])),
+ ?m(ok, wxTreeCtrl:setItemData(Tree, Item3, {data, item3})),
+
+ Sizer = wxBoxSizer:new(?wxVERTICAL),
+ wxSizer:add(Sizer, Tree, [{flag, ?wxEXPAND}, {proportion, 1}]),
+
+ wxWindow:setSizerAndFit(Panel, Sizer),
+ wxFrame:show(Frame),
+
+ ?m([], wxTreeCtrl:getItemData(Tree, Root)),
+ ?m({data,item1}, wxTreeCtrl:getItemData(Tree, Item1)),
+ ?m({data,item2}, wxTreeCtrl:getItemData(Tree, Item2)),
+ ?m({data,item3}, wxTreeCtrl:getItemData(Tree, Item3)),
+
+ wxFrame:connect(Tree, command_tree_item_expanded),
+ wxFrame:connect(Tree, command_tree_item_collapsed),
+ wxFrame:connect(Frame, close_window),
+
+ wx_test_lib:wx_destroy(Frame,Config).
+
+notebook(TestInfo) when is_atom(TestInfo) -> wx_test_lib:tc_info(TestInfo);
+notebook(Config) ->
+ Wx = wx:new(),
+
+ Frame = wxFrame:new(Wx, ?wxID_ANY, "Frame"),
+ Panel = wxPanel:new(Frame, []),
+ Book = wxNotebook:new(Panel, ?wxID_ANY, []),
+
+ Panel1 = wxPanel:new(Book, []),
+ List1 = wxListBox:new(Panel1,
+ ?wxID_ANY,
+ [{choices, ["aaa1", "bb1", "c1"]},
+ {style,
+ ?wxLB_SORT bor
+ ?wxLB_NEEDED_SB bor
+ ?wxLB_EXTENDED}]),
+ wxNotebook:addPage(Book, Panel1, "List1", []),
+ Sizer1 = wxBoxSizer:new(?wxVERTICAL),
+ wxSizer:add(Sizer1, List1, [{flag, ?wxEXPAND}, {proportion, 1}]),
+ wxWindow:setSizer(Panel1, Sizer1),
+
+ Panel2 = wxPanel:new(Book, []),
+ List2 = wxListBox:new(Panel2,
+ ?wxID_ANY,
+ [{choices, ["aaa2", "bb2", "c2"]},
+ {style,
+ ?wxLB_SORT bor
+ ?wxLB_NEEDED_SB bor
+ ?wxLB_EXTENDED}]),
+ wxNotebook:addPage(Book, Panel2, "List2", []),
+ Sizer2 = wxBoxSizer:new(?wxVERTICAL),
+ wxSizer:add(Sizer2, List2, [{flag, ?wxEXPAND}, {proportion, 1}]),
+ wxWindow:setSizer(Panel2, Sizer2),
+
+ Panel3 = wxPanel:new(Book, []),
+ List3 = wxListBox:new(Panel3,
+ ?wxID_ANY,
+ [{choices, ["aaa3", "bb3", "c3"]},
+ {style,
+ ?wxLB_SORT bor
+ ?wxLB_NEEDED_SB bor
+ ?wxLB_EXTENDED}]),
+ wxNotebook:addPage(Book, Panel3, "List3", []),
+ Sizer3 = wxBoxSizer:new(?wxVERTICAL),
+ wxSizer:add(Sizer3, List3, [{flag, ?wxEXPAND}, {proportion, 1}]),
+ wxWindow:setSizer(Panel3, Sizer3),
+
+ Sizer = wxBoxSizer:new(?wxVERTICAL),
+ wxSizer:add(Sizer, Book, [{flag, ?wxEXPAND}, {proportion, 1}]),
+
+
+ wxWindow:setSizer(Panel, Sizer),
+ wxSizer:fit(Sizer, Frame),
+ wxSizer:setSizeHints(Sizer, Frame),
+ wxFrame:show(Frame),
+
+ wxFrame:connect(Frame, close_window),
+
+ wx_test_lib:wx_destroy(Frame,Config).
+
+staticBoxSizer(TestInfo) when is_atom(TestInfo) -> wx_test_lib:tc_info(TestInfo);
+staticBoxSizer(Config) ->
+ Wx = wx:new(),
+ wx:debug(2),
+ Frame = wxFrame:new(Wx, ?wxID_ANY, "Frame"),
+ Panel = wxPanel:new(Frame, []),
+ InclSizer = ?mt(wxStaticBoxSizer,
+ wxStaticBoxSizer:new(?wxVERTICAL, Panel,
+ [{label, "Module inclusion policy"}])),
+ Sizer = wxBoxSizer:new(?wxVERTICAL),
+ wxSizer:add(Sizer, InclSizer,
+ [{border, 2}, {flag, ?wxALL bor ?wxEXPAND}, {proportion, 1}]),
+ wxWindow:setSizerAndFit(Panel, Sizer),
+
+ wxWindow:show(Frame),
+ wx_test_lib:wx_destroy(Frame,Config).
+
+
+clipboard(TestInfo) when is_atom(TestInfo) -> wx_test_lib:tc_info(TestInfo);
+clipboard(_Config) ->
+ wx:new(),
+ CB = ?mt(wxClipboard, wxClipboard:get()),
+ wxClipboard:usePrimarySelection(CB),
+ ?m(false, wx:is_null(CB)),
+ case wxClipboard:open(CB) of
+ true ->
+ case wxClipboard:isSupported(CB, ?wxDF_TEXT) of
+ false ->
+ ?log("No text on the clipboard~n",[]);
+ true ->
+ Text = ?mt(wxTextDataObject, wxTextDataObject:new()),
+ case wxClipboard:getData(CB,Text) of
+ true ->
+ ?log("PASTE: ~s ~n", [wxTextDataObject:getText(Text)]);
+ false ->
+ ?log("Couldn't access clipboard~n",[])
+ end,
+ wxTextDataObject:destroy(Text)
+ end,
+ wxClipboard:close(CB);
+ false ->
+ ?log("Clipboard open failed~n",[])
+ end,
+ case wxClipboard:open(CB) of
+ true ->
+ Paste = ?mt(wxTextDataObject, wxTextDataObject:new([{text,"From Erlang"}])),
+ case wxClipboard:addData(CB,Paste) of
+ true ->
+ ?log("Put text on clipboard~n", []);
+ false ->
+ ?log("Couldn't copy data to clipboard~n",[])
+ end,
+ wxClipboard:close(CB);
+ false ->
+ ?log("Clipboard open failed~n",[])
+ end,
+ ?log("Flushing ~n",[]),
+ wxClipboard:flush(CB),
+ ?log("Stopping ~n",[]),
+ ok.
+
+helpFrame(TestInfo) when is_atom(TestInfo) -> wx_test_lib:tc_info(TestInfo);
+helpFrame(Config) ->
+ Wx = wx:new(),
+ MFrame = wx:batch(fun() ->
+ MFrame = wxFrame:new(Wx, ?wxID_ANY, "Main Frame"),
+ wxPanel:new(MFrame, [{size, {600,400}}]),
+ wxWindow:show(MFrame),
+ MFrame
+ end),
+ timer:sleep(9),
+
+ {X0, Y0} = wxWindow:getScreenPosition(MFrame),
+ {X, Y, W,H} = wxWindow:getScreenRect(MFrame),
+ io:format("Pos0: ~p ~p ~p Pos: ~p:~p Size: ~p:~p ~n",
+ [X0,Y0, wxWindow:clientToScreen(MFrame, {0,0}), X,Y,W,H]),
+
+ Pos = {X+5, Y+(H div 2)},
+ Size = {W-10, (H div 2) - 5},
+
+ Comp = wxFrame:new(MFrame, ?wxID_ANY, "Completion Window",
+ [{pos, Pos}, {size, Size},
+ {style, ?wxFRAME_FLOAT_ON_PARENT}]),
+ LB = wxListBox:new(Comp, 42, [{style, ?wxLB_SINGLE},
+ {size, Size}]),
+
+ Items = ["Item " ++ integer_to_list(N) || N <- lists:seq(1, 10)],
+ wxListBox:insertItems(LB,Items,0),
+
+ wxWindow:show(Comp),
+ wx_test_lib:wx_destroy(MFrame,Config).
+
+htmlWindow(TestInfo) when is_atom(TestInfo) -> wx_test_lib:tc_info(TestInfo);
+htmlWindow(Config) ->
+ Wx = wx:new(),
+ {MFrame,HPanel} =
+ wx:batch(fun() ->
+ MFrame = wxFrame:new(Wx, ?wxID_ANY, "Main Frame"),
+ HPanel = wxHtmlWindow:new(MFrame, [{size, {600,400}}]),
+ wxWindow:show(MFrame),
+ {MFrame, HPanel}
+ end),
+ timer:sleep(9),
+
+ WxMod = code:which(wx),
+ WxDir = filename:split(filename:dirname(WxMod)) -- ["ebin"],
+ Html = filename:join(filename:join(WxDir),filename:join("doc", "html")),
+
+ Index = filename:join(Html, "wx.html"),
+
+ ?m(ok, wxHtmlWindow:connect(HPanel, command_html_link_clicked,
+ [{callback,
+ fun(Ev,_) ->
+ io:format("Link clicked: ~p~n",[Ev])
+ end}])),
+
+ case filelib:is_file(Index) of
+ true ->
+ ?m(true, wxHtmlWindow:loadFile(HPanel, Index)),
+ ok;
+ false ->
+ ok
+ end,
+
+ wx_test_lib:wx_destroy(MFrame,Config).
+
+
+listCtrlSort(TestInfo) when is_atom(TestInfo) -> wx_test_lib:tc_info(TestInfo);
+listCtrlSort(Config) ->
+ Wx = wx:new(),
+ Frame = wxFrame:new(Wx, ?wxID_ANY, "Frame"),
+
+ LC = wxListCtrl:new(Frame, [{style, ?wxLC_REPORT bor ?wxLC_SORT_ASCENDING}]),
+
+ %% must be done crashes in wxwidgets otherwise.
+ wxListCtrl:insertColumn(LC, 0, "Column"),
+
+ Add = fun(Int) ->
+ wxListCtrl:insertItem(LC, Int, integer_to_list(Int)),
+ %% ItemData Can only be integers currently
+ wxListCtrl:setItemData(LC, Int, abs(2500-Int))
+ end,
+
+ wx:foreach(Add, lists:seq(0,5000)),
+ wxWindow:show(Frame),
+
+ timer:sleep(200),
+
+ Sort = fun() ->
+ wxListCtrl:sortItems(LC, fun(A, B) ->
+ %% io:format("S ~p ~p ~n",[A,B]),
+ if A =:= B -> 0;
+ A < B -> -1;
+ true -> 1
+ end
+ end)
+ end,
+
+ Time = timer:tc(erlang, apply, [Sort,[]]),
+ io:format("Sorted ~p ~n",[Time]),
+
+ wx_test_lib:wx_destroy(Frame,Config).
+
+
+radioBox(TestInfo) when is_atom(TestInfo) -> wx_test_lib:tc_info(TestInfo);
+radioBox(Config) ->
+ Wx = wx:new(),
+ Frame = wxFrame:new(Wx, ?wxID_ANY, "Frame"),
+
+ TrSortRadioBox = wxRadioBox:new(Frame, ?wxID_ANY, "Sort by:",
+ {100, 100},{100, 100}, ["Timestamp"]),
+
+ io:format("TrSortRadioBox ~p ~n", [TrSortRadioBox]),
+ %% If I uncomment any of these lines, it will crash
+
+ ?m(_, catch wxControlWithItems:setClientData(TrSortRadioBox, 0, timestamp)),
+ %?m(_, wxListBox:append(TrSortRadioBox, "Session Id", session_id)),
+ %?m(_, wxListBox:insert(TrSortRadioBox, "Session Id", 0, session_id)),
+
+ wxWindow:show(Frame),
+ wx_test_lib:wx_destroy(Frame,Config).
diff --git a/lib/wx/test/wx_event_SUITE.erl b/lib/wx/test/wx_event_SUITE.erl
new file mode 100644
index 0000000000..dea10d892e
--- /dev/null
+++ b/lib/wx/test/wx_event_SUITE.erl
@@ -0,0 +1,331 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2008-2009. 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.
+%%
+%% %CopyrightEnd%
+%%%-------------------------------------------------------------------
+%%% File : wx_event_SUITE.erl
+%%% Author : Dan Gudmundsson <[email protected]>
+%%% Description : Test event handling as much as possible
+%%% Created : 3 Nov 2008 by Dan Gudmundsson <[email protected]>
+%%%-------------------------------------------------------------------
+-module(wx_event_SUITE).
+-export([all/0, init_per_suite/1, end_per_suite/1,
+ init_per_testcase/2, fin_per_testcase/2, end_per_testcase/2]).
+
+-compile(export_all).
+
+-include("wx_test_lib.hrl").
+
+%% Initialization functions.
+init_per_suite(Config) ->
+ wx_test_lib:init_per_suite(Config).
+
+end_per_suite(Config) ->
+ wx_test_lib:end_per_suite(Config).
+
+init_per_testcase(Func,Config) ->
+ wx_test_lib:init_per_testcase(Func,Config).
+end_per_testcase(Func,Config) ->
+ wx_test_lib:end_per_testcase(Func,Config).
+fin_per_testcase(Func,Config) -> %% For test_server
+ wx_test_lib:end_per_testcase(Func,Config).
+
+%% SUITE specification
+all() ->
+ all(suite).
+all(suite) ->
+ [
+ connect,
+ disconnect,
+ connect_msg_20,
+ connect_cb_20,
+ mouse_on_grid,
+ spin_event,
+ connect_in_callback
+ ].
+
+%% The test cases
+
+%% Test that the various options to connect work as expected.
+connect(TestInfo) when is_atom(TestInfo) -> wx_test_lib:tc_info(TestInfo);
+connect(Config) ->
+ ?mr(wx_ref, wx:new()),
+ Frame = ?mt(wxFrame, wxFrame:new(wx:null(), 1, "Event Testing")),
+ Panel = ?mt(wxPanel, wxPanel:new(Frame)),
+ Window = wxWindow:new(Panel, -1),
+
+ Tester = self(),
+ CB = fun(#wx{event=#wxSize{},userData=UserD}, SizeEvent) ->
+ ?mt(wxSizeEvent, SizeEvent),
+ 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}])),
+
+ ?m({'EXIT', {{badarg,_},_}},
+ wxEvtHandler:connect(Panel, there_is_no_such_event)),
+
+ ?m({'EXIT', {{badarg,_},_}},
+ wxEvtHandler:connect(Panel, there_is_no_such_event, [{callback,CB}])),
+
+ ?m(ok, wxWindow:connect(Window, size,[{callback,CB},{userData, window}])),
+ ?m(ok, wxWindow:connect(Window, size,[{skip,true},{userData, window}])),
+
+ ?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]),
+
+ wx_test_lib:wx_destroy(Frame, Config).
+
+get_size_messages(_, []) -> ok;
+get_size_messages(Frame, Msgs) ->
+ receive
+ #wx{obj=Frame,event=#wxSize{}} -> %% ok
+ get_size_messages(Frame, lists:delete(frame, Msgs));
+ #wx{userData=window, event=#wxSize{}} ->
+ ?m(true, lists:member(window_cb, Msgs)),
+ get_size_messages(Frame, lists:delete(window, Msgs));
+ #wx{userData=panel, event=#wxSize{}} ->
+ ?m(true, lists:member(panel, Msgs)),
+ get_size_messages(Frame, lists:delete(panel, Msgs));
+ {got_size,window} ->
+ ?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));
+ Other ->
+ ?error("Got unexpected msg ~p ~p~n", [Other,Msgs])
+ after 1000 ->
+ ?error("Timeout ~p~n", [Msgs])
+ end.
+
+disconnect(TestInfo) when is_atom(TestInfo) -> wx_test_lib:tc_info(TestInfo);
+disconnect(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),
+ Tester ! {got_size, UserD}
+ end,
+ ?m(ok, wxFrame:connect(Frame, close_window)),
+ ?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}])),
+
+ ?m(true, wxFrame:show(Frame)),
+
+ wxWindow:setSize(Panel, {200,100}),
+ get_size_messages(Frame, [frame, panel_cb]),
+ wx_test_lib:flush(),
+
+ ?m(true, wxEvtHandler:disconnect(Panel, size, [{callback,CB}])),
+ ?m(ok, wxWindow:setSize(Panel, {200,101})),
+ get_size_messages(Frame, [panel]),
+ timer:sleep(1000),
+ wx_test_lib:flush(),
+
+ ?m({'EXIT', {{badarg,_},_}}, 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).
+
+
+
+%% Test that the msg events are forwarded as supposed to
+connect_msg_20(TestInfo)
+ when is_atom(TestInfo) -> wx_test_lib:tc_info(TestInfo);
+connect_msg_20(Config) ->
+ ?mr(wx_ref, wx:new()),
+ Frame = ?mt(wxFrame, wxFrame:new(wx:null(), 1, "Event 20 Testing")),
+ Tester = self(),
+ Env = wx:get_env(),
+
+ EvtHandler = fun() ->
+ wx:set_env(Env),
+ wxFrame:connect(Frame,size,[{skip,true}]),
+ Tester ! initiated,
+ receive #wx{obj=Frame,event=#wxSize{}} ->
+ Tester ! got_it
+ end
+ end,
+ Msgs = [begin spawn_link(EvtHandler), got_it end|| _ <- lists:seq(1,20)],
+
+ ?m_multi_receive(lists:duplicate(20, initiated)),
+ ?m(true, wxFrame:show(Frame)),
+
+ ?m_multi_receive(Msgs),
+ wx_test_lib:wx_destroy(Frame, Config).
+
+%% Test that the callbacks works as msgs
+connect_cb_20(TestInfo)
+ when is_atom(TestInfo) -> wx_test_lib:tc_info(TestInfo);
+connect_cb_20(Config) ->
+ ?mr(wx_ref, wx:new()),
+ Frame = ?mt(wxFrame, wxFrame:new(wx:null(), 1, "Event 20 Testing")),
+ Tester = self(),
+ Env = wx:get_env(),
+
+ wxFrame:connect(Frame,size,[{callback,
+ fun(#wx{event=#wxSize{}},_SizeEv) ->
+ Tester ! main_got_it
+ end}]),
+
+ EvtHandler = fun() ->
+ wx:set_env(Env),
+ Self = self(),
+ CB = fun(#wx{event=#wxSize{}},
+ WxSizeEventObj) ->
+ wxEvent:skip(WxSizeEventObj),
+ Tester ! got_it,
+ Self ! quit
+ end,
+ wxFrame:connect(Frame,size,[{callback, CB}]),
+ Tester ! initiated,
+ receive quit -> ok
+ end
+ end,
+ Msgs = [begin spawn_link(EvtHandler), got_it end|| _ <- lists:seq(1,20)],
+
+ ?m_multi_receive(lists:duplicate(20, initiated)),
+ ?m(true, wxFrame:show(Frame)),
+
+ ?m_multi_receive(Msgs),
+ ?m_receive(main_got_it),
+
+ wx_test_lib:wx_destroy(Frame, Config).
+
+
+mouse_on_grid(TestInfo)
+ when is_atom(TestInfo) -> wx_test_lib:tc_info(TestInfo);
+mouse_on_grid(Config) ->
+ Wx = ?mr(wx_ref, wx:new()),
+
+ Frame = wxFrame:new(Wx, ?wxID_ANY, "Frame"),
+ Panel = wxPanel:new(Frame, []),
+ Sizer = wxBoxSizer:new(?wxVERTICAL),
+
+ Grid = wxGrid:new(Panel, ?wxID_ANY),
+ wxGrid:createGrid(Grid, 10, 10, []),
+ wxSizer:add(Sizer, Grid, [{proportion, 1}]),
+
+ wxWindow:connect(Panel, motion),
+ wxWindow:connect(Panel, middle_down),
+
+ %% Undocumented function
+ GridWindow = ?mt(wxWindow, wxGrid:getGridWindow(Grid)),
+ wxWindow:connect(GridWindow, motion),
+ wxWindow:connect(GridWindow, middle_down),
+
+ wxWindow:setSizerAndFit(Panel, Sizer),
+ wxFrame:show(Frame),
+
+ wx_test_lib:wx_destroy(Frame, Config).
+
+
+spin_event(TestInfo)
+ when is_atom(TestInfo) -> wx_test_lib:tc_info(TestInfo);
+spin_event(Config) ->
+ Wx = ?mr(wx_ref, wx:new()),
+
+ %% Spin events and scrollEvent share some events id's
+ %% test that they work
+
+ Frame = wxFrame:new(Wx, ?wxID_ANY, "Spin Events"),
+ Panel = wxPanel:new(Frame, []),
+ Sizer = wxBoxSizer:new(?wxVERTICAL),
+ HSz = wxBoxSizer:new(?wxHORIZONTAL),
+
+ SB = wxSpinButton:new(Panel, [{id, 100}]),
+ wxSizer:add(HSz, SB, []),
+ wxSpinButton:connect(SB, spin),
+ wxSpinButton:connect(SB, spin_up),
+ wxSpinButton:connect(SB, spin_down),
+
+ SC = wxSpinCtrl:new(Panel, [{id, 101}, {min, -12}, {max, 12},
+ {value, "-3"}, {initial, 3},
+ {style, ?wxSP_ARROW_KEYS bor ?wxSP_WRAP}]),
+ wxSpinCtrl:connect(SC, command_spinctrl_updated),
+ wxSizer:add(HSz, SC, [{proportion, 1}, {flag, ?wxEXPAND}]),
+ wxSizer:add(Sizer, HSz, [{proportion, 0},{flag, ?wxEXPAND}]),
+
+ SL = wxSlider:new(Panel, 102, 57, 22, 99),
+ wxSlider:connect(SL, scroll_thumbtrack),
+ wxSlider:connect(SL, scroll_lineup),
+ wxSlider:connect(SL, scroll_linedown),
+ wxSizer:add(Sizer, SL, [{proportion, 0},{flag, ?wxEXPAND}]),
+
+ wxWindow:setSizerAndFit(Panel, Sizer),
+ wxFrame:show(Frame),
+ wx_test_lib:flush(),
+
+%% Set value does not generate a spin event...
+%% wxSpinButton:setValue(SB, 7),
+%% ?m_receive(#wx{id=100, event=#wxSpin{type=spin}}),
+%% wxSpinCtrl:setValue(SC, 8),
+%% ?m_receive(#wx{id=101, event=#wxSpin{type=command_spinctrl_updated}}),
+%% wxSlider:setValue(SL, 29),
+%% ?m_receive(#wx{id=102, event=#wxScroll{}}),
+
+ wx_test_lib:wx_destroy(Frame, Config).
+
+
+%% Test that we can connect to events from inside a callback fun
+%% This is needed for example inside a callback that does a wxWindow:popupMenu/2
+connect_in_callback(TestInfo)
+ when is_atom(TestInfo) -> wx_test_lib:tc_info(TestInfo);
+connect_in_callback(Config) ->
+ Wx = ?mr(wx_ref, wx:new()),
+ Frame = wxFrame:new(Wx, ?wxID_ANY, "Connect in callback"),
+ Panel = wxPanel:new(Frame, []),
+
+ wxFrame:connect(Frame,size,
+ [{callback,
+ fun(#wx{event=#wxSize{}},_SizeEv) ->
+ io:format("Frame got size~n",[]),
+ F1 = wxFrame:new(Frame, ?wxID_ANY, "Frame size event"),
+ CBPid = self(),
+ wxFrame:connect(F1,size,[{callback,
+ fun(_,_) ->
+ io:format("CB2 got size~n",[]),
+ CBPid ! continue
+ end}]),
+ wxWindow:show(F1),
+ receive continue -> wxFrame:destroy(F1) end
+ end}]),
+ wxPanel:connect(Panel,size,
+ [{callback,
+ fun(#wx{event=#wxSize{}},_SizeEv) ->
+ io:format("Panel got size~n",[]),
+ F1 = wxFrame:new(Frame, ?wxID_ANY, "Panel size event"),
+ wxFrame:connect(F1,size),
+ wxWindow:show(F1),
+ receive #wx{event=#wxSize{}} -> wxFrame:destroy(F1) end
+ end}]),
+ wxFrame:show(Frame),
+ wx_test_lib:flush(),
+
+ wx_test_lib:wx_destroy(Frame, Config).
diff --git a/lib/wx/test/wx_opengl_SUITE.erl b/lib/wx/test/wx_opengl_SUITE.erl
new file mode 100644
index 0000000000..ce4651bcb1
--- /dev/null
+++ b/lib/wx/test/wx_opengl_SUITE.erl
@@ -0,0 +1,182 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2008-2009. 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.
+%%
+%% %CopyrightEnd%
+%%%-------------------------------------------------------------------
+%%% File : wx_opengl_SUITE.erl
+%%% Author : Dan Gudmundsson <[email protected]>
+%%% Description : Test opengl basics, i.e. functions can be loaded, glu works.
+%%% Created : 3 Nov 2008 by Dan Gudmundsson <[email protected]>
+%%%-------------------------------------------------------------------
+-module(wx_opengl_SUITE).
+-export([all/0, init_per_suite/1, end_per_suite/1,
+ init_per_testcase/2, fin_per_testcase/2, end_per_testcase/2]).
+
+-compile(export_all).
+
+-include("wx_test_lib.hrl").
+-include_lib("wx/include/gl.hrl").
+
+%% Initialization functions.
+init_per_suite(Config) ->
+ case wx_test_lib:init_per_suite(Config) of
+ Skipped = {skipped, _} -> Skipped;
+ Config2 ->
+ case wx_test_lib:user_available(Config2) of
+ true -> Config2;
+ false -> {skipped, "Ignoring opengl tests: run manually"}
+ end
+ end.
+
+end_per_suite(Config) ->
+ wx_test_lib:end_per_suite(Config).
+
+init_per_testcase(Func,Config) ->
+ wx_test_lib:init_per_testcase(Func,Config).
+end_per_testcase(Func,Config) ->
+ wx_test_lib:end_per_testcase(Func,Config).
+fin_per_testcase(Func,Config) -> %% For test_server
+ wx_test_lib:end_per_testcase(Func,Config).
+
+%% SUITE specification
+all() ->
+ all(suite).
+all(suite) ->
+ [
+ canvas,
+ glu_tesselation
+ ].
+
+%% The test cases
+
+-define(VS, {{ 0.5, 0.5, -0.5}, %1
+ { 0.5, -0.5, -0.5}, %2
+ {-0.5, -0.5, -0.5},
+ {-0.5, 0.5, -0.5}, %4
+ {-0.5, 0.5, 0.5},
+ { 0.5, 0.5, 0.5}, %6
+ { 0.5, -0.5, 0.5},
+ {-0.5, -0.5, 0.5}}).%8
+
+-define(FACES,
+ %% Faces Normal
+ [{{1,2,3,4},{0,0,-1} }, %
+ {{3,8,5,4},{-1,0,0}}, %
+ {{1,6,7,2},{1,0,0} }, %
+ {{6,5,8,7},{0,0,1} }, %
+ {{6,1,4,5},{0,1,0} }, %
+ {{7,8,3,2},{0,-1,0}}]).
+
+
+%% Test we can create a glCanvas and that functions are loaded dynamicly
+canvas(TestInfo) when is_atom(TestInfo) -> wx_test_lib:tc_info(TestInfo);
+canvas(Config) ->
+ WX = ?mr(wx_ref, wx:new()),
+ Frame = wxFrame:new(WX,1,"Hello 3D-World",[]),
+ Attrs = [{attribList, [?WX_GL_RGBA,?WX_GL_DOUBLEBUFFER,0]}],
+ Canvas = ?mt(wxGLCanvas, wxGLCanvas:new(Frame, Attrs)),
+
+ ?m(true, wxWindow:show(Frame)),
+ ?m(false, wx:is_null(wxGLCanvas:getContext(Canvas))),
+ ?m({'EXIT', {{no_gl_context,_},_}}, gl:getString(?GL_VENDOR)),
+
+ ?m(ok, wxGLCanvas:setCurrent(Canvas)),
+ io:format("Vendor: ~s~n", [gl:getString(?GL_VENDOR)]),
+ io:format("Renderer: ~s~n", [gl:getString(?GL_RENDERER)]),
+ io:format("Version: ~s~n", [gl:getString(?GL_VERSION)]),
+
+ {W,H} = ?m({_,_}, wxWindow:getClientSize(Canvas)),
+ gl:viewport(0,0,W,H),
+ gl:matrixMode(?GL_PROJECTION),
+ gl:loadIdentity(),
+ %%gl:frustum( -2.0, 2.0, -2.0, 2.0, 5.0, 25.0 ),
+ gl:ortho( -2.0, 2.0, -2.0*H/W, 2.0*H/W, -20.0, 20.0),
+ gl:matrixMode(?GL_MODELVIEW),
+ gl:loadIdentity(),
+ gl:enable(?GL_DEPTH_TEST),
+ gl:depthFunc(?GL_LESS),
+ {R,G,B,_} = wxWindow:getBackgroundColour(Frame),
+ gl:clearColor(R/255,B/255,G/255,1.0),
+ Data = {?FACES,?VS},
+ drawBox(0, Data),
+ ?m(ok, wxGLCanvas:swapBuffers(Canvas)),
+
+ Env = wx:get_env(),
+ Tester = self(),
+ spawn_link(fun() ->
+ wx:set_env(Env),
+ ?m(ok, wxGLCanvas:setCurrent(Canvas)),
+ ?m(ok, drawBox(1, Data)),
+ ?m(ok, wxGLCanvas:swapBuffers(Canvas)),
+ Tester ! works,
+ %% This may fail when window is deleted
+ catch draw_loop(2,Data,Canvas)
+ end),
+
+ ?m_receive(works),
+ wx_test_lib:wx_destroy(Frame, Config).
+
+draw_loop(Deg,Data,Canvas) ->
+ timer:sleep(15),
+ drawBox(Deg,Data),
+ ?m(ok, wxGLCanvas:swapBuffers(Canvas)),
+ draw_loop(Deg+1, Data,Canvas).
+
+
+drawBox(Deg,{Fs,Vs}) ->
+ gl:matrixMode(?GL_MODELVIEW),
+ gl:loadIdentity(),
+ gl:rotatef(Deg, 0.0, 1.0, 0.0),
+ gl:rotatef(20, 1.0, 0.0, 1.0),
+ gl:clear(?GL_COLOR_BUFFER_BIT bor ?GL_DEPTH_BUFFER_BIT),
+ gl:'begin'(?GL_QUADS),
+ lists:foreach(fun(Face) -> drawFace(Face,Vs) end, Fs),
+ gl:'end'().
+
+drawFace({{V1,V2,V3,V4},N={N1,N2,N3}}, Cube) ->
+ gl:normal3fv(N),
+ gl:color3f(abs(N1),abs(N2),abs(N3)),
+ gl:texCoord2f(0.0, 1.0), gl:vertex3fv(element(V1, Cube)),
+ gl:texCoord2f(0.0, 0.0), gl:vertex3fv(element(V2, Cube)),
+ gl:texCoord2f(1.0, 0.0), gl:vertex3fv(element(V3, Cube)),
+ gl:texCoord2f(1.0, 1.0), gl:vertex3fv(element(V4, Cube)).
+
+
+glu_tesselation(TestInfo) when is_atom(TestInfo) -> wx_test_lib:tc_info(TestInfo);
+glu_tesselation(Config) ->
+ WX = ?mr(wx_ref, wx:new()),
+ Frame = wxFrame:new(WX,1,"Hello 3D-World",[]),
+ Attrs = [{attribList, [?WX_GL_RGBA,?WX_GL_DOUBLEBUFFER,0]}],
+ Canvas = ?mt(wxGLCanvas, wxGLCanvas:new(Frame, Attrs)),
+ ?m(true, wxWindow:show(Frame)),
+ ?m(ok, wxGLCanvas:setCurrent(Canvas)),
+
+ {RL1,RB1} = ?m({_,_}, glu:tesselate({0,0,1}, [{-1,0,0},{1,0,0},{0,1,0}])),
+ ?m(3, length(RL1)),
+ ?m(8*3*3, size(RB1)),
+ {RL2,RB2} = ?m({_,_}, glu:tesselate({0,0,1},
+ [{-1,0,0},{1,0,0},{1,1,0},{-1,1,0}])),
+ ?m(6, length(RL2)),
+ ?m(8*3*4, size(RB2)),
+ {RL3,RB3} = ?m({_,_}, glu:tesselate({0,0,1},
+ [{-1,0,0},{1,0,0},{1,1,0},
+ {-1,1,0},{-5,0.5,0}])),
+ ?m(9, length(RL3)),
+ ?m(8*3*5, size(RB3)),
+
+ wx_test_lib:wx_destroy(Frame, Config).
+
+
diff --git a/lib/wx/test/wx_test_lib.erl b/lib/wx/test/wx_test_lib.erl
new file mode 100644
index 0000000000..9368aa4bdc
--- /dev/null
+++ b/lib/wx/test/wx_test_lib.erl
@@ -0,0 +1,234 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2008-2009. 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.
+%%
+%% %CopyrightEnd%
+%%%-------------------------------------------------------------------
+%%% File : wx_test_lib.erl
+%%% Author : Dan Gudmundsson <[email protected]>
+%%% Description : Library for testing wxerlang.
+%%%
+%%% Created : 30 Oct 2008 by Dan Gudmundsson <[email protected]>
+%%%-------------------------------------------------------------------
+-module(wx_test_lib).
+-compile(export_all).
+
+-include("wx_test_lib.hrl").
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+init_per_suite(Config) ->
+ try
+ case os:type() of
+ {unix,darwin} ->
+ exit("Can not test on MacOSX");
+ {unix, _} ->
+ io:format("DISPLAY ~s~n", [os:getenv("DISPLAY")]),
+ case proplists:get_value(xserver, Config, none) of
+ none -> ignore;
+ Server ->
+ os:putenv("DISPLAY", Server)
+ end;
+ _ -> ignore
+ end,
+ wx:new(),
+ wx:destroy(),
+ Config
+ catch
+ _:undef ->
+ {skipped, "No wx compiled for this platform"};
+ _:Reason ->
+ {skipped, lists:flatten(io_lib:format("Start wx failed: ~p", [Reason]))}
+ end.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_testcase(_Func, Config) ->
+ global:register_name(wx_global_logger, group_leader()),
+ Config.
+
+end_per_testcase(_Func, Config) ->
+ global:unregister_name(wx_global_logger),
+ Config.
+
+%% Backwards compatible with test_server
+tc_info(suite) -> [];
+tc_info(doc) -> "".
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+%% Use ?log(Format, Args) as wrapper
+log(Format, Args, LongFile, Line) ->
+ File = filename:basename(LongFile),
+ Format2 = lists:concat([File, "(", Line, ")", ": ", Format]),
+ log(Format2, Args).
+
+log(Format, Args) ->
+ case global:whereis_name(wx_global_logger) of
+ undefined ->
+ io:format(user, Format, Args);
+ Pid ->
+ io:format(Pid, Format, Args)
+ end.
+
+verbose(Format, Args, File, Line) ->
+ Arg = wx_test_verbose,
+ case get(Arg) of
+ false ->
+ ok;
+ true ->
+ log(Format, Args, File, Line);
+ undefined ->
+ case init:get_argument(Arg) of
+ {ok, List} when is_list(List) ->
+ case lists:last(List) of
+ ["true"] ->
+ put(Arg, true),
+ log(Format, Args, File, Line);
+ _ ->
+ put(Arg, false),
+ ok
+ end;
+ _ ->
+ put(Arg, false),
+ ok
+ end
+ end.
+
+error(Format, Args, File, Line) ->
+ global:send(wx_global_logger, {failed, File, Line}),
+ Fail = {filename:basename(File),Line,Args},
+ case global:whereis_name(wx_test_case_sup) of
+ undefined -> ignore;
+ Pid -> Pid ! Fail
+ %% global:send(wx_test_case_sup, Fail),
+ end,
+ log("<ERROR>~n" ++ Format, Args, File, Line).
+
+
+pick_msg() ->
+ receive
+ Message -> Message
+ after 4000 -> timeout
+ end.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% Utility functions
+
+user_available(Config) ->
+ false /= proplists:get_value(user, Config, false).
+
+
+wx_destroy(Frame, Config) ->
+ case proplists:get_value(user, Config, false) of
+ false ->
+ timer:sleep(100),
+ ?m(ok, wxFrame:destroy(Frame)),
+ ?m(ok, wx:destroy());
+ true ->
+ timer:sleep(500),
+ ?m(ok, wxFrame:destroy(Frame)),
+ ?m(ok, wx:destroy());
+ step -> %% Wait for user to close window
+ ?m(ok, wxEvtHandler:connect(Frame, close_window, [{skip,true}])),
+ wait_for_close()
+ end.
+
+wait_for_close() ->
+ receive
+ #wx{event=#wxClose{}} ->
+ ?log("Got close~n",[]),
+ ?m(ok, wx:destroy());
+ #wx{obj=Obj, event=Event} ->
+ try
+ Name = wxTopLevelWindow:getTitle(Obj),
+ ?log("~p Event: ~p~n", [Name, Event])
+ catch _:_ ->
+ ?log("Event: ~p~n", [Event])
+ end,
+ wait_for_close();
+ Other ->
+ ?log("Unexpected: ~p~n", [Other]),
+ wait_for_close()
+ end.
+
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% A small test server, which can be run standalone in a shell
+
+run_test(Test = {_,_},Config) ->
+ run_test([Test],Config);
+run_test([{Module, TC}|Rest], Config) ->
+ [run_test(Module, TC, Config) |
+ run_test(Rest, Config)];
+run_test([], _Config) -> [].
+
+run_test(Module, all, Config) ->
+ All = [{Module, Test} || Test <- Module:all()],
+ run_test(All, Config);
+run_test(Module, TestCase, Config) ->
+ log("Eval test case: ~w~n", [{Module, TestCase}]),
+ Sec = timer:seconds(1) * 1000,
+ {T, Res} =
+ timer:tc(?MODULE, eval_test_case, [Module, TestCase, Config]),
+ log("Tested ~w in ~w sec~n", [TestCase, T div Sec]),
+ {T div Sec, Res}.
+
+eval_test_case(Mod, Fun, Config) ->
+ flush(),
+ global:register_name(wx_test_case_sup, self()),
+ Flag = process_flag(trap_exit, true),
+ Pid = spawn_link(?MODULE, test_case_evaluator, [Mod, Fun, [Config]]),
+ R = wait_for_evaluator(Pid, Mod, Fun, Config),
+ global:unregister_name(wx_test_case_sup),
+ process_flag(trap_exit, Flag),
+ R.
+
+test_case_evaluator(Mod, Fun, [Config]) ->
+ NewConfig = Mod:init_per_testcase(Fun, Config),
+ R = apply(Mod, Fun, [NewConfig]),
+ Mod:fin_per_testcase(Fun, NewConfig),
+ exit({test_case_ok, R}).
+
+wait_for_evaluator(Pid, Mod, Fun, Config) ->
+ receive
+ {'EXIT', Pid, {test_case_ok, _PidRes}} ->
+ Errors = flush(),
+ Res =
+ case Errors of
+ [] -> ok;
+ Errors -> failed
+ end,
+ {Res, {Mod, Fun}, Errors};
+ {'EXIT', Pid, {skipped, Reason}} ->
+ log("<WARNING> Test case ~w skipped, because ~p~n",
+ [{Mod, Fun}, Reason]),
+ Mod:fin_per_testcase(Fun, Config),
+ {skip, {Mod, Fun}, Reason};
+ {'EXIT', Pid, Reason} ->
+ log("<ERROR> Eval process ~w exited, because ~p~n",
+ [{Mod, Fun}, Reason]),
+ Mod:fin_per_testcase(Fun, Config),
+ {crash, {Mod, Fun}, Reason}
+ end.
+
+flush() ->
+ receive Msg -> [Msg | flush()]
+ after 0 -> []
+ end.
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
diff --git a/lib/wx/test/wx_test_lib.hrl b/lib/wx/test/wx_test_lib.hrl
new file mode 100644
index 0000000000..34e1e9c6b8
--- /dev/null
+++ b/lib/wx/test/wx_test_lib.hrl
@@ -0,0 +1,110 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2008-2009. 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.
+%%
+%% %CopyrightEnd%
+%%%-------------------------------------------------------------------
+%%% File : wx_test_lib.hrl
+%%% Author : Dan Gudmundsson <[email protected]>
+%%% Description : Testing Macros
+%%%
+%%% Created : 30 Oct 2008 by Dan Gudmundsson <[email protected]>
+%%%-------------------------------------------------------------------
+
+-include_lib("wx/include/wx.hrl").
+
+-define(log(Format,Args),wx_test_lib:log(Format,Args,?FILE,?LINE)).
+-define(warning(Format,Args),?log("<WARNING>~n " ++ Format,Args)).
+-define(error(Format,Args), wx_test_lib:error(Format,Args,?FILE,?LINE)).
+-define(verbose(Format,Args),wx_test_lib:verbose(Format,Args,?FILE,?LINE)).
+
+-define(fatal(Format,Args),
+ ?error(Format, Args),
+ exit({test_case_fatal, Format, Args, ?FILE, ?LINE})).
+
+-define(skip(Format,Args),
+ ?warning(Format, Args),
+ exit({skipped, ?flat_format(Format, Args)})).
+
+-define(m(ExpectedRes, Expr),
+ fun() ->
+ {TeStFILe, TeSTLiNe} = {?FILE, ?LINE},
+ AcTuAlReS = (catch (Expr)),
+ case AcTuAlReS of
+ ExpectedRes ->
+ ?verbose("ok: ~p~n",[AcTuAlReS]),
+ AcTuAlReS;
+ _ ->
+ wx_test_lib:error("Not Matching Actual result was:~n ~p ~n Expected ~s~n",
+ [AcTuAlReS, ??ExpectedRes],
+ TeStFILe,TeSTLiNe),
+ AcTuAlReS
+ end
+ end()).
+
+-define(mt(Expected, Expr),
+ fun() ->
+ {TeStFILe, TeSTLiNe} = {?FILE, ?LINE},
+ AcTuAlReS = (catch (Expr)),
+ case catch element(3,AcTuAlReS) of
+ Expected ->
+ wx_test_lib:verbose("ok: ~s~n",[??Expected],TeStFILe,TeSTLiNe),
+ AcTuAlReS;
+ _ ->
+ wx_test_lib:error("Not Matching Actual result was:~n ~p ~n Expected ~s~n",
+ [AcTuAlReS, ??Expected],
+ TeStFILe,TeSTLiNe),
+ AcTuAlReS
+ end
+ end()).
+
+-define(mr(Expected, Expr),
+ fun() ->
+ {TeStFILe, TeSTLiNe} = {?FILE, ?LINE},
+ AcTuAlReS = (catch (Expr)),
+ case catch element(1,AcTuAlReS) of
+ Expected ->
+ wx_test_lib:verbose("ok: ~s~n",[??Expected],TeStFILe,TeSTLiNe),
+ AcTuAlReS;
+ _ ->
+ wx_test_lib:error("Not Matching Actual result was:~n ~p ~n Expected ~s~n",
+ [AcTuAlReS, ??Expected],
+ TeStFILe,TeSTLiNe),
+ AcTuAlReS
+ end
+ end()).
+
+-define(m_receive(ExpectedMsg),
+ ?m(ExpectedMsg,wx_test_lib:pick_msg())).
+
+-define(m_multi_receive(ExpectedMsgs),
+ fun() ->
+ {TeStFILe, TeSTLiNe} = {?FILE, ?LINE},
+ TmPeXpCtEdMsGs = lists:sort(ExpectedMsgs),
+ AcTuAlReS =
+ lists:sort(lists:map(fun(_) ->
+ wx_test_lib:pick_msg()
+ end, TmPeXpCtEdMsGs)),
+ case AcTuAlReS of
+ TmPeXpCtEdMsGs ->
+ ?verbose("ok: ~p~n",[AcTuAlReS]),
+ AcTuAlReS;
+ _ ->
+ wx_test_lib:error("Not Matching Actual result was:~n ~p ~n Expected ~p~n",
+ [AcTuAlReS, ExpectedMsgs],
+ TeStFILe,TeSTLiNe),
+ AcTuAlReS
+ end
+ end()).
diff --git a/lib/wx/test/wx_xtra_SUITE.erl b/lib/wx/test/wx_xtra_SUITE.erl
new file mode 100644
index 0000000000..2ce1d18039
--- /dev/null
+++ b/lib/wx/test/wx_xtra_SUITE.erl
@@ -0,0 +1,176 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2009. 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.
+%%
+%% %CopyrightEnd%
+%%%-------------------------------------------------------------------
+%%% File : wx_basic_SUITE.erl
+%%% Author : Dan Gudmundsson <[email protected]>
+%%% Description : Basic SUITE, some simple tests to show that the basics
+%%% are working.
+%%% Created : 3 Nov 2008 by Dan Gudmundsson <[email protected]>
+%%%-------------------------------------------------------------------
+-module(wx_xtra_SUITE).
+-export([all/0, init_per_suite/1, end_per_suite/1,
+ init_per_testcase/2, fin_per_testcase/2, end_per_testcase/2]).
+
+-compile(export_all).
+
+-include("wx_test_lib.hrl").
+
+%% Initialization functions.
+init_per_suite(Config) ->
+ wx_test_lib:init_per_suite(Config).
+
+end_per_suite(Config) ->
+ wx_test_lib:end_per_suite(Config).
+
+init_per_testcase(Func,Config) ->
+ wx_test_lib:init_per_testcase(Func,Config).
+end_per_testcase(Func,Config) ->
+ wx_test_lib:end_per_testcase(Func,Config).
+fin_per_testcase(Func,Config) -> %% For test_server
+ wx_test_lib:end_per_testcase(Func,Config).
+
+%% SUITE specification
+all() ->
+ all(suite).
+all(suite) ->
+ [
+ destroy_app,
+ multiple_add_in_sizer,
+ app_dies
+ ].
+
+%% The test cases
+
+%% Verify that everything is handled on the queue first
+%% before wx:destroy is called.
+destroy_app(TestInfo) when is_atom(TestInfo) -> wx_test_lib:tc_info(TestInfo);
+destroy_app(_Config) ->
+ %% This is timing releated but we test a couple of times
+ wx_test_lib:flush(),
+ ?m(ok, destroy_app_test(15)).
+
+destroy_app_test(N) when N > 0 ->
+ Wx = ?mr(wx_ref, wx:new()),
+ Frame = wxFrame:new(Wx, 1, "Destroy"),
+ ?m(ok, wxFrame:destroy(Frame)),
+ wx:destroy(),
+ receive
+ Msg -> Msg
+ after 150 -> destroy_app_test(N-1)
+ end;
+destroy_app_test(_) ->
+ receive
+ Msg -> Msg
+ after 1000 -> ok
+ end.
+
+
+%% This should work, and does but not when run automaticly on windows
+%% for some strange reason (it just hangs), run it last.
+app_dies(TestInfo) when is_atom(TestInfo) -> wx_test_lib:tc_info(TestInfo);
+app_dies(_Config) ->
+ Tester = fun(Die0) ->
+ Die = (Die0*2) + ?LINE,
+ Wx = wx:new(),
+ oops(Die,?LINE),
+ Frame = wxFrame:new(Wx, 1, ?MODULE_STRING ++ integer_to_list(?LINE)),
+ oops(Die,?LINE),
+ wxFrame:createStatusBar(Frame, []),
+ oops(Die,?LINE),
+ Win=wxWindow:new(Frame, ?wxID_ANY),
+ oops(Die,?LINE),
+ _Pen = wxPen:new({0,0,0}, [{width, 3}]),
+ oops(Die,?LINE),
+ _Font = wxFont:new(10, ?wxSWISS, ?wxNORMAL, ?wxNORMAL,[]),
+ oops(Die,?LINE),
+ wxWindow:connect(Win, key_up),
+ oops(Die,?LINE),
+ wxWindow:connect(Win, key_up, [{callback, fun(_,_) -> callback end}]),
+ oops(Die,?LINE),
+ wxFrame:show(Frame),
+ oops(Die,?LINE),
+ DC0 = wxClientDC:new(Win),
+ oops(Die,?LINE),
+ DC = wxBufferedDC:new(DC0),
+ oops(Die,?LINE),
+ _Size = wxWindow:getSize(Win),
+ oops(Die,?LINE), %% redraw(DC, Size, G),
+ wxBufferedDC:destroy(DC),
+ oops(Die,?LINE),
+ wxClientDC:destroy(DC0),
+ oops(last,?LINE)
+ end,
+ process_flag(trap_exit,true),
+ app_dies2(Tester, 1),
+ ok.
+
+app_dies2(Test, N) ->
+ spawn_link(fun() -> Test(N) end),
+ receive
+ {'EXIT', _, {oops, last}} -> ok;
+ {'EXIT', _, {oops, _}} -> app_dies2(Test, N+1)
+ end.
+
+oops(Die, Line) when (Die =:= last) orelse (Die =< Line) ->
+ timer:sleep(500),
+ ?log(" Exits at line ~p~n",[Line]),
+ exit({oops, Die});
+oops(_,_) -> ok.
+
+
+%% This have happend often enough that I have special code to handle
+%% this user error (i.e. using the a window twice in an sizer).
+multiple_add_in_sizer(TestInfo) when is_atom(TestInfo) -> wx_test_lib:tc_info(TestInfo);
+multiple_add_in_sizer(Config) ->
+ Wx = wx:new(),
+ Frame = wxFrame:new(Wx, -1, "Button Fix"),
+ wxFrame:connect(Frame, close_window),
+
+ FramePanel = wxPanel:new(Frame),
+ Sizer = wxBoxSizer:new(?wxVERTICAL),
+ wxPanel:setSizer(FramePanel, Sizer),
+ wxSizer:setSizeHints(Sizer, Frame),
+
+ Panel = wxPanel:new(FramePanel),
+ Button = wxButton:new(Panel, -1, [{label, "Centre Me!"}]),
+
+ PanelSizer = wxBoxSizer:new(?wxVERTICAL),
+
+%%%%%%%%%%% THIS CALL CRASHES BEAM AT DESTROY TIME %%%%%%%%%%%%%
+ wxPanel:setSizer(Panel, PanelSizer),
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+ ButtonSizer = wxBoxSizer:new(?wxVERTICAL),
+
+ SizerFlags = wxSizerFlags:new(),
+ wxSizerFlags:align(SizerFlags, ?wxALIGN_CENTRE),
+
+ wxSizer:add(ButtonSizer, Button, SizerFlags), %% no tricks
+
+ wxSizerFlags:expand(SizerFlags), %
+ wxSizer:add(PanelSizer, ButtonSizer, SizerFlags),
+
+ %% PanelSizer is added to a size twice
+ wxSizer:add(Sizer, PanelSizer, SizerFlags),
+
+ wxFrame:setSize(Frame, 400, 300),
+ io:format("Panel ~p PSizer ~p ~n",[Panel, PanelSizer]),
+ %% io:format("F
+ wxWindow:show(Frame),
+ wx_test_lib:wx_destroy(Frame, Config).
+
diff --git a/lib/wx/test/wxt b/lib/wx/test/wxt
new file mode 100755
index 0000000000..f94350e47b
--- /dev/null
+++ b/lib/wx/test/wxt
@@ -0,0 +1,41 @@
+#! /bin/sh -f
+#
+# %CopyrightBegin%
+#
+# Copyright Ericsson AB 2008-2009. 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.
+#
+# %CopyrightEnd%
+#
+# Usage: mt <args to erlang startup script>
+
+log=test_log_$$
+latest=test_log_latest
+args=${1+"$@"}
+erlcmd="erl -sname test_server -smp -pa ../ebin $p $args -wx_test_verbose true -wx_test_timeout"
+
+echo "Give the following command in order to see the outcome:"
+echo ""
+echo " less test_log$$"
+
+rm "$latest" 2>/dev/null
+ln -s "$log" "$latest"
+touch "$log"
+
+ostype=`uname -s`
+if [ "$ostype" = "SunOS" ] ; then
+ /usr/openwin/bin/xterm -T Testing -l -lf "$log" -e $erlcmd &
+else
+ xterm -T Testing -e script -f -c "$erlcmd" "$log" &
+fi
+tail -f "$log" | egrep 'Eval|<ERROR>|NYI' \ No newline at end of file
diff --git a/lib/wx/test/wxt.erl b/lib/wx/test/wxt.erl
new file mode 100644
index 0000000000..a346a6bdb8
--- /dev/null
+++ b/lib/wx/test/wxt.erl
@@ -0,0 +1,160 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2008-2009. 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.
+%%
+%% %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]>
+%%%-------------------------------------------------------------------
+-module(wxt).
+-compile(export_all).
+
+%% Modules or suites can be shortcuts i.e. basic expands to wx_basic_SUITE.
+%%
+%% t(Tests) run wx testcases.
+%% Tests can be module, {module, test_case} or [module|{module,test_case}]
+
+t() ->
+ t(read_test_case()).
+t(Test) ->
+ t(Test, []).
+
+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(Test,Config) when is_list(Config) ->
+ Tests = resolve(Test),
+ write_test_case(Test),
+ Res = wx_test_lib:run_test(Tests, Config),
+ append_test_case_info(Test, Res).
+
+
+user() ->
+ user(read_test_case()).
+user(Mod) ->
+ t(Mod, [{user,step}]).
+user(Mod,Tc) when is_atom(Tc) ->
+ t({Mod,Tc}, [{user,step}]).
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% Resolves the name of test suites and test cases
+%% according to the alias definitions. Single atoms
+%% are assumed to be the name of a test suite.
+resolve(Suite0) when atom(Suite0) ->
+ case alias(Suite0) of
+ Suite when atom(Suite) ->
+ {Suite, all};
+ {Suite, Case} ->
+ {Suite, Case}
+ end;
+resolve({Suite0, Case}) when atom(Suite0), atom(Case) ->
+ case alias(Suite0) of
+ Suite when atom(Suite) ->
+ {Suite, Case};
+ {Suite, Case2} ->
+ {Suite, Case2}
+ end;
+resolve(List) when list(List) ->
+ [resolve(Case) || Case <- List].
+
+alias(Suite) when is_atom(Suite) ->
+ Str = atom_to_list(Suite),
+ case {Str, lists:reverse(Str)} of
+ {"wx" ++ _, "ETIUS" ++ _} ->
+ Suite;
+ _ ->
+ list_to_atom("wx_" ++ Str ++ "_SUITE")
+ end.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+config_fname() ->
+ "wx_test_case_config".
+
+%% Read default config file
+read_config() ->
+ Fname = config_fname(),
+ wx_test_lib:log("Consulting file ~s...~n", [Fname]),
+ case file:consult(Fname) of
+ {ok, Config} ->
+ wx_test_lib:log("Read config ~w~n", [Config]),
+ Config;
+ _Error ->
+ Config = wx_test_lib:default_config(),
+ wx_test_lib:log("<>WARNING<> Using default config: ~w~n", [Config]),
+ Config
+ end.
+
+%% Write new default config file
+write_config(Config) when list(Config) ->
+ Fname = config_fname(),
+ {ok, Fd} = file:open(Fname, write),
+ write_list(Fd, Config),
+ file:close(Fd).
+
+write_list(Fd, [H | T]) ->
+ ok = io:format(Fd, "~p.~n",[H]),
+ write_list(Fd, T);
+write_list(_, []) ->
+ ok.
+
+test_case_fname() ->
+ "wx_test_case_info".
+
+%% Read name of test case
+read_test_case() ->
+ Fname = test_case_fname(),
+ case file:open(Fname, [read]) of
+ {ok, Fd} ->
+ Res = io:read(Fd, []),
+ file:close(Fd),
+ case Res of
+ {ok, TestCase} ->
+ wx_test_lib:log("Using test case ~w from file ~s~n",
+ [TestCase, Fname]),
+ TestCase;
+ {error, _} ->
+ default_test_case(Fname)
+ end;
+ {error, _} ->
+ default_test_case(Fname)
+ end.
+
+default_test_case(Fname) ->
+ TestCase = all,
+ wx_test_lib:log("<>WARNING<> Cannot read file ~s, "
+ "using default test case: ~w~n",
+ [Fname, TestCase]),
+ TestCase.
+
+write_test_case(TestCase) ->
+ Fname = test_case_fname(),
+ {ok, Fd} = file:open(Fname, write),
+ ok = io:format(Fd, "~p.~n",[TestCase]),
+ file:close(Fd).
+
+append_test_case_info(TestCase, TestCaseInfo) ->
+ Fname = test_case_fname(),
+ {ok, Fd} = file:open(Fname, [read, write]),
+ ok = io:format(Fd, "~p.~n",[TestCase]),
+ ok = io:format(Fd, "~p.~n",[TestCaseInfo]),
+ file:close(Fd),
+ TestCaseInfo.