Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Slurping up everything from my local repo

  • Loading branch information...
commit d4785ee300d7fbc395f9f303da69e6fa474baa2b 0 parents
@petdance authored
17 Changes
@@ -0,0 +1,17 @@
+Revision history for App-HWD
+
+0.04 Tue Aug 2 15:47:23 CDT 2005
+ [ENHANCEMENTS]
+ * Added --started feature. Thanks to Neil Watkiss and Luke
+ Closs from Sophos.
+
+0.02 Mon Aug 1 14:32:29 PDT 2005
+ [FIXES]
+ * Fixes silly syntax bummers.
+
+ [ENHANCEMENTS]
+ * Added --nextid
+
+0.01
+ First version, released on an unsuspecting world.
+
77 HWD.pm
@@ -0,0 +1,77 @@
+package App::HWD;
+
+use warnings;
+use strict;
+
+=head1 NAME
+
+App::HWD - The great new App::HWD!
+
+=head1 VERSION
+
+Version 0.04
+
+=cut
+
+our $VERSION = '0.04';
+
+=head1 SYNOPSIS
+
+Quick summary of what the module does.
+
+Perhaps a little code snippet.
+
+ use App::HWD;
+
+ my $foo = App::HWD->new();
+ ...
+
+=head1 EXPORT
+
+A list of functions that can be exported. You can delete this section
+if you don't export anything, such as for a purely object-oriented module.
+
+=head1 FUNCTIONS
+
+=head2 function1
+
+=cut
+
+sub function1 {
+}
+
+=head2 function2
+
+=cut
+
+sub function2 {
+}
+
+=head1 AUTHOR
+
+Andy Lester, C<< <andy@petdance.com> >>
+
+=head1 BUGS
+
+Please report any bugs or feature requests to
+C<bug-app-hwd@rt.cpan.org>, or through the web interface at
+L<http://rt.cpan.org/NoAuth/ReportBug.html?Queue=App-HWD>.
+I will be notified, and then you'll automatically be notified of progress on
+your bug as I make changes.
+
+=head1 ACKNOWLEDGEMENTS
+
+Thanks to
+Neil Watkiss
+and Luke Closs for features and patches.
+
+=head1 COPYRIGHT & LICENSE
+
+Copyright 2005 Andy Lester, all rights reserved.
+
+This program is free software; you can redistribute it and/or modify it
+under the same terms as Perl itself.
+
+=cut
+
+1; # End of App::HWD
14 MANIFEST
@@ -0,0 +1,14 @@
+Changes
+MANIFEST
+Makefile.PL
+README
+HWD.pm
+Task.pm
+Work.pm
+bin/hwd
+eg/sked.txt
+t/00-load.t
+t/pod-coverage.t
+t/pod.t
+t/task.t
+t/work.t
37 Makefile.PL
@@ -0,0 +1,37 @@
+use strict;
+use warnings;
+use ExtUtils::MakeMaker;
+
+WriteMakefile(
+ NAME => 'App::HWD',
+ AUTHOR => 'Andy Lester <andy@petdance.com>',
+ VERSION_FROM => 'HWD.pm',
+ ABSTRACT_FROM => 'HWD.pm',
+ PL_FILES => {},
+ EXE_FILES => [ 'bin/hwd' ],
+ PM => {
+ 'HWD.pm' => '$(INST_LIBDIR)/HWD.pm',
+ 'Task.pm' => '$(INST_LIBDIR)/HWD/Task.pm',
+ 'Work.pm' => '$(INST_LIBDIR)/HWD/Work.pm',
+ },
+ PREREQ_PM => {
+ 'Test::More' => 0,
+ 'Getopt::Long' => 0,
+ 'Pod::Usage' => 0,
+ },
+ MAN3PODS => { }, # no need for docs on these
+ dist => { COMPRESS => 'gzip -9f', SUFFIX => 'gz', },
+ clean => { FILES => 'App-HWD-*' },
+);
+
+sub MY::postamble {
+ return <<'MAKE_FRAG';
+.PHONY: tags
+
+tags:
+ ctags -f tags --recurse --totals \
+ --exclude=blib/ --exclude=t/lib \
+ --exclude=.svn --exclude='*~' \
+ --languages=Perl --langmap=Perl:+.t \
+MAKE_FRAG
+}
29 README
@@ -0,0 +1,29 @@
+App-HWD
+
+The README is used to introduce the module and provide instructions on
+how to install the module, any machine dependencies it may have (for
+example C compilers and installed libraries) and any other information
+that should be provided before the module is installed.
+
+A README file is required for CPAN modules since CPAN extracts the README
+file from a module distribution so that people browsing the archive
+can use it get an idea of the modules uses. It is usually a good idea
+to provide version information here so that people can decide whether
+fixes for the module are worth downloading.
+
+INSTALLATION
+
+To install this module, run the following commands:
+
+ perl Makefile.PL
+ make
+ make test
+ make install
+
+
+COPYRIGHT AND LICENCE
+
+Copyright (C) 2005 Andy Lester
+
+This program is free software; you can redistribute it and/or modify it
+under the same terms as Perl itself.
214 Task.pm
@@ -0,0 +1,214 @@
+package App::HWD::Task;
+
+use warnings;
+use strict;
+
+=head1 NAME
+
+App::HWD::Task - Tasks for HWD
+
+=head1 SYNOPSIS
+
+Used only by the F<hwd> application.
+
+Note that these functions are pretty fragile, and do almost no data
+checking.
+
+=head1 FUNCTIONS
+
+=head2 App::HWD::Task->parse()
+
+Returns an App::HWD::Task object from an input line
+
+=cut
+
+sub parse {
+ my $class = shift;
+ my $line = shift;
+
+ my $line_regex = qr/
+ ^
+ (-+) # leading dashes
+ \s* # whitespace
+ (.+) # everything else
+ $
+ /x;
+
+ if ( $line =~ $line_regex ) {
+ my $level = length $1;
+ my $name = $2;
+ my $id;
+ my $estimate;
+
+ if ( $name =~ s/\s*\(([^)]+)\)$// ) {
+ my $parens = $1;
+ my @subfields = split /,/, $parens;
+ for ( @subfields ) {
+ s/^\s+//;
+ s/\s+$//;
+ /^#(\d+)$/ and $id = $1, next;
+ /^(\d+)h$/ and $estimate = $1, next;
+ warn "Don't understand $_";
+ }
+ }
+
+ my $task = $class->new( {
+ level => $level,
+ name => $name,
+ id => $id,
+ estimate => $estimate,
+ } );
+ }
+ else {
+ return;
+ }
+}
+
+=head2 App::HWD::Task->new( { args } )
+
+Creates a new task from the args passed in. They should include at
+least I<level>, I<name> and I<id>, even if I<id> is C<undef>.
+
+ my $task = App::HWD::Task->new( {
+ level => $level,
+ name => $name,
+ id => $id,
+ estimate => $estimate,
+ } );
+
+=cut
+
+sub new {
+ my $class = shift;
+ my $args = shift;
+
+ my $self = bless {
+ %$args,
+ work => [],
+ }, $class;
+
+ return $self;
+}
+
+=head2 $task->level()
+
+Returns the level of the task
+
+=head2 $task->name()
+
+Returns the name of the task
+
+=head2 $task->id()
+
+Returns the ID of the task, or the empty string if there isn't one.
+
+=head2 $task->estimate()
+
+Returns the estimate, or 0 if it's not set.
+
+=cut
+
+sub level { return shift->{level} }
+sub name { return shift->{name} }
+sub id { return shift->{id} || "" }
+sub estimate { return shift->{estimate} || 0 }
+
+=head2 $task->set( $key => $value )
+
+Sets the I<$key> field to I<$value>.
+
+=cut
+
+sub set {
+ my $self = shift;
+ my $key = shift;
+ my $value = shift;
+
+ die "Dupe key $key" if exists $self->{$key};
+ $self->{$key} = $value;
+}
+
+=head2 add_work( $work )
+
+Adds a Work record to the task, for later accumulating
+
+=cut
+
+sub add_work {
+ my $self = shift;
+ my $work = shift;
+
+ push( @{$self->{work}}, $work );
+}
+
+=head2 hours_worked()
+
+Returns the number of hours worked, but counting up all the work records added in L</add_work>.
+
+=cut
+
+sub hours_worked {
+ my $self = shift;
+
+ my $hours = 0;
+ for my $work ( @{$self->{work}} ) {
+ $hours += $work->hours;
+ }
+ return $hours;
+}
+
+=head2 completed()
+
+Returns whether the task has been completed.
+
+=cut
+
+sub completed {
+ my $self = shift;
+
+ my $completed = 0;
+ for my $work ( @{$self->{work}} ) {
+ $completed = $work->completed;
+ }
+
+ return $completed;
+}
+
+=head2 summary
+
+Returns a simple one line description of the Work.
+
+=cut
+
+sub summary {
+ my $self = shift;
+ my $sum;
+ $sum = $self->id . " - " if $self->id;
+ $sum .= sprintf( "%s (%s/%s)", $self->name, $self->estimate, $self->hours_worked );
+ return $sum;
+}
+
+=head1 AUTHOR
+
+Andy Lester, C<< <andy at petdance.com> >>
+
+=head1 BUGS
+
+Please report any bugs or feature requests to
+C<bug-app-hwd-task@rt.cpan.org>, or through the web interface at
+L<http://rt.cpan.org/NoAuth/ReportBug.html?Queue=App-HWD>.
+I will be notified, and then you'll automatically be notified of progress on
+your bug as I make changes.
+
+=head1 ACKNOWLEDGEMENTS
+
+=head1 COPYRIGHT & LICENSE
+
+Copyright 2005 Andy Lester, all rights reserved.
+
+This program is free software; you can redistribute it and/or modify it
+under the same terms as Perl itself.
+
+=cut
+
+1; # End of App::HWD::Task
144 Work.pm
@@ -0,0 +1,144 @@
+package App::HWD::Work;
+
+use warnings;
+use strict;
+
+=head1 NAME
+
+App::HWD::Work - Work completed on HWD projects
+
+=head1 SYNOPSIS
+
+Used only by the F<hwd> application.
+
+Note that these functions are pretty fragile, and do almost no data
+checking.
+
+=head1 FUNCTIONS
+
+=head2 App::HWD::Work->parse()
+
+Returns an App::HWD::Work object from an input line
+
+=cut
+
+sub parse {
+ my $class = shift;
+ my $line = shift;
+
+ my @cols = split " ", $line, 5;
+ die "Invalid work line: $line" unless @cols >= 4;
+
+ my ($who, $when, $task, $hours, $comment) = @cols;
+ my $completed;
+ if ( defined $comment ) {
+ if ( $comment =~ s/X\s*//i ) {
+ $completed = 1;
+ }
+ $comment =~ s/^#\s*//;
+ $comment =~ s/\s+$//;
+ }
+ else {
+ $comment = '';
+ }
+
+ my $self =
+ $class->new( {
+ who => $who,
+ when => $when,
+ task => $task,
+ hours => $hours,
+ comment => $comment,
+ completed => $completed,
+ } );
+
+ return $self;
+}
+
+=head2 App::HWD::Work->new( { args } )
+
+Creates a new task from the args passed in. They should include at
+least I<level>, I<name> and I<id>, even if I<id> is C<undef>.
+
+=cut
+
+sub new {
+ my $class = shift;
+ my $args = shift;
+
+ my $self = bless { %$args }, $class;
+}
+
+
+=head2 $work->set( $key => $value )
+
+Sets the I<$key> field to I<$value>.
+
+=cut
+
+sub set {
+ my $self = shift;
+ my $key = shift;
+ my $value = shift;
+
+ die "Dupe key $key" if exists $self->{$key};
+ $self->{$key} = $value;
+}
+
+=head2 $work->who()
+
+Returns who did the work
+
+=head2 $work->when()
+
+Returns the when of the work
+
+=head2 $work->task()
+
+Returns the ID of the work that was worked on.
+
+=head2 $work->hours()
+
+Returns the hours spent.
+
+=head2 $work->completed()
+
+Returns a boolean that says whether the work was completed or not.
+
+=head2 $work->comment()
+
+Returns the comment from the file, if any.
+
+=cut
+
+sub who { return shift->{who} }
+sub when { return shift->{when} }
+sub task { return shift->{task} }
+sub hours { return shift->{hours} }
+sub completed { return shift->{completed} }
+sub comment { return shift->{comment} }
+
+=head1 AUTHOR
+
+Andy Lester, C<< <andy at petdance.com> >>
+
+=head1 BUGS
+
+Please report any bugs or feature requests to
+C<bug-app-hwd-task@rt.cpan.org>, or through the web interface at
+L<http://rt.cpan.org/NoAuth/ReportBug.html?Queue=App-HWD>.
+I will be notified, and then you'll automatically be notified of progress on
+your bug as I make changes.
+
+=head1 ACKNOWLEDGEMENTS
+
+=head1 COPYRIGHT & LICENSE
+
+Copyright 2005 Andy Lester, all rights reserved.
+
+This program is free software; you can redistribute it and/or modify it
+under the same terms as Perl itself.
+
+=cut
+
+1; # End of App::HWD::Task
195 bin/hwd
@@ -0,0 +1,195 @@
+#!/usr/bin/perl -w
+
+use strict;
+use warnings;
+use Getopt::Long;
+use Pod::Usage;
+use App::HWD::Task;
+use App::HWD::Work;
+use List::Util qw( max );
+
+our $detail_level;
+our $started;
+
+our $show_nextid;
+
+Getopt::Long::Configure( "no_ignore_case" );
+Getopt::Long::Configure( "bundling" );
+GetOptions(
+ 'detail=n' => \$detail_level,
+ nextid => \$show_nextid,
+ 'started:s' => \$started,
+ 'h|help|?' => sub { pod2usage({-verbose => 1}); exit; },
+ 'H|man' => sub { pod2usage({-verbose => 2}); exit; },
+ 'V|version' => sub { print_version(); exit; },
+) or exit 1;
+
+MAIN: {
+ my ($tasks,$works,$tasks_by_id) = get_tasks_and_work();
+
+ if ( $show_nextid ) {
+ my $max = max( keys %$tasks_by_id );
+ $max = $max ? $max+1 : 101;
+ print "Next task ID: $max\n";
+ exit;
+ }
+
+ for my $work ( @$works ) {
+ my $task = $tasks_by_id->{ $work->task } or die "No task ID ", $work->task, "\n";
+ $task->add_work( $work );
+ }
+
+ if (defined $started) {
+ my %started;
+ foreach my $w (@$works) {
+ next if $started and $started ne $w->who;
+ my $t = $tasks_by_id->{$w->task};
+ next if $t->completed();
+ $started{$w->who}{$t->id}++;
+ }
+ foreach my $w (sort keys %started) {
+ print "$w is working on...\n";
+ foreach my $t (sort keys %{$started{$w}}) {
+ print " " . $tasks_by_id->{$t}->summary . "\n";
+ }
+ print "\n";
+ }
+ exit;
+ }
+
+ my $total_estimated = 0;
+ my $total_velocity = 0;
+ for my $task ( @$tasks ) {
+ $total_estimated += $task->estimate || 0;
+ $total_velocity += $task->estimate if $task->completed;
+ print_task( $task );
+ }
+ print "Total points: $total_estimated\n";
+ print "Total velocity: $total_velocity\n";
+}
+
+sub get_tasks_and_work {
+ my @tasks;
+ my @work;
+ my %tasks_by_id;
+
+ while ( my $line = <> ) {
+ chomp $line;
+ next if $line =~ /^\s*#/;
+ next if $line !~ /./;
+
+ if ( $line =~ /^-/ ) {
+ my $task = App::HWD::Task->parse( $line );
+ die "Can't parse: $line\n" unless $task;
+ if ( $task->id ) {
+ if ( $tasks_by_id{ $task->id } ) {
+ die "Dupe task ID ", $task->id, "\n";
+ }
+ else {
+ $tasks_by_id{ $task->id } = $task;
+ }
+ }
+ push( @tasks, $task );
+ }
+ else {
+ my $work = App::HWD::Work->parse( $line );
+ push( @work, $work );
+ }
+ } # while
+ return( \@tasks, \@work, \%tasks_by_id );
+}
+
+sub print_version {
+ printf( "hwd v%s\n", $App::HWD::VERSION, $^V );
+}
+
+sub print_task {
+ my $task = shift;
+
+ my $level = $task->level;
+ my $name = $task->name;
+ my $id = $task->id;
+ my $estimate = $task->estimate;
+ my $indent = " " x (($level-1)*4);
+
+ if ( $id ) {
+ if ( !$detail_level ) {
+ my $worked = $task->hours_worked;
+ $worked = $worked ? sprintf( "%6.2f", $worked ) : "";
+ $worked =~ s/\.00$/ /;
+ my $x = $task->completed ? "X" : " ";
+ print_cols( $id, $estimate, $worked, $x, $indent, $name );
+ }
+ }
+ else {
+ print_cols( (undef) x 4, $indent, $name );
+ }
+}
+
+sub print_cols {
+ my @cols = @_;
+
+ for ( @cols[0..1] ) {
+ $_ = $_ ? sprintf( "%4d", $_ ) : "";
+ }
+ for ( @cols[2..5] ) {
+ $_ = "" unless defined $_;
+ }
+ printf( "%4s %4s %6.6s %1s %s %s\n", @cols );
+}
+
+__END__
+
+=head1 NAME
+
+hwd -- The How We Doin'? project tracking tool
+
+=head1 SYNOPSIS
+
+hwd [options] schedule-file(s)
+
+Options:
+ --nextid Display the next highest task ID
+ --started Displays tasks that have been started
+ --started=person
+ Displays tasks started by person
+
+ -h, --help Display this help
+ -H, --man Longer manpage for prove
+ -V, --version Display version info
+
+=head1 COMMAND LINE OPTIONS
+
+=head2 --started[=who]
+
+Shows what tasks have been started by the person specified, or by everyone
+if no one one is specified.
+
+=head2 --nextid
+
+Shows the next ID available.
+
+=head2 -V, --version
+
+Display version info.
+
+=head1 BUGS
+
+Please use the CPAN bug ticketing system at L<http://rt.cpan.org/>.
+You can also mail bugs, fixes and enhancements to
+C<< <bug-app-hwd at rt.cpan.org> >>.
+
+=head1 AUTHORS
+
+Andy Lester C<< <andy at petdance.com> >>
+
+=head1 COPYRIGHT
+
+Copyright 2005 by Andy Lester C<< <andy at petdance.com> >>.
+
+This program is free software; you can redistribute it and/or
+modify it under the same terms as Perl itself.
+
+See L<http://www.perl.com/perl/misc/Artistic.html>.
+
+=cut
259 eg/sked.txt
@@ -0,0 +1,259 @@
+# This is an actual schedule and work, with specific names changed to
+# protect confidentiality. Anything that is "foo", "bar", "baz",
+# "quux" or "wango" has been changed from something else.
+
+
+-Infrastructure
+--FOO*
+---Add new columns to track by type (#101, 2h)
+---Add new columns to record new checkout features (#102, 2h)
+---Add FK constraints between FOOHEAD and FOODETAIL (#103, 2h)
+---Add FK constraints between FOOHEAD and BARDETAIL (#104, 2h)
+
+--ORDERFORM
+---Create migration script to modify table automatically (#105, 2h)
+
+-TW::DB::FooForm
+--Review (#106, 1h)
+--Refactor (#107, 1h)
+
+-TW::DB::FooDefault
+--Review (#108, 1h)
+--Refactor (#109, 1h)
+
+-Foo Entry Wizard
+--Handler
+---API Pod Docs (#110, 4h)
+---Review (#111, 1h)
+---Tests (#112, 8h)
+---Code (#113, 8h)
+---Refactor (#114, 4h)
+--Screens
+---Foo Summary Template Component (#115, 5h)
+---Foo Summary Template - CA & C&P (#228, 2h)
+---Wango Template (#116, 5h)
+---Wango Template - CA & C&P (#229, 2h)
+---Main and List page buttons (#117, 4h)
+---C&P Template (#118, 5h)
+---C&P Template - CA & C&P (#236, 2h)
+---Tango Options Template (#119, 5h)
+---Tango Options Template - CA & C&P (#230, 2h)
+---Ebook Options Template (#120, 5h)
+---Ebook Options Template - CA & C&P (#231, 2h)
+---Contact Information Template (#121, 5h)
+---Contact Information Template - CA & C&P (#232, 2h)
+---Baz Template (#122, 5h)
+---Baz Template - CA & C&P (#233, 2h)
+---Quux Template (#123, 5h)
+---Quux Template - CA & C&P (#234, 2h)
+---Confirm Template (#124, 5h)
+---Confirm Template - CA & C&P (#235, 2h)
+---Thank You Template (#125, 7h)
+--E-mail Confirmation (#126, 7h)
+
+-TW::FooWizard
+--Review (#127, 4h)
+--Tests (#128, 4h)
+--CA & C&P Tests (#226, 4h)
+--Code (#129, 8h)
+--CA & C&P Code (#227, 8h)
+--Refactor (#130, 2h)
+
+-TW::FooMaker
+--API Pod Docs (#131, 12h)
+--Review (#132, 4h)
+--Tests (#133, 8h)
+--Code (#134, 16h)
+---Bar Promotion (#135, 8h)
+--Refactor (#136, 2h)
+
+-TW::DB::FooHead
+--API Pod Docs (#137, 2h)
+--Review (#138, 1h)
+--Tests (#139, 4h)
+--Code (#140, 4h)
+--Refactor (#141, 1h)
+
+-TW::DB::FooDetail
+--API Pod Docs (#142, 2h)
+--Review (#143, 1h)
+--Tests (#144, 4h)
+--Code (#145, 4h)
+--Refactor (#146, 1h)
+
+-TW::DB::BarDetail
+--API Pod Docs (#147, 2h)
+--Review (#148, 1h)
+--Tests (#149, 4h)
+--Code (#150, 4h)
+--Refactor (#151, 1h)
+
+-TW::CP
+--API Pod Docs (#152, 7h)
+--Review (#153, 1h)
+--Tests (#154, 7h)
+--Code
+---Create "new" method for TW::CP (#155, 1h)
+---Refactor interfaces between TW::CP and TW::CPSet (#156, 7h)
+---Convert TW::CP class methods to instance methods (#157, 4h)
+---Change current TW::CP users to using instance methods (#158, 4h)
+---Create accessor methods which delegate appropriately (#160, 4h)
+---Create support for dynamically loading delegatees (#161, 2h)
+---Create method to invalidate dynamically loaded delegatees (#162, 1h)
+---Create method to invalidate dynamically calculated costs (#163, 1h)
+---Create interface definition module for Foo implementors (#164, 1h)
+---Create methods to return delegatees (#165, 1h)
+--Refactor (#166, 2h)
+
+-TW::DB::BarSubset
+--API Pod Docs (#167, 7h)
+--Review (#168, 1h)
+--Tests (#169, 7h)
+--Code
+---Create base Class::DBI module from POD (#170, 1h)
+---Calculate bar from aggregate totals of a supplied object (#171, 4h)
+---Create processing methods to format specs as text or HTML (#172, 8h)
+---Create methods to support delegated accessors interface for TW::CP (#173, 4h)
+--Refactor (#174, 2h)
+
+-TW::CPSet
+--API Pod Docs (#175, 7h)
+--Review (#176, 1h)
+--Tests (#177, 7h)
+--Code
+---Calculate Book C&P costs from aggregate totals of a supplied object (#178, 2h)
+---Create methods to support delegated accessors interface for TW::CP (#179, 4h)
+--Refactor (#180, 2h)
+
+-TW::List
+--Review (#181, 1h)
+--Add Code
+---Refactor (#182, 2h)
+
+-TW::TitleCounts
+--Review (#183, 1h)
+--Refactor (#184, 1h)
+
+-Bar Creation PL/SQL script (#185, 16h)
+
+-Foo Creation PL/SQL script (#186, 16h)
+
+-TW::BarMaker
+--API Pod docs (#223, 4h)
+--Review (#224, 1h)
+--Tests (#187, 7h)
+--Code (#188, 7h)
+--Refactor (#189, 4h)
+
+-TW::Bar
+--API Pod Docs (#190, 14h)
+--Review (#191, 4h)
+--Tests (#192, 14h)
+--Code (#193, 21h)
+--Refactor (#194, 4h)
+
+-TW::DB::BarItem
+--Tests (#195, 2h)
+--Code (#196, 3h)
+--Refactor (#197, 1h)
+
+-TW::DB::BarHead
+--API Pod Docs (#198, 4h)
+--Review (#199, 1h)
+--Tests (#200, 2h)
+--Code (#201, 3h)
+--Refactor (#202, 1h)
+
+-Bar Print
+--TW::Apache::Bar Handler
+---Select List & Request Bar (#203, 7h)
+---Bar Print Options (#204, 7h)
+---Bar Print (#205, 7h)
+--Select List & Request Bar Template
+---Bar Select Template (#207, 7h)
+---Bar Request email (#208, 7h)
+---Bar Request Confirm Template (#209, 7h)
+---Bar Print Options Template (#210, 7h)
+--Bar Print Screen
+---Main Bar Template (#211, 4h)
+---Standard Detail template (#212, 4h)
+---Single Line Detail template (#213, 4h)
+---Annotated Detail template (#214, 4h)
+-Spec Change E-mail (#217, 16h)
+-Custom Foo Email (#218, 16h)
+
+-Rollout
+--Run alter scripts against production database and verify OK (#219, 7h)
+--Merge to trunk (#221, 28h)
+--Rollout internally (#220, 1h)
+--Rollout (#222, 6h)
+
+
+Pete 7/11 195 2 X
+Pete 7/11 196 3 X
+Pete 7/11 198 2
+Pete 7/11 127 .5 X
+Pete 7/11 108 .25 X
+Pete 7/11 106 .25 X
+Pete 7/11 111 .5 X
+Pete 7/12 198 1.25 X
+Pete 7/13 200 2 X
+Pete 7/13 201 1
+Pete 7/13 175 2.75
+Pete 7/14 175 7.5
+Pete 7/15 167 5
+
+Bruce 7/11 185 5
+Bruce 7/11 127 .5 X
+Bruce 7/11 108 .25 X
+Bruce 7/11 106 .25 X
+Bruce 7/11 111 .5 X
+Bruce 7/12 185 6
+Bruce 7/13 185 5 x
+Bruce 7/13 223 1
+Bruce 7/14 185 2 x refactor
+Bruce 7/14 223 1.5
+Bruce 7/14 188 2
+Bruce 7/15 223 3 x
+Bruce 7/15 187 1
+Bruce 7/15 188 1
+
+Bob 7/11 127 .5
+Bob 7/11 108 .75 X
+Bob 7/11 106 .25 X
+Bob 7/11 111 .5 X
+Bob 7/11 127 1.5 X
+Bob 7/11 110 .25 X
+Bob 7/11 117 1
+Bob 7/11 113 1
+Bob 7/12 128 2
+Bob 7/12 129 3.75
+Bob 7/13 128 .75
+Bob 7/13 129 1
+Bob 7/13 116 .5
+Bob 7/13 115 .5
+Bob 7/13 118 .5
+Bob 7/13 119 .5
+Bob 7/13 120 .5
+Bob 7/13 121 .5
+Bob 7/13 122 .5
+Bob 7/13 123 .5
+Bob 7/13 124 .5
+Bob 7/14 128 1
+Bob 7/14 129 1
+Bob 7/14 116 .25 X
+Bob 7/14 115 .25 X
+Bob 7/14 118 .25 X
+Bob 7/14 119 .25 X
+Bob 7/14 120 .25 X
+Bob 7/14 121 .75
+Bob 7/14 122 .75
+Bob 7/14 123 .75
+Bob 7/14 124 .25
+Bob 7/15 128 1 X
+Bob 7/15 129 1 X
+Bob 7/15 113 1 X
+Bob 7/15 121 .25 X
+Bob 7/15 122 .25 X
+Bob 7/15 123 .25 X
+Bob 7/15 124 .25 X
10 t/00-load.t
@@ -0,0 +1,10 @@
+#!perl -T
+
+use Test::More tests => 2;
+
+BEGIN {
+ use_ok( 'App::HWD' );
+ use_ok( 'App::HWD::Task' );
+}
+
+diag( "Testing App::HWD $App::HWD::VERSION, Perl $], $^X" );
6 t/pod-coverage.t
@@ -0,0 +1,6 @@
+#!perl -T
+
+use Test::More;
+eval "use Test::Pod::Coverage 1.04";
+plan skip_all => "Test::Pod::Coverage 1.04 required for testing POD coverage" if $@;
+all_pod_coverage_ok();
6 t/pod.t
@@ -0,0 +1,6 @@
+#!perl -T
+
+use Test::More;
+eval "use Test::Pod 1.14";
+plan skip_all => "Test::Pod 1.14 required for testing POD" if $@;
+all_pod_files_ok();
82 t/task.t
@@ -0,0 +1,82 @@
+#!perl
+
+use strict;
+use warnings;
+
+use Test::More tests => 37;
+
+BEGIN {
+ use_ok( 'App::HWD::Task' );
+}
+
+
+SIMPLE: {
+ my $str = '-Create TW::DB::QuoteHead';
+
+ my $task = App::HWD::Task->parse( $str );
+ isa_ok( $task, 'App::HWD::Task' );
+ is( $task->name, 'Create TW::DB::QuoteHead' );
+ is( $task->level, 1 );
+ is( $task->estimate, 0 );
+ is( $task->id, '' );
+ is( $task->summary, 'Create TW::DB::QuoteHead (0/0)', 'Summary');
+}
+
+WITH_ID: {
+ my $str = '--API Pod Docs (#198)';
+
+ my $task = App::HWD::Task->parse( $str );
+ isa_ok( $task, 'App::HWD::Task' );
+ is( $task->name, 'API Pod Docs' );
+ is( $task->level, 2 );
+ is( $task->estimate, 0 );
+ is( $task->id, 198 );
+ is( $task->summary, '198 - API Pod Docs (0/0)', 'Summary');
+}
+
+WITH_ESTIMATE: {
+ my $str = '---API Pod Docs (4h)';
+
+ my $task = App::HWD::Task->parse( $str );
+ isa_ok( $task, 'App::HWD::Task' );
+ is( $task->name, 'API Pod Docs' );
+ is( $task->level, 3 );
+ is( $task->estimate, 4 );
+ is( $task->id, '' );
+ is( $task->summary, 'API Pod Docs (4/0)', 'Summary');
+}
+
+WITH_ID_AND_ESTIMATE: {
+ my $str = '----Retrofitting widgets (#142, 3h)';
+
+ my $task = App::HWD::Task->parse( $str );
+ isa_ok( $task, 'App::HWD::Task' );
+ is( $task->name, 'Retrofitting widgets' );
+ is( $task->level, 4 );
+ is( $task->estimate, 3 );
+ is( $task->id, 142 );
+ is( $task->summary, '142 - Retrofitting widgets (3/0)', 'Summary');
+}
+
+WITH_ESTIMATE_AND_ID: {
+ my $str = '-Flargling dangows (9h ,#2112)';
+
+ my $task = App::HWD::Task->parse( $str );
+ isa_ok( $task, 'App::HWD::Task' );
+ is( $task->name, 'Flargling dangows' );
+ is( $task->level, 1 );
+ is( $task->estimate, 9 );
+ is( $task->id, 2112 );
+ is( $task->summary, '2112 - Flargling dangows (9/0)', 'Summary');
+}
+
+WITH_PARENS: {
+ my $str = '-Voodoo Chile (Slight Return) (#43)';
+ my $task = App::HWD::Task->parse( $str );
+ isa_ok( $task, 'App::HWD::Task' );
+ is( $task->name, 'Voodoo Chile (Slight Return)' );
+ is( $task->level, 1 );
+ is( $task->estimate, 0 );
+ is( $task->id, 43 );
+ is( $task->summary, '43 - Voodoo Chile (Slight Return) (0/0)', 'Summary');
+}
49 t/work.t
@@ -0,0 +1,49 @@
+#!perl
+
+use strict;
+use warnings;
+
+use Test::More tests => 22;
+
+BEGIN {
+ use_ok( 'App::HWD::Work' );
+}
+
+SIMPLE: {
+ my $str = 'Pete 7/11 195 0000.250';
+ my $work = App::HWD::Work->parse( $str );
+ isa_ok( $work, 'App::HWD::Work' );
+
+ is( $work->who, 'Pete', 'Who' );
+ is( $work->when, '7/11', 'When' );
+ is( $work->task, 195, 'Task' );
+ cmp_ok( $work->hours, '==', .25, 'Hours match' );
+ is( $work->comment, '', 'no comment' );
+ ok( !$work->completed, 'not completed' );
+}
+
+COMPLETED: {
+ my $str = 'Pete 7/11 195 2 x ';
+ my $work = App::HWD::Work->parse( $str );
+ isa_ok( $work, 'App::HWD::Work' );
+
+ is( $work->who, 'Pete', 'Who' );
+ is( $work->when, '7/11', 'When' );
+ is( $work->task, 195, 'Task' );
+ cmp_ok( $work->hours, '==', 2, 'Hours match' );
+ is( $work->comment, '', 'no commment' );
+ ok( $work->completed, 'completed' );
+}
+
+COMPLETED: {
+ my $str = 'Bob 8/11 1 .75 X # Refactoring ';
+ my $work = App::HWD::Work->parse( $str );
+ isa_ok( $work, 'App::HWD::Work' );
+
+ is( $work->who, 'Bob', 'Who' );
+ is( $work->when, '8/11', 'When' );
+ is( $work->task, 1, 'task' );
+ cmp_ok( $work->hours, '==', .75, 'Hours match' );
+ is( $work->comment, 'Refactoring', 'Non-empty comment' );
+ ok( $work->completed, 'Completed' );
+}
Please sign in to comment.
Something went wrong with that request. Please try again.