Skip to content
Browse files

Add SitemapFile class and tests

  • Loading branch information...
1 parent 13b3aec commit bc96afdfbff53767719439ea6f69f65855f2168a @reyesyang committed Mar 5, 2014
Showing with 147 additions and 2 deletions.
  1. +6 −0 Rakefile
  2. +69 −0 lib/sitemaper/sitemap_file.rb
  3. +5 −2 sitemaper.gemspec
  4. +67 −0 spec/sitemaper/sitemap_file_spec.rb
View
6 Rakefile
@@ -1 +1,7 @@
require "bundler/gem_tasks"
+require 'rspec/core/rake_task'
+
+RSpec::Core::RakeTask.new
+
+task default: :spec
+task test: :spec
View
69 lib/sitemaper/sitemap_file.rb
@@ -0,0 +1,69 @@
+require 'builder'
+
+module Sitemaper
+ class ContentOverflowError < StandardError; end
+
+ class SitemapFile
+ attr_accessor :file_path, :items_count, :items_content, :reserved_content, :bytesize
+
+ def initialize(file_path)
+ @file_path = file_path
+ @items_count = 0
+ @items_content = ''
+ @reserved_content = build_reserved_content
+ @bytesize = @reserved_content.bytesize
+ end
+
+ def content
+ @reserved_content.gsub /(<\/\w+?>)$/, "#{@items_content}\\1"
+ end
+
+ def add(options)
+ item_str = build_item_xml(options).target!
+ @bytesize += item_str.bytesize
+ @items_count += 1
+
+ if !overflow?
+ @items_content << item_str
+ else
+ @bytesize -= item_str.bytesize
+ @items_count -= 1
+ nil
+ end
+ end
+
+ def generate!
+ if !overflow?
+ File.open(@file_path, 'w') { |file| file.write content }
+ @file_path
+ else
+ nil
+ end
+ end
+
+ private
+
+ def overflow?
+ @bytesize > 10 * 1024 * 1024 || @items_count > 50000
+ end
+
+ def build_reserved_content
+ xml = Builder::XmlMarkup.new
+ xml.instruct!
+ xml.urlset(xmlns: "http://www.sitemaps.org/schemas/sitemap/0.9") { |urlset| urlset }
+ xml.target!
+ end
+
+ def build_item_xml(options)
+ xml = Builder::XmlMarkup.new
+ xml.url do |url|
+ url.loc options[:loc]
+ url.lastmod options[:lastmod]
+ url.changefreq(options[:changefreq] || 'weekly')
+ url.priority(options[:priority] || 0.5)
+ end
+
+ xml
+ end
+ end
+end
View
7 sitemaper.gemspec
@@ -8,8 +8,8 @@ Gem::Specification.new do |spec|
spec.version = Sitemaper::VERSION
spec.authors = ["Reyes Yang"]
spec.email = ["reyes.yang@gmail.com"]
- spec.summary = %q{TODO: Write a short summary. Required.}
- spec.description = %q{TODO: Write a longer description. Optional.}
+ spec.summary = %q{A ruby tool used to generate sitemap.}
+ spec.description = %q{A ruby tool used to generate sitemap.}
spec.homepage = ""
spec.license = "MIT"
@@ -20,4 +20,7 @@ Gem::Specification.new do |spec|
spec.add_development_dependency "bundler", "~> 1.5"
spec.add_development_dependency "rake"
+ spec.add_development_dependency "rspec"
+
+ spec.add_runtime_dependency "builder"
end
View
67 spec/sitemaper/sitemap_file_spec.rb
@@ -0,0 +1,67 @@
+require 'sitemaper/sitemap_file'
+
+describe Sitemaper::SitemapFile do
+ subject(:sitemap_file) { Sitemaper::SitemapFile.new('/tmp/sitemap.xml') }
+ let(:reserved_content) do
+ '<?xml version="1.0" encoding="UTF-8"?><urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"></urlset>'
+ end
+ let(:items_content) do
+ '<url><loc>http://reyesyang.info</loc><lastmod>1988-2-29</lastmod><changefreq>weekly</changefreq><priority>0.5</priority></url>'
+ end
+ let(:content) do
+ '<?xml version="1.0" encoding="UTF-8"?><urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"><url><loc>http://reyesyang.info</loc><lastmod>1988-2-29</lastmod><changefreq>weekly</changefreq><priority>0.5</priority></url></urlset>'
+ end
+
+ let(:options) do
+ {
+ loc: 'http://reyesyang.info',
+ lastmod: '1988-2-29'
+ }
+ end
+
+ describe '#initialize' do
+ its(:file_path) { should eq('/tmp/sitemap.xml') }
+ its(:items_count) { should eq(0) }
+ its(:items_content) { should eq('') }
+ its(:reserved_content) { should eq(reserved_content) }
+ its(:bytesize) { should eq(reserved_content.bytesize) }
+ end
+
+ describe '#content' do
+ context 'items_content is blank' do
+ it 'return reserved_content' do
+ expect(sitemap_file.content).to eq(reserved_content)
+ end
+ end
+
+ context 'items_content is not blank' do
+ it 'return reserved_content with items_content' do
+ sitemap_file.items_content = items_content
+ expect(sitemap_file.content).to eq(content)
+ end
+ end
+ end
+
+ describe '#add' do
+ context 'fit limit' do
+ it 'return items_content' do
+ expect(sitemap_file.add(options)).to eq(items_content)
+ end
+ end
+
+ context 'over limit' do
+ it 'return nil when bytesize more than 10M' do
+ subject.bytesize = 10 * 1024 * 1024
+ expect(sitemap_file.add(options)).to be_nil
+ end
+
+ it 'return nil when items_count more than 50000' do
+ subject.items_count = 50000
+ expect(sitemap_file.add(options)).to be_nil
+ end
+ end
+ end
+
+ describe '#generate!' do
+ end
+end

0 comments on commit bc96afd

Please sign in to comment.
Something went wrong with that request. Please try again.