monad 0.0.1

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.
Files changed (143) hide show
  1. data/CONTRIBUTING.md +68 -0
  2. data/Gemfile +2 -0
  3. data/LICENSE +21 -0
  4. data/README.md +88 -0
  5. data/Rakefile +136 -0
  6. data/bin/monad +102 -0
  7. data/cucumber.yml +3 -0
  8. data/features/create_sites.feature +112 -0
  9. data/features/data_sources.feature +76 -0
  10. data/features/drafts.feature +25 -0
  11. data/features/embed_filters.feature +60 -0
  12. data/features/markdown.feature +30 -0
  13. data/features/pagination.feature +54 -0
  14. data/features/permalinks.feature +65 -0
  15. data/features/post_data.feature +214 -0
  16. data/features/site_configuration.feature +206 -0
  17. data/features/site_data.feature +101 -0
  18. data/features/step_definitions/monad_steps.rb +175 -0
  19. data/features/support/env.rb +25 -0
  20. data/lib/monad.rb +90 -0
  21. data/lib/monad/command.rb +27 -0
  22. data/lib/monad/commands/build.rb +64 -0
  23. data/lib/monad/commands/doctor.rb +29 -0
  24. data/lib/monad/commands/new.rb +50 -0
  25. data/lib/monad/commands/serve.rb +33 -0
  26. data/lib/monad/configuration.rb +183 -0
  27. data/lib/monad/converter.rb +48 -0
  28. data/lib/monad/converters/identity.rb +21 -0
  29. data/lib/monad/converters/markdown.rb +43 -0
  30. data/lib/monad/converters/markdown/kramdown_parser.rb +44 -0
  31. data/lib/monad/converters/markdown/maruku_parser.rb +47 -0
  32. data/lib/monad/converters/markdown/rdiscount_parser.rb +35 -0
  33. data/lib/monad/converters/markdown/redcarpet_parser.rb +70 -0
  34. data/lib/monad/converters/textile.rb +50 -0
  35. data/lib/monad/convertible.rb +152 -0
  36. data/lib/monad/core_ext.rb +68 -0
  37. data/lib/monad/deprecator.rb +32 -0
  38. data/lib/monad/draft.rb +35 -0
  39. data/lib/monad/drivers/json_driver.rb +39 -0
  40. data/lib/monad/drivers/yaml_driver.rb +23 -0
  41. data/lib/monad/errors.rb +4 -0
  42. data/lib/monad/filters.rb +154 -0
  43. data/lib/monad/generator.rb +4 -0
  44. data/lib/monad/generators/pagination.rb +143 -0
  45. data/lib/monad/layout.rb +42 -0
  46. data/lib/monad/logger.rb +54 -0
  47. data/lib/monad/mime.types +85 -0
  48. data/lib/monad/page.rb +163 -0
  49. data/lib/monad/plugin.rb +75 -0
  50. data/lib/monad/post.rb +377 -0
  51. data/lib/monad/site.rb +455 -0
  52. data/lib/monad/static_file.rb +70 -0
  53. data/lib/monad/tags/gist.rb +30 -0
  54. data/lib/monad/tags/highlight.rb +85 -0
  55. data/lib/monad/tags/include.rb +37 -0
  56. data/lib/monad/tags/post_url.rb +61 -0
  57. data/lib/site_template/.gitignore +1 -0
  58. data/lib/site_template/_config.yml +2 -0
  59. data/lib/site_template/_layouts/default.html +46 -0
  60. data/lib/site_template/_layouts/post.html +9 -0
  61. data/lib/site_template/_posts/0000-00-00-welcome-to-monad.markdown.erb +24 -0
  62. data/lib/site_template/css/main.css +165 -0
  63. data/lib/site_template/css/syntax.css +60 -0
  64. data/lib/site_template/index.html +13 -0
  65. data/monad.gemspec +197 -0
  66. data/script/bootstrap +2 -0
  67. data/test/fixtures/broken_front_matter1.erb +5 -0
  68. data/test/fixtures/broken_front_matter2.erb +4 -0
  69. data/test/fixtures/broken_front_matter3.erb +7 -0
  70. data/test/fixtures/exploit_front_matter.erb +4 -0
  71. data/test/fixtures/front_matter.erb +4 -0
  72. data/test/fixtures/members.yaml +7 -0
  73. data/test/helper.rb +62 -0
  74. data/test/source/.htaccess +8 -0
  75. data/test/source/_includes/sig.markdown +3 -0
  76. data/test/source/_layouts/default.html +27 -0
  77. data/test/source/_layouts/simple.html +1 -0
  78. data/test/source/_plugins/dummy.rb +8 -0
  79. data/test/source/_posts/2008-02-02-not-published.textile +8 -0
  80. data/test/source/_posts/2008-02-02-published.textile +8 -0
  81. data/test/source/_posts/2008-10-18-foo-bar.textile +8 -0
  82. data/test/source/_posts/2008-11-21-complex.textile +8 -0
  83. data/test/source/_posts/2008-12-03-permalinked-post.textile +9 -0
  84. data/test/source/_posts/2008-12-13-include.markdown +8 -0
  85. data/test/source/_posts/2009-01-27-array-categories.textile +10 -0
  86. data/test/source/_posts/2009-01-27-categories.textile +7 -0
  87. data/test/source/_posts/2009-01-27-category.textile +7 -0
  88. data/test/source/_posts/2009-01-27-empty-categories.textile +7 -0
  89. data/test/source/_posts/2009-01-27-empty-category.textile +7 -0
  90. data/test/source/_posts/2009-03-12-hash-#1.markdown +6 -0
  91. data/test/source/_posts/2009-05-18-empty-tag.textile +6 -0
  92. data/test/source/_posts/2009-05-18-empty-tags.textile +6 -0
  93. data/test/source/_posts/2009-05-18-tag.textile +6 -0
  94. data/test/source/_posts/2009-05-18-tags.textile +9 -0
  95. data/test/source/_posts/2009-06-22-empty-yaml.textile +3 -0
  96. data/test/source/_posts/2009-06-22-no-yaml.textile +1 -0
  97. data/test/source/_posts/2010-01-08-triple-dash.markdown +5 -0
  98. data/test/source/_posts/2010-01-09-date-override.textile +7 -0
  99. data/test/source/_posts/2010-01-09-time-override.textile +7 -0
  100. data/test/source/_posts/2010-01-09-timezone-override.textile +7 -0
  101. data/test/source/_posts/2010-01-16-override-data.textile +4 -0
  102. data/test/source/_posts/2011-04-12-md-extension.md +7 -0
  103. data/test/source/_posts/2011-04-12-text-extension.text +0 -0
  104. data/test/source/_posts/2013-01-02-post-excerpt.markdown +14 -0
  105. data/test/source/_posts/2013-01-12-nil-layout.textile +6 -0
  106. data/test/source/_posts/2013-01-12-no-layout.textile +5 -0
  107. data/test/source/_posts/2013-03-19-not-a-post.markdown/.gitkeep +0 -0
  108. data/test/source/_posts/2013-04-11-custom-excerpt.markdown +10 -0
  109. data/test/source/_posts/2013-05-10-number-category.textile +7 -0
  110. data/test/source/_posts/es/2008-11-21-nested.textile +8 -0
  111. data/test/source/about.html +6 -0
  112. data/test/source/category/_posts/2008-9-23-categories.textile +6 -0
  113. data/test/source/contacts.html +5 -0
  114. data/test/source/contacts/bar.html +5 -0
  115. data/test/source/contacts/index.html +5 -0
  116. data/test/source/css/screen.css +76 -0
  117. data/test/source/deal.with.dots.html +7 -0
  118. data/test/source/foo/_posts/bar/2008-12-12-topical-post.textile +8 -0
  119. data/test/source/index.html +22 -0
  120. data/test/source/sitemap.xml +32 -0
  121. data/test/source/symlink-test/symlinked-file +22 -0
  122. data/test/source/win/_posts/2009-05-24-yaml-linebreak.markdown +7 -0
  123. data/test/source/z_category/_posts/2008-9-23-categories.textile +6 -0
  124. data/test/suite.rb +11 -0
  125. data/test/test_command.rb +39 -0
  126. data/test/test_configuration.rb +137 -0
  127. data/test/test_convertible.rb +51 -0
  128. data/test/test_core_ext.rb +88 -0
  129. data/test/test_filters.rb +102 -0
  130. data/test/test_generated_site.rb +83 -0
  131. data/test/test_json_driver.rb +63 -0
  132. data/test/test_kramdown.rb +35 -0
  133. data/test/test_new_command.rb +104 -0
  134. data/test/test_page.rb +193 -0
  135. data/test/test_pager.rb +115 -0
  136. data/test/test_post.rb +573 -0
  137. data/test/test_rdiscount.rb +22 -0
  138. data/test/test_redcarpet.rb +61 -0
  139. data/test/test_redcloth.rb +86 -0
  140. data/test/test_site.rb +374 -0
  141. data/test/test_tags.rb +310 -0
  142. data/test/test_yaml_driver.rb +35 -0
  143. metadata +554 -0
@@ -0,0 +1,22 @@
1
+ ---
2
+ layout: default
3
+ title: Tom Preston-Werner
4
+ ---
5
+
6
+ h1. Welcome to my site
7
+
8
+ h2. Please read our {{ site.posts | size }} Posts
9
+
10
+ <ul>
11
+ {% for post in site.posts %}
12
+ <li>{{ post.date }} <a href="{{ post.url }}">{{ post.title }}</a></li>
13
+ {% endfor %}
14
+ </ul>
15
+
16
+ {% assign first_post = site.posts.first %}
17
+ <div id="first_post">
18
+ <h1>{{ first_post.title }}</h1>
19
+ <div>
20
+ {{ first_post.content }}
21
+ </div>
22
+ </div>
@@ -0,0 +1,7 @@
1
+ ---
2
+ layout: post
3
+ title: "Test title"
4
+ tag: "Ruby"
5
+ ---
6
+
7
+ This is the content
@@ -0,0 +1,6 @@
1
+ ---
2
+ layout: default
3
+ title: Categories
4
+ ---
5
+
6
+ Categories _should_ work. Even if ordered after index.
@@ -0,0 +1,11 @@
1
+ require 'rubygems'
2
+ gem 'test-unit'
3
+ require 'test/unit'
4
+
5
+ # for some reason these tests fail when run via TextMate
6
+ # but succeed when run on the command line.
7
+
8
+ tests = Dir[File.expand_path("#{File.dirname(__FILE__)}/test_*.rb")]
9
+ tests.each do |file|
10
+ require file
11
+ end
@@ -0,0 +1,39 @@
1
+ require 'helper'
2
+
3
+ class TestCommand < Test::Unit::TestCase
4
+ context "when calling .globs" do
5
+ context "when non-default dest & source dirs" do
6
+ setup do
7
+ @source = source_dir
8
+ @dest = dest_dir
9
+ directory_with_contents(@dest)
10
+ @globs = Command.globs(@source, @dest)
11
+ end
12
+ should "return an array without the destination dir" do
13
+ assert @globs.is_a?(Array)
14
+ assert !@globs.include?(@dest)
15
+ end
16
+ teardown do
17
+ clear_dest
18
+ end
19
+ end
20
+ context "when using default dest dir" do
21
+ setup do
22
+ @source = test_dir
23
+ @dest = test_dir('_site')
24
+ directory_with_contents(@dest)
25
+ @globs = Command.globs(@source, @dest)
26
+ end
27
+ should "return an array without the destination dir" do
28
+ assert @globs.is_a?(Array)
29
+ assert !@globs.include?(@dest)
30
+ @globs.each do |glob|
31
+ assert !glob.include?(File.basename(@dest))
32
+ end
33
+ end
34
+ teardown do
35
+ FileUtils.rm_r(@dest)
36
+ end
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,137 @@
1
+ require 'helper'
2
+
3
+ class TestConfiguration < Test::Unit::TestCase
4
+ context "#stringify_keys" do
5
+ setup do
6
+ @mixed_keys = Configuration[{
7
+ 'markdown' => 'maruku',
8
+ :permalink => 'date',
9
+ 'baseurl' => '/',
10
+ :include => ['.htaccess'],
11
+ :source => './'
12
+ }]
13
+ @string_keys = Configuration[{
14
+ 'markdown' => 'maruku',
15
+ 'permalink' => 'date',
16
+ 'baseurl' => '/',
17
+ 'include' => ['.htaccess'],
18
+ 'source' => './'
19
+ }]
20
+ end
21
+ should "stringify symbol keys" do
22
+ assert_equal @string_keys, @mixed_keys.stringify_keys
23
+ end
24
+ should "not mess with keys already strings" do
25
+ assert_equal @string_keys, @string_keys.stringify_keys
26
+ end
27
+ end
28
+ context "#config_files" do
29
+ setup do
30
+ @config = Configuration[{"source" => source_dir}]
31
+ @no_override = {}
32
+ @one_config_file = {"config" => "config.yml"}
33
+ @multiple_files = {"config" => %w[config/site.yml config/deploy.yml configuration.yml]}
34
+ end
35
+
36
+ should "always return an array" do
37
+ assert @config.config_files(@no_override).is_a?(Array)
38
+ assert @config.config_files(@one_config_file).is_a?(Array)
39
+ assert @config.config_files(@multiple_files).is_a?(Array)
40
+ end
41
+ should "return the default config path if no config files are specified" do
42
+ assert_equal [File.join(source_dir, "_config.yml")], @config.config_files(@no_override)
43
+ end
44
+ should "return the config if given one config file" do
45
+ assert_equal %w[config.yml], @config.config_files(@one_config_file)
46
+ end
47
+ should "return an array of the config files if given many config files" do
48
+ assert_equal %w[config/site.yml config/deploy.yml configuration.yml], @config.config_files(@multiple_files)
49
+ end
50
+ end
51
+ context "#backwards_compatibilize" do
52
+ setup do
53
+ @config = Configuration[{
54
+ "auto" => true,
55
+ "watch" => true,
56
+ "server" => true
57
+ }]
58
+ end
59
+ should "unset 'auto' and 'watch'" do
60
+ assert @config.has_key?("auto")
61
+ assert @config.has_key?("watch")
62
+ assert !@config.backwards_compatibilize.has_key?("auto")
63
+ assert !@config.backwards_compatibilize.has_key?("watch")
64
+ end
65
+ should "unset 'server'" do
66
+ assert @config.has_key?("server")
67
+ assert !@config.backwards_compatibilize.has_key?("server")
68
+ end
69
+ end
70
+ context "loading configuration" do
71
+ setup do
72
+ @path = File.join(Dir.pwd, '_config.yml')
73
+ end
74
+
75
+ should "fire warning with no _config.yml" do
76
+ mock(YAML).safe_load_file(@path) { raise SystemCallError, "No such file or directory - #{@path}" }
77
+ mock($stderr).puts("Configuration file: none".yellow)
78
+ assert_equal Monad::Configuration::DEFAULTS, Monad.configuration({})
79
+ end
80
+
81
+ should "load configuration as hash" do
82
+ mock(YAML).safe_load_file(@path) { Hash.new }
83
+ mock($stdout).puts("Configuration file: #{@path}")
84
+ assert_equal Monad::Configuration::DEFAULTS, Monad.configuration({})
85
+ end
86
+
87
+ should "fire warning with bad config" do
88
+ mock(YAML).safe_load_file(@path) { Array.new }
89
+ mock($stderr).puts(("WARNING: ".rjust(20) + "Error reading configuration. Using defaults (and options).").yellow)
90
+ mock($stderr).puts("Configuration file: (INVALID) #{@path}".yellow)
91
+ assert_equal Monad::Configuration::DEFAULTS, Monad.configuration({})
92
+ end
93
+ end
94
+ context "loading config from external file" do
95
+ setup do
96
+ @paths = {
97
+ :default => File.join(Dir.pwd, '_config.yml'),
98
+ :other => File.join(Dir.pwd, '_config.live.yml'),
99
+ :empty => ""
100
+ }
101
+ end
102
+
103
+ should "load default config if no config_file is set" do
104
+ mock(YAML).safe_load_file(@paths[:default]) { Hash.new }
105
+ mock($stdout).puts("Configuration file: #{@paths[:default]}")
106
+ assert_equal Monad::Configuration::DEFAULTS, Monad.configuration({})
107
+ end
108
+
109
+ should "load different config if specified" do
110
+ mock(YAML).safe_load_file(@paths[:other]) { {"baseurl" => "http://wahoo.dev"} }
111
+ mock($stdout).puts("Configuration file: #{@paths[:other]}")
112
+ assert_equal Monad::Configuration::DEFAULTS.deep_merge({ "baseurl" => "http://wahoo.dev" }), Monad.configuration({ "config" => @paths[:other] })
113
+ end
114
+
115
+ should "load default config if path passed is empty" do
116
+ mock(YAML).safe_load_file(@paths[:default]) { Hash.new }
117
+ mock($stdout).puts("Configuration file: #{@paths[:default]}")
118
+ assert_equal Monad::Configuration::DEFAULTS, Monad.configuration({ "config" => @paths[:empty] })
119
+ end
120
+
121
+ should "load multiple config files" do
122
+ mock(YAML).safe_load_file(@paths[:default]) { Hash.new }
123
+ mock(YAML).safe_load_file(@paths[:other]) { Hash.new }
124
+ mock($stdout).puts("Configuration file: #{@paths[:default]}")
125
+ mock($stdout).puts("Configuration file: #{@paths[:other]}")
126
+ assert_equal Monad::Configuration::DEFAULTS, Monad.configuration({ "config" => [@paths[:default], @paths[:other]] })
127
+ end
128
+
129
+ should "load multiple config files and last config should win" do
130
+ mock(YAML).safe_load_file(@paths[:default]) { {"baseurl" => "http://example.dev"} }
131
+ mock(YAML).safe_load_file(@paths[:other]) { {"baseurl" => "http://wahoo.dev"} }
132
+ mock($stdout).puts("Configuration file: #{@paths[:default]}")
133
+ mock($stdout).puts("Configuration file: #{@paths[:other]}")
134
+ assert_equal Monad::Configuration::DEFAULTS.deep_merge({ "baseurl" => "http://wahoo.dev" }), Monad.configuration({ "config" => [@paths[:default], @paths[:other]] })
135
+ end
136
+ end
137
+ end
@@ -0,0 +1,51 @@
1
+ require 'helper'
2
+ require 'ostruct'
3
+
4
+ class TestConvertible < Test::Unit::TestCase
5
+ context "yaml front-matter" do
6
+ setup do
7
+ @convertible = OpenStruct.new
8
+ @convertible.extend Monad::Convertible
9
+ @base = File.expand_path('../fixtures', __FILE__)
10
+ end
11
+
12
+ should "parse the front-matter correctly" do
13
+ ret = @convertible.read_yaml(@base, 'front_matter.erb')
14
+ assert_equal({'test' => 'good'}, ret)
15
+ end
16
+
17
+ should "not parse if the front-matter is not at the start of the file" do
18
+ ret = @convertible.read_yaml(@base, 'broken_front_matter1.erb')
19
+ assert_equal({}, ret)
20
+ end
21
+
22
+ should "not parse if there is syntax error in front-matter" do
23
+ name = 'broken_front_matter2.erb'
24
+ out = capture_stdout do
25
+ ret = @convertible.read_yaml(@base, name)
26
+ assert_equal({}, ret)
27
+ end
28
+ assert_match(/YAML Exception|syntax error|Error reading file/, out)
29
+ assert_match(/#{File.join(@base, name)}/, out)
30
+ end
31
+
32
+ should "not allow ruby objects in yaml" do
33
+ out = capture_stdout do
34
+ @convertible.read_yaml(@base, 'exploit_front_matter.erb')
35
+ end
36
+ assert_no_match /undefined class\/module DoesNotExist/, out
37
+ end
38
+
39
+ if RUBY_VERSION >= '1.9.2'
40
+ should "not parse if there is encoding error in file" do
41
+ name = 'broken_front_matter3.erb'
42
+ out = capture_stdout do
43
+ ret = @convertible.read_yaml(@base, name)
44
+ assert_equal({}, ret)
45
+ end
46
+ assert_match(/invalid byte sequence in UTF-8/, out)
47
+ assert_match(/#{File.join(@base, name)}/, out)
48
+ end
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,88 @@
1
+ require 'helper'
2
+
3
+ class TestCoreExt < Test::Unit::TestCase
4
+ context "hash" do
5
+
6
+ context "pluralized_array" do
7
+
8
+ should "return empty array with no values" do
9
+ data = {}
10
+ assert_equal [], data.pluralized_array('tag', 'tags')
11
+ end
12
+
13
+ should "return empty array with no matching values" do
14
+ data = { 'foo' => 'bar' }
15
+ assert_equal [], data.pluralized_array('tag', 'tags')
16
+ end
17
+
18
+ should "return empty array with matching nil singular" do
19
+ data = { 'foo' => 'bar', 'tag' => nil, 'tags' => ['dog', 'cat'] }
20
+ assert_equal [], data.pluralized_array('tag', 'tags')
21
+ end
22
+
23
+ should "return single value array with matching singular" do
24
+ data = { 'foo' => 'bar', 'tag' => 'dog', 'tags' => ['dog', 'cat'] }
25
+ assert_equal ['dog'], data.pluralized_array('tag', 'tags')
26
+ end
27
+
28
+ should "return single value array with matching singular with spaces" do
29
+ data = { 'foo' => 'bar', 'tag' => 'dog cat', 'tags' => ['dog', 'cat'] }
30
+ assert_equal ['dog cat'], data.pluralized_array('tag', 'tags')
31
+ end
32
+
33
+ should "return empty array with matching nil plural" do
34
+ data = { 'foo' => 'bar', 'tags' => nil }
35
+ assert_equal [], data.pluralized_array('tag', 'tags')
36
+ end
37
+
38
+ should "return empty array with matching empty array" do
39
+ data = { 'foo' => 'bar', 'tags' => [] }
40
+ assert_equal [], data.pluralized_array('tag', 'tags')
41
+ end
42
+
43
+ should "return single value array with matching plural with single string value" do
44
+ data = { 'foo' => 'bar', 'tags' => 'dog' }
45
+ assert_equal ['dog'], data.pluralized_array('tag', 'tags')
46
+ end
47
+
48
+ should "return multiple value array with matching plural with single string value with spaces" do
49
+ data = { 'foo' => 'bar', 'tags' => 'dog cat' }
50
+ assert_equal ['dog', 'cat'], data.pluralized_array('tag', 'tags')
51
+ end
52
+
53
+ should "return single value array with matching plural with single value array" do
54
+ data = { 'foo' => 'bar', 'tags' => ['dog'] }
55
+ assert_equal ['dog'], data.pluralized_array('tag', 'tags')
56
+ end
57
+
58
+ should "return multiple value array with matching plural with multiple value array" do
59
+ data = { 'foo' => 'bar', 'tags' => ['dog', 'cat'] }
60
+ assert_equal ['dog', 'cat'], data.pluralized_array('tag', 'tags')
61
+ end
62
+
63
+ end
64
+
65
+ end
66
+
67
+ context "enumerable" do
68
+ context "glob_include?" do
69
+ should "return false with no glob patterns" do
70
+ assert ![].glob_include?("a.txt")
71
+ end
72
+
73
+ should "return false with all not match path" do
74
+ data = ["a*", "b?"]
75
+ assert !data.glob_include?("ca.txt")
76
+ assert !data.glob_include?("ba.txt")
77
+ end
78
+
79
+ should "return true with match path" do
80
+ data = ["a*", "b?", "**/a*"]
81
+ assert data.glob_include?("a.txt")
82
+ assert data.glob_include?("ba")
83
+ assert data.glob_include?("c/a/a.txt")
84
+ assert data.glob_include?("c/a/b/a.txt")
85
+ end
86
+ end
87
+ end
88
+ end
@@ -0,0 +1,102 @@
1
+ require 'helper'
2
+
3
+ class TestFilters < Test::Unit::TestCase
4
+ class MonadFilter
5
+ include Monad::Filters
6
+
7
+ def initialize
8
+ site = Monad::Site.new(Monad.configuration({}))
9
+ @context = Liquid::Context.new({}, {}, { :site => site })
10
+ end
11
+ end
12
+
13
+ context "filters" do
14
+ setup do
15
+ @filter = MonadFilter.new
16
+ @sample_time = Time.utc(2013, 03, 27, 11, 22, 33)
17
+ @time_as_string = "September 11, 2001 12:46:30 -0000"
18
+ end
19
+
20
+ should "textilize with simple string" do
21
+ assert_equal "<p>something <strong>really</strong> simple</p>", @filter.textilize("something *really* simple")
22
+ end
23
+
24
+ should "markdownify with simple string" do
25
+ assert_equal "<p>something <strong>really</strong> simple</p>", @filter.markdownify("something **really** simple")
26
+ end
27
+
28
+ should "convert array to sentence string with no args" do
29
+ assert_equal "", @filter.array_to_sentence_string([])
30
+ end
31
+
32
+ should "convert array to sentence string with one arg" do
33
+ assert_equal "1", @filter.array_to_sentence_string([1])
34
+ assert_equal "chunky", @filter.array_to_sentence_string(["chunky"])
35
+ end
36
+
37
+ should "convert array to sentence string with two args" do
38
+ assert_equal "1 and 2", @filter.array_to_sentence_string([1, 2])
39
+ assert_equal "chunky and bacon", @filter.array_to_sentence_string(["chunky", "bacon"])
40
+ end
41
+
42
+ should "convert array to sentence string with multiple args" do
43
+ assert_equal "1, 2, 3, and 4", @filter.array_to_sentence_string([1, 2, 3, 4])
44
+ assert_equal "chunky, bacon, bits, and pieces", @filter.array_to_sentence_string(["chunky", "bacon", "bits", "pieces"])
45
+ end
46
+
47
+ context "date filters" do
48
+ context "with Time object" do
49
+ should "format a date with short format" do
50
+ assert_equal "27 Mar 2013", @filter.date_to_string(@sample_time)
51
+ end
52
+
53
+ should "format a date with long format" do
54
+ assert_equal "27 March 2013", @filter.date_to_long_string(@sample_time)
55
+ end
56
+
57
+ should "format a time with xmlschema" do
58
+ assert_equal "2013-03-27T11:22:33Z", @filter.date_to_xmlschema(@sample_time)
59
+ end
60
+
61
+ should "format a time according to RFC-822" do
62
+ assert_equal "Wed, 27 Mar 2013 11:22:33 -0000", @filter.date_to_rfc822(@sample_time)
63
+ end
64
+ end
65
+
66
+ context "with String object" do
67
+ should "format a date with short format" do
68
+ assert_equal "11 Sep 2001", @filter.date_to_string(@time_as_string)
69
+ end
70
+
71
+ should "format a date with long format" do
72
+ assert_equal "11 September 2001", @filter.date_to_long_string(@time_as_string)
73
+ end
74
+
75
+ should "format a time with xmlschema" do
76
+ assert_equal "2001-09-11T12:46:30Z", @filter.date_to_xmlschema(@time_as_string)
77
+ end
78
+
79
+ should "format a time according to RFC-822" do
80
+ assert_equal "Tue, 11 Sep 2001 12:46:30 -0000", @filter.date_to_rfc822(@time_as_string)
81
+ end
82
+ end
83
+ end
84
+
85
+ should "escape xml with ampersands" do
86
+ assert_equal "AT&amp;T", @filter.xml_escape("AT&T")
87
+ assert_equal "&lt;code&gt;command &amp;lt;filename&amp;gt;&lt;/code&gt;", @filter.xml_escape("<code>command &lt;filename&gt;</code>")
88
+ end
89
+
90
+ should "escape space as plus" do
91
+ assert_equal "my+things", @filter.cgi_escape("my things")
92
+ end
93
+
94
+ should "escape special characters" do
95
+ assert_equal "hey%21", @filter.cgi_escape("hey!")
96
+ end
97
+
98
+ should "escape space as %20" do
99
+ assert_equal "my%20things", @filter.uri_escape("my things")
100
+ end
101
+ end
102
+ end