jekyll-import 0.1.0 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -68,13 +68,16 @@ module JekyllImport
68
68
  # Writes a post out to disk
69
69
  def self.write_post(post, use_markdown, add_highlights)
70
70
  content = post[:content]
71
- if use_markdown
72
- content = html_to_markdown content
73
- content = add_syntax_highlights content if add_highlights
74
- end
75
71
 
76
- File.open("_posts/tumblr/#{post[:name]}", "w") do |f|
77
- f.puts post[:header].to_yaml + "---\n" + content
72
+ if content
73
+ if use_markdown
74
+ content = html_to_markdown content
75
+ content = add_syntax_highlights content if add_highlights
76
+ end
77
+
78
+ File.open("_posts/tumblr/#{post[:name]}", "w") do |f|
79
+ f.puts post[:header].to_yaml + "---\n" + content
80
+ end
78
81
  end
79
82
  end
80
83
 
@@ -125,6 +128,9 @@ module JekyllImport
125
128
  unless post["video-caption"].nil?
126
129
  content << "<br/>" + post["video-caption"]
127
130
  end
131
+ when "answer"
132
+ title = post["question"]
133
+ content = post["answer"]
128
134
  end
129
135
  date = Date.parse(post['date']).to_s
130
136
  title = Nokogiri::HTML(title).text
@@ -140,7 +146,7 @@ module JekyllImport
140
146
  "layout" => "post",
141
147
  "title" => title,
142
148
  "date" => Time.parse(post['date']).xmlschema,
143
- "tags" => post["tags"],
149
+ "tags" => (post["tags"] or []),
144
150
  "tumblr_url" => post["url-with-slug"]
145
151
  },
146
152
  :content => content,
@@ -115,6 +115,7 @@ module JekyllImport
115
115
  posts.post_title AS `title`,
116
116
  posts.post_name AS `slug`,
117
117
  posts.post_date AS `date`,
118
+ posts.post_date_gmt AS `date_gmt`,
118
119
  posts.post_content AS `content`,
119
120
  posts.post_excerpt AS `excerpt`,
120
121
  posts.comment_count AS `comment_count`,
@@ -276,7 +277,8 @@ module JekyllImport
276
277
  'more_anchor' => more_anchor,
277
278
  'wordpress_id' => post[:id],
278
279
  'wordpress_url' => post[:guid].to_s,
279
- 'date' => date,
280
+ 'date' => date.to_s,
281
+ 'date_gmt' => post[:date_gmt].to_s,
280
282
  'categories' => options[:categories] ? categories : nil,
281
283
  'tags' => options[:tags] ? tags : nil,
282
284
  'comments' => options[:comments] ? comments : nil,
@@ -286,7 +288,7 @@ module JekyllImport
286
288
  File.open("_posts/#{name}", "w") do |f|
287
289
  f.puts data
288
290
  f.puts "---"
289
- f.puts content
291
+ f.puts Util.wpautop(content)
290
292
  end
291
293
  end
292
294
 
@@ -26,6 +26,19 @@ module JekyllImport
26
26
  import_count = Hash.new(0)
27
27
  doc = Hpricot::XML(File.read(source))
28
28
 
29
+ # Fetch authors data from header
30
+ authors = Hash[
31
+ (doc/:channel/'wp:author').map do |author|
32
+ [author.at("wp:author_login").inner_text.strip, {
33
+ "login" => author.at("wp:author_login").inner_text.strip,
34
+ "email" => author.at("wp:author_email").inner_text,
35
+ "display_name" => author.at("wp:author_display_name").inner_text,
36
+ "first_name" => author.at("wp:author_first_name").inner_text,
37
+ "last_name" => author.at("wp:author_last_name").inner_text
38
+ }]
39
+ end
40
+ ] rescue {}
41
+
29
42
  (doc/:channel/:item).each do |item|
30
43
  title = item.at(:title).inner_text.strip
31
44
  permalink_title = item.at('wp:post_name').inner_text
@@ -51,9 +64,11 @@ module JekyllImport
51
64
  item.search("wp:postmeta").each do |meta|
52
65
  key = meta.at('wp:meta_key').inner_text
53
66
  value = meta.at('wp:meta_value').inner_text
54
- metas[key] = value;
67
+ metas[key] = value
55
68
  end
56
69
 
70
+ author_login = item.at('dc:creator').inner_text.strip
71
+
57
72
  name = "#{date.strftime('%Y-%m-%d')}-#{permalink_title}.html"
58
73
  header = {
59
74
  'layout' => type,
@@ -63,7 +78,8 @@ module JekyllImport
63
78
  'status' => status,
64
79
  'type' => type,
65
80
  'published' => published,
66
- 'meta' => metas
81
+ 'meta' => metas,
82
+ 'author' => authors[author_login]
67
83
  }
68
84
 
69
85
  begin
@@ -71,7 +87,7 @@ module JekyllImport
71
87
  File.open("_#{type}s/#{name}", "w") do |f|
72
88
  f.puts header.to_yaml
73
89
  f.puts '---'
74
- f.puts item.at('content:encoded').inner_text
90
+ f.puts Util.wpautop(item.at('content:encoded').inner_text)
75
91
  end
76
92
  rescue => e
77
93
  puts "Couldn't import post!"
@@ -0,0 +1,76 @@
1
+ module JekyllImport
2
+ module Util
3
+
4
+ # Ruby translation of wordpress wpautop (see https://core.trac.wordpress.org/browser/trunk/src/wp-includes/formatting.php)
5
+ #
6
+ # A group of regex replaces used to identify text formatted with newlines and
7
+ # replace double line-breaks with HTML paragraph tags. The remaining
8
+ # line-breaks after conversion become <<br />> tags, unless $br is set to false
9
+ #
10
+ # @param string pee The text which has to be formatted.
11
+ # @param bool br Optional. If set, this will convert all remaining line-breaks after paragraphing. Default true.
12
+ # @return string Text which has been converted into correct paragraph tags.
13
+ #
14
+ def self.wpautop(pee, br = true)
15
+ return '' if pee.strip == ''
16
+
17
+ allblocks = '(?:table|thead|tfoot|caption|col|colgroup|tbody|tr|td|th|div|dl|dd|dt|ul|ol|li|pre|select|option|form|map|area|blockquote|address|math|style|p|h[1-6]|hr|fieldset|noscript|legend|section|article|aside|hgroup|header|footer|nav|figure|figcaption|details|menu|summary)'
18
+ pre_tags = {}
19
+ pee = pee + "\n"
20
+
21
+ if pee.include?('<pre')
22
+ pee_parts = pee.split('</pre>')
23
+ last_pee = pee_parts.pop
24
+ pee = ''
25
+ pee_parts.each_with_index do |pee_part, i|
26
+ start = pee_part.index('<pre')
27
+
28
+ unless start
29
+ pee += pee_part
30
+ continue
31
+ end
32
+
33
+ name = "<pre wp-pre-tag-#{i}></pre>"
34
+ pre_tags[name] = pee_part[start..-1] + '</pre>'
35
+
36
+ pee += pee_part[0, start] + name
37
+ end
38
+ pee += last_pee
39
+ end
40
+
41
+ pee = pee.gsub(Regexp.new('<br />\s*<br />'), "\n\n")
42
+ pee = pee.gsub(Regexp.new("(<" + allblocks + "[^>]*>)"), "\n\\1")
43
+ pee = pee.gsub(Regexp.new("(</" + allblocks + ">)"), "\\1\n\n")
44
+ pee = pee.gsub("\r\n", "\n").gsub("\r", "\n")
45
+ if pee.include? '<object'
46
+ pee = pee.gsub(Regexp.new('\s*<param([^>]*)>\s*'), "<param\\1>")
47
+ pee = pee.gsub(Regexp.new('\s*</embed>\s*'), '</embed>')
48
+ end
49
+
50
+ pees = pee.split(/\n\s*\n/).compact
51
+ pee = ''
52
+ pees.each { |tinkle| pee += '<p>' + tinkle.chomp("\n") + "</p>\n" }
53
+ pee = pee.gsub(Regexp.new('<p>\s*</p>'), '')
54
+ pee = pee.gsub(Regexp.new('<p>([^<]+)</(div|address|form)>'), "<p>\\1</p></\\2>")
55
+ pee = pee.gsub(Regexp.new('<p>\s*(</?' + allblocks + '[^>]*>)\s*</p>'), "\\1")
56
+ pee = pee.gsub(Regexp.new('<p>(<li.+?)</p>'), "\\1")
57
+ pee = pee.gsub(Regexp.new('<p><blockquote([^>]*)>', 'i'), "<blockquote\\1><p>")
58
+ pee = pee.gsub('</blockquote></p>', '</p></blockquote>')
59
+ pee = pee.gsub(Regexp.new('<p>\s*(</?' + allblocks + '[^>]*>)'), "\\1")
60
+ pee = pee.gsub(Regexp.new('(</?' + allblocks + '[^>]*>)\s*</p>'), "\\1")
61
+ if br
62
+ pee = pee.gsub(Regexp.new('<(script|style).*?</\1>')) { |match| match.gsub("\n", "<WPPreserveNewline />") }
63
+ pee = pee.gsub(Regexp.new('(?<!<br />)\s*\n'), "<br />\n")
64
+ pee = pee.gsub('<WPPreserveNewline />', "\n")
65
+ end
66
+ pee = pee.gsub(Regexp.new('(</?' + allblocks + '[^>]*>)\s*<br />'), "\\1")
67
+ pee = pee.gsub(Regexp.new('<br />(\s*</?(?:p|li|div|dl|dd|dt|th|pre|td|ul|ol)[^>]*>)'), "\\1")
68
+ pee = pee.gsub(Regexp.new('\n</p>$'), '</p>')
69
+
70
+ pre_tags.each do |name, value|
71
+ pee.gsub!(name, value)
72
+ end
73
+ pee
74
+ end
75
+ end
76
+ end
@@ -0,0 +1,3 @@
1
+ module JekyllImport
2
+ VERSION = '0.2.0'
3
+ end
@@ -5,6 +5,7 @@ require 'jekyll-import'
5
5
  module Jekyll
6
6
  module Commands
7
7
  class Import < Command
8
+
8
9
  IMPORTERS = {
9
10
  :behance => 'Behance',
10
11
  :csv => 'CSV',
@@ -28,26 +29,47 @@ module Jekyll
28
29
  :wordpressdotcom => 'WordpressDotCom'
29
30
  }
30
31
 
31
- def self.abort_on_invalid_migrator(migrator)
32
- msg = "Sorry, '#{migrator}' isn't a valid migrator. Valid choices:\n"
33
- IMPORTERS.keys.each do |k, v|
34
- msg += "* #{k}\n"
32
+ class << self
33
+
34
+ def init_with_program(prog)
35
+ prog.command(:import) do |c|
36
+ c.syntax 'import <platform> [options]'
37
+ c.description 'Import your old blog to Jekyll'
38
+ importers = JekyllImport.add_importer_commands(c)
39
+
40
+ c.action do |args, options|
41
+ if args.empty?
42
+ Jekyll.logger.warn "You must specify an importer."
43
+ Jekyll.logger.info "Valid options are:"
44
+ importers.each { |i| Jekyll.logger.info "*", "#{i}" }
45
+ end
46
+ end
47
+ end
35
48
  end
36
- abort msg
37
- end
38
49
 
39
- def self.process(migrator, options)
40
- migrator = migrator.to_s.downcase
50
+ def process(migrator, options)
51
+ migrator = migrator.to_s.downcase
41
52
 
42
- if IMPORTERS.keys.include?(migrator.to_sym)
43
- if JekyllImport::Importers.const_defined?(IMPORTERS[migrator.to_sym])
44
- klass = JekyllImport::Importers.const_get(IMPORTERS[migrator.to_sym])
45
- klass.run(options.__hash__)
53
+ if IMPORTERS.keys.include?(migrator.to_sym)
54
+ if JekyllImport::Importers.const_defined?(IMPORTERS[migrator.to_sym])
55
+ klass = JekyllImport::Importers.const_get(IMPORTERS[migrator.to_sym])
56
+ klass.run(options.__hash__)
57
+ end
58
+ else
59
+ abort_on_invalid_migrator(migrator)
46
60
  end
47
- else
48
- abort_on_invalid_migrator(migrator)
49
61
  end
62
+
63
+ def abort_on_invalid_migrator(migrator)
64
+ msg = "Sorry, '#{migrator}' isn't a valid migrator. Valid choices:\n"
65
+ IMPORTERS.keys.each do |k, v|
66
+ msg += "* #{k}\n"
67
+ end
68
+ abort msg
69
+ end
70
+
50
71
  end
72
+
51
73
  end
52
74
  end
53
75
  end
@@ -0,0 +1,16 @@
1
+ ---
2
+ layout: news_item
3
+ title: 'jekyll-import 0.2.0 Released'
4
+ date: 2014-03-16 01:05:25 -0400
5
+ author: parkr
6
+ version: 0.2.0
7
+ categories: [release]
8
+ ---
9
+
10
+ It seems jekyll-import has been collecting some dust lately. There are some
11
+ great fixes and feature improvements in here so, hey, why let them lay
12
+ unutilized? No reason at all, my dear Watson, no reason at all.
13
+
14
+ Please enjoy! Check out the [GitHub Release][] for more specifics.
15
+
16
+ [GitHub Release]: https://github.com/jekyll/jekyll-import/releases/tag/v0.2.0
@@ -220,17 +220,16 @@ body > footer a:hover img {
220
220
  .quickstart .code {
221
221
  font-size: 12px;
222
222
  display: block;
223
- margin: 0 0 -30px;
223
+ margin: 10px 0 20px;
224
224
  }
225
225
 
226
226
  @media (min-width: 768px){
227
227
  .quickstart .code {
228
228
  font-size: 18px;
229
- margin: -30px 0;
230
- float: right;
229
+ margin: 10px 0 30px;
231
230
  }
232
231
  .quickstart h4 {
233
- margin: 50px 0 0;
232
+ margin: 20px 0 0;
234
233
  text-align: center;
235
234
  }
236
235
  }
@@ -15,9 +15,25 @@ $ ruby -rubygems -e 'require "jekyll-import";
15
15
  "dbname" => "name",
16
16
  "user" => "myuser",
17
17
  "password" => "mypassword",
18
- "host" => "myhost"
18
+ "host" => "myhost",
19
+ "comments" => true
19
20
  })'
20
21
  {% endhighlight %}
21
22
 
23
+ Posts will be generated and placed in `_posts` directory.
24
+
22
25
  The only required fields are `dbname` and `user`. `password` defaults to `""`
23
- and `host` defaults to `"localhost"`.
26
+ and `host` defaults to `"localhost"`.
27
+
28
+ `comments`, which defaults to false, control the generation of
29
+ comment. If `comments` set to true, posts will be generated and placed
30
+ in `_comments` directory.
31
+
32
+
33
+ All of the posts and comments will include `post_id` in YAML front
34
+ matter to link a post and its comments.
35
+
36
+ To include imported comments as part of a post, use the yet to merge
37
+ [fork of mt-static-comments](https://github.com/shigeya/jekyll-static-comments/tree/mt_static_comments)
38
+ to include statically generate comments in your post. Fork and provide
39
+ feedback if necessary.
@@ -13,12 +13,12 @@ To import your posts from [Tumblr](http://tumblr.com), run:
13
13
  $ ruby -rubygems -e 'require "jekyll-import";
14
14
  JekyllImport::Importers::Tumblr.run({
15
15
  "url" => "http://myblog.tumblr.com",
16
- "user" => "html", # or "md"
17
- "password" => false, # whether to download images as well.
16
+ "format" => "html", # or "md"
17
+ "grab_images" => false, # whether to download images as well.
18
18
  "add_highlights" => false, # whether to wrap code blocks (indented 4 spaces) in a Liquid "highlight" tag
19
19
  "rewrite_urls" => false # whether to write pages that redirect from the old Tumblr paths to the new Jekyll paths
20
20
  })'
21
21
  {% endhighlight %}
22
22
 
23
23
  The only required field is `url`. The other fields default to their above
24
- values.
24
+ values.
@@ -29,3 +29,12 @@ $ ruby -rubygems -e 'require "jekyll-import";
29
29
  {% endhighlight %}
30
30
 
31
31
  None of the fields are required. Their defaults are as you see above.
32
+
33
+ <div class="note info">
34
+ <h5>This only imports post &amp; page data &amp; content</h5>
35
+ <p>
36
+ This importer only converts your posts and creates YAML front-matter.
37
+ It does not import any layouts, styling, or external files
38
+ (images, CSS, etc.).
39
+ </p>
40
+ </div>
@@ -37,10 +37,10 @@ overview: true
37
37
  </section>
38
38
  <section class="quickstart">
39
39
  <div class="grid">
40
- <div class="unit golden-small center-on-mobiles">
40
+ <div class="unit whole center-on-mobiles">
41
41
  <h4>Get up and running <em>in&nbsp;seconds</em>.</h4>
42
42
  </div>
43
- <div class="unit golden-large code">
43
+ <div class="unit whole center-on-mobiles code">
44
44
  <p class="title">Quick-start Instructions</p>
45
45
  <div class="shell">
46
46
  <p class="line">
@@ -61,12 +61,7 @@ overview: true
61
61
  <p class="line">
62
62
  <span class="path">~/my-awesome-site</span>
63
63
  <span class="prompt">$</span>
64
- <span class="command">jekyll import wordpress \ </span>
65
- </p>
66
- <p class="line">
67
- <span class="path"> </span>
68
- <span class="prompt"> </span>
69
- <span class="command">--source wordpress.xml</span>
64
+ <span class="command">jekyll import wordpressdotcom --source wordpress.xml</span>
70
65
  </p>
71
66
  <p class="line">
72
67
  <span class="path">~/my-awesome-site</span>
@@ -3,59 +3,88 @@ require 'json'
3
3
 
4
4
  class TestTumblrImporter < Test::Unit::TestCase
5
5
 
6
- context "A Tumblr blog" do
7
- setup do
6
+ context "A Tumblr blog" do
7
+ setup do
8
8
  Importers::Tumblr.require_deps
9
- @jsonPayload = '{"tumblelog":{"title":"JekyllImport","description":"Jekyll Importer Test.","name":"JekyllImport","timezone":"Canada\/Atlantic","cname":"https://github.com/jekyll/jekyll-import/","feeds":[]},"posts-start":0,"posts-total":"1","posts-type":false,"posts":[{"id":54759400073,"url":"https:\/\/github.com\/post\/54759400073","url-with-slug":"http:\/\/github.com\/post\/54759400073\/jekyll-test","type":"regular","date-gmt":"2013-07-06 16:27:23 GMT","date":"Sat, 06 Jul 2013 13:27:23","bookmarklet":null,"mobile":null,"feed-item":"","from-feed-id":0,"unix-timestamp":1373128043,"format":"html","reblog-key":"0L6yPcHr","slug":"jekyll-test","regular-title":"Jekyll: Test","regular-body":"<p>Testing...<\/p>","tags":["jekyll"]}]}'
10
- @posts = JSON.parse(@jsonPayload)
11
- end
9
+ @jsonPayload = '{"tumblelog":{"title":"JekyllImport","description":"Jekyll Importer Test.","name":"JekyllImport","timezone":"Canada\/Atlantic","cname":"https://github.com/jekyll/jekyll-import/","feeds":[]},"posts-start":0,"posts-total":"2","posts-type":false,"posts":[{"id":54759400073,"url":"https:\/\/github.com\/post\/54759400073","url-with-slug":"http:\/\/github.com\/post\/54759400073\/jekyll-test","type":"regular","date-gmt":"2013-07-06 16:27:23 GMT","date":"Sat, 06 Jul 2013 13:27:23","bookmarklet":null,"mobile":null,"feed-item":"","from-feed-id":0,"unix-timestamp":1373128043,"format":"html","reblog-key":"0L6yPcHr","slug":"jekyll-test","regular-title":"Jekyll: Test","regular-body":"<p>Testing...<\/p>","tags":["jekyll"]},{"id":"71845593082","url":"http:\/\/example.com\/post\/71845593082","url-with-slug":"http:\/\/example.com\/post\/71845593082\/knock-knock","type":"answer","date-gmt":"2014-01-01 14:08:45 GMT","date":"Wed, 01 Jan 2014 09:08:45","bookmarklet":0,"mobile":0,"feed-item":"","from-feed-id":0,"unix-timestamp":1388585325,"format":"html","reblog-key":"jPfWHFnT","slug":"knock-knock","question":"Knock knock?","answer":"<p>Who is there?<\/p>"}]}'
10
+ @posts = JSON.parse(@jsonPayload)
11
+ @batch = @posts["posts"].map { |post| Importers::Tumblr.post_to_hash(post, 'html') }
12
+ end
12
13
 
13
- should "have a post" do
14
- assert_equal(1, @posts["posts"].size)
15
- end
14
+ should "have a post" do
15
+ assert_equal(2, @posts["posts"].size)
16
+ end
17
+
18
+ should "convert post into hash" do
19
+ refute_nil(@batch, "a batch with a valid post should exist")
20
+ end
16
21
 
17
- should "have a regular post" do
18
- assert_equal("regular", @posts['posts'][0]['type'])
19
- end
22
+ context "post" do
23
+ should "have a corresponding type" do
24
+ assert_equal("regular", @posts['posts'][0]['type'])
25
+ end
26
+
27
+ should "have a hash with a valid name" do
28
+ assert_equal("2013-07-06-jekyll-test.html", @batch[0][:name])
29
+ end
30
+
31
+ should "have a hash with a valid layout" do
32
+ assert_equal("post", @batch[0][:header]['layout'])
33
+ end
34
+
35
+ should "have a hash with a valid title" do
36
+ assert_equal("Jekyll: Test", @batch[0][:header]['title'])
37
+ end
38
+
39
+ should "have a hash with valid tags" do
40
+ assert_equal("jekyll", @batch[0][:header]['tags'][0])
41
+ end
42
+
43
+ should "have a hash with valid content" do
44
+ assert_equal("<p>Testing...</p>", @batch[0][:content])
45
+ end
46
+
47
+ should "have a hash with a valid url" do
48
+ assert_equal("https://github.com/post/54759400073", @batch[0][:url])
49
+ end
50
+
51
+ should "have a hash with a valid slug" do
52
+ assert_equal("http://github.com/post/54759400073/jekyll-test", @batch[0][:slug])
53
+ end
54
+ end
20
55
 
21
- should "convert post into hash" do
22
- batch = @posts["posts"].map { |post| Importers::Tumblr.post_to_hash(post, 'html') }
23
- refute_nil(batch, "a batch with a valid post should exist")
24
- end
25
-
26
- should "have a hash with a valid name" do
27
- batch = @posts["posts"].map { |post| Importers::Tumblr.post_to_hash(post, 'html') }
28
- assert_equal("2013-07-06-jekyll-test.html", batch[0][:name])
29
- end
30
-
31
- should "have a hash with a valid layout" do
32
- batch = @posts["posts"].map { |post| Importers::Tumblr.post_to_hash(post, 'html') }
33
- assert_equal("post", batch[0][:header]['layout'])
34
- end
35
-
36
- should "have a hash with a valid title" do
37
- batch = @posts["posts"].map { |post| Importers::Tumblr.post_to_hash(post, 'html') }
38
- assert_equal("Jekyll: Test", batch[0][:header]['title'])
39
- end
40
-
41
- should "have a hash with valid tags" do
42
- batch = @posts["posts"].map { |post| Importers::Tumblr.post_to_hash(post, 'html') }
43
- assert_equal("jekyll", batch[0][:header]['tags'][0])
44
- end
45
-
46
- should "have a hash with valid content" do
47
- batch = @posts["posts"].map { |post| Importers::Tumblr.post_to_hash(post, 'html') }
48
- assert_equal("<p>Testing...</p>", batch[0][:content])
49
- end
50
-
51
- should "have a hash with a valid url" do
52
- batch = @posts["posts"].map { |post| Importers::Tumblr.post_to_hash(post, 'html') }
53
- assert_equal("https://github.com/post/54759400073", batch[0][:url])
54
- end
55
-
56
- should "have a hash with a valid slug" do
57
- batch = @posts["posts"].map { |post| Importers::Tumblr.post_to_hash(post, 'html') }
58
- assert_equal("http://github.com/post/54759400073/jekyll-test", batch[0][:slug])
59
- end
60
- end
61
- end
56
+ context "answer" do
57
+ should "have a corresponding type" do
58
+ assert_equal("answer", @posts['posts'][1]['type'])
59
+ end
60
+
61
+ should "have a hash with a valid name" do
62
+ assert_equal("2014-01-01-knock-knock.html", @batch[1][:name])
63
+ end
64
+
65
+ should "have a hash with a valid layout" do
66
+ assert_equal("post", @batch[1][:header]['layout'])
67
+ end
68
+
69
+ should "have a hash with a valid title" do
70
+ assert_equal("Knock knock?", @batch[1][:header]['title'])
71
+ end
72
+
73
+ should "have a hash with valid tags" do
74
+ assert_equal([], @batch[1][:header]['tags'])
75
+ end
76
+
77
+ should "have a hash with valid content" do
78
+ assert_equal("<p>Who is there?</p>", @batch[1][:content])
79
+ end
80
+
81
+ should "have a hash with a valid url" do
82
+ assert_equal("http://example.com/post/71845593082", @batch[1][:url])
83
+ end
84
+
85
+ should "have a hash with a valid slug" do
86
+ assert_equal("http://example.com/post/71845593082/knock-knock", @batch[1][:slug])
87
+ end
88
+ end
89
+ end
90
+ end