require File.expand_path(File.dirname(__FILE__) + '/spec_helper') describe "Rack::Gist" do before(:all) do @gist_id = 348301 @app = lambda do |env| headers = { 'Content-Type' => 'text/html' } body = File.read(File.join(File.dirname(__FILE__), "body-#{env['PATH_INFO'].gsub(/[^\w]/, '')}.html")) [200, headers, body] end end def mock_env(path = '/full') Rack::MockRequest.env_for(path) end def middleware(options = {}) Rack::Gist.new(@app, options) end it 'should pass Rack::Lint' do status, headers, body = Rack::Lint.new(middleware).call(mock_env) status, headers, body = Rack::Lint.new(middleware).call(mock_env('/multiple')) status, headers, body = Rack::Lint.new(middleware).call(mock_env("/gist.github.com/#{@gist_id}/example.pig.js")) end it 'should rewrite gist embed tags for full gists' do middleware.tap do |a| status, headers, body = a.call(mock_env) status.should == 200 headers['Content-Type'].should == 'text/html' body.to_s.should have_html_tag('div').with('id' => "rack-gist-#{@gist_id}", 'gist-id' => @gist_id, 'class' => 'rack-gist') end end it 'should rewrite gist embed tags for partial gists' do middleware.tap do |a| status, headers, body = a.call(mock_env('/partial')) status.should == 200 headers['Content-Type'].should == 'text/html' body.to_s.should have_html_tag('div').with('id' => "rack-gist-#{@gist_id}", 'gist-id' => @gist_id, 'class' => 'rack-gist', 'rack-gist-file' => 'example.pig') end end it 'should not include the github css file if no gists are present' do middleware.tap do |a| status, headers, body = a.call(mock_env('/none')) status.should == 200 headers['Content-Type'].should == 'text/html' body.to_s.should_not have_html_tag('link').with('rel' => 'stylesheet', 'href' => 'http://gist.github.com/stylesheets/gist/embed.css') end end it 'should include the github css file once' do middleware.tap do |a| status, headers, body = a.call(mock_env('/multiple')) status.should == 200 headers['Content-Type'].should == 'text/html' body.to_s.should have_html_tag('link').with('rel' => 'stylesheet', 'href' => 'http://gist.github.com/stylesheets/gist/embed.css') end end it 'should include jquery by default' do middleware.tap do |a| status, headers, body = a.call(mock_env) status.should == 200 headers['Content-Type'].should == 'text/html' body.to_s.should have_html_tag('script[@src*="jquery"]') end end it 'should not include jquery if the option is passed to disable it' do middleware(:jquery => false).tap do |a| status, headers, body = a.call(mock_env) status.should == 200 headers['Content-Type'].should == 'text/html' body.to_s.should_not have_html_tag('script[@src*="jquery"]') end end it 'should include required jquery helper' do middleware(:jquery => false).tap do |a| status, headers, body = a.call(mock_env) status.should == 200 headers['Content-Type'].should == 'text/html' body.to_s.should have_html_tag('script').containing('CDATA') end end it "shouldn't include the jquery helper if no gist is present" do middleware.tap do |a| status, headers, body = a.call(mock_env) status.should == 200 headers['Content-Type'].should == 'text/html' body.to_s.should_not have_html_tag('script') end end it 'should update Content-Length' do middleware.tap do |a| status, headers, body = a.call(mock_env) status.should == 200 headers['Content-Type'].should == 'text/html' headers['Content-Length'].should == '913' end end it 'should proxy/serve single gists' do middleware.tap do |a| status, headers, body = a.call(mock_env("/gist.github.com/#{@gist_id}/example.pig.js")) status.should == 200 headers['Content-Type'].should == 'application/javascript' body.to_s.should == %q{$('#rack-gist-%s[rack-gist-file="example.pig"]').replaceWith('
\n \n \n \n \n\n
\n
\n \n \n \n
REGISTER com.darkhax.blog.pig.jar;<\/div>
DEFINE Parser com.darkhax.blog.pig.LogParser();<\/div>

<\/div>
logs = LOAD \'apache.log.bz2\' USING TextLoader AS (line: chararray);<\/div>
log_events = FOREACH logs GENERATE FLATTEN(Parser(line));<\/div>

<\/div>
by_action = GROUP log_events BY action;<\/div>
counts = FOREACH by_action GENERATE group, COUNT(log_events);<\/div>
STORE counts INTO \'count_summary\';<\/div><\/pre><\/div>\n \n <\/div>\n\n
\n view raw<\/a>\n example.pig<\/a>\n This Gist<\/a> brought to you by GitHub<\/a>.\n <\/div>\n <\/div>\n \n \n \n<\/div>\n')} % @gist_id end end it 'should proxy/server multiple gists' do middleware.tap do |a| status, headers, body = a.call(mock_env("/gist.github.com/#{@gist_id}.js")) status.should == 200 headers['Content-Type'].should == 'application/javascript' body.to_s.should == %q{$('#rack-gist-%s').replaceWith('
\n \n \n \n \n\n
\n
\n \n \n \n
REGISTER com.darkhax.blog.pig.jar;<\/div>
DEFINE Parser com.darkhax.blog.pig.LogParser();<\/div>

<\/div>
logs = LOAD \'apache.log.bz2\' USING TextLoader AS (line: chararray);<\/div>
log_events = FOREACH logs GENERATE FLATTEN(Parser(line));<\/div>

<\/div>
by_action = GROUP log_events BY action;<\/div>
counts = FOREACH by_action GENERATE group, COUNT(log_events);<\/div>
STORE counts INTO \'count_summary\';<\/div><\/pre><\/div>\n \n <\/div>\n\n
\n view raw<\/a>\n example.pig<\/a>\n This Gist<\/a> brought to you by GitHub<\/a>.\n <\/div>\n <\/div>\n \n \n\n
\n
\n \n \n \n
package<\/span> com<\/span>.<\/span>codebaby<\/span>.<\/span>monitor<\/span>.<\/span>pig<\/span>;<\/span><\/div>

<\/div>
import<\/span> java.io.IOException<\/span>;<\/span><\/div>

<\/div>
import<\/span> org.apache.pig.EvalFunc<\/span>;<\/span><\/div>
import<\/span> org.apache.pig.data.DataType<\/span>;<\/span><\/div>
import<\/span> org.apache.pig.data.Tuple<\/span>;<\/span><\/div>
import<\/span> org.apache.pig.data.TupleFactory<\/span>;<\/span><\/div>
import<\/span> org.apache.pig.impl.logicalLayer.schema.Schema<\/span>;<\/span><\/div>

<\/div>
// Inherit from EvalFunc<Tuple> to implement a EvalFunc that returns a Tuple<\/span><\/div>
public<\/span> class<\/span> LogParser<\/span> extends<\/span> EvalFunc<\/span><<\/span>Tuple<\/span>><\/span> {<\/span><\/div>

<\/div>
    // The main method in question. Gets run for every 'thing' that gets sent to<\/span><\/div>
    // this UDF<\/span><\/div>
    public<\/span> Tuple<\/span> exec<\/span>(<\/span>Tuple<\/span> input<\/span>)<\/span> throws<\/span> IOException<\/span> {<\/span><\/div>
        if<\/span> (<\/span>null<\/span> ==<\/span> input<\/span> ||<\/span> input<\/span>.<\/span>size<\/span>()<\/span> !=<\/span> 1<\/span>)<\/span> {<\/span><\/div>
            return<\/span> null<\/span>;<\/span><\/div>
        }<\/span><\/div>
        <\/div>
        String<\/span> line<\/span> =<\/span> (<\/span>String<\/span>)<\/span> input<\/span>.<\/span>get<\/span>(<\/span>0<\/span>);<\/span><\/div>
        try<\/span> {<\/span><\/div>
            // In Soviet Russia, factory builds you!<\/span><\/div>
            TupleFactory<\/span> tf<\/span> =<\/span> TupleFactory<\/span>.<\/span>getInstance<\/span>();<\/span><\/div>
            Tuple<\/span> t<\/span> =<\/span> tf<\/span>.<\/span>newTuple<\/span>();<\/span><\/div>

<\/div>
            t<\/span>.<\/span>append<\/span>(<\/span>getHttpMethod<\/span>());<\/span><\/div>
            t<\/span>.<\/span>append<\/span>(<\/span>getIP<\/span>());<\/span><\/div>
            t<\/span>.<\/span>append<\/span>(<\/span>getDate<\/span>());<\/span><\/div>

<\/div>
            // The tuple we are returning now has 3 elements, all strings.<\/span><\/div>
            // In order, they are the HTTP method, the IP address, and the date.<\/span><\/div>

<\/div>
            return<\/span> t<\/span>;<\/span><\/div>
        }<\/span> catch<\/span> (<\/span>Exception<\/span> e<\/span>)<\/span> {<\/span><\/div>
            // Any problems? Just return null and this one doesn't get<\/span><\/div>
            // 'generated' by pig<\/span><\/div>
            return<\/span> null<\/span>;<\/span><\/div>
        }<\/span><\/div>
    }<\/span><\/div>

<\/div>
    public<\/span> Schema<\/span> outputSchema<\/span>(<\/span>Schema<\/span> input<\/span>)<\/span> {<\/span><\/div>
        try<\/span> {<\/span><\/div>
            Schema<\/span> s<\/span> =<\/span> new<\/span> Schema<\/span>();<\/span><\/div>

<\/div>
            s<\/span>.<\/span>add<\/span>(<\/span>new<\/span> Schema<\/span>.<\/span>FieldSchema<\/span>(<\/span>\"action\"<\/span>,<\/span> DataType<\/span>.<\/span>CHARARRAY<\/span>));<\/span><\/div>
            s<\/span>.<\/span>add<\/span>(<\/span>new<\/span> Schema<\/span>.<\/span>FieldSchema<\/span>(<\/span>\"ip\"<\/span>,<\/span> DataType<\/span>.<\/span>CHARARRAY<\/span>));<\/span><\/div>
            s<\/span>.<\/span>add<\/span>(<\/span>new<\/span> Schema<\/span>.<\/span>FieldSchema<\/span>(<\/span>\"date\"<\/span>,<\/span> DataType<\/span>.<\/span>CHARARRAY<\/span>));<\/span><\/div>

<\/div>
            return<\/span> s<\/span>;<\/span><\/div>
        }<\/span> catch<\/span> (<\/span>Exception<\/span> e<\/span>)<\/span> {<\/span><\/div>
            // Any problems? Just return null...there probably won't be any<\/span><\/div>
            // problems though.<\/span><\/div>
            return<\/span> null<\/span>;<\/span><\/div>
        }<\/span><\/div>
    }<\/span><\/div>

<\/div>
    public<\/span> String<\/span> getHttpMethod<\/span>()<\/span> {<\/span><\/div>