Monthly Archives: 11月 2011

変態Comparatorを書いてユニットテストをしてみた

変態アドベントカレンダーが止まってしまいそうなので支援します。

最近、勤務先の会社で、アルバイト希望の学生に試験を出したりしているのですが、Comparatorが書ける子いないので、(ある意味)模範例のつもりで颯爽と書いてみたいと思います。(いえーい!みんな見てるー?w)

どんなときでも"hentai"または"HENTAI"が先頭に来るコンパレーターです。

import java.util.Comparator;
public class HentaiComparator implements Comparator<String> {
    public int compare(String o1, String o2) {
        if ("hentai".equalsIgnoreCase(o1)) {
            if ("hentai".equalsIgnoreCase(o2)) {
                return o1.compareTo(o2);
            }
            return -1;
        } else if ("hentai".equalsIgnoreCase(o2)) {
            return 1;
        }
        if (o1 == null) {
            if (o2 == null) {
                return 0;
            }
            return 1;
        }
        if (o2 == null) {
            return -1;
        }
        return o1.compareTo(o2);
    };
}

ついでにユニットテストも書いてみましょう。


import static org.hamcrest.CoreMatchers.*; import static org.junit.Assert.*; import java.util.Iterator; import java.util.TreeSet; import org.junit.Test; public class HentaiCompareTest { @Test public void 並び順テスト() { TreeSet<String> hentaiSet = new TreeSet<String>(new HentaiComparator()); hentaiSet.add("susumuis"); hentaiSet.add("hoge"); hentaiSet.add("HENTAI"); hentaiSet.add("fuga"); hentaiSet.add(null); hentaiSet.add("hentai"); Iterator<String> iter = hentaiSet.iterator(); assertThat(iter.hasNext(), is(true)); assertThat(iter.next(), is("HENTAI")); assertThat(iter.hasNext(), is(true)); assertThat(iter.next(), is("hentai")); assertThat(iter.hasNext(), is(true)); assertThat(iter.next(), is("fuga")); assertThat(iter.hasNext(), is(true)); assertThat(iter.next(), is("hoge")); assertThat(iter.hasNext(), is(true)); assertThat(iter.next(), is("susumuis")); assertThat(iter.hasNext(), is(true)); assertThat(iter.next(), nullValue()); assertThat(iter.hasNext(), is(false)); } }

注意:このコードを参考にして弊社の試験を落ちても何の保証もできません。


変態テンプレートでみんなの変態を集めてみた

変態アドベントカレンダー2011に参加しました。他の参加者の方々は、Twitterなどで見かけてはおりますが、リアルでの面識はありません。そんな僕がこの企画に参加した理由は、半年前、出身高校の文化祭に行ったのですが、科学部の理系女子高生がおっさんに向かって「人間は変態しませんよ〜。オタマジャクシは変態しますけどー」と言っていたところ(脈略不明)を目撃してしまいまして、そのことを思い出したからです。ところが、まさかの前日の方にもっと素晴らしい形に同じネタを取られてしまったので、別のネタを考えます。

とは言え、他の方の記事は素晴らしい変態クオリティでなかなか勝てません。技術を突っ込もうとしてはもっとかないません。そこで、こういう時は他力本願全力、みなさんの変態エネルギーを集めて変態パワーを集約するページを作ろうと思います。しかし、僕はWebエンジニアではありますが、デザインスキルがありません。そんな時は、本職の人に頼りましょう。Mayaaテンプレートエンジンを使えば、HTMLの作成をデザイナーさんに丸投げすることができる素晴らしい変態コラボレーションツール*1です。

テンプレート

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
    xmlns:m="http://mayaa.seasar.org" lang="ja">
<head>
   <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
   <meta http-equiv="Content-Script-Type" content="text/javascript" />
   <meta name="nobots" content="noindex,nofollow" />
   <title>変態ブログストーカー</title>
</head>
<body>
<h1>変態ブログストーカー</h1>
<p>あの変態ブロガーさん達は今はどんなブログを書いているのかな?</p>
<div m:id="LOOP_HENTAI_BLOGGER">
    <H2>
        <a href="javascript:void(0);" m:id="HENTAI_LINK_TAG">
            <span m:id="IF_HENTAI_NAME">
                <span m:id="HENTAI_NAME_HERE">変態一号</span> さんのブログ
            </span>「<span m:id="HENTAI_BLOG_NAME_HERE">変態のブログ</span>」
        </a>
    </H2>
    <div m:id="LOOP_HENTAI_ENTRY">
        <span m:id="HENTAI_ENTRY_DATE_HERE">2011-11-19 00:00</span>
        <a href="javascript:void(0);" m:id="HENTAI_ENTRY_LINK_TAG">
            <span m:id="HENTAI_ENTRY_TITLE_HERE">変態エントリ</span>
        </a>
    </div>
    <div m:id="DUMMY">2011-11-18 00:00 <a href="javascript:void(0);">変態エントリ</a></div>
    <div m:id="DUMMY">2011-11-17 00:00 <a href="javascript:void(0);">変態エントリ</a></div>
    <div m:id="DUMMY">2011-11-16 00:00 <a href="javascript:void(0);">変態エントリ</a></div>
</div>
<div m:id="DUMMY">
    <H2><a href="javascript:void(0);">変態二号さんのブログ「変態の通」</a></H2>
    <div>2011-11-18 00:00 <a href="javascript:void(0);">変態エントリ</a></div>
    <div>2011-11-17 00:00 <a href="javascript:void(0);">変態エントリ</a></div>
    <div>2011-11-16 00:00 <a href="javascript:void(0);">変態エントリ</a></div>
</div>
<div m:id="DUMMY">
    <H2><a href="javascript:void(0);">変態三号さんのブログ「変態参上」</a></H2>
    <div>2011-11-18 00:00 <a href="javascript:void(0);">変態エントリ</a></div>
    <div>2011-11-17 00:00 <a href="javascript:void(0);">変態エントリ</a></div>
    <div>2011-11-16 00:00 <a href="javascript:void(0);">変態エントリ</a></div>
</div>
</html>

mayaaファイル

<?xml version="1.0" encoding="UTF-8"?>
<m:mayaa xmlns:m="http://mayaa.seasar.org">
    <m:beforeRender>
    <![CDATA[
      var fetcher = new Packages.org.rometools.fetcher.impl.HttpURLFeedFetcher();
      var hentaiFeeds = [
          "http://d.hatena.ne.jp/backpaper0/rss"     // 11/11の人
          , "http://daiksy.blogspot.com/rss.xml"     // 11/12の人
          , "http://d.hatena.ne.jp/razon/rss"        // 11/13の人
          , "http://d.hatena.ne.jp/tan_go238/rss"    // 11/14の人
          , "http://d.hatena.ne.jp/kuchitama/rss"    // 11/15の人
          , "http://d.hatena.ne.jp/hakurai+java/rss" // 11/16の人
          , "http://feedblog.ameba.jp/rss/ameblo/kozake/rss20.xml" // 11/17の人
          , "http://d.hatena.ne.jp/issan2009/rss"    // 11/18の人
          , "http://d.hatena.ne.jp/winplus/rss"      // 11/19の人
          , "http://d.hatena.ne.jp/s-ishigami/rss"   // 11/20の人
      ];

      function getFeed(url) {
          try {
              return fetcher.retrieveFeed(new java.net.URL(url));
          } catch (e) {
              return null;
          }
      }
    ]]>
    </m:beforeRender>
    <m:null m:id="DUMMY" />
    <m:forEach m:id="LOOP_HENTAI_BLOGGER"
                items="${hentaiFeeds}"
                var="hentaiUrl">
        <m:exec script="${var feed = getFeed(hentaiUrl)}" />
        <m:if test="${feed != null}">
            <m:echo><m:doBody /></m:echo>
        </m:if>
    </m:forEach>
    <m:if m:id="IF_HENTAI_NAME" test="${feed.getAuthor() != null}">
        <m:echo><m:doBody /></m:echo>
    </m:if>
    <m:write m:id="HENTAI_NAME_HERE" value="${feed.getAuthor()}" />
    <m:write m:id="HENTAI_BLOG_NAME_HERE" value="${feed.getTitle()}" />
    <m:echo m:id="HENTAI_LINK_TAG">
        <m:attribute name="href" value="${feed.getUri()}" />
    </m:echo>
    <m:forEach m:id="LOOP_HENTAI_ENTRY"
                items="${feed.getEntries()}"
                var="entry">
        <m:echo><m:doBody /></m:echo>
    </m:forEach>
    <m:formatDate m:id="HENTAI_ENTRY_DATE_HERE" value="${entry.getPublishedDate()}" format="yyyy/MM/dd hh:mm" />
    <m:write m:id="HENTAI_ENTRY_TITLE_HERE" value="${entry.getTitle()}" />
    <m:echo m:id="HENTAI_ENTRY_LINK_TAG">
        <m:attribute name="href" value="${entry.getUri()}" />
    </m:echo>
</m:mayaa>

RSS解析にRomeを使用しました。これ、本家からダウンロード不能だったので、Mavenレポジトリから落としたのですが良いんですかね?

実行する

Google App Engineにデプロイしました。
こちらです → http://hentai-2011-susumuis.appspot.com/

これで僕も明日から「デザイナーとプログラマーのコラボレーション!」などという事はおぞましくて言えない、変態の仲間入りをしました。どうぞ変態仲間に入れてくだしあ。

*1:明日会社に行けなくなるかもしれない。