Playwright.t 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182
  1. use Test2::V0;
  2. use Test2::Tools::Explain;
  3. use JSON::MaybeXS;
  4. use Test::MockModule qw{strict};
  5. use Test::MockFile;
  6. use Test::Fatal qw{exception};
  7. use Async;
  8. my ($qxret,$qxcode) = ('',255);
  9. use Test::Mock::Cmd qx => sub { $? = $qxcode; return $qxret }, system => sub { print $qxret };
  10. #De-Fang our BEGIN block so we can test safely
  11. no warnings qw{redefine once};
  12. $Playwright::SKIP_BEGIN = 1;
  13. use warnings;
  14. require Playwright;
  15. my $path2here = File::Basename::dirname(Cwd::abs_path($INC{'Playwright.pm'}));
  16. subtest "_check_and_build_spec" => sub {
  17. local $Playwright::spec = {};
  18. is(Playwright::_check_and_build_spec({}),{},"Already defined spec short-circuits");
  19. my $utilmock = Test::MockModule->new('Playwright::Util');
  20. $utilmock->redefine('request', sub { 'eee' });
  21. undef $Playwright::spec;
  22. like(exception { Playwright::_check_and_build_spec({ ua => 'eeep', port => 666} ) },qr/Could not retrieve/,"Fetch explodes when playwright_server doesn't have spec");
  23. };
  24. subtest "_build_classes" => sub {
  25. local $Playwright::spec = {
  26. Fake => {
  27. members => {
  28. tickle => {
  29. args => {
  30. chase => { type => { name => 'boolean' }, order => 1 },
  31. tickleOptions => {
  32. order => 0,
  33. type => {
  34. name => 'Object',
  35. properties => {
  36. intense => { name => 'intense', type => { name => 'boolean' } },
  37. tickler => { name => 'tickler', type => { name => 'string' } },
  38. optional => { name => 'optional', type => { name => 'boolean' } }, # Optional, shouldn't show up in output
  39. },
  40. },
  41. },
  42. who => { type => { name => 'string' }, order => 2 },
  43. hug => { type => { name => 'boolean' }, order => 3 }, # Optional bool arg, make sure we dont choke
  44. },
  45. },
  46. }
  47. },
  48. };
  49. #Very light testing here, example.pl is really what tests this
  50. Playwright::_build_classes();
  51. ok(defined &Playwright::Fake::new, "Constructors set up correctly");
  52. ok(defined &Playwright::Fake::tickle, "Class methods set up correctly");
  53. };
  54. subtest "_check_node" => sub {
  55. my $which = Test::MockModule->new('File::Which');
  56. my %to_return = (
  57. node => '/bogus',
  58. npm => '/hokum',
  59. playwright_server => "$path2here/../bin/playwright_server",
  60. );
  61. $which->redefine('which', sub { my $to = shift; $to_return{$to} } );
  62. my $node = Test::MockFile->file('/bogus', undef, { mode => 0777 } );
  63. my $npm = Test::MockFile->file('/hokum', undef, { mode => 0777 } );
  64. like( dies { Playwright::_check_node() }, qr/node must exist/i, "node not existing throws");
  65. undef $node;
  66. $node = Test::MockFile->file('/bogus', '', { mode => 0777 } );
  67. my $bin = Test::MockFile->file("$path2here/../bin/playwright_server");
  68. like( dies { Playwright::_check_node() }, qr/server in/i, "Server not existing throws");
  69. undef $bin;
  70. $bin = Test::MockFile->file("$path2here/../bin/playwright_server",'');
  71. like( dies { Playwright::_check_node() }, qr/npm must exist/i, "npm not existing throws");
  72. undef $npm;
  73. $npm = Test::MockFile->file('/hokum', '', { mode => 0777 } );
  74. my $fakecapture = Test::MockModule->new('Capture::Tiny');
  75. $fakecapture->redefine('capture_stderr', sub { 'oh no' });
  76. my $pmock = Test::MockModule->new('File::pushd');
  77. $pmock->redefine('pushd', sub {shift});
  78. #XXX doesn't look like we can mock $? correctly
  79. #like( dies { Playwright::_check_node($path2here, $decoder) }, qr/installing node/i, "npm failure throws");
  80. $fakecapture->redefine('capture_stderr', sub { 'package-lock' });
  81. $qxcode = 0;
  82. ok( lives { Playwright::_check_node() }, "Can run all the way thru") or note $@;
  83. };
  84. subtest "new" => sub {
  85. my $portmock = Test::MockModule->new('Net::EmptyPort');
  86. $portmock->redefine('empty_port', sub { 420 });
  87. my $lwpmock = Test::MockModule->new('LWP::UserAgent');
  88. $lwpmock->redefine('new', sub { bless({},'LWP::UserAgent') });
  89. $lwpmock->redefine('request', sub {});
  90. my $selfmock = Test::MockModule->new('Playwright');
  91. $selfmock->redefine('_start_server', sub { 666 });
  92. $selfmock->redefine('_check_and_build_spec', sub {});
  93. $selfmock->redefine('_build_classes',sub {});
  94. $selfmock->redefine('DESTROY', sub {});
  95. my $expected = bless({
  96. ua => 'whee',
  97. debug => 1,
  98. parent => $$,
  99. pid => 666,
  100. port => 420,
  101. timeout => 5,
  102. }, 'Playwright');
  103. is(Playwright->new( timeout => 5, ua => 'whee', debug => 1), $expected, "Constructor functions as expected");
  104. $expected = bless({
  105. ua => bless({},'LWP::UserAgent'),
  106. debug => undef,
  107. parent => $$,
  108. pid => 666,
  109. port => 420,
  110. timeout => 30,
  111. }, 'Playwright');
  112. is(Playwright->new(), $expected, "Constructor defaults expected");
  113. };
  114. subtest "launch" => sub {
  115. my $basemock = Test::MockModule->new('Playwright::Base');
  116. $basemock->redefine('_coerce', sub {});
  117. my $utilmock = Test::MockModule->new('Playwright::Util');
  118. $utilmock->redefine('request', sub { 'eee' });
  119. my $selfmock = Test::MockModule->new('Playwright');
  120. $selfmock->redefine('DESTROY', sub {});
  121. my $obj = bless({}, 'Playwright');
  122. is($obj->launch( type => 'eee' ), 'eee' ,"launch passthru works");
  123. #XXX Don't feel like mocking the objectification right now
  124. };
  125. subtest "await" => sub {
  126. my $selfmock = Test::MockModule->new('Playwright');
  127. $selfmock->redefine('DESTROY', sub {});
  128. my $res = {};
  129. no warnings qw{redefine once};
  130. local *AsyncData::result = sub { $res };
  131. use warnings;
  132. my $promise = bless({},'AsyncData');
  133. my $obj = bless({ ua => 'eee', 'port' => 1 }, 'Playwright');
  134. no warnings qw{redefine once};
  135. local *Playwright::Bogus::new = sub { my ($class, %input) = @_; return bless({ spec => 'whee', ua => $input{handle}{ua}, port => $input{handle}{port}, type => $input{type}, guid => $input{id} }, 'Playwright::Bogus') };
  136. use warnings;
  137. is($obj->await($promise),{},"await passthru works");
  138. $res = { _guid => 'abc123', _type => 'Bogus' };
  139. my $expected = bless({ spec => 'whee', ua => 'eee', port => 1, guid => 'abc123', type => 'Bogus' }, 'Bogus');
  140. is($obj->await($promise),$expected,"await objectification works");
  141. };
  142. #XXX Omitting destructor and server startup testing for now
  143. done_testing();