nesta 0.11.1 → 0.12.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.
Files changed (71) hide show
  1. checksums.yaml +5 -5
  2. data/.gitmodules +6 -0
  3. data/.travis.yml +9 -4
  4. data/CHANGES +18 -2
  5. data/Gemfile +1 -1
  6. data/Gemfile.lock +70 -54
  7. data/LICENSE +1 -1
  8. data/RELEASING.md +5 -6
  9. data/Rakefile +20 -3
  10. data/lib/nesta/app.rb +4 -8
  11. data/lib/nesta/commands/command.rb +1 -2
  12. data/lib/nesta/commands/demo/content.rb +23 -5
  13. data/lib/nesta/commands/theme/install.rb +9 -7
  14. data/lib/nesta/helpers.rb +14 -0
  15. data/lib/nesta/models.rb +26 -22
  16. data/lib/nesta/navigation.rb +1 -1
  17. data/lib/nesta/version.rb +1 -1
  18. data/nesta.gemspec +10 -11
  19. data/templates/config/config.yml +1 -1
  20. data/{spec → test}/fixtures/nesta-plugin-test/Gemfile +0 -0
  21. data/{spec → test}/fixtures/nesta-plugin-test/Rakefile +0 -0
  22. data/{spec → test}/fixtures/nesta-plugin-test/lib/nesta-plugin-test.rb +0 -0
  23. data/{spec → test}/fixtures/nesta-plugin-test/lib/nesta-plugin-test/init.rb +0 -0
  24. data/{spec → test}/fixtures/nesta-plugin-test/lib/nesta-plugin-test/version.rb +0 -0
  25. data/{spec → test}/fixtures/nesta-plugin-test/nesta-plugin-test.gemspec +0 -0
  26. data/test/integration/atom_feed_test.rb +178 -0
  27. data/test/integration/commands/demo/content_test.rb +31 -0
  28. data/test/integration/commands/edit_test.rb +21 -0
  29. data/test/integration/commands/new_test.rb +120 -0
  30. data/test/integration/commands/plugin/create_test.rb +128 -0
  31. data/test/integration/commands/theme/create_test.rb +35 -0
  32. data/test/integration/commands/theme/enable_test.rb +22 -0
  33. data/test/integration/commands/theme/install_test.rb +62 -0
  34. data/test/integration/default_theme_test.rb +220 -0
  35. data/test/integration/overrides_test.rb +118 -0
  36. data/test/integration/route_handlers_test.rb +96 -0
  37. data/test/integration/sitemap_test.rb +85 -0
  38. data/test/integration_test_helper.rb +61 -0
  39. data/test/support/model_factory.rb +169 -0
  40. data/test/support/silence_commands_during_tests.rb +5 -0
  41. data/test/support/temporary_files.rb +33 -0
  42. data/test/support/test_configuration.rb +19 -0
  43. data/test/test_helper.rb +26 -0
  44. data/test/unit/commands_test.rb +23 -0
  45. data/test/unit/config_test.rb +138 -0
  46. data/test/unit/file_model_test.rb +71 -0
  47. data/test/unit/menu_test.rb +82 -0
  48. data/test/unit/page_test.rb +571 -0
  49. data/test/unit/path_test.rb +41 -0
  50. data/test/unit/plugin_test.rb +47 -0
  51. data/views/master.sass +1 -1
  52. metadata +81 -85
  53. data/smoke-test.sh +0 -107
  54. data/spec/atom_spec.rb +0 -141
  55. data/spec/commands/demo/content_spec.rb +0 -65
  56. data/spec/commands/edit_spec.rb +0 -27
  57. data/spec/commands/new_spec.rb +0 -88
  58. data/spec/commands/plugin/create_spec.rb +0 -97
  59. data/spec/commands/system_spec.rb +0 -25
  60. data/spec/commands/theme/create_spec.rb +0 -41
  61. data/spec/commands/theme/enable_spec.rb +0 -44
  62. data/spec/commands/theme/install_spec.rb +0 -56
  63. data/spec/config_spec.rb +0 -127
  64. data/spec/model_factory.rb +0 -92
  65. data/spec/models_spec.rb +0 -700
  66. data/spec/overrides_spec.rb +0 -132
  67. data/spec/page_spec.rb +0 -560
  68. data/spec/path_spec.rb +0 -28
  69. data/spec/plugin_spec.rb +0 -51
  70. data/spec/sitemap_spec.rb +0 -105
  71. data/spec/spec_helper.rb +0 -114
@@ -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
@@ -1,3 +1,3 @@
1
1
  module Nesta
2
- VERSION = '0.11.1'
2
+ VERSION = '0.12.0'
3
3
  end
@@ -24,8 +24,6 @@ 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) }
@@ -33,19 +31,20 @@ EOF
33
31
 
34
32
  s.add_dependency('haml', '>= 3.1')
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
@@ -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,31 @@
1
+ require 'test_helper'
2
+ require_relative '../../../support/silence_commands_during_tests'
3
+ require_relative '../../../../lib/nesta/commands'
4
+
5
+ Nesta::Commands::Demo::Content.send(:include, SilenceCommandsDuringTests)
6
+
7
+ describe 'nesta demo:content' do
8
+ include TemporaryFiles
9
+
10
+ before do
11
+ Nesta::Commands::Demo::Content.demo_repository = '../../fixtures/demo-content.git'
12
+ end
13
+
14
+ it 'clones the demo repository and configures project to use it' do
15
+ in_temporary_project do
16
+ Nesta::Commands::Demo::Content.new.execute
17
+ assert_exists_in_project 'content-demo/pages/index.haml'
18
+
19
+ yaml = File.read(File.join(project_root, 'config', 'config.yml'))
20
+ assert_match /content: content-demo/, yaml
21
+ end
22
+ end
23
+
24
+ it 'ensures demo repository is ignored by git' do
25
+ in_temporary_project do
26
+ FileUtils.mkdir('.git')
27
+ Nesta::Commands::Demo::Content.new.execute
28
+ assert_match /content-demo/, File.read(project_path('.git/info/exclude'))
29
+ end
30
+ end
31
+ 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'] = 'touch'
13
+ edited_file = 'path/to/page.md'
14
+ with_temp_content_directory do
15
+ FileUtils.mkdir_p(Nesta::Config.page_path(File.dirname(edited_file)))
16
+ command = Nesta::Commands::Edit.new(edited_file)
17
+ command.execute
18
+ assert File.exist?(Nesta::Config.page_path(edited_file)), 'editor not run'
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,120 @@
1
+ require 'test_helper'
2
+ require_relative '../../support/silence_commands_during_tests'
3
+ require_relative '../../../lib/nesta/commands'
4
+
5
+ Nesta::Commands::New.send(:include, SilenceCommandsDuringTests)
6
+
7
+ describe 'nesta new' do
8
+ include TemporaryFiles
9
+
10
+ def gemfile_source
11
+ File.read(project_path('Gemfile'))
12
+ end
13
+
14
+ def rakefile_source
15
+ File.read(project_path('Rakefile'))
16
+ end
17
+
18
+ after do
19
+ remove_temp_directory
20
+ end
21
+
22
+ describe 'without options' do
23
+ it 'creates the content directories' do
24
+ Nesta::Commands::New.new(project_root).execute
25
+ assert_exists_in_project 'content/attachments'
26
+ assert_exists_in_project 'content/pages'
27
+ end
28
+
29
+ it 'creates the home page' do
30
+ Nesta::Commands::New.new(project_root).execute
31
+ assert_exists_in_project 'content/pages/index.haml'
32
+ end
33
+
34
+ it 'creates the rackup file' do
35
+ Nesta::Commands::New.new(project_root).execute
36
+ assert_exists_in_project 'config.ru'
37
+ end
38
+
39
+ it 'creates the config.yml file' do
40
+ Nesta::Commands::New.new(project_root).execute
41
+ assert_exists_in_project 'config/config.yml'
42
+ end
43
+
44
+ it 'creates a Gemfile' do
45
+ Nesta::Commands::New.new(project_root).execute
46
+ assert_exists_in_project 'Gemfile'
47
+ assert_match /gem 'nesta'/, gemfile_source
48
+ end
49
+ end
50
+
51
+ describe 'with --git option' do
52
+ it 'creates a .gitignore file' do
53
+ command = Nesta::Commands::New.new(project_root, 'git' => '')
54
+ command.stub(:run_process, nil) do
55
+ command.execute
56
+ assert_match /\.bundle/, File.read(project_path('.gitignore'))
57
+ end
58
+ end
59
+
60
+ def disabling_git_hooks
61
+ # I (@gma) have got a git repository template setup on my computer
62
+ # containing git hooks that automatically run ctags in a
63
+ # background process whenever I run `git commit`. The hooks are
64
+ # copied into new repositories when I run `git init`.
65
+ #
66
+ # The generation of the ctags file (in a forked process) causes a
67
+ # race condition; sometimes ctags will recreate a test's project
68
+ # folder and git directory after the test's `after` block has
69
+ # deleted it. If the project directory isn't removed after each
70
+ # test, the New command will throw an error in the subsequent
71
+ # test (complaining that the project directory already exists).
72
+ #
73
+ templates = temp_path('git_template')
74
+ FileUtils.mkdir_p(templates)
75
+ ENV['GIT_TEMPLATE_DIR'] = templates
76
+ yield
77
+ ENV.delete('GIT_TEMPLATE_DIR')
78
+ FileUtils.rm_r(templates)
79
+ end
80
+
81
+ it 'creates a git repo' do
82
+ disabling_git_hooks do
83
+ command = Nesta::Commands::New.new(project_root, 'git' => '')
84
+ command.execute
85
+ assert_exists_in_project '.git/config'
86
+ end
87
+ end
88
+
89
+ it 'commits the blank project' do
90
+ disabling_git_hooks do
91
+ command = Nesta::Commands::New.new(project_root, 'git' => '')
92
+ command.execute
93
+ Dir.chdir(project_root) do
94
+ assert_match /Initial commit/, `git log --pretty=oneline | head -n 1`
95
+ end
96
+ end
97
+ end
98
+ end
99
+
100
+ describe 'with --vlad option' do
101
+ it 'adds vlad to Gemfile' do
102
+ Nesta::Commands::New.new(project_root, 'vlad' => '').execute
103
+ assert_match /gem 'vlad', '2.1.0'/, gemfile_source
104
+ assert_match /gem 'vlad-git', '2.2.0'/, gemfile_source
105
+ end
106
+
107
+ it 'configures the vlad rake tasks' do
108
+ Nesta::Commands::New.new(project_root, 'vlad' => '').execute
109
+ assert_exists_in_project 'Rakefile'
110
+ assert_match /require 'vlad'/, rakefile_source
111
+ end
112
+
113
+ it 'creates deploy.rb' do
114
+ Nesta::Commands::New.new(project_root, 'vlad' => '').execute
115
+ assert_exists_in_project 'config/deploy.rb'
116
+ deploy_source = File.read(project_path('config/deploy.rb'))
117
+ assert_match /set :application, 'mysite.com'/, deploy_source
118
+ end
119
+ end
120
+ end
@@ -0,0 +1,128 @@
1
+ require 'test_helper'
2
+ require_relative '../../../../lib/nesta/commands'
3
+
4
+ describe 'nesta plugin:create' do
5
+ include TemporaryFiles
6
+
7
+ def working_directory
8
+ temp_path('plugins')
9
+ end
10
+
11
+ before do
12
+ FileUtils.mkdir_p(working_directory)
13
+ end
14
+
15
+ after do
16
+ remove_temp_directory
17
+ end
18
+
19
+ def plugin_name
20
+ 'my-feature'
21
+ end
22
+
23
+ def gem_name
24
+ "nesta-plugin-#{plugin_name}"
25
+ end
26
+
27
+ def create_plugin(&block)
28
+ Dir.chdir(working_directory) do
29
+ command = Nesta::Commands::Plugin::Create.new(plugin_name)
30
+ command.stub(:run_process, nil) do
31
+ command.execute
32
+ yield
33
+ end
34
+ end
35
+ end
36
+
37
+ def assert_exists_in_plugin(path)
38
+ full_path = File.join(gem_name, path)
39
+ assert File.exist?(full_path), "#{path} not found in plugin"
40
+ end
41
+
42
+ def assert_file_contains(path, pattern)
43
+ assert_match pattern, File.read(File.join(gem_name, path))
44
+ end
45
+
46
+ it "creates the gem's directory" do
47
+ create_plugin { assert File.directory?(gem_name), 'gem directory not found' }
48
+ end
49
+
50
+ it 'creates README.md file' do
51
+ create_plugin { assert_exists_in_plugin('README.md') }
52
+ end
53
+
54
+ it 'includes installation instructions in README.md' do
55
+ create_plugin do
56
+ assert_file_contains('README.md', /echo 'gem "#{gem_name}"' >> Gemfile/)
57
+ end
58
+ end
59
+
60
+ it 'creates .gitignore file' do
61
+ create_plugin { assert_exists_in_plugin('.gitignore') }
62
+ end
63
+
64
+ it 'creates the gemspec' do
65
+ create_plugin do
66
+ gemspec = "#{gem_name}.gemspec"
67
+ assert_exists_in_plugin(gemspec)
68
+ assert_file_contains(gemspec, %r{require "#{gem_name}/version"})
69
+ assert_file_contains(gemspec, %r{Nesta::Plugin::My::Feature::VERSION})
70
+ end
71
+ end
72
+
73
+ it 'creates a Gemfile' do
74
+ create_plugin { assert_exists_in_plugin('Gemfile') }
75
+ end
76
+
77
+ it 'creates Rakefile for packaging the gem' do
78
+ create_plugin { assert_exists_in_plugin('Rakefile') }
79
+ end
80
+
81
+ it "creates default folder for Ruby files" do
82
+ create_plugin do
83
+ code_directory = File.join(gem_name, 'lib', gem_name)
84
+ assert File.directory?(code_directory), 'directory for code not found'
85
+ end
86
+ end
87
+
88
+ it 'creates file required when gem loaded' do
89
+ create_plugin do
90
+ path = "#{File.join('lib', gem_name)}.rb"
91
+ assert_exists_in_plugin(path)
92
+ assert_file_contains(path, %r{require "#{gem_name}/version"})
93
+ end
94
+ end
95
+
96
+ it 'creates version.rb' do
97
+ create_plugin do
98
+ version = File.join('lib', gem_name, 'version.rb')
99
+ assert_exists_in_plugin(version)
100
+ assert_file_contains version, <<-EOF
101
+ module Nesta
102
+ module Plugin
103
+ module My
104
+ module Feature
105
+ VERSION = '0.1.0'
106
+ end
107
+ end
108
+ end
109
+ end
110
+ EOF
111
+ end
112
+ end
113
+
114
+ it 'creates skeleton code for the plugin in init.rb' do
115
+ create_plugin do
116
+ init = File.join('lib', gem_name, 'init.rb')
117
+ assert_exists_in_plugin(init)
118
+
119
+ assert_file_contains init, <<-MODULE
120
+ module Nesta
121
+ module Plugin
122
+ module My::Feature
123
+ MODULE
124
+
125
+ assert_file_contains init, 'helpers Nesta::Plugin::My::Feature::Helpers'
126
+ end
127
+ end
128
+ end