[Bps-public-commit] r17657 - in Net-Google-Code/trunk: lib/Net/Google lib/Net/Google/Code t/sample

fayland at bestpractical.com fayland at bestpractical.com
Fri Jan 9 00:47:49 EST 2009


Author: fayland
Date: Fri Jan  9 00:47:49 2009
New Revision: 17657

Added:
   Net-Google-Code/trunk/lib/Net/Google/Code/Home.pm
   Net-Google-Code/trunk/t/sample/20.code.html
Modified:
   Net-Google-Code/trunk/lib/Net/Google/Code.pm
   Net-Google-Code/trunk/t/20.code.t

Log:
add ->owners ->members in Net::Google::Code

Modified: Net-Google-Code/trunk/lib/Net/Google/Code.pm
==============================================================================
--- Net-Google-Code/trunk/lib/Net/Google/Code.pm	(original)
+++ Net-Google-Code/trunk/lib/Net/Google/Code.pm	Fri Jan  9 00:47:49 2009
@@ -30,6 +30,17 @@
     default => sub { 'http://' . $_[0]->project . '.googlecode.com/svn/' },
 );
 
+has 'home'  => (
+    isa     => 'Net::Google::Code::Home',
+    is      => 'ro',
+    lazy    => 1,
+    default => sub {
+        require Net::Google::Code::Home;
+        Net::Google::Code::Home->new( parent => $_[0] );
+    },
+    handles => [ 'owners', 'members' ],
+);
+
 has 'issue' => (
     isa     => 'Net::Google::Code::Issue',
     is      => 'ro',
@@ -77,7 +88,9 @@
 =head1 SYNOPSIS
 
     use Net::Google::Code;
+    
     my $project = Net::Google::Code->new( project => 'net-google-code' );
+    
     $project->issue;
     $project->downloads;
     $project->wiki;
@@ -98,6 +111,14 @@
 
 the project svn url (without trunk)
 
+=head2 owners
+
+ArrayRef. project owners
+
+=head2 members
+
+ArrayRef. project members
+
 =head1 METHODS
 
 =head2 issue

Added: Net-Google-Code/trunk/lib/Net/Google/Code/Home.pm
==============================================================================
--- (empty file)
+++ Net-Google-Code/trunk/lib/Net/Google/Code/Home.pm	Fri Jan  9 00:47:49 2009
@@ -0,0 +1,84 @@
+package Net::Google::Code::Home;
+
+use Moose;
+
+our $VERSION = '0.02';
+our $AUTHORITY = 'cpan:FAYLAND';
+
+has parent => (
+    isa => 'Net::Google::Code',
+    is  => 'ro',
+    required => 1,
+);
+
+has '__html' => (
+    isa => 'Str',
+    is  => 'ro',
+    lazy => 1,
+    default => sub {
+        my $self = shift;
+        
+        my $connection = $self->parent->connection;
+        
+        my $content = $connection->_fetch( $self->parent->url );
+        return $content;
+    }
+);
+
+has '__html_tree' => (
+    is  => 'ro',
+    lazy => 1,
+    default => sub {
+        my $self = shift;
+        
+        my $html = $self->__html;
+        
+        require HTML::TreeBuilder;
+        my $tree = HTML::TreeBuilder->new;
+        $tree->parse_content($html);
+        $tree->elementify;
+        
+        return $tree;
+    },
+);
+
+has 'owners' => (
+    isa => 'ArrayRef',
+    is  => 'ro',
+    lazy => 1,
+    default => sub {
+        my $self = shift;
+        
+        my $tree = $self->__html_tree;
+        my @tags = $tree->look_down(id => 'owners')->find_by_tag_name('a');
+        my @owners;
+        foreach my $tag ( @tags ) {
+	        push @owners, $tag->content_array_ref->[0];
+	    }
+	    return \@owners;
+    },
+);
+has 'members' => (
+    isa => 'ArrayRef',
+    is  => 'ro',
+    lazy => 1,
+    default => sub {
+        my $self = shift;
+        
+        my $tree = $self->__html_tree;
+        my @tags = $tree->look_down(id => 'members')->find_by_tag_name('a');
+        my @members;
+        foreach my $tag ( @tags ) {
+	        push @members, $tag->content_array_ref->[0];
+	    }
+	    return \@members;
+    },
+);
+
+no Moose;
+__PACKAGE__->meta->make_immutable;
+
+1;
+__END__
+
+# Fayland Lam, C<< <fayland at gmail.com> >>

Modified: Net-Google-Code/trunk/t/20.code.t
==============================================================================
--- Net-Google-Code/trunk/t/20.code.t	(original)
+++ Net-Google-Code/trunk/t/20.code.t	Fri Jan  9 00:47:49 2009
@@ -3,15 +3,34 @@
 use strict;
 use warnings;
 
-use Test::More tests => 8;
+use Test::More tests => 10;
+use Test::MockModule;
+use FindBin qw/$Bin/;
+use File::Slurp;
 use_ok('Net::Google::Code');
 
+my $homepage_file = "$Bin/sample/20.code.html";
+my $homepage_content = read_file($homepage_file);
+
+my $mock_connection = Test::MockModule->new('Net::Google::Code::Connection');
+$mock_connection->mock(
+    '_fetch',
+    sub {
+    	( undef, my $uri ) = @_;
+    	if ( $uri eq 'http://code.google.com/p/net-google-code/' ) {
+    		return $homepage_content;
+    	}
+    }
+);
+
 my $name = 'net-google-code';
 my $project = Net::Google::Code->new( project => $name );
 
 is( $project->url, "http://code.google.com/p/$name/", 'default url' );
 is( $project->svn_url, "http://$name.googlecode.com/svn/", 'svn url' );
 is( $project->project, $name, 'project name' );
+is_deeply( $project->owners, [ 'sunnavy' ] );
+is_deeply( $project->members, [ 'jessev', 'fayland' ] );
 
 isa_ok( $project->connection, 'Net::Google::Code::Connection' );
 isa_ok( $project->issue,      'Net::Google::Code::Issue' );

Added: Net-Google-Code/trunk/t/sample/20.code.html
==============================================================================
--- (empty file)
+++ Net-Google-Code/trunk/t/sample/20.code.html	Fri Jan  9 00:47:49 2009
@@ -0,0 +1,409 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+ 
+ <title>
+ net-google-code -
+ 
+ Google Code</title>
+ <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" >
+ 
+ <link type="text/css" rel="stylesheet" href="http://www.gstatic.com/codesite/ph/3596478537346627501/css/d_20081117.css">
+ 
+ 
+ 
+<!--[if IE]>
+ <link type="text/css" rel="stylesheet" href="http://www.gstatic.com/codesite/ph/3596478537346627501/css/d_ie.css" >
+<![endif]-->
+</head>
+<body class="t1">
+ <div id="gaia">
+  <font size="-1">
+
+ 
+ <b>xxxx at gmail.com</b>
+ 
+ | <a href="/p/support/wiki/WhatsNew" style="color:#a03">What's new?</a>
+ | <a href="/u/xxxx/">Profile</a>
+ | <a href="/hosting/settings">Settings</a>
+ | <a href="/p/support/">Help</a>
+
+ | <a href="http://www.google.com/accounts/Logout?continue=http%3A%2F%2Fcode.google.com%2Fp%2Fnet-google-code%2F">Sign out</a>
+ 
+ </font> 
+
+ </div>
+ <div class="gbh" style="left: 0pt;"></div>
+ <div class="gbh" style="right: 0pt;"></div>
+ 
+ 
+ <div style="height: 1px"></div>
+ <table style="padding:0px; margin: 20px 0px 0px 0px; width:100%" cellpadding="0" cellspacing="0">
+ <tr>
+
+ <td style="width:153px"><a href="/"><img src="http://www.gstatic.com/codesite/ph/images/code_sm.png" width="153" height="55" alt="Google"></a></td>
+ <td style="padding-left: 0.8em">
+ 
+ <div id="pname" style="margin: 0px 0px -3px 0px">
+ <a href="/p/net-google-code/" style="text-decoration:none; color:#000">net-google-code</a>
+ </div>
+ <div id="psum">
+ <i><a href="/p/net-google-code/" style="text-decoration:none; color:#000">a simple client library for google code</a></i>
+ </div>
+
+ 
+ </td>
+ <td style="white-space:nowrap; text-align:right">
+ 
+ <form action="/hosting/search">
+ <input size="30" name="q" value="">
+ <input type="submit" name="projectsearch" value="Search Projects" >
+ </form>
+ 
+ </tr>
+ </table>
+
+<table id="mt" cellspacing="0" cellpadding="0" width="100%" border="0">
+ <tr>
+ <th onclick="if (!cancelBubble) _go('/p/net-google-code/');">
+ <div class="tab active">
+ <div class="round4"></div>
+ <div class="round2"></div>
+ <div class="round1"></div>
+ <div class="box-inner">
+ <a onclick="cancelBubble=true;" href="/p/net-google-code/">Project Home</a>
+
+ </div>
+ </div>
+ </th><td>  </td>
+ 
+ 
+ 
+ 
+ <th onclick="if (!cancelBubble) _go('/p/net-google-code/downloads/list');">
+ <div class="tab inactive">
+ <div class="round4"></div>
+ <div class="round2"></div>
+ <div class="round1"></div>
+ <div class="box-inner">
+
+ <a onclick="cancelBubble=true;" href="/p/net-google-code/downloads/list">Downloads</a>
+ </div>
+ </div>
+ </th><td>  </td>
+ 
+ 
+ 
+ 
+ 
+ <th onclick="if (!cancelBubble) _go('/p/net-google-code/w/list');">
+ <div class="tab inactive">
+ <div class="round4"></div>
+ <div class="round2"></div>
+
+ <div class="round1"></div>
+ <div class="box-inner">
+ <a onclick="cancelBubble=true;" href="/p/net-google-code/w/list">Wiki</a>
+ </div>
+ </div>
+ </th><td>  </td>
+ 
+ 
+ 
+ 
+ 
+ <th onclick="if (!cancelBubble) _go('/p/net-google-code/issues/list');">
+ <div class="tab inactive">
+
+ <div class="round4"></div>
+ <div class="round2"></div>
+ <div class="round1"></div>
+ <div class="box-inner">
+ <a onclick="cancelBubble=true;" href="/p/net-google-code/issues/list">Issues</a>
+ </div>
+ </div>
+ </th><td>  </td>
+
+ 
+ 
+ 
+ 
+ 
+ <th onclick="if (!cancelBubble) _go('/p/net-google-code/source/list');">
+ <div class="tab inactive">
+ <div class="round4"></div>
+ <div class="round2"></div>
+ <div class="round1"></div>
+ <div class="box-inner">
+ <a onclick="cancelBubble=true;" href="/p/net-google-code/source/list">Source</a>
+ </div>
+
+ </div>
+ </th><td>  </td>
+ 
+ 
+ <td width="100%"> </td>
+ </tr>
+</table>
+<table cellspacing="0" cellpadding="0" width="100%" align="center" border="0" class="st">
+ <tr>
+ 
+ 
+ 
+ 
+ 
+ 
+ 
+ 
+ <td>
+ 
+<style type="text/css">
+ .project-summary-page .inProjectSummary a,
+ .project-updates-page .inProjectUpdates a {
+ font-weight: bold;
+ text-decoration: none;
+ color: black;
+ }
+</style>
+
+<div class="project-summary-page">
+ <div class="isf">
+ <span class="inProjectSummary">
+ <a href="/p/net-google-code/">Summary</a>
+ </span> |
+ <span class="inProjectUpdates">
+ <a href="/p/net-google-code/updates/list">Updates</a>
+ </span>
+
+ </div>
+</div>
+
+ </td>
+ 
+ 
+ 
+ <td height="4" align="right" valign="top" class="bevel-right">
+ <div class="round4"></div>
+ <div class="round2"></div>
+ <div class="round1"></div>
+ </td>
+ </tr>
+
+</table>
+<script type="text/javascript">
+ var cancelBubble = false;
+ function _go(url) { document.location = url; }
+</script>
+
+<div id="maincol">
+<!-- IE -->
+
+
+
+<style type="text/css">
+ #downloadbox {
+ padding: 6px;
+ overflow: hidden;
+ white-space: nowrap;
+ text-overflow: ellipsis;
+ }
+ #downloadbox a {
+ margin: 6px 0 0 3em;
+ display: block;
+ padding-left: 18px;
+ background: url(http://www.gstatic.com/codesite/ph/images/dl_arrow.gif) no-repeat bottom left;
+ }
+ #owners a, #members a { white-space: nowrap; }
+</style>
+<div style="float:right; width:25em; margin:0 0 1em 2em">
+ 
+ 
+ 
+ 
+ 
+ <div class="pmeta_bubble_bg">
+ <div class="round4"></div>
+ <div class="round2"></div>
+
+ <div class="round1"></div>
+ <div class="box-inner">
+ <table class="pmeta" cellpadding="5">
+ <tr>
+ <td>
+ <img width="15" height="15"
+ src="http://www.gstatic.com/codesite/ph/images/star_on.gif"
+ style="cursor:pointer" 
+ 
+ onclick="_CS_toggleStar(this, {'scope': 'projects', 'user':
+ '_CURRENT_USER', 'item': 'net-google-code'}, 'star_msg',
+ 'Starred (\x3ca href\x3d\x22/u/xxxx/\x22\x3eview starred projects\x3c/a\x3e)', 'Star this project');"/>
+  
+ <span id="star_msg">
+ 
+ 
+ Starred (<a href="/u/xxxx/">view starred projects</a>)
+ 
+ </span>
+
+ </td>
+ </tr>
+ </table>
+ </div>
+ <div class="round1"></div>
+ <div class="round2"></div>
+ <div class="round4"></div>
+ </div>
+ 
+ 
+ 
+ <div class="pmeta_bubble_bg">
+
+ <div class="round4"></div>
+ <div class="round2"></div>
+ <div class="round1"></div>
+ <div class="box-inner">
+ <table class="pmeta" cellpadding="5">
+ 
+ <tr>
+ <th><span style="white-space:nowrap">Code License:</span></th>
+ <td>
+
+ <a href="http://dev.perl.org/licenses/" rel="nofollow">Artistic License/GPL</a>
+ </td>
+ </tr>
+ 
+ 
+ 
+ <tr><th>Labels:</th>
+ <td>
+ 
+ <a href="/hosting/search?q=label:perl">perl</a>
+ 
+ </td>
+
+ </tr>
+ 
+ </table>
+ </div>
+ <div class="round1"></div>
+ <div class="round2"></div>
+ <div class="round4"></div>
+ </div>
+ 
+ 
+ <div class="pmeta_bubble_bg">
+ <div class="round4"></div>
+
+ <div class="round2"></div>
+ <div class="round1"></div>
+ <div class="box-inner">
+ <table class="pmeta" cellpadding="5">
+ 
+ 
+ <tr><th>Feeds:</th>
+ <td><ul>
+ <li><a href="/p/net-google-code/feeds">Project Feeds</a></li>
+ </ul></td>
+
+ </tr>
+ 
+ </table>
+ </div>
+ <div class="round1"></div>
+ <div class="round2"></div>
+ <div class="round4"></div>
+ </div>
+ <div class="pmeta_bubble_bg">
+ <div class="round4"></div>
+
+ <div class="round2"></div>
+ <div class="round1"></div>
+ <div class="box-inner">
+ 
+ 
+ <table class="pmeta" cellpadding="3" style="padding:3px">
+ 
+ <tr><th colspan="2">Project owners:</th></tr>
+ <tr><td style="width:4em"> </td>
+ <td id="owners">
+ 
+ <a href="/u/sunnavy/">sunnavy</a>
+
+ 
+ </td>
+ </tr>
+ 
+ 
+ 
+ <tr><th colspan="2" style="padding-top:6px">Project members:</th></tr>
+ <tr><td></td>
+ <td id="members">
+ 
+ <a href="/u/jessev/">jessev</a>, 
+ 
+ <a href="/u/fayland/">fayland</a>
+ 
+ </td>
+
+ </tr>
+ 
+ 
+ </table>
+ </div>
+ <div class="round1"></div>
+ <div class="round2"></div>
+ <div class="round4"></div>
+ </div>
+</div>
+ <div id="wikicontent" style="padding:0 3em 1.2em 0">
+
+ <p>Net::Google::Code is a simple client library for projects hosted in Google Code. </p><p>Currently, it focuses on the issue tracker, and the basic read functionality for that is provided. </p>
+ </div>
+<br><br><br><br><br><br><br><br>
+ 
+ <script type="text/javascript" src="http://www.gstatic.com/codesite/ph/3596478537346627501/js/core_scripts_20081103.js"></script>
+ 
+ 
+ 
+ </div>
+<div id="footer" dir="ltr">
+ 
+ <div class="text">
+ 
+ ©2008 Google -
+ <a href="/">Code Home</a> -
+ <a href="/tos.html">Terms of Service</a> -
+ <a href="http://www.google.com/privacy.html">Privacy Policy</a> -
+ <a href="/more/">Site Directory</a>
+
+ 
+ </div>
+</div>
+<script type="text/javascript">
+/**
+ * Reports analytics.
+ * It checks for the analytics functionality (window._gat) every 100ms
+ * until the analytics script is fully loaded in order to invoke siteTracker.
+ */
+function _CS_reportAnalytics() {
+ window.setTimeout(function() {
+ if (window._gat) {
+ var siteTracker = _gat._getTracker("UA-18071-1");
+ siteTracker._initData();
+ siteTracker._trackPageview();
+ 
+ } else {
+ _CS_reportAnalytics();
+ }
+ }, 100);
+}
+</script>
+
+ 
+ 
+
+
+ 
+ </body>
+</html>
+



More information about the Bps-public-commit mailing list