Re[5] [user32: 2/2] Testcase for font size = 0x7fff

Michael Karcher wine at mkarcher.dialup.fu-berlin.de
Sun Oct 12 07:13:36 CDT 2008


Am Sonntag, den 12.10.2008, 01:33 -0400 schrieb Koro:
> > ok() is for calls never expected to fail, broken() is for broken API
> > implementations and should never be used for Wine.
> Noted.
More specifically: You *never* use broken on its own.

This is an explanation of the test primitives. Feel free to put it on
the Wine wiki, if you like it.

All tests are spelled out in form of ok(), and you write your ok
statement in a way that it expresses what behaviour is OK according to
the Win32 API. There might be more than one possibility, like

  status = WinFrobnicate(foo);
  ok(status == E_FAIL /* Win98*/ ||
     status == E_INVALIDARG /* WinNT,2k,XP*/, "status %08x\n",status);

if we think that E_FAIL and E_INVALIDARG are both valid responses. Now,
it could be that Wine does not yet handle the WinFrobnicate call yet and
returns E_NOT_IMPLEMENTED. As we do not want the test suite on Wine, you
might be tempted to write this:

  status = WinFrobnicate(foo);
  ok(status == E_FAIL /* Win98*/ ||
     status == E_INVALIDARG /* WinNT,2k,XP*/ ||
     status == E_NOT_IMPLEMENTED /* Wine */, "status %08x\n",status);

DO NOT DO THAT! This means, that the return code E_NOT_IMPLEMENTED is
OK. It definitely is not, but the work on Wine that fixes this problem
has still *to be done*, so you should use a todo block:

  status = WinFrobnicate(foo);
  todo_wine ok(status == E_FAIL /* Win98*/ ||
     status == E_INVALIDARG /* WinNT,2k,XP*/, "status %08x\n",status);

A todo block is used like an if statement or a for loop. The todo
applies to the next statement or to all statements inside a block
following the todo, like here:

  answer = 0;
  status = WinFrobnicateWithOutput(foo, &answer);
  todo_wine {
     ok(status == E_FAIL /* Win98*/ ||
       status == E_INVALIDARG /* WinNT,2k,XP*/, "status %08x\n",status);
     ok(answer == 42, "Expected the universal answer, got %d\n",answer);
  }

If todo is applied to an OK statement, it must(!) fail for the test to
be successfull. As the Wine test suite is meant to not only show what
how wine should behave but also document where wine does misbehave, the
todo has to be removed as soon as Wine is going to behave correctly. The
only common form of the todo block is the todo_wine block that enters
the todo mode (inverting tests) if the test is run on Wine and does
nothing if the test is run on windows.

Next, lets assume that WinFrobnicate is not implemented on Win95/Win98,
but implemented on WinNT and up. So in this case, one would write

  status = WinFrobnicate(foo);
  ok(status == E_NOT_IMPLEMENTED /* Win98*/ ||
     status == E_INVALIDARG /* WinNT,2k,XP*/, "status %08x\n",status);

But in this case, we allow both W_NOT_IMPLEMENTED and E_INVALIDARG as
valid return values, and even Wine passes the test if it just returns
E_INVALIDARG. If Wine should implement this interface, Wine should not
get away with E_NOT_IMPLEMENTED. This is where broken() is used.
broken() returns the value of its argument if the test runs on Windows,
but always false (even if the argument is true) if the test runs on
Wine, so the example should be written like this:

  status = WinFrobnicate(foo);
  ok(broken(status == E_NOT_IMPLEMENTED) /* Win98*/ ||
     status == E_INVALIDARG /* WinNT,2k,XP*/, "status %08x\n",status);

The last testing primitive to introduce is skip. skip is meant to be
used if a part of tests could not be executed because the tested system
lacks prerequisites, for example a font with a special codepage, a CD
drive, a sufficiently recent version of a DLL or because the operations
the test wants to perform needs administrative priviledges that the test
does not have. It has just statistical value, in incrementing the number
of skips. It is used like this:

  pMagic = CreateMagicInterface("xyzzy");
  if(pMagic)
  {
     ISpell *spell = IMagic_CreateSpell(pMagic,NULL);
     /* lots of tests */
     IMagic_Release(pMagic);
  }
  else
    skip("CreateMagicInterface returned NULL\n");

Again, this is like the multiple alternatives in the ok() function: Wine
gets away without an error being flagged (just a skip, which might be OK
in certain tests) if it does not create the magic interface. So like the
broken() function inside the ok() function, the Wine testing framework
provides a primitive called win_skip() that logs a skip on Windows but
an error on Wine.

> > What's the source of info you have used for that?
> It was on a comment to that post: 
> http://blogs.msdn.com/oldnewthing/archive/2005/04/29/412577.aspx
> 
> It seems to have been deleted since then though. The comment said about 
> the 0x7fff part, but not about the missing members. I found about the 
> missing members through experimentation after that.
Use this URL instead:
http://web.archive.org/web/20061224095348/http://blogs.msdn.com/oldnewthing/archive/2005/04/29/412577.aspx

Regards,
  Michael Karcher




More information about the wine-devel mailing list