Trog-Themes-themed-templates.t 3.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091
  1. use strict;
  2. use warnings;
  3. use Test::More;
  4. use Test::MockModule qw{strict};
  5. use Path::Tiny();
  6. use FindBin;
  7. use lib "$FindBin::Bin/../lib";
  8. require_ok('Trog::Themes') or BAIL_OUT("Can't find SUT");
  9. # A stock template tree and a theme which only partially overrides it.
  10. my $root = Path::Tiny->tempdir();
  11. my $stock = $root->child('www/templates/html/components/forms');
  12. my $theme = $root->child('www/themes/spec/templates/html/components/forms');
  13. $_->mkpath foreach ( $stock, $theme );
  14. $stock->child($_)->spew_utf8("stock $_") foreach qw{blog.tx series.tx profile.tx blog.json series.json};
  15. $theme->child($_)->spew_utf8("themed $_") foreach qw{blog.tx gallery.tx blog.json};
  16. my $themedir = '';
  17. my $mock = Test::MockModule->new('Trog::Themes');
  18. $mock->redefine( 'get_dir', sub { $themedir } );
  19. # $template_dir is what the stock tree hangs off; point it at the fixture.
  20. {
  21. no warnings qw{once};
  22. $Trog::Themes::template_dir = "$root/www/templates";
  23. }
  24. subtest 'with no theme, nothing changes' => sub {
  25. $themedir = '';
  26. is_deeply(
  27. [ Trog::Themes::template_dirs( 'text/html', 1 ) ],
  28. ["$root/www/templates/html/components"],
  29. "only the stock dir is searched"
  30. );
  31. my $old = [ sort @{ Trog::Themes::templates_in_dir( 'forms', 'text/html', 1 ) } ];
  32. my $new = [ sort @{ Trog::Themes::themed_templates_in_dir( 'forms', 'text/html', 1 ) } ];
  33. is_deeply( $new, $old, "the themed helper agrees with the old one" );
  34. is_deeply( $new, [qw{blog.tx profile.tx series.tx}], "...and lists the stock templates" );
  35. };
  36. subtest 'with a partial theme, the two disagree' => sub {
  37. $themedir = "$root/www/themes/spec";
  38. is_deeply(
  39. [ Trog::Themes::template_dirs( 'text/html', 1 ) ],
  40. [ "$root/www/themes/spec/templates/html/components", "$root/www/templates/html/components" ],
  41. "the theme is searched first, then the stock tree"
  42. );
  43. # This is the shortcoming: one forms/ dir in a theme hides every stock
  44. # post type the theme didn't happen to copy.
  45. is_deeply(
  46. [ sort @{ Trog::Themes::templates_in_dir( 'forms', 'text/html', 1 ) } ],
  47. [qw{blog.tx gallery.tx}],
  48. "templates_in_dir() sees only the theme's"
  49. );
  50. is_deeply(
  51. [ sort @{ Trog::Themes::themed_templates_in_dir( 'forms', 'text/html', 1 ) } ],
  52. [qw{blog.tx gallery.tx profile.tx series.tx}],
  53. "themed_templates_in_dir() adds back the ones the theme didn't override"
  54. );
  55. my $listed = Trog::Themes::themed_templates_in_dir( 'forms', 'text/html', 1 );
  56. is( scalar( grep { $_ eq 'blog.tx' } @$listed ), 1, "an overridden template is listed once, not twice" );
  57. is( $listed->[0], 'blog.tx', "and the theme's copies come first" );
  58. };
  59. subtest 'themed_file_in_dir prefers the theme, falls back to stock' => sub {
  60. $themedir = "$root/www/themes/spec";
  61. is( Trog::Themes::themed_file_in_dir( 'forms', 'blog.json', 'text/html', 1 ),
  62. "$theme/blog.json", "the theme's copy wins" );
  63. is( Trog::Themes::themed_file_in_dir( 'forms', 'series.json', 'text/html', 1 ),
  64. "$stock/series.json", "one the theme lacks falls back" );
  65. is( Trog::Themes::themed_file_in_dir( 'forms', 'nope.json', 'text/html', 1 ),
  66. undef, "and one nobody has is undef, not a path that doesn't exist" );
  67. };
  68. subtest 'an empty or missing dir is not fatal' => sub {
  69. $themedir = "$root/www/themes/spec";
  70. is_deeply( Trog::Themes::themed_templates_in_dir( 'nosuchdir', 'text/html', 1 ), [], "just an empty list" );
  71. };
  72. done_testing();