File Coverage

blib/lib/Crypt/HSXKPasswd/Dictionary.pm
Criterion Covered Total %
statement 64 77 83.1
branch 3 6 50.0
condition 2 5 40.0
subroutine 18 22 81.8
pod 0 6 0.0
total 87 116 75.0


line stmt bran cond sub pod time code
1             package Crypt::HSXKPasswd::Dictionary;
2              
3             # import required modules
4 3     3   1279 use strict;
  3         3  
  3         89  
5 3     3   14 use warnings;
  3         4  
  3         82  
6 3     3   14 use Carp; # for nicer 'exception' handling for users of the module
  3         3  
  3         188  
7 3     3   14 use Fatal qw( :void open close binmode ); # make builtins throw exceptions on failure
  3         3  
  3         22  
8 3     3   4220 use English qw( -no_match_vars ); # for more readable code
  3         5  
  3         21  
9 3     3   1201 use Scalar::Util qw( blessed ); # for checking if a reference is blessed
  3         5  
  3         182  
10 3     3   15 use List::MoreUtils qw( uniq ); # for array deduplication
  3         5  
  3         35  
11 3     3   1719 use Readonly; # for truly constant constants
  3         5  
  3         161  
12 3     3   17 use Types::Standard qw( :types slurpy ); # for data validation
  3         5  
  3         34  
13 3     3   10562 use Type::Params qw( compile ); # for argument valdiation
  3         7  
  3         29  
14 3     3   663 use Crypt::HSXKPasswd::Types qw( :types ); # for data validation
  3         8  
  3         68  
15 3     3   6591 use Crypt::HSXKPasswd::Helper; # exports utility functions like _error & _warn
  3         6  
  3         287  
16              
17             # set things up for using UTF-8
18 3     3   84 use 5.016; # min Perl for good UTF-8 support, implies feature 'unicode_strings'
  3         14  
19 3     3   13 use Encode qw( encode decode );
  3         4  
  3         146  
20 3     3   15 use utf8;
  3         5  
  3         21  
21             binmode STDOUT, ':encoding(UTF-8)';
22              
23             # Copyright (c) 2015, Bart Busschots T/A Bartificer Web Solutions All rights
24             # reserved.
25             #
26             # Code released under the FreeBSD license (included in the POD at the bottom of
27             # HSXKPasswd.pm)
28              
29             #
30             # === Constants & Package Vars ================================================#
31             #
32              
33             # version info
34 3     3   130 use version; our $VERSION = qv('1.2');
  3         4  
  3         15  
35              
36             # utility variables
37             Readonly my $_CLASS => __PACKAGE__;
38              
39             #
40             # --- Constructor -------------------------------------------------------------
41             #
42              
43             #####-SUB-#####################################################################
44             # Type : CONSTRUCTOR (CLASS)
45             # Purpose : A place-holder for the constructor - just throws an error
46             # Returns : VOID
47             # Arguments : NONE
48             # Throws : ALWAYS throws an error to say this class must be extended.
49             # Notes :
50             # See Also :
51             ## no critic (Subroutines::RequireFinalReturn);
52             sub new{
53 0     0 0 0 _error("$_CLASS must be extended to be used");
54             }
55             ## use critic
56              
57             #
58             # --- Public Instance functions -----------------------------------------------
59             #
60              
61             #####-SUB-######################################################################
62             # Type : INSTANCE
63             # Purpose : A place-holder for the function to clone self.
64             # Returns : NOTHING - but in subclasses should return a clone of self
65             # Arguments : NONE
66             # Throws : ALWAYS throws an error to say this class must be extended, and
67             # this function must be overridden.
68             # Notes :
69             # See Also :
70             ## no critic (Subroutines::RequireFinalReturn);
71             sub clone{
72 0     0 0 0 _error("$_CLASS must be extended to be used, and the function clone() must be overridden");
73             }
74             ## use critic
75              
76             #####-SUB-#####################################################################
77             # Type : INSTANCE
78             # Purpose : A place-holder for the function to get the list of words.
79             # Returns : NOTHING - but in subclasses should return an array ref.
80             # Arguments : NONE
81             # Throws : ALWAYS throws an error to say this class must be extended, and
82             # this function must be overridden.
83             # Notes :
84             # See Also :
85             ## no critic (Subroutines::RequireFinalReturn);
86             sub word_list{
87 0     0 0 0 _error("$_CLASS must be extended to be used, and the function word_list() must be overridden");
88             }
89             ## use critic
90              
91             #####-SUB-#####################################################################
92             # Type : INSTANCE
93             # Purpose : A function to return the source of the words as a string
94             # Returns : A scalar string
95             # Arguments : NONE
96             # Throws : Croaks on invalid invocation
97             # Notes :
98             # See Also :
99             sub source{
100 10     10 0 13 my $self = shift;
101 10         24 _force_instance($self);
102            
103             # return the instances class
104 10         47 return blessed($self);
105             }
106              
107             #####-SUB-#####################################################################
108             # Type : INSTANCE
109             # Purpose : A function to print out the words in the dictionary
110             # Returns : Always returns 1 (to keep PerlCritic happy)
111             # Arguments : NONE
112             # Throws : Croaks on invalid invocation, and throws any errors word_list()
113             # Notes :
114             # See Also :
115             sub print_words{
116 0     0 0 0 my $self = shift;
117 0         0 _force_instance($self);
118            
119 0         0 print join "\n", @{$self->word_list()};
  0         0  
120 0         0 print "\n";
121            
122             # final truthy return to keep perlcritic happy
123 0         0 return 1;
124             }
125              
126             #
127             # === Public Class Functions ==================================================#
128             #
129              
130             #####-SUB-######################################################################
131             # Type : CLASS
132             # Purpose : Distil an array of strings down to a de-duplicated array of only
133             # the valid words.
134             # Returns : An array of words
135             # Arguments : 1) A reference to an array of strings
136             # 2) OPTIONAL - a named argument warn with a value of 0 or 1. If 1
137             # is passed, warnings will be issued each time an invalid string
138             # is skipped over.
139             # Throws : Croaks on invalid invocation or args, and warns on request when
140             # skipping words.
141             # Notes :
142             # See Also :
143             sub distil_to_words{
144 10     10 0 75 my @args = @_;
145 10         45 my $class = shift @args;
146 10         31 _force_class($class);
147            
148             # validate args
149 10         22 state $args_check = compile(ArrayRef[Str], slurpy Dict[warn => Optional[TrueFalse]]);
150 10         6431 my ($array_ref, $options) = $args_check->(@args);
151 10   50     875 my $warn = $options->{warn} || 0;
152            
153             # loop through the array and copy all valid words to a new array
154 10         22 my @valid_words = ();
155 10         14 foreach my $potential_word (@{$array_ref}){
  10         26  
156 11666 100       15001 if(Word->check($potential_word)){
157 11334         49004 push @valid_words, $potential_word;
158             }else{
159 332 50 33     1529 if($warn || _do_debug()){
160 0         0 my $msg = 'skipping invalid word: '.Word->get_message($potential_word);
161 0 0       0 if($warn){
162 0         0 _warn($msg);
163             }else{
164 0         0 _debug($msg);
165             }
166             }
167             }
168             }
169            
170             # de-dupe the valid words
171 10         11177 my @final_words = uniq(@valid_words);
172            
173             # return the valid words
174 10         5147 return @final_words;
175             }
176              
177             1; # because Perl is just a little bit odd :)