diff --git a/HISTORY.md b/HISTORY.md index e2620f58..6938de58 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -5,6 +5,8 @@ how `Sanitize.clean` modifies formatted wiki content. * Add `--config` option for the command line, to specify a ruby file that is run during startup. + * Provide access to a parsed Nokogiri::DocumentFragment during markup + rendering for added customization. * Bug Fixes * Use `@wiki.page_class` in Gollum::Markup where appropriate (#63). diff --git a/gollum.gemspec b/gollum.gemspec index e2586d7e..00666d58 100644 --- a/gollum.gemspec +++ b/gollum.gemspec @@ -460,6 +460,7 @@ Gem::Specification.new do |s| lib/gollum/frontend/views/layout.rb lib/gollum/frontend/views/page.rb lib/gollum/frontend/views/search.rb + lib/gollum/git_access.rb lib/gollum/markup.rb lib/gollum/page.rb lib/gollum/pagination.rb @@ -504,6 +505,7 @@ Gem::Specification.new do |s| test/examples/lotr.git/refs/heads/master test/helper.rb test/test_file.rb + test/test_git_access.rb test/test_markup.rb test/test_page.rb test/test_wiki.rb diff --git a/lib/gollum.rb b/lib/gollum.rb index 78b0010a..6970d0be 100644 --- a/lib/gollum.rb +++ b/lib/gollum.rb @@ -11,6 +11,7 @@ require 'sanitize' require 'gollum/ruby1.8' # internal +require 'gollum/git_access' require 'gollum/pagination' require 'gollum/blob_entry' require 'gollum/wiki' diff --git a/lib/gollum/blob_entry.rb b/lib/gollum/blob_entry.rb index b224fc4a..cbadc01c 100644 --- a/lib/gollum/blob_entry.rb +++ b/lib/gollum/blob_entry.rb @@ -3,21 +3,25 @@ module Gollum # Gets the String SHA for this blob. attr_reader :sha - # Gets the String full path for this blob. + # Gets the full path String for this blob. attr_reader :path - def initialize(sha, path) + # Gets the Fixnum size of this blob. + attr_reader :size + + def initialize(sha, path, size = nil) @sha = sha @path = path - @dir = @name = @blob = nil + @size = size + @dir = @name = @blob = nil end - # Gets the normalized directory path for this blob. + # Gets the normalized directory path String for this blob. def dir @dir ||= self.class.normalize_dir(::File.dirname(@path)) end - # Gets the String file base name for this blob. + # Gets the file base name String for this blob. def name @name ||= ::File.basename(@path) end @@ -28,7 +32,8 @@ module Gollum # # Returns an unbaked Grit::Blob instance. def blob(repo) - @blob ||= Grit::Blob.create(repo, :id => @sha, :name => @name) + @blob ||= Grit::Blob.create(repo, + :id => @sha, :name => name, :size => @size) end # Gets a Page instance for this blob. diff --git a/lib/gollum/file.rb b/lib/gollum/file.rb index 8e7c33d3..acea37a6 100644 --- a/lib/gollum/file.rb +++ b/lib/gollum/file.rb @@ -53,11 +53,10 @@ module Gollum def find(name, version) checked = name.downcase map = @wiki.tree_map_for(version) - sha = @wiki.ref_map[version] || version if entry = map.detect { |entry| entry.path.downcase == checked } @path = name - @blob = Grit::Blob.create(@wiki.repo, :id => entry.sha, :name => entry.name) - @version = Grit::Commit.create(@wiki.repo, :id => sha) + @blob = entry.blob(@wiki.repo) + @version = version.is_a?(Grit::Commit) ? version : @wiki.commit_for(version) self end end diff --git a/lib/gollum/git_access.rb b/lib/gollum/git_access.rb new file mode 100644 index 00000000..9306c893 --- /dev/null +++ b/lib/gollum/git_access.rb @@ -0,0 +1,275 @@ +module Gollum + # Controls all access to the Git objects from Gollum. Extend this class to + # add custom caching for special cases. + class GitAccess + def initialize(path) + @path = path + @repo = Grit::Repo.new(path) + clear + end + + # Public: Determines whether the Git repository exists on disk. + # + # Returns true if it exists, or false. + def exist? + @repo.git.exist? + end + + # Public: Converts a given Git reference to a SHA, using the cache if + # available. + # + # ref - a String Git reference (ex: "master") + # + # Returns a String. + def ref_to_sha(ref) + if sha?(ref) + ref + else + get_cache(:ref, ref) { ref_to_sha!(ref) } + end + end + + # Public: Gets a recursive list of Git blobs for the whole tree at the + # given commit. + # + # ref - A String Git reference or Git SHA to a commit. + # + # Returns an Array of BlobEntry instances. + def tree(ref) + if sha = ref_to_sha(ref) + get_cache(:tree, sha) { tree!(sha) } + else + [] + end + end + + # Public: Fetches the contents of the Git blob at the given SHA. + # + # sha - A String Git SHA. + # + # Returns the String content of the blob. + def blob(sha) + cat_file!(sha) + end + + # Public: Looks up the Git commit using the given Git SHA or ref. + # + # ref - A String Git SHA or ref. + # + # Returns a Grit::Commit. + def commit(ref) + if sha?(ref) + get_cache(:commit, ref) { commit!(ref) } + else + if sha = get_cache(:ref, ref) + commit(sha) + else + if cm = commit!(ref) + set_cache(:ref, ref, cm.id) + set_cache(:commit, cm.id, cm) + end + end + end + end + + # Public: Gets a list of Git commits. + # + # *shas - An Array of String SHAs. + # + # Returns an Array of Grit::Commit instances. + def commits(*shas) + shas.flatten! + cached_commits = multi_get(:commit, shas) + missing_shas = shas.select do |sha| + !cached_commits.key?(sha) + end + + multi_commit!(missing_shas, cached_commits) if !missing_shas.empty? + + shas.map { |sha| cached_commits[sha] } + end + + # Public: Clears all of the cached data that this GitAccess is tracking. + # + # Returns nothing. + def clear + @ref_map = {} + @tree_map = {} + @commit_map = {} + end + + # Public: Refreshes just the cached Git reference data. This should + # be called after every Gollum update. + # + # Returns nothing. + def refresh + @ref_map.clear + end + + ######################################################################### + # + # Internal Methods + # + ######################################################################### + + # Gets the String path to the Git repository. + attr_reader :path + + # Gets the Grit::Repo instance for the Git repository. + attr_reader :repo + + # Gets a Hash cache of refs to commit SHAs. + # + # {"master" => "abc123", ...} + # + attr_reader :ref_map + + # Gets a Hash cache of commit SHAs to a recursive tree of blobs. + # + # {"abc123" => [, ]} + # + attr_reader :tree_map + + # Gets a Hash cache of commit SHAs to the Grit::Commit instance. + # + # {"abcd123" => } + # + attr_reader :commit_map + + # Raw method for fetching a list of Git commits. + # + # shas - An Array of String SHAs. + # hash - Optional Hash to store the found commits, indexed by their SHA. + # + # Returns the same Hash instance. + def multi_commit!(shas, hash = {}) + shas.each_slice(500) do |slice| + @repo.batch(slice).each do |commit| + hash[commit.id] = commit + end + end + hash + end + + # Checks to see if the given String is a 40 character hex SHA. + # + # str - Possible String SHA. + # + # Returns true if the String is a SHA, or false. + def sha?(str) + !!(str =~ /^[0-9a-f]{40}$/) + end + + # Looks up the Git SHA for the given Git ref. + # + # ref - String Git ref. + # + # Returns a String SHA. + def ref_to_sha!(ref) + @repo.git.rev_list({:max_count=>1}, ref) + rescue Grit::GitRuby::Repository::NoSuchShaFound + end + + # Looks up the Git blobs for a given commit. + # + # sha - String commit SHA. + # + # Returns an Array of BlobEntry instances. + def tree!(sha) + tree = @repo.git.native(:ls_tree, + {:r => true, :l => true, :z => true}, sha) + tree.split("\0").inject([]) do |items, line| + items << parse_tree_line(line) + end + end + + # Reads the content from the Git db at the given SHA. + # + # sha - The String SHA. + # + # Returns the String content of the Git object. + def cat_file!(sha) + @repo.git.cat_file({:p => true}, sha) + end + + # Reads a Git commit. + # + # sha - The string SHA of the Git commit. + # + # Returns a Grit::Commit. + def commit!(sha) + @repo.commit(sha) + end + + # Attempts to get the given data from a cache. If it doesn't exist, it'll + # pass the results of the yielded block to the cache for future accesses. + # + # name - The cache prefix used in building the full cache key. + # key - The unique cache key suffix, usually a String Git SHA. + # + # Yields a block to pass to the cache. + # Returns the cached result. + def get_cache(name, key) + cache = instance_variable_get("@#{name}_map") + value = cache[key] + if value.nil? && block_given? + set_cache(name, key, value = yield) + end + value == :_nil ? nil : value + end + + # Writes some data to the internal cache. + # + # name - The cache prefix used in building the full cache key. + # key - The unique cache key suffix, usually a String Git SHA. + # value - The value to write to the cache. + # + # Returns nothing. + def set_cache(name, key, value) + cache = instance_variable_get("@#{name}_map") + cache[key] = value || :_nil + end + + # Gets multiple values from the cache in a single call. + # + # name - The cache prefix used in building the full cache key. + # keys - Array of cache key names to fetch. + # + # Returns a Hash of the objects that were found in the cache, indexed by + # the cache key. + def multi_get(name, keys) + value = instance_variable_get("@#{name}_map") + keys.inject({}) do |memo, key| + if v = value[key] + memo[key] = v + end + memo + end + end + + # Parses a line of output from the `ls-tree` command. + # + # line - A String line of output: + # "100644 blob 839c2291b30495b9a882c17d08254d3c90d8fb53 Home.md" + # + # Returns an Array of BlobEntry instances. + def parse_tree_line(line) + mode, type, sha, size, *name = line.split(/\s+/) + BlobEntry.new(sha, name.to_s, size.to_i) + end + + # Decode octal sequences (\NNN) in tree path names. + # + # path - String path name. + # + # Returns a decoded String. + def decode_git_path(path) + if path[0] == ?" && path[-1] == ?" + path = path[1...-1] + path.gsub!(/\\\d{3}/) { |m| m[1..-1].to_i(8).chr } + end + path.gsub!(/\\[rn"\\]/) { |m| eval(%("#{m.to_s}")) } + path + end + end +end \ No newline at end of file diff --git a/lib/gollum/markup.rb b/lib/gollum/markup.rb index 4c72c3b9..e63e96b1 100644 --- a/lib/gollum/markup.rb +++ b/lib/gollum/markup.rb @@ -27,9 +27,9 @@ module Gollum # # Returns the formatted String content. def render(no_follow = false) - sanitize_options = no_follow ? - @wiki.history_sanitization : - @wiki.sanitization + sanitize = no_follow ? + @wiki.history_sanitizer : + @wiki.sanitizer data = extract_tex(@data) data = extract_code(data) @@ -44,12 +44,21 @@ module Gollum end data = process_tags(data) data = process_code(data) - data = Sanitize.clean(data, sanitize_options.to_hash) if sanitize_options + if sanitize || block_given? + doc = Nokogiri::HTML::DocumentFragment.parse(data) + doc = sanitize.clean_node!(doc) if sanitize + yield doc if block_given? + data = doc_to_html(doc) + end data = process_tex(data) data.gsub!(/

<\/p>/, '') data end + def doc_to_html(doc) + doc.to_xhtml(:save_with => Nokogiri::XML::Node::SaveOptions::AS_XHTML) + end + ######################################################################### # # TeX @@ -349,8 +358,11 @@ module Gollum # Returns the placeholder'd String data. def extract_code(data) data.gsub(/^``` ?(.+?)\r?\n(.+?)\r?\n```\r?$/m) do - id = Digest::SHA1.hexdigest($2) - @codemap[id] = { :lang => $1, :code => $2 } + id = Digest::SHA1.hexdigest($2) + cached = check_cache(:code, id) + @codemap[id] = cached ? + { :output => cached } : + { :lang => $1, :code => $2 } id end end @@ -363,14 +375,38 @@ module Gollum # Returns the marked up String data. def process_code(data) @codemap.each do |id, spec| - lang = spec[:lang] - code = spec[:code] - if code.lines.all? { |line| line =~ /\A\r?\n\Z/ || line =~ /^( |\t)/ } - code.gsub!(/^( |\t)/m, '') + formatted = spec[:output] || begin + lang = spec[:lang] + code = spec[:code] + if code.lines.all? { |line| line =~ /\A\r?\n\Z/ || line =~ /^( |\t)/ } + code.gsub!(/^( |\t)/m, '') + end + formatted = Gollum::Albino.new(code, lang).colorize + update_cache(:code, id, formatted) + formatted end - data.gsub!(id, Gollum::Albino.new(code, lang).colorize) + data.gsub!(id, formatted) end data end + + # Hook for getting the formatted value of extracted tag data. + # + # type - Symbol value identifying what type of data is being extracted. + # id - String SHA1 hash of original extracted tag data. + # + # Returns the String cached formatted data, or nil. + def check_cache(type, id) + end + + # Hook for caching the formatted value of extracted tag data. + # + # type - Symbol value identifying what type of data is being extracted. + # id - String SHA1 hash of original extracted tag data. + # data - The String formatted value to be cached. + # + # Returns nothing. + def update_cache(type, id, data) + end end end diff --git a/lib/gollum/page.rb b/lib/gollum/page.rb index 6e2e66d7..5ec7cfb5 100644 --- a/lib/gollum/page.rb +++ b/lib/gollum/page.rb @@ -132,8 +132,8 @@ module Gollum # Public: The formatted contents of the page. # # Returns the String data. - def formatted_data - @blob && Gollum::Markup.new(self).render(historical?) + def formatted_data(&block) + @blob && @wiki.markup_class.new(self).render(historical?, &block) end # Public: The format of the page. @@ -196,19 +196,7 @@ module Gollum # # Returns the footer Page or nil if none exists. def footer - return nil if page_match('_Footer', self.filename) - - dirs = self.path.split('/') - dirs.pop - map = @wiki.tree_map_for(self.version.id) - while !dirs.empty? - if page = find_page_in_tree(map, '_Footer', dirs.join('/')) - return page - end - dirs.pop - end - - find_page_in_tree(map, '_Footer', '') + find_sub_page :footer end # Gets a Boolean determining whether this page is a historical version. @@ -283,11 +271,11 @@ module Gollum # # Returns a Gollum::Page or nil if the page could not be found. def find(name, version) - map = @wiki.tree_map_for(version) + map = @wiki.tree_map_for(version.to_s) if page = find_page_in_tree(map, name) - sha = @wiki.ref_map[version] || version - page.version = Grit::Commit.create(@wiki.repo, :id => sha) - page.historical = sha == version + page.version = version.is_a?(Grit::Commit) ? + version : @wiki.commit_for(version) + page.historical = page.version.to_s == version.to_s page end rescue Grit::GitRuby::Repository::NoSuchShaFound @@ -302,7 +290,7 @@ module Gollum # # Returns a Gollum::Page or nil if the page could not be found. def find_page_in_tree(map, name, checked_dir = nil) - return nil if name.to_s.empty? + return nil if !map || name.to_s.empty? if checked_dir = BlobEntry.normalize_dir(checked_dir) checked_dir.downcase! end @@ -356,5 +344,28 @@ module Gollum false end end + + # Loads a sub page. Sub page nanes (footers) are prefixed with + # an underscore to distinguish them from other Pages. + # + # name - String page name. + # + # Returns the Page or nil if none exists. + def find_sub_page(name) + name = "_#{name.to_s.capitalize}" + return nil if page_match(name, self.filename) + + dirs = self.path.split('/') + dirs.pop + map = @wiki.tree_map_for(self.version.id) + while !dirs.empty? + if page = find_page_in_tree(map, name, dirs.join('/')) + return page + end + dirs.pop + end + + find_page_in_tree(map, name, '') + end end end diff --git a/lib/gollum/sanitization.rb b/lib/gollum/sanitization.rb index 72ba2ec9..153cd570 100644 --- a/lib/gollum/sanitization.rb +++ b/lib/gollum/sanitization.rb @@ -1,5 +1,4 @@ module Gollum - # Encapsulate sanitization options. # # This class does not yet support all options of Sanitize library. @@ -104,6 +103,13 @@ module Gollum :allow_comments => allow_comments? } end + + # Builds a Sanitize instance from the current options. + # + # Returns a Sanitize instance. + def to_sanitize + Sanitize.new(to_hash) + end end end diff --git a/lib/gollum/wiki.rb b/lib/gollum/wiki.rb index 6afd74da..9d9b7b10 100644 --- a/lib/gollum/wiki.rb +++ b/lib/gollum/wiki.rb @@ -9,6 +9,9 @@ module Gollum # Sets the file class used by all instances of this Wiki. attr_writer :file_class + # Sets the markup class used by all instances of this Wiki. + attr_writer :markup_class + # Sets the default name for commits. attr_accessor :default_committer_name @@ -45,6 +48,17 @@ module Gollum end end + # Gets the markup class used by all instances of this Wiki. + # Default: Gollum::Markup + def markup_class + @markup_class || + if superclass.respond_to?(:markup_class) + superclass.markup_class + else + ::Gollum::Markup + end + end + # Gets the default sanitization options for current pages used by # instances of this Wiki. def sanitization @@ -89,27 +103,32 @@ module Gollum # Default: "/" # :page_class - The page Class. Default: Gollum::Page # :file_class - The file Class. Default: Gollum::File + # :markup_class - The markup Class. Default: Gollum::Markup # :sanitization - An instance of Sanitization. # # Returns a fresh Gollum::Repo. def initialize(path, options = {}) + if path.is_a?(GitAccess) + options[:access] = path + path = path.path + end @path = path - @repo = Grit::Repo.new(path) + @access = options[:access] || GitAccess.new(path) @base_path = options[:base_path] || "/" @page_class = options[:page_class] || self.class.page_class @file_class = options[:file_class] || self.class.file_class + @markup_class = options[:markup_class] || self.class.markup_class + @repo = @access.repo @sanitization = options[:sanitization] || self.class.sanitization @history_sanitization = options[:history_sanitization] || self.class.history_sanitization - - clear_cache end # Public: check whether the wiki's git repo exists on the filesystem. # # Returns true if the repo exists, and false if it does not. def exist? - @repo.git.exist? + @access.exist? end # Public: Get the formatted page for a given page name. @@ -147,7 +166,7 @@ module Gollum path = @page_class.cname(name) + '.' + ext blob = OpenStruct.new(:name => path, :data => data) page.populate(blob, path) - page.version = self.repo.commit("HEAD") + page.version = @access.commit('HEAD') page end @@ -176,7 +195,7 @@ module Gollum actor = Grit::Actor.new(commit[:name], commit[:email]) sha1 = index.commit(commit[:message], parents, actor) - @ref_map.clear + @access.refresh update_working_dir(index, '', name, format) sha1 @@ -219,7 +238,7 @@ module Gollum actor = Grit::Actor.new(commit[:name], commit[:email]) sha1 = index.commit(commit[:message], [pcommit], actor) - @ref_map.clear + @access.refresh update_working_dir(index, dir, page.name, page.format) update_working_dir(index, dir, name, format) @@ -248,7 +267,7 @@ module Gollum actor = Grit::Actor.new(commit[:name], commit[:email]) sha1 = index.commit(commit[:message], [pcommit], actor) - @ref_map.clear + @access.refresh update_working_dir(index, dir, page.name, page.format) sha1 @@ -307,6 +326,34 @@ module Gollum @repo.log('master', nil, log_pagination_options(options)) end + # Public: Refreshes just the cached Git reference data. This should + # be called after every Gollum update. + # + # Returns nothing. + def clear_cache + @access.refresh + end + + # Public: Creates a Sanitize instance using the Wiki's sanitization + # options. + # + # Returns a Sanitize instance. + def sanitizer + if options = sanitization + @sanitizer ||= options.to_sanitize + end + end + + # Public: Creates a Sanitize instance using the Wiki's history sanitization + # options. + # + # Returns a Sanitize instance. + def history_sanitizer + if options = history_sanitization + @history_sanitizer ||= options.to_sanitize + end + end + ######################################################################### # # Internal Methods @@ -323,26 +370,15 @@ module Gollum # Returns the String path. attr_reader :path - # Gets a Hash cache of refs to commit SHAs. - # - # {"master" => "abc123", ...} - # - # Returns the Hash cache. - attr_reader :ref_map - - # Gets a Hash cache of commit SHAs to a recursive tree of blobs. - # - # {"abc123" => [["lib/foo.rb", "blob-sha"], [file, sha], ...], ...} - # - # Returns the Hash cache. - attr_reader :tree_map - # Gets the page class used by all instances of this Wiki. attr_reader :page_class # Gets the file class used by all instances of this Wiki. attr_reader :file_class + # Gets the markup class used by all instances of this Wiki. + attr_reader :markup_class + # Normalize the data. # # data - The String data to be normalized. @@ -397,10 +433,11 @@ module Gollum # # Returns a flat Array of Gollum::Page instances. def tree_list(ref) - tree_map_for(ref).inject([]) do |list, entry| + sha = @access.ref_to_sha(ref) + commit = @access.commit(sha) + tree_map_for(sha).inject([]) do |list, entry| next list unless @page_class.valid_page_name?(entry.name) - sha = ref_map[ref] - list << entry.page(self, @repo.commit(sha)) + list << entry.page(self, commit) end end @@ -519,6 +556,11 @@ module Gollum @repo.config['user.email'] || self.class.default_committer_email end + def commit_for(ref) + @access.commit(ref) + rescue Grit::GitRuby::Repository::NoSuchShaFound + end + # Finds a full listing of files and their blob SHA for a given ref. Each # listing is cached based on its actual commit SHA. # @@ -526,62 +568,9 @@ module Gollum # # Returns an Array of BlobEntry instances. def tree_map_for(ref) - sha = @ref_map[ref] || ref - @tree_map[sha] || begin - real_sha = @repo.git.rev_list({:max_count=>1}, ref) - @ref_map[ref] = real_sha if real_sha != ref - @tree_map[real_sha] ||= parse_tree_for(real_sha) - end + @access.tree(ref) rescue Grit::GitRuby::Repository::NoSuchShaFound [] end - - # Finds the full listing of files and their blob SHA for a given commit - # SHA. No caching or ref lookups are performed. - # - # sha - String commit SHA. - # - # Returns an Array of BlobEntry instances. - def parse_tree_for(sha) - tree = @repo.git.native(:ls_tree, {:r => true, :z => true}, sha) - items = [] - tree.split("\0").each do |line| - items << parse_tree_line(line) - end - items - end - - # Parses a line of output from the `ls-tree` command. - # - # line - A String line of output: - # "100644 blob 839c2291b30495b9a882c17d08254d3c90d8fb53 Home.md" - # - # Returns an Array of BlobEntry instances. - def parse_tree_line(line) - data, name = line.split("\t") - mode, type, sha = data.split(' ') - name = decode_git_path(name) - BlobEntry.new sha, name - end - - # Decode octal sequences (\NNN) in tree path names. - # - # path - String path name. - # - # Returns a decoded String. - def decode_git_path(path) - if path[0] == ?" && path[-1] == ?" - path = path[1...-1] - path.gsub!(/\\\d{3}/) { |m| m[1..-1].to_i(8).chr } - end - path.gsub!(/\\[rn"\\]/) { |m| eval(%("#{m.to_s}")) } - path - end - - # Resets the ref and tree caches for this wiki. - def clear_cache - @ref_map = {} - @tree_map = {} - end end end diff --git a/test/test_git_access.rb b/test/test_git_access.rb new file mode 100644 index 00000000..ef13fbeb --- /dev/null +++ b/test/test_git_access.rb @@ -0,0 +1,59 @@ +require File.join(File.dirname(__FILE__), *%w[helper]) + +context "GitAccess" do + setup do + @access = Gollum::GitAccess.new(testpath("examples/lotr.git")) + end + + test "#commit fills commit_map cache" do + assert @access.commit_map.empty? + actual = @access.repo.commits.first + expected = @access.commit(actual.id) + assert_equal actual.message, expected.message + assert_equal actual.message, @access.commit_map[actual.id].message + end + + test "#commits uses commit_map" do + actual = @access.repo.commits.first + @access.commit_map['abc'] = 1 + commits = @access.commits('abc', actual.id) + assert_equal 1, commits[0] + assert_equal actual.message, commits[1].message + end + + test "#tree_map_for caches ref and tree" do + assert @access.ref_map.empty? + assert @access.tree_map.empty? + @access.tree 'master' + assert_equal({"master"=>"60f12f4254f58801b9ee7db7bca5fa8aeefaa56b"}, @access.ref_map) + + map = @access.tree_map['60f12f4254f58801b9ee7db7bca5fa8aeefaa56b'] + assert_equal 'Bilbo-Baggins.md', map[0].path + assert_equal '', map[0].dir + assert_equal map[0].path, map[0].name + assert_equal 'Mordor/Eye-Of-Sauron.md', map[3].path + assert_equal '/Mordor', map[3].dir + assert_equal 'Eye-Of-Sauron.md', map[3].name + end + + test "#tree_map_for only caches tree for commit" do + assert @access.tree_map.empty? + @access.tree '60f12f4254f58801b9ee7db7bca5fa8aeefaa56b' + assert @access.ref_map.empty? + + entry = @access.tree_map['60f12f4254f58801b9ee7db7bca5fa8aeefaa56b'][0] + assert_equal 'Bilbo-Baggins.md', entry.path + end + + test "cannot access commit from invalid ref" do + assert_nil @access.commit('foo') + end + + test "cannot access sha from invalid ref" do + assert_nil @access.ref_to_sha('foo') + end + + test "cannot access tree from invalid ref" do + assert_equal [], @access.tree('foo') + end +end \ No newline at end of file diff --git a/test/test_markup.rb b/test/test_markup.rb index c75ad1a6..892685af 100644 --- a/test/test_markup.rb +++ b/test/test_markup.rb @@ -25,6 +25,31 @@ context "Markup" do end end + test "Gollum::Markup#render yields a DocumentFragment" do + yielded = false + @wiki.write_page("Yielded", :markdown, "abc", commit_details) + + page = @wiki.page("Yielded") + markup = Gollum::Markup.new(page) + markup.render do |doc| + assert_kind_of Nokogiri::HTML::DocumentFragment, doc + yielded = true + end + assert yielded + end + + test "Gollum::Page#formatted_data yields a DocumentFragment" do + yielded = false + @wiki.write_page("Yielded", :markdown, "abc", commit_details) + + page = @wiki.page("Yielded") + page.formatted_data do |doc| + assert_kind_of Nokogiri::HTML::DocumentFragment, doc + yielded = true + end + assert yielded + end + ######################################################################### # # Links diff --git a/test/test_wiki.rb b/test/test_wiki.rb index c4beadea..fde5580b 100644 --- a/test/test_wiki.rb +++ b/test/test_wiki.rb @@ -60,29 +60,29 @@ context "Wiki" do @wiki.normalize_commit(commit.dup)) end - test "#tree_map_for caches ref and tree" do - assert @wiki.ref_map.empty? - assert @wiki.tree_map.empty? - @wiki.tree_map_for 'master' - assert_equal({"master"=>"60f12f4254f58801b9ee7db7bca5fa8aeefaa56b"}, @wiki.ref_map) - - map = @wiki.tree_map['60f12f4254f58801b9ee7db7bca5fa8aeefaa56b'] - assert_equal 'Bilbo-Baggins.md', map[0].path - assert_equal '', map[0].dir - assert_equal map[0].path, map[0].name - assert_equal 'Mordor/Eye-Of-Sauron.md', map[3].path - assert_equal '/Mordor', map[3].dir - assert_equal 'Eye-Of-Sauron.md', map[3].name - end - - test "#tree_map_for only caches tree for commit" do - assert @wiki.tree_map.empty? - @wiki.tree_map_for '60f12f4254f58801b9ee7db7bca5fa8aeefaa56b' - assert @wiki.ref_map.empty? - - entry = @wiki.tree_map['60f12f4254f58801b9ee7db7bca5fa8aeefaa56b'][0] - assert_equal 'Bilbo-Baggins.md', entry.path - end + #test "#tree_map_for caches ref and tree" do + # assert @wiki.ref_map.empty? + # assert @wiki.tree_map.empty? + # @wiki.tree_map_for 'master' + # assert_equal({"master"=>"60f12f4254f58801b9ee7db7bca5fa8aeefaa56b"}, @wiki.ref_map) + # + # map = @wiki.tree_map['60f12f4254f58801b9ee7db7bca5fa8aeefaa56b'] + # assert_equal 'Bilbo-Baggins.md', map[0].path + # assert_equal '', map[0].dir + # assert_equal map[0].path, map[0].name + # assert_equal 'Mordor/Eye-Of-Sauron.md', map[3].path + # assert_equal '/Mordor', map[3].dir + # assert_equal 'Eye-Of-Sauron.md', map[3].name + #end + # + #test "#tree_map_for only caches tree for commit" do + # assert @wiki.tree_map.empty? + # @wiki.tree_map_for '60f12f4254f58801b9ee7db7bca5fa8aeefaa56b' + # assert @wiki.ref_map.empty? + # + # entry = @wiki.tree_map['60f12f4254f58801b9ee7db7bca5fa8aeefaa56b'][0] + # assert_equal 'Bilbo-Baggins.md', entry.path + #end test "text_data" do wiki = Gollum::Wiki.new(testpath("examples/yubiwa.git"))