Skip to content

Commit

Permalink
Only add /version/ to URLs accessed with /version/
Browse files Browse the repository at this point in the history
Adds request.version_supplied to detect whether the version was parsed out
of the URL. Rewrote some of the URL helpers and serializers to respect this
new behaviour.

The biggest change is that the DocServerSerializer will no longer add the
/prefix to the serialized_path, and it will now ignore the command passed
in to the constructor (which is now optional). Instead,
DocServerHelper#url_for should be used to generate a URL with a prefix.

Closes #426
  • Loading branch information
lsegal committed Dec 11, 2011
1 parent 0f1003d commit 5c10c7b
Show file tree
Hide file tree
Showing 11 changed files with 88 additions and 40 deletions.
2 changes: 1 addition & 1 deletion lib/yard/server/commands/library_command.rb
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ class LibraryCommand < Base

def initialize(opts = {})
super
self.serializer = DocServerSerializer.new(self)
self.serializer = DocServerSerializer.new
end

def call(request)
Expand Down
6 changes: 3 additions & 3 deletions lib/yard/server/doc_server_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,8 @@ module DocServerHelper
def url_for(obj, anchor = nil, relative = false)
return '' if obj.nil?
return "/#{obj}" if String === obj
super(obj, anchor, false)
File.join('', base_path(router.docs_prefix), super(obj, anchor, false))
end

# Modifies {Templates::Helpers::HtmlHelper#url_for_file} to return a URL instead
# of a disk location.
# @param (see Templates::Helpers::HtmlHelper#url_for_file)
Expand All @@ -30,7 +29,8 @@ def url_for_file(filename, anchor = nil)
# @param [String] path the path prefix for a base path URI
# @return [String] the base URI for a library with an extra +path+ prefix
def base_path(path)
path + (@single_library ? '' : "/#{@library}")
libname = router.request.version_supplied ? @library.to_s : @library.name
path + (@single_library ? '' : "/#{libname}")
end

# @return [Router] convenience method for accessing the router
Expand Down
18 changes: 9 additions & 9 deletions lib/yard/server/doc_server_serializer.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,24 +7,24 @@ module Server
class DocServerSerializer < Serializers::FileSystemSerializer
include WEBrick::HTTPUtils

def initialize(command)
super(:command => command, :extension => '')
def initialize(command = nil)
super(:basepath => '', :extension => '')
end

def serialized_path(object)
path = case object
case object
when CodeObjects::RootObject
"toplevel"
when CodeObjects::MethodObject
return escape_path(serialized_path(object.namespace) + (object.scope == :instance ? ":" : ".") + object.name.to_s)
serialized_path(object.namespace) +
(object.scope == :instance ? ":" : ".") + escape(object.name.to_s)
when CodeObjects::ConstantObject, CodeObjects::ClassVariableObject
return escape_path(serialized_path(object.namespace)) + "##{object.name}-#{object.type}"
serialized_path(object.namespace) + "##{object.name}-#{object.type}"
when CodeObjects::ExtraFileObject
super(object).gsub(/^file./, 'file/')
else
object.path.gsub('::', '/')
super(object)
end
command = options[:command]
library_path = command.single_library ? '' : '/' + command.library.to_s
return escape_path(File.join('', command.adapter.router.docs_prefix, library_path, path))
end
end
end
Expand Down
1 change: 1 addition & 0 deletions lib/yard/server/rack_adapter.rb
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ def print_start_message(server)

# @private
class Rack::Request
attr_accessor :version_supplied
alias query params
def xhr?; (env['HTTP_X_REQUESTED_WITH'] || "").downcase == "xmlhttprequest" end
end
2 changes: 2 additions & 0 deletions lib/yard/server/router.rb
Original file line number Diff line number Diff line change
Expand Up @@ -80,8 +80,10 @@ def parse_library_from_path(paths)
if libs = adapter.libraries[paths.first]
paths.shift
if library = libs.find {|l| l.version == paths.first }
request.version_supplied = true if request
paths.shift
else # use the last lib in the list
request.version_supplied = false if request
library = libs.last
end
end
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
<li class="r<%= @row = @row == 1 ? 2 : 1 %>">
<% library_versions = library_versions.dup %>
<% first_lib = library_versions.pop %>
<a href="/<%= router.docs_prefix %>/<%= first_lib %>/frames"><%= name %></a>
<a href="/<%= router.docs_prefix %>/<%= first_lib.name %>/frames"><%= name %></a>
<% if first_lib.version %>
<small>(<%= first_lib.version %><% if library_versions.size > 0 %>,
<%= library_versions.reverse.map {|lib| "<a href=\"/#{router.docs_prefix}/#{lib}/frames\">#{lib.version}</a>" }.join(', ') %><% end %>)</small>
Expand Down
3 changes: 1 addition & 2 deletions lib/yard/server/templates/doc_server/search/html/search.erb
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,7 @@
<% name = result.type == :method ? result.name(true).to_s : result.name.to_s %>
<% path = name.gsub(/(#{Regexp.quote @query})/i, '<strong>\1</strong>') %>
<li class="r<%= n %>">
<a href="<%= serializer.serialized_path(result) %>"
title="<%= result.path %>"><%= path %></a>
<a href="<%= url_for(result) %>" title="<%= result.path %>"><%= path %></a>
<% if !result.namespace.root? %>
<small>(<%= result.namespace.path %>)</small>
<% end %>
Expand Down
1 change: 1 addition & 0 deletions lib/yard/server/webrick_adapter.rb
Original file line number Diff line number Diff line change
Expand Up @@ -38,5 +38,6 @@ def do_GET(request, response)

# @private
class WEBrick::HTTPRequest
attr_accessor :version_supplied
def xhr?; (self['X-Requested-With'] || "").downcase == 'xmlhttprequest' end
end
51 changes: 51 additions & 0 deletions spec/server/doc_server_helper_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
require File.dirname(__FILE__) + "/spec_helper"

class MyDocServerSerializerRouter
attr_accessor :request
def docs_prefix; 'PREFIX' end
def initialize; @request = mock_request end
end

class MockDocServerHelper
include YARD::Templates::Helpers::BaseHelper
include YARD::Templates::Helpers::HtmlHelper
include YARD::Server::DocServerHelper

attr_accessor :adapter
attr_accessor :single_library
attr_accessor :library

def initialize
@single_library = false
@library = LibraryVersion.new('foo')
@adapter = mock_adapter(:router => MyDocServerSerializerRouter.new)
@serializer = YARD::Server::DocServerSerializer.new
@object = YARD::Registry.root
end
end

describe YARD::Server::DocServerHelper do
before do
@helper = MockDocServerHelper.new
end

describe '#url_for' do
it "should not link to /library/ if single_library = true" do
@helper.single_library = true
@helper.url_for(Registry.root).should == "/PREFIX/toplevel"
end

it "should return /PREFIX/foo/version if foo has a version" do
@helper.library = LibraryVersion.new('foo', 'bar')
@helper.adapter.router.request.version_supplied = true
@helper.url_for(P('A')).should == '/PREFIX/foo/bar/A'
end
end

describe '#url_for_file' do
it "should properly link file objects using file/ prefix" do
file = CodeObjects::ExtraFileObject.new('a/b/FooBar.md', '')
@helper.url_for_file(file).should == '/PREFIX/foo/file/a/b/FooBar.md'
end
end
end
33 changes: 10 additions & 23 deletions spec/server/doc_server_serializer_spec.rb
Original file line number Diff line number Diff line change
@@ -1,58 +1,45 @@
require File.dirname(__FILE__) + '/spec_helper'

class MyDocServerSerializerRouter
def docs_prefix; 'PREFIX' end
end

describe YARD::Server::DocServerSerializer do
describe '#serialized_path' do
before do
Registry.clear
@command = mock(:command)
@command.stub!(:single_library).and_return(false)
@command.stub!(:library).and_return(LibraryVersion.new('foo'))
@command.stub!(:adapter).and_return(mock_adapter(:router => MyDocServerSerializerRouter.new))
@serializer = Server::DocServerSerializer.new(@command)
@serializer = Server::DocServerSerializer.new
end

after(:all) { Server::Adapter.shutdown }

it "should return '/PREFIX/library/toplevel' for root" do
@serializer.serialized_path(Registry.root).should == "/PREFIX/foo/toplevel"
@serializer.serialized_path(Registry.root).should == "toplevel"
end

it "should return /PREFIX/library/Object for Object in a library" do
@serializer.serialized_path(P('A::B::C')).should == '/PREFIX/foo/A/B/C'
@serializer.serialized_path(P('A::B::C')).should == 'A/B/C'
end

it "should link to instance method as Class:method" do
obj = CodeObjects::MethodObject.new(:root, :method)
@serializer.serialized_path(obj).should == '/PREFIX/foo/toplevel:method'
@serializer.serialized_path(obj).should == 'toplevel:method'
end

it "should link to class method as Class.method" do
obj = CodeObjects::MethodObject.new(:root, :method, :class)
@serializer.serialized_path(obj).should == '/PREFIX/foo/toplevel.method'
@serializer.serialized_path(obj).should == 'toplevel.method'
end

it "should link to anchor for constant" do
obj = CodeObjects::ConstantObject.new(:root, :FOO)
@serializer.serialized_path(obj).should == '/PREFIX/foo/toplevel#FOO-constant'
@serializer.serialized_path(obj).should == 'toplevel#FOO-constant'
end

it "should link to anchor for class variable" do
obj = CodeObjects::ClassVariableObject.new(:root, :@@foo)
@serializer.serialized_path(obj).should == '/PREFIX/foo/toplevel#@@foo-classvariable'
end

it "should not link to /library/ if single_library = true" do
@command.stub!(:single_library).and_return(true)
@serializer.serialized_path(Registry.root).should == "/PREFIX/toplevel"
@serializer.serialized_path(obj).should == 'toplevel#@@foo-classvariable'
end

it "should return /PREFIX/foo/version if foo has a version" do
@command.stub!(:library).and_return(LibraryVersion.new('foo', 'bar'))
@serializer.serialized_path(P('A')).should == '/PREFIX/foo/bar/A'
it "should link files using file/ prefix" do
file = CodeObjects::ExtraFileObject.new('a/b/FooBar.md', '')
@serializer.serialized_path(file).should == 'file/FooBar'
end
end
end
9 changes: 8 additions & 1 deletion spec/server/router_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,23 +12,30 @@ def check_static_cache; nil end
before do
@adapter = mock_adapter
@projects = @adapter.libraries['project']
@request = mock_request
end

describe '#parse_library_from_path' do
def parse(*args)
MyRouterSpecRouter.new(@adapter).parse_library_from_path(args.flatten)
@request.path = '/' + args.join('/')
@router = MyRouterSpecRouter.new(@adapter)
@router.request = @request
@router.parse_library_from_path(args.flatten)
end

it "should parse library and version name out of path" do
parse('project', '1.0.0').should == [@projects[0], []]
@request.version_supplied.should be_true
end

it "should parse library and use latest version if version is not supplied" do
parse('project').should == [@projects[1], []]
@request.version_supplied.should be_false
end

it "should parse library and use latest version if next component is not a version" do
parse('project', 'notaversion').should == [@projects[1], ['notaversion']]
@request.version_supplied.should be_false
end

it "should return nil library if no library is found" do
Expand Down

0 comments on commit 5c10c7b

Please sign in to comment.