nesta 0.11.1 → 0.13.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (86) hide show
  1. checksums.yaml +5 -5
  2. data/.github/workflows/tests.yml +21 -0
  3. data/.gitmodules +0 -0
  4. data/CHANGES +44 -2
  5. data/Gemfile +1 -1
  6. data/Gemfile.lock +73 -55
  7. data/LICENSE +1 -1
  8. data/README.md +7 -14
  9. data/RELEASING.md +10 -9
  10. data/Rakefile +20 -3
  11. data/bin/nesta +1 -1
  12. data/config/deploy.rb.sample +1 -1
  13. data/lib/nesta/app.rb +4 -8
  14. data/lib/nesta/commands/demo/content.rb +28 -12
  15. data/lib/nesta/commands/edit.rb +2 -6
  16. data/lib/nesta/commands/new.rb +9 -11
  17. data/lib/nesta/commands/plugin/create.rb +7 -9
  18. data/lib/nesta/commands/template.rb +20 -0
  19. data/lib/nesta/commands/theme/create.rb +8 -8
  20. data/lib/nesta/commands/theme/enable.rb +3 -5
  21. data/lib/nesta/commands/theme/install.rb +12 -14
  22. data/lib/nesta/commands.rb +8 -0
  23. data/lib/nesta/config_file.rb +25 -0
  24. data/lib/nesta/helpers.rb +14 -0
  25. data/lib/nesta/models.rb +26 -22
  26. data/lib/nesta/navigation.rb +1 -1
  27. data/lib/nesta/system_command.rb +15 -0
  28. data/lib/nesta/version.rb +1 -1
  29. data/lib/nesta.rb +6 -1
  30. data/nesta.gemspec +11 -12
  31. data/templates/config/config.yml +1 -1
  32. data/{spec → test}/fixtures/nesta-plugin-test/Gemfile +0 -0
  33. data/{spec → test}/fixtures/nesta-plugin-test/Rakefile +0 -0
  34. data/{spec → test}/fixtures/nesta-plugin-test/lib/nesta-plugin-test/init.rb +0 -0
  35. data/{spec → test}/fixtures/nesta-plugin-test/lib/nesta-plugin-test/version.rb +0 -0
  36. data/{spec → test}/fixtures/nesta-plugin-test/lib/nesta-plugin-test.rb +0 -0
  37. data/{spec → test}/fixtures/nesta-plugin-test/nesta-plugin-test.gemspec +0 -0
  38. data/test/integration/atom_feed_test.rb +178 -0
  39. data/test/integration/commands/demo/content_test.rb +33 -0
  40. data/test/integration/commands/edit_test.rb +21 -0
  41. data/test/integration/commands/new_test.rb +91 -0
  42. data/test/integration/commands/plugin/create_test.rb +131 -0
  43. data/test/integration/commands/theme/create_test.rb +41 -0
  44. data/test/integration/commands/theme/enable_test.rb +28 -0
  45. data/test/integration/commands/theme/install_test.rb +66 -0
  46. data/test/integration/default_theme_test.rb +220 -0
  47. data/test/integration/overrides_test.rb +118 -0
  48. data/test/integration/route_handlers_test.rb +96 -0
  49. data/test/integration/sitemap_test.rb +85 -0
  50. data/test/integration_test_helper.rb +61 -0
  51. data/test/support/model_factory.rb +169 -0
  52. data/test/support/temporary_files.rb +33 -0
  53. data/test/support/test_configuration.rb +19 -0
  54. data/test/test_helper.rb +26 -0
  55. data/test/unit/config_test.rb +138 -0
  56. data/test/unit/file_model_test.rb +71 -0
  57. data/test/unit/menu_test.rb +82 -0
  58. data/test/unit/page_test.rb +571 -0
  59. data/test/unit/path_test.rb +41 -0
  60. data/test/unit/plugin_test.rb +47 -0
  61. data/test/unit/system_command_test.rb +20 -0
  62. data/views/master.sass +1 -1
  63. metadata +90 -89
  64. data/.hound.yml +0 -2
  65. data/.rspec +0 -1
  66. data/.travis.yml +0 -6
  67. data/lib/nesta/commands/command.rb +0 -58
  68. data/smoke-test.sh +0 -107
  69. data/spec/atom_spec.rb +0 -141
  70. data/spec/commands/demo/content_spec.rb +0 -65
  71. data/spec/commands/edit_spec.rb +0 -27
  72. data/spec/commands/new_spec.rb +0 -88
  73. data/spec/commands/plugin/create_spec.rb +0 -97
  74. data/spec/commands/system_spec.rb +0 -25
  75. data/spec/commands/theme/create_spec.rb +0 -41
  76. data/spec/commands/theme/enable_spec.rb +0 -44
  77. data/spec/commands/theme/install_spec.rb +0 -56
  78. data/spec/config_spec.rb +0 -127
  79. data/spec/model_factory.rb +0 -92
  80. data/spec/models_spec.rb +0 -700
  81. data/spec/overrides_spec.rb +0 -132
  82. data/spec/page_spec.rb +0 -560
  83. data/spec/path_spec.rb +0 -28
  84. data/spec/plugin_spec.rb +0 -51
  85. data/spec/sitemap_spec.rb +0 -105
  86. data/spec/spec_helper.rb +0 -114
@@ -1,11 +1,9 @@
1
- require File.expand_path('../command', File.dirname(__FILE__))
1
+ require File.expand_path('../../config_file', File.dirname(__FILE__))
2
2
 
3
3
  module Nesta
4
4
  module Commands
5
5
  module Theme
6
6
  class Enable
7
- include Command
8
-
9
7
  def initialize(*args)
10
8
  name = args.shift
11
9
  options = args.shift || {}
@@ -13,8 +11,8 @@ module Nesta
13
11
  @name = name
14
12
  end
15
13
 
16
- def execute
17
- update_config_yaml(/^\s*#?\s*theme:.*/, "theme: #{@name}")
14
+ def execute(process)
15
+ Nesta::ConfigFile.new.set_value('theme', @name)
18
16
  end
19
17
  end
20
18
  end
@@ -1,27 +1,25 @@
1
- require File.expand_path('../command', File.dirname(__FILE__))
2
-
3
1
  module Nesta
4
2
  module Commands
5
3
  module Theme
6
4
  class Install
7
- include Command
8
-
9
5
  def initialize(*args)
10
- url = args.shift
6
+ @url = args.shift
7
+ @url.nil? && (raise UsageError.new('URL not specified'))
11
8
  options = args.shift || {}
12
- url.nil? && (raise UsageError.new('URL not specified'))
13
- @url = url
14
- @name = File.basename(url, '.git').sub(/nesta-theme-/, '')
15
9
  end
16
10
 
17
- def execute
18
- run_process('git', 'clone', @url, "themes/#{@name}")
19
- FileUtils.rm_r(File.join("themes/#{@name}", '.git'))
20
- enable
11
+ def theme_name
12
+ File.basename(@url, '.git').sub(/nesta-theme-/, '')
13
+ end
14
+
15
+ def execute(process)
16
+ process.run('git', 'clone', @url, "themes/#{theme_name}")
17
+ FileUtils.rm_rf(File.join("themes/#{theme_name}", '.git'))
18
+ enable(process)
21
19
  end
22
20
 
23
- def enable
24
- Enable.new(@name).execute
21
+ def enable(process)
22
+ Enable.new(theme_name).execute(process)
25
23
  end
26
24
  end
27
25
  end
@@ -4,10 +4,18 @@ require 'fileutils'
4
4
  require File.expand_path('env', File.dirname(__FILE__))
5
5
  require File.expand_path('app', File.dirname(__FILE__))
6
6
  require File.expand_path('path', File.dirname(__FILE__))
7
+ require File.expand_path('system_command', File.dirname(__FILE__))
7
8
  require File.expand_path('version', File.dirname(__FILE__))
8
9
 
9
10
  require File.expand_path('commands/demo', File.dirname(__FILE__))
10
11
  require File.expand_path('commands/edit', File.dirname(__FILE__))
11
12
  require File.expand_path('commands/new', File.dirname(__FILE__))
12
13
  require File.expand_path('commands/plugin', File.dirname(__FILE__))
14
+ require File.expand_path('commands/template', File.dirname(__FILE__))
13
15
  require File.expand_path('commands/theme', File.dirname(__FILE__))
16
+
17
+ module Nesta
18
+ module Commands
19
+ class UsageError < RuntimeError; end
20
+ end
21
+ end
@@ -0,0 +1,25 @@
1
+ module Nesta
2
+ class ConfigFile
3
+ def set_value(key, value)
4
+ pattern = /^\s*#?\s*#{key}:.*/
5
+ replacement = "#{key}: #{value}"
6
+
7
+ configured = false
8
+ File.open(Nesta::Config.yaml_path, 'r+') do |file|
9
+ output = ''
10
+ file.each_line do |line|
11
+ if configured
12
+ output << line
13
+ else
14
+ output << line.sub(pattern, replacement)
15
+ configured = true if line =~ pattern
16
+ end
17
+ end
18
+ output << "#{replacement}\n" unless configured
19
+ file.pos = 0
20
+ file.print(output)
21
+ file.truncate(file.pos)
22
+ end
23
+ end
24
+ end
25
+ end
data/lib/nesta/helpers.rb CHANGED
@@ -42,6 +42,20 @@ module Nesta
42
42
  end
43
43
  end
44
44
 
45
+ # Returns the current page's heading or the site's title, if we
46
+ # don't have a current page, or the page doesn't have a heading
47
+ # defined.
48
+ #
49
+ # Useful in templates that generate links to social sharing sites,
50
+ # which need a suitable description for the page being shared or
51
+ # bookmarked.
52
+ #
53
+ def heading_or_site_title
54
+ @page && @page.heading
55
+ rescue Nesta::HeadingNotSet
56
+ @title
57
+ end
58
+
45
59
  def format_date(date)
46
60
  date.strftime("%d %B %Y")
47
61
  end
data/lib/nesta/models.rb CHANGED
@@ -1,10 +1,19 @@
1
1
  require 'time'
2
2
 
3
- Tilt.register Tilt::MarukuTemplate, 'mdown', 'md'
4
- Tilt.register Tilt::KramdownTemplate, 'mdown', 'md'
5
- Tilt.register Tilt::BlueClothTemplate, 'mdown', 'md'
6
- Tilt.register Tilt::RDiscountTemplate, 'mdown', 'md'
7
- Tilt.register Tilt::RedcarpetTemplate, 'mdown', 'md'
3
+ require 'rdiscount'
4
+
5
+ def register_template_handler(class_name, *extensions)
6
+ Tilt.register Tilt.const_get(class_name), *extensions
7
+ rescue LoadError
8
+ # Only one of the Markdown processors needs to be available, so we can
9
+ # safely ignore these load errors.
10
+ end
11
+
12
+ register_template_handler :MarukuTemplate, 'mdown', 'md'
13
+ register_template_handler :KramdownTemplate, 'mdown', 'md'
14
+ register_template_handler :BlueClothTemplate, 'mdown', 'md'
15
+ register_template_handler :RDiscountTemplate, 'mdown', 'md'
16
+ register_template_handler :RedcarpetTemplate, 'mdown', 'md'
8
17
 
9
18
  module Nesta
10
19
  class HeadingNotSet < RuntimeError; end
@@ -13,7 +22,7 @@ module Nesta
13
22
 
14
23
  class FileModel
15
24
  FORMATS = [:mdown, :md, :haml, :textile]
16
- @@page_cache = {}
25
+ @@model_cache = {}
17
26
  @@filename_cache = {}
18
27
 
19
28
  attr_reader :filename, :mtime
@@ -52,26 +61,21 @@ module Nesta
52
61
  end
53
62
 
54
63
  def self.needs_loading?(path, filename)
55
- @@page_cache[path].nil? || File.mtime(filename) > @@page_cache[path].mtime
64
+ @@model_cache[path].nil? || File.mtime(filename) > @@model_cache[path].mtime
56
65
  end
57
66
 
58
67
  def self.load(path)
59
68
  if (filename = find_file_for_path(path)) && needs_loading?(path, filename)
60
- @@page_cache[path] = self.new(filename)
69
+ @@model_cache[path] = self.new(filename)
61
70
  end
62
- @@page_cache[path]
71
+ @@model_cache[path]
63
72
  end
64
73
 
65
74
  def self.purge_cache
66
- @@page_cache = {}
75
+ @@model_cache = {}
67
76
  @@filename_cache = {}
68
77
  end
69
78
 
70
- def self.menu_items
71
- Nesta.deprecated('Page.menu_items', 'see Menu.top_level and Menu.for_path')
72
- Menu.top_level
73
- end
74
-
75
79
  def initialize(filename)
76
80
  @filename = filename
77
81
  @format = filename.split('.').last.to_sym
@@ -84,16 +88,20 @@ module Nesta
84
88
  @mtime = File.mtime(filename)
85
89
  end
86
90
 
91
+ def ==(other)
92
+ other.respond_to?(:path) && (self.path == other.path)
93
+ end
94
+
87
95
  def index_page?
88
96
  @filename =~ /\/?index\.\w+$/
89
97
  end
90
98
 
91
99
  def abspath
92
- page_path = @filename.sub(Nesta::Config.page_path, '')
100
+ file_path = @filename.sub(self.class.model_path, '')
93
101
  if index_page?
94
- File.dirname(page_path)
102
+ File.dirname(file_path)
95
103
  else
96
- File.join(File.dirname(page_path), File.basename(page_path, '.*'))
104
+ File.join(File.dirname(file_path), File.basename(file_path, '.*'))
97
105
  end
98
106
  end
99
107
 
@@ -206,10 +214,6 @@ module Nesta
206
214
  end.sort { |x, y| y.date <=> x.date }
207
215
  end
208
216
 
209
- def ==(other)
210
- other.respond_to?(:path) && (self.path == other.path)
211
- end
212
-
213
217
  def draft?
214
218
  flagged_as?('draft')
215
219
  end
@@ -70,7 +70,7 @@ module Nesta
70
70
  end
71
71
 
72
72
  def current_item?(item)
73
- request.path == item.abspath
73
+ request.path_info == item.abspath
74
74
  end
75
75
 
76
76
  def current_menu_item_class
@@ -0,0 +1,15 @@
1
+ module Nesta
2
+ class SystemCommand
3
+ def run(*args)
4
+ system(*args)
5
+ if ! $?.success?
6
+ message = if $?.exitstatus == 127
7
+ "#{args[0]} not found"
8
+ else
9
+ "'#{args.join(' ')}' failed with status #{$?.exitstatus}"
10
+ end
11
+ Nesta.fail_with(message)
12
+ end
13
+ end
14
+ end
15
+ end
data/lib/nesta/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Nesta
2
- VERSION = '0.11.1'
2
+ VERSION = '0.13.0'
3
3
  end
data/lib/nesta.rb CHANGED
@@ -4,6 +4,11 @@ module Nesta
4
4
  $stderr.puts "DEPRECATION WARNING: #{name} is deprecated; #{message}"
5
5
  end
6
6
  end
7
+
8
+ def self.fail_with(message)
9
+ $stderr.puts "Error: #{message}"
10
+ exit 1
11
+ end
7
12
  end
8
13
 
9
- require 'nesta/plugin'
14
+ require File.expand_path('nesta/plugin', File.dirname(__FILE__))
data/nesta.gemspec CHANGED
@@ -24,28 +24,27 @@ Implementing your site's design is easy, but Nesta also has a small
24
24
  selection of themes to choose from.
25
25
  EOF
26
26
 
27
- s.rubyforge_project = "nesta"
28
-
29
27
  s.files = `git ls-files`.split("\n")
30
28
  s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
31
29
  s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
32
30
  s.require_paths = ["lib"]
33
31
 
34
- s.add_dependency('haml', '>= 3.1')
32
+ s.add_dependency('haml', '>= 3.1', '< 6.0')
35
33
  s.add_dependency('haml-contrib', '>= 1.0')
36
- s.add_dependency('rack', '>= 1.3')
34
+ s.add_dependency('rack', '~> 2.0')
37
35
  s.add_dependency('rdiscount', '~> 2.1')
38
36
  s.add_dependency('RedCloth', '~> 4.2')
39
- s.add_dependency('sass', '>= 3.1')
40
- s.add_dependency('sinatra', '~> 1.4')
41
- s.add_dependency('tilt', '~> 1.4')
37
+ s.add_dependency('sassc', '>= 2.2')
38
+ s.add_dependency('sinatra', '~> 2.0')
39
+ s.add_dependency('tilt', '~> 2.0')
42
40
 
43
41
  # Useful in development
44
- s.add_development_dependency('mr-sparkle', '>= 0.0.2')
42
+ s.add_development_dependency('mr-sparkle')
45
43
 
46
44
  # Test libraries
47
- s.add_development_dependency('rack-test', '0.6.1')
48
- s.add_development_dependency('rspec', '~> 2.14.0')
49
- s.add_development_dependency('test-unit', '1.2.3')
50
- s.add_development_dependency('webrat', '~> 0.7.3')
45
+ s.add_development_dependency('byebug')
46
+ s.add_development_dependency('capybara', '~> 2.0')
47
+ s.add_development_dependency('minitest', '~> 5.0')
48
+ s.add_development_dependency('minitest-reporters')
49
+ s.add_development_dependency('rake')
51
50
  end
@@ -8,7 +8,7 @@ subtitle: "(change this text in config/config.yml)"
8
8
  # Atom feed. Specify at least one of name, uri or email, and Nesta will
9
9
  # include it in your feed. See the Atom spec for more info:
10
10
  #
11
- # http://www.atomenabled.org/developers/syndication/atom-format-spec.php#element.feed
11
+ # https://tools.ietf.org/html/rfc4287#section-4.1.1
12
12
  #
13
13
  # author:
14
14
  # name: Your Name
File without changes
File without changes
@@ -0,0 +1,178 @@
1
+ require 'integration_test_helper'
2
+
3
+ describe 'Atom feed' do
4
+ include Nesta::IntegrationTest
5
+
6
+ def visit_feed
7
+ visit '/articles.xml'
8
+ end
9
+
10
+ describe 'site' do
11
+ it 'renders successfully' do
12
+ with_temp_content_directory do
13
+ visit_feed
14
+ assert_equal 200, page.status_code
15
+ end
16
+ end
17
+
18
+ it "uses Atom's XML namespace" do
19
+ with_temp_content_directory do
20
+ visit_feed
21
+ assert_has_xpath '//feed[@xmlns="http://www.w3.org/2005/Atom"]'
22
+ end
23
+ end
24
+
25
+ it 'has an ID element' do
26
+ with_temp_content_directory do
27
+ visit_feed
28
+ assert page.has_selector?('id:contains("tag:www.example.com,2009:/")')
29
+ end
30
+ end
31
+
32
+ it 'has an alternate link element' do
33
+ with_temp_content_directory do
34
+ visit_feed
35
+ assert_has_xpath(
36
+ '//feed/link[@rel="alternate"][@href="http://www.example.com/"]')
37
+ end
38
+ end
39
+
40
+ it 'has a self link element' do
41
+ with_temp_content_directory do
42
+ visit_feed
43
+ assert_has_xpath(
44
+ '//feed/link[@rel="self"][@href="http://www.example.com/articles.xml"]')
45
+ end
46
+ end
47
+
48
+ it 'has title and subtitle' do
49
+ site_config = {
50
+ 'title' => 'My blog',
51
+ 'subtitle' => 'about stuff',
52
+ }
53
+ stub_config(temp_content.merge(site_config)) do
54
+ visit_feed
55
+ assert_has_xpath '//feed/title[@type="text"]', text: 'My blog'
56
+ assert_has_xpath '//feed/subtitle[@type="text"]', text: 'about stuff'
57
+ end
58
+ end
59
+
60
+ it 'includes the author details' do
61
+ author_config = temp_content.merge('author' => {
62
+ 'name' => 'Fred Bloggs',
63
+ 'uri' => 'http://fredbloggs.com',
64
+ 'email' => 'fred@fredbloggs.com'
65
+ })
66
+ stub_config(temp_content.merge(author_config)) do
67
+ visit_feed
68
+ assert_has_xpath '//feed/author/name', text: 'Fred Bloggs'
69
+ assert_has_xpath '//feed/author/uri', text: 'http://fredbloggs.com'
70
+ assert_has_xpath '//feed/author/email', text: 'fred@fredbloggs.com'
71
+ end
72
+ end
73
+ end
74
+
75
+ describe 'site with articles' do
76
+ it 'only lists latest 10' do
77
+ with_temp_content_directory do
78
+ 11.times { create(:article) }
79
+ visit_feed
80
+ end
81
+ assert page.has_selector?('entry', count: 10), 'expected 10 articles'
82
+ end
83
+ end
84
+
85
+ def with_category(options = {})
86
+ with_temp_content_directory do
87
+ model = create(:category, options)
88
+ visit_feed
89
+ yield(model)
90
+ end
91
+ end
92
+
93
+ def with_article(options = {})
94
+ with_temp_content_directory do
95
+ article = create(:article, options)
96
+ visit_feed
97
+ yield(article)
98
+ end
99
+ end
100
+
101
+ def with_article_in_category(options = {})
102
+ with_temp_content_directory do
103
+ category = create(:category, options)
104
+ article_options = options.merge(metadata: {
105
+ 'categories' => category.path
106
+ })
107
+ article = create(:article, article_options)
108
+ visit_feed
109
+ yield(article, category)
110
+ end
111
+ end
112
+
113
+ describe 'article' do
114
+ it 'sets the title' do
115
+ with_article do |article|
116
+ assert_has_xpath '//entry/title', text: article.heading
117
+ end
118
+ end
119
+
120
+ it 'links to the HTML version' do
121
+ with_article do |article|
122
+ url = "http://www.example.com/#{article.path}"
123
+ assert_has_xpath(
124
+ "//entry/link[@href='#{url}'][@rel='alternate'][@type='text/html']")
125
+ end
126
+ end
127
+
128
+ it 'defines unique ID' do
129
+ with_article do |article|
130
+ assert_has_xpath(
131
+ '//entry/id', text: "tag:www.example.com,2008-12-29:#{article.abspath}")
132
+ end
133
+ end
134
+
135
+ it 'uses pre-defined ID if specified' do
136
+ with_article(metadata: { 'atom id' => 'use-this-id' }) do
137
+ assert_has_xpath '//entry/id', text: 'use-this-id'
138
+ end
139
+ end
140
+
141
+ it 'specifies date published' do
142
+ with_article do
143
+ assert_has_xpath '//entry/published', text: '2008-12-29T00:00:00+00:00'
144
+ end
145
+ end
146
+
147
+ it 'specifies article categories' do
148
+ with_article_in_category do |article, category|
149
+ assert_has_xpath "//category[@term='#{category.permalink}']"
150
+ end
151
+ end
152
+
153
+ it 'has article content' do
154
+ with_article do
155
+ assert_has_xpath '//entry/content[@type="html"]', text: 'Content'
156
+ end
157
+ end
158
+
159
+ it 'includes hostname in URLs' do
160
+ with_article(content: '[a link](/foo)') do
161
+ url = 'http://www.example.com/foo'
162
+ assert_has_xpath '//entry/content', text: url
163
+ end
164
+ end
165
+
166
+ it 'does not include article heading in content' do
167
+ with_article do |article|
168
+ assert page.has_no_selector?("summary:contains('#{article.heading}')")
169
+ end
170
+ end
171
+
172
+ it 'does not include pages with no date in feed' do
173
+ with_category(path: 'no-date') do
174
+ assert page.has_no_selector?('entry id:contains("no-date")')
175
+ end
176
+ end
177
+ end
178
+ end
@@ -0,0 +1,33 @@
1
+ require 'test_helper'
2
+ require_relative '../../../../lib/nesta/commands'
3
+
4
+ describe 'nesta demo:content' do
5
+ include TemporaryFiles
6
+
7
+ before do
8
+ Nesta::Commands::Demo::Content.demo_repository = '../../fixtures/demo-content.git'
9
+ end
10
+
11
+ def process_stub
12
+ Object.new.tap do |stub|
13
+ def stub.run(*args); end
14
+ end
15
+ end
16
+
17
+ it 'clones the demo repository and configures project to use it' do
18
+ in_temporary_project do
19
+ Nesta::Commands::Demo::Content.new.execute(process_stub)
20
+
21
+ yaml = File.read(File.join(project_root, 'config', 'config.yml'))
22
+ assert_match /content: content-demo/, yaml
23
+ end
24
+ end
25
+
26
+ it 'ensures demo repository is ignored by git' do
27
+ in_temporary_project do
28
+ FileUtils.mkdir('.git')
29
+ Nesta::Commands::Demo::Content.new.execute(process_stub)
30
+ assert_match /content-demo/, File.read(project_path('.git/info/exclude'))
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,21 @@
1
+ require 'test_helper'
2
+ require_relative '../../../lib/nesta/commands'
3
+
4
+ describe 'nesta edit' do
5
+ include TestConfiguration
6
+
7
+ after do
8
+ remove_temp_directory
9
+ end
10
+
11
+ it 'launches the editor' do
12
+ ENV['EDITOR'] = 'vi'
13
+ edited_file = 'path/to/page.md'
14
+ process = Minitest::Mock.new
15
+ process.expect(:run, true, [ENV['EDITOR'], /#{edited_file}$/])
16
+ with_temp_content_directory do
17
+ command = Nesta::Commands::Edit.new(edited_file)
18
+ command.execute(process)
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,91 @@
1
+ require 'test_helper'
2
+ require_relative '../../../lib/nesta/commands'
3
+
4
+ describe 'nesta new' do
5
+ include TemporaryFiles
6
+
7
+ def gemfile_source
8
+ File.read(project_path('Gemfile'))
9
+ end
10
+
11
+ def rakefile_source
12
+ File.read(project_path('Rakefile'))
13
+ end
14
+
15
+ after do
16
+ remove_temp_directory
17
+ end
18
+
19
+ def process_stub
20
+ Object.new.tap do |stub|
21
+ def stub.run(*args); end
22
+ end
23
+ end
24
+
25
+ describe 'without options' do
26
+ it 'creates the content directories' do
27
+ Nesta::Commands::New.new(project_root).execute(process_stub)
28
+ assert_exists_in_project 'content/attachments'
29
+ assert_exists_in_project 'content/pages'
30
+ end
31
+
32
+ it 'creates the home page' do
33
+ Nesta::Commands::New.new(project_root).execute(process_stub)
34
+ assert_exists_in_project 'content/pages/index.haml'
35
+ end
36
+
37
+ it 'creates the rackup file' do
38
+ Nesta::Commands::New.new(project_root).execute(process_stub)
39
+ assert_exists_in_project 'config.ru'
40
+ end
41
+
42
+ it 'creates the config.yml file' do
43
+ Nesta::Commands::New.new(project_root).execute(process_stub)
44
+ assert_exists_in_project 'config/config.yml'
45
+ end
46
+
47
+ it 'creates a Gemfile' do
48
+ Nesta::Commands::New.new(project_root).execute(process_stub)
49
+ assert_exists_in_project 'Gemfile'
50
+ assert_match /gem 'nesta'/, gemfile_source
51
+ end
52
+ end
53
+
54
+ describe 'with --git option' do
55
+ it 'creates a .gitignore file' do
56
+ command = Nesta::Commands::New.new(project_root, 'git' => '')
57
+ command.execute(process_stub)
58
+ assert_match /\.bundle/, File.read(project_path('.gitignore'))
59
+ end
60
+
61
+ it 'creates a git repo' do
62
+ command = Nesta::Commands::New.new(project_root, 'git' => '')
63
+ process = Minitest::Mock.new
64
+ process.expect(:run, true, ['git', 'init'])
65
+ process.expect(:run, true, ['git', 'add', '.'])
66
+ process.expect(:run, true, ['git', 'commit', '-m', 'Initial commit'])
67
+ command.execute(process)
68
+ end
69
+ end
70
+
71
+ describe 'with --vlad option' do
72
+ it 'adds vlad to Gemfile' do
73
+ Nesta::Commands::New.new(project_root, 'vlad' => '').execute(process_stub)
74
+ assert_match /gem 'vlad', '2.1.0'/, gemfile_source
75
+ assert_match /gem 'vlad-git', '2.2.0'/, gemfile_source
76
+ end
77
+
78
+ it 'configures the vlad rake tasks' do
79
+ Nesta::Commands::New.new(project_root, 'vlad' => '').execute(process_stub)
80
+ assert_exists_in_project 'Rakefile'
81
+ assert_match /require 'vlad'/, rakefile_source
82
+ end
83
+
84
+ it 'creates deploy.rb' do
85
+ Nesta::Commands::New.new(project_root, 'vlad' => '').execute(process_stub)
86
+ assert_exists_in_project 'config/deploy.rb'
87
+ deploy_source = File.read(project_path('config/deploy.rb'))
88
+ assert_match /set :application, 'mysite.com'/, deploy_source
89
+ end
90
+ end
91
+ end