Entries.t 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228
  1. #!/usr/bin/perl
  2. use strict;
  3. use warnings;
  4. ################################################################################
  5. # A Fcm::Keyword::Entry sub-class for testing
  6. {
  7. package TestEntry;
  8. use base qw{Fcm::Keyword::Entry};
  9. }
  10. ################################################################################
  11. # A mock loader implementing the Fcm::Keyword::Loader interface
  12. {
  13. package MockLoader0;
  14. use Scalar::Util qw{blessed};
  15. ############################################################################
  16. # Constructor
  17. sub new {
  18. my ($class) = @_;
  19. return bless({number_of_calls_to_load_to => 0}, $class);
  20. }
  21. ############################################################################
  22. ##Returns the package name
  23. sub get_source {
  24. my ($self) = @_;
  25. return blessed($self);
  26. }
  27. ############################################################################
  28. # Returns number of times $self->load_to() has been called
  29. sub get_number_of_calls_to_load_to {
  30. my ($self) = @_;
  31. return $self->{number_of_calls_to_load_to};
  32. }
  33. ############################################################################
  34. # Loads data into $entries, and returns number of entries loaded
  35. sub load_to {
  36. my ($self, $entries) = @_;
  37. $self->{number_of_calls_to_load_to}++;
  38. return $self->load_to_impl($entries);
  39. }
  40. ############################################################################
  41. # Returns 0
  42. sub load_to_impl {
  43. my ($self, $entries) = @_;
  44. return 0;
  45. }
  46. }
  47. ################################################################################
  48. # A mock loader implementing the Fcm::Keyword::Loader interface
  49. {
  50. package MockLoader1;
  51. our @ISA = qw{MockLoader0};
  52. my %VALUE_OF = (foo => 'foo1', bar => 'bar2', baz => 'baz3');
  53. ############################################################################
  54. # Returns a reference to the mock data
  55. sub get_data {
  56. my ($class) = @_;
  57. return \%VALUE_OF;
  58. }
  59. ############################################################################
  60. ##Writes mock data to the $entries object
  61. sub load_to_impl {
  62. my ($self, $entries) = @_;
  63. my $counter = 0;
  64. for my $key (keys(%{$self->get_data()})) {
  65. $entries->add_entry($key, $self->get_data()->{$key});
  66. $counter++;
  67. }
  68. return $counter;
  69. }
  70. }
  71. ################################################################################
  72. # A mock loader implementing the Fcm::Keyword::Loader interface
  73. {
  74. package MockLoader2;
  75. our @ISA = qw{MockLoader1};
  76. my %VALUE_OF = (sausages => 'pig', eggs => 'hen', chips => 'potato');
  77. ############################################################################
  78. # Returns a reference to the mock data
  79. sub get_data {
  80. my ($class) = @_;
  81. return \%VALUE_OF;
  82. }
  83. }
  84. package main;
  85. use Test::More qw{no_plan};
  86. main();
  87. sub main {
  88. my $class = 'Fcm::Keyword::Entries';
  89. use_ok($class);
  90. test_empty_constructor($class);
  91. test_constructor($class);
  92. test_add_entry($class);
  93. test_loaders($class);
  94. }
  95. ################################################################################
  96. # Tests empty constructor
  97. sub test_empty_constructor {
  98. my ($class) = @_;
  99. my $prefix = 'empty constructor';
  100. my $entries = $class->new();
  101. isa_ok($entries, $class);
  102. is($entries->get_entry_class(), 'Fcm::Keyword::Entry',
  103. "$prefix: default entry class");
  104. is_deeply([$entries->get_loaders()], [], "$prefix: empty list of loaders");
  105. is_deeply([$entries->get_all_entries()], [],
  106. "$prefix: empty list of entries");
  107. for my $arg ('foo', undef) {
  108. is($entries->get_entry_by_key($arg), undef,
  109. "$prefix: entry by key: undef");
  110. is($entries->get_entry_by_value($arg), undef,
  111. "$prefix: entry by value: undef");
  112. }
  113. }
  114. ################################################################################
  115. # Tests other constructor usages
  116. sub test_constructor {
  117. my ($class) = @_;
  118. my $prefix = 'constructor';
  119. my @loaders = (MockLoader1->new(), MockLoader2->new());
  120. my $entries = $class->new({
  121. entry_class => 'not-a-class',
  122. loaders => \@loaders,
  123. });
  124. isa_ok($entries, $class);
  125. is($entries->get_entry_class(), 'not-a-class', "$prefix: entry class");
  126. is_deeply([$entries->get_loaders()], \@loaders, "$prefix: list of loaders");
  127. eval {
  128. $entries->add_entry('key', 'value');
  129. };
  130. isnt($@, undef, "$prefix: invalid entry class");
  131. }
  132. ################################################################################
  133. # Tests adding entries
  134. sub test_add_entry {
  135. my ($class) = @_;
  136. my $prefix = 'add entry';
  137. my %VALUE_OF = (key1 => 'value1', egg => 'white and yolk', 'xyz.abc' => '');
  138. for my $entry_class ('Fcm::Keyword::Entry', 'TestEntry') {
  139. my $entries = $class->new({entry_class => $entry_class});
  140. my $number_of_entries = 0;
  141. for my $key (keys(%VALUE_OF)) {
  142. my $entry = $entries->add_entry($key, $VALUE_OF{$key});
  143. isa_ok($entry, $entry_class);
  144. is(scalar(@{$entries->get_all_entries()}), ++$number_of_entries,
  145. "$prefix: number of entries: $number_of_entries");
  146. }
  147. for my $key (keys(%VALUE_OF)) {
  148. my $entry = $entries->get_entry_by_key($key);
  149. isa_ok($entry, $entry_class);
  150. is($entry->get_key(), uc($key), "$prefix: get by key: $key");
  151. is($entry->get_value(), $VALUE_OF{$key},
  152. "$prefix: get by key: $key: value");
  153. }
  154. for my $key (keys(%VALUE_OF)) {
  155. my $entry = $entries->get_entry_by_value($VALUE_OF{$key});
  156. isa_ok($entry, $entry_class);
  157. is($entry->get_key(), uc($key), "$prefix: get by value: $key");
  158. is($entry->get_value(), $VALUE_OF{$key},
  159. "$prefix: get by value: $key: value");
  160. }
  161. is($entries->get_entry_by_key('no-such-key'), undef,
  162. "$prefix: get by key: no-such-key");
  163. is($entries->get_entry_by_value('no-such-value'), undef,
  164. "$prefix: get by value: no-such-value");
  165. }
  166. }
  167. ################################################################################
  168. # Tests usage of loaders
  169. sub test_loaders {
  170. my ($class) = @_;
  171. my $prefix = "loader";
  172. my @loaders = (MockLoader0->new(), MockLoader1->new(), MockLoader2->new());
  173. my $entries = $class->new({loaders => \@loaders});
  174. for my $loader (@loaders) {
  175. is($loader->get_number_of_calls_to_load_to(), 0, "$prefix: not loaded");
  176. }
  177. for my $key (keys(%{$loaders[1]->get_data()})) {
  178. my $value = $loaders[1]->get_data()->{$key};
  179. my $entry = $entries->get_entry_by_key($key);
  180. is($entry->get_key(), uc($key), "$prefix: by key: $key: key");
  181. is($entries->get_entry_by_value($value), $entry,
  182. "$prefix: by value: $key: object");
  183. }
  184. is($loaders[0]->get_number_of_calls_to_load_to(), 1,
  185. "$prefix: loaded once: 0");
  186. is($loaders[1]->get_number_of_calls_to_load_to(), 1,
  187. "$prefix: loaded once: 1");
  188. is($loaders[2]->get_number_of_calls_to_load_to(), 0,
  189. "$prefix: not loaded: 2");
  190. for my $key (keys(%{$loaders[2]->get_data()})) {
  191. my $value = $loaders[2]->get_data()->{$key};
  192. my $entry = $entries->get_entry_by_key($key);
  193. is($entry->get_key(), uc($key), "$prefix: by key: $key: key");
  194. is($entries->get_entry_by_value($value), $entry,
  195. "$prefix: by value: $key: object");
  196. }
  197. is($loaders[0]->get_number_of_calls_to_load_to(), 2,
  198. "$prefix: loaded once: 0");
  199. is($loaders[1]->get_number_of_calls_to_load_to(), 1,
  200. "$prefix: loaded once: 1");
  201. is($loaders[2]->get_number_of_calls_to_load_to(), 1,
  202. "$prefix: not loaded: 2");
  203. }
  204. __END__