nesta 0.9.13 → 0.10.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 (53) hide show
  1. checksums.yaml +7 -0
  2. data/{spec/spec.opts → .rspec} +0 -0
  3. data/.travis.yml +3 -2
  4. data/CHANGES +130 -1
  5. data/Gemfile +1 -8
  6. data/Gemfile.lock +68 -51
  7. data/LICENSE +1 -1
  8. data/README.md +38 -6
  9. data/Rakefile +2 -5
  10. data/bin/nesta +59 -3
  11. data/config.ru +3 -0
  12. data/lib/nesta.rb +1 -1
  13. data/lib/nesta/app.rb +20 -17
  14. data/lib/nesta/commands.rb +6 -3
  15. data/lib/nesta/config.rb +52 -15
  16. data/lib/nesta/helpers.rb +30 -3
  17. data/lib/nesta/models.rb +48 -30
  18. data/lib/nesta/navigation.rb +32 -12
  19. data/lib/nesta/overrides.rb +5 -5
  20. data/lib/nesta/version.rb +1 -1
  21. data/nesta.gemspec +9 -10
  22. data/smoke-test.sh +102 -0
  23. data/spec/atom_spec.rb +52 -49
  24. data/spec/commands_spec.rb +22 -16
  25. data/spec/config_spec.rb +66 -6
  26. data/spec/fixtures/nesta-plugin-test/lib/nesta-plugin-test/init.rb +1 -3
  27. data/spec/model_factory.rb +16 -16
  28. data/spec/models_spec.rb +197 -144
  29. data/spec/overrides_spec.rb +21 -21
  30. data/spec/page_spec.rb +182 -136
  31. data/spec/sitemap_spec.rb +48 -43
  32. data/spec/spec_helper.rb +32 -17
  33. data/templates/Gemfile +5 -2
  34. data/templates/config/config.yml +13 -13
  35. data/templates/config/deploy.rb +2 -2
  36. data/templates/index.haml +2 -0
  37. data/templates/themes/app.rb +1 -1
  38. data/templates/themes/views/layout.haml +7 -0
  39. data/templates/themes/views/master.sass +3 -0
  40. data/templates/themes/views/page.haml +1 -0
  41. data/views/atom.haml +3 -3
  42. data/views/comments.haml +1 -1
  43. data/views/error.haml +1 -1
  44. data/views/feed.haml +1 -1
  45. data/views/layout.haml +6 -3
  46. data/views/master.sass +143 -133
  47. data/views/mixins.sass +53 -28
  48. data/views/normalize.scss +396 -0
  49. data/views/page_meta.haml +2 -2
  50. data/views/sitemap.haml +2 -2
  51. data/views/summaries.haml +2 -2
  52. metadata +155 -202
  53. data/lib/nesta/cache.rb +0 -138
@@ -2,10 +2,10 @@ module Nesta
2
2
  module Navigation
3
3
  module Renderers
4
4
  def display_menu(menu, options = {})
5
- defaults = { :class => nil, :levels => 2 }
5
+ defaults = { class: nil, levels: 2 }
6
6
  options = defaults.merge(options)
7
7
  if options[:levels] > 0
8
- haml_tag :ul, :class => options[:class] do
8
+ haml_tag :ul, class: options[:class] do
9
9
  menu.each do |item|
10
10
  display_menu_item(item, options)
11
11
  end
@@ -17,14 +17,14 @@ module Nesta
17
17
  if item.respond_to?(:each)
18
18
  if (options[:levels] - 1) > 0
19
19
  haml_tag :li do
20
- display_menu(item, :levels => (options[:levels] - 1))
20
+ display_menu(item, levels: (options[:levels] - 1))
21
21
  end
22
22
  end
23
23
  else
24
- html_class = current_item?(item) ? "current" : nil
25
- haml_tag :li, :class => html_class do
26
- haml_tag :a, :<, :href => url(item.abspath) do
27
- haml_concat item.heading
24
+ html_class = current_item?(item) ? current_menu_item_class : nil
25
+ haml_tag :li, class: html_class do
26
+ haml_tag :a, :<, href: path_to(item.abspath) do
27
+ haml_concat link_text(item)
28
28
  end
29
29
  end
30
30
  end
@@ -41,25 +41,45 @@ module Nesta
41
41
  end
42
42
 
43
43
  def display_breadcrumbs(options = {})
44
- haml_tag :ul, :class => options[:class] do
44
+ haml_tag :ul, class: options[:class] do
45
45
  breadcrumb_ancestors[0...-1].each do |page|
46
46
  haml_tag :li do
47
- haml_tag :a, :<, :href => url(page.abspath) do
48
- haml_concat breadcrumb_label(page)
47
+ haml_tag :a, :<, href: path_to(page.abspath), itemprop: 'url' do
48
+ haml_tag :span, :<, itemprop: 'title' do
49
+ haml_concat link_text(page)
50
+ end
49
51
  end
50
52
  end
51
53
  end
52
- haml_tag(:li) { haml_concat breadcrumb_label(@page) }
54
+ haml_tag(:li, class: current_breadcrumb_class) do
55
+ haml_concat link_text(@page)
56
+ end
53
57
  end
54
58
  end
55
59
 
60
+ def link_text(page)
61
+ page.link_text
62
+ rescue LinkTextNotSet
63
+ return 'Home' if page.abspath == '/'
64
+ raise
65
+ end
66
+
56
67
  def breadcrumb_label(page)
57
- (page.abspath == '/') ? 'Home' : page.heading
68
+ Nesta.deprecated('breadcrumb_label', 'use link_text')
69
+ link_text(page)
58
70
  end
59
71
 
60
72
  def current_item?(item)
61
73
  request.path == item.abspath
62
74
  end
75
+
76
+ def current_menu_item_class
77
+ 'current'
78
+ end
79
+
80
+ def current_breadcrumb_class
81
+ nil
82
+ end
63
83
  end
64
84
  end
65
85
  end
@@ -29,15 +29,15 @@ module Nesta
29
29
  end
30
30
 
31
31
  def self.load_local_app
32
- require Nesta::Path.local("app")
33
- rescue LoadError
32
+ app_file = Nesta::Path.local('app.rb')
33
+ require app_file if File.exist?(app_file)
34
34
  end
35
35
 
36
36
  def self.load_theme_app
37
37
  if Nesta::Config.theme
38
- require Nesta::Path.themes(Nesta::Config.theme, "app")
38
+ app_file = Nesta::Path.themes(Nesta::Config.theme, 'app.rb')
39
+ require app_file if File.exist?(app_file)
39
40
  end
40
- rescue LoadError
41
41
  end
42
42
 
43
43
  private
@@ -49,7 +49,7 @@ module Nesta
49
49
  [local_view_path, theme_view_path].each do |path|
50
50
  engines.each do |engine|
51
51
  if template_exists?(engine, path, template)
52
- return { :views => path }, engine
52
+ return { views: path }, engine
53
53
  end
54
54
  end
55
55
  end
@@ -1,3 +1,3 @@
1
1
  module Nesta
2
- VERSION = '0.9.13'
2
+ VERSION = '0.10.0'
3
3
  end
@@ -31,20 +31,19 @@ EOF
31
31
  s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
32
32
  s.require_paths = ["lib"]
33
33
 
34
- s.add_dependency('haml', '~> 3.1')
35
- s.add_dependency('sass', '~> 3.1')
36
- s.add_dependency('rdiscount', '~> 1.6')
34
+ s.add_dependency('haml', '>= 3.1')
35
+ s.add_dependency('sass', '>= 3.1')
36
+ s.add_dependency('rdiscount', '~> 2.1')
37
37
  s.add_dependency('RedCloth', '~> 4.2')
38
- s.add_dependency('sinatra', '~> 1.3')
39
- s.add_dependency('rack', '~> 1.1')
40
-
38
+ s.add_dependency('sinatra', '~> 1.4')
39
+ s.add_dependency('rack', '>= 1.3')
40
+
41
41
  # Useful in development
42
- s.add_dependency('shotgun', '>= 0.8')
42
+ s.add_development_dependency('mr-sparkle', '>= 0.0.2')
43
43
 
44
44
  # Test libraries
45
- s.add_development_dependency('hpricot', '0.8.4')
46
45
  s.add_development_dependency('rack-test', '0.6.1')
47
- s.add_development_dependency('rspec', '1.3.0')
48
- s.add_development_dependency('rspec_hpricot_matchers', '1.0')
46
+ s.add_development_dependency('rspec', '~> 2.14.0')
49
47
  s.add_development_dependency('test-unit', '1.2.3')
48
+ s.add_development_dependency('webrat', '~> 0.7.3')
50
49
  end
@@ -0,0 +1,102 @@
1
+ #!/bin/sh
2
+
3
+ # This script just makes it easy to test that Nesta can install a new
4
+ # site, launch it, and that it runs properly on supported versions of
5
+ # Ruby.
6
+ #
7
+ # It assumes you've got the relevant versions of Ruby installed locally
8
+ # via rbenv.
9
+
10
+
11
+ RUBIES="1.9.3-p392 2.0.0-p353 2.1.0 2.1.1"
12
+
13
+
14
+ ## Functions
15
+
16
+ log()
17
+ {
18
+ cat <<-EOF
19
+
20
+ ###############################################################################
21
+ ##
22
+ ## $1
23
+ ##
24
+ ###############################################################################
25
+
26
+ EOF
27
+ }
28
+
29
+ nesta_version()
30
+ {
31
+ grep VERSION lib/nesta/version.rb | sed -e 's/ //g' | cut -f 2 -d "'"
32
+ }
33
+
34
+ gem_file()
35
+ {
36
+ echo "nesta-$(nesta_version).gem"
37
+ }
38
+
39
+ get_ruby()
40
+ {
41
+ # Why not just use RUBY_VERSION? Because tmux can prevent rbenv from
42
+ # changing the local version if the RBENV_VERSION variable is set in
43
+ # another session. If we don't notice we'll think we've been testing
44
+ # Nesta under multiple versions, but in fact we'll just have been
45
+ # testing it under the same copy of Ruby every time.
46
+ ruby --version | cut -f 2 -d ' '
47
+ }
48
+
49
+ run_tests()
50
+ {
51
+ bundle install
52
+ bundle exec rake spec
53
+ }
54
+
55
+ build_and_install()
56
+ {
57
+ echo rm -f pkg/$(gem_file)
58
+ bundle install
59
+ bundle exec rake install
60
+ }
61
+
62
+ site_folder()
63
+ {
64
+ echo "test-site-${RUBY_VERSION}"
65
+ }
66
+
67
+ create_and_test_new_site()
68
+ {
69
+ bundle exec nesta new $(site_folder)
70
+ cd $(site_folder)
71
+ echo "gem 'haml-contrib'" >> Gemfile
72
+ bundle install
73
+ bundle exec nesta demo:content
74
+
75
+ log "Starting server in $(site_folder)"
76
+ set +e
77
+ bundle exec mr-sparkle
78
+ set -e
79
+
80
+ cd - >/dev/null
81
+ rm -rf $(site_folder)
82
+ }
83
+
84
+
85
+ ## Main program
86
+
87
+ set -e
88
+ [ -n "$DEBUG" ] && set -x
89
+
90
+ for RUBY_VERSION in $RUBIES; do
91
+ rbenv local $RUBY_VERSION
92
+ log "Rebuilding nesta gem with Ruby $(get_ruby)"
93
+
94
+ run_tests
95
+ build_and_install
96
+ create_and_test_new_site
97
+
98
+ read -p "Was Ruby ${RUBY_VERSION} okay? Press return to continue..."
99
+ done
100
+
101
+ rm -f .ruby-version
102
+ log "Reset Ruby version to $(get_ruby)"
@@ -4,7 +4,7 @@ require File.expand_path('model_factory', File.dirname(__FILE__))
4
4
  describe "atom feed" do
5
5
  include ModelFactory
6
6
  include RequestSpecHelper
7
-
7
+
8
8
  before(:each) do
9
9
  stub_configuration
10
10
  stub_config_key("author", {
@@ -14,41 +14,41 @@ describe "atom feed" do
14
14
  })
15
15
  get "/articles.xml"
16
16
  end
17
-
17
+
18
18
  after(:each) do
19
19
  remove_temp_directory
20
20
  end
21
-
21
+
22
22
  it "should render successfully" do
23
23
  last_response.should be_ok
24
24
  end
25
-
25
+
26
26
  it "should use Atom's XML namespace" do
27
- body.should have_tag("/feed[@xmlns=http://www.w3.org/2005/Atom]")
27
+ assert_xpath("//feed[@xmlns='http://www.w3.org/2005/Atom']")
28
28
  end
29
-
29
+
30
30
  it "should have an ID element" do
31
- body.should have_tag("/feed/id", "tag:example.org,2009:/")
31
+ assert_selector("id:contains('tag:example.org,2009:/')")
32
32
  end
33
-
33
+
34
34
  it "should have an alternate link element" do
35
- body.should have_tag("/feed/link[@rel=alternate][@href='http://example.org/']")
35
+ assert_xpath("//feed/link[@rel='alternate'][@href='http://example.org/']")
36
36
  end
37
37
 
38
38
  it "should have a self link element" do
39
- body.should have_tag(
40
- "/feed/link[@rel=self][@href='http://example.org/articles.xml']")
39
+ assert_xpath(
40
+ "//feed/link[@rel='self'][@href='http://example.org/articles.xml']")
41
41
  end
42
-
42
+
43
43
  it "should have title and subtitle" do
44
- body.should have_tag("/feed/title[@type=text]", "My blog")
45
- body.should have_tag("/feed/subtitle[@type=text]", "about stuff")
44
+ assert_xpath("//feed/title[@type='text']", content: "My blog")
45
+ assert_xpath("//feed/subtitle[@type='text']", content: "about stuff")
46
46
  end
47
-
47
+
48
48
  it "should include the author details" do
49
- body.should have_tag("/feed/author/name", "Fred Bloggs")
50
- body.should have_tag("/feed/author/uri", "http://fredbloggs.com")
51
- body.should have_tag("/feed/author/email", "fred@fredbloggs.com")
49
+ assert_xpath("//feed/author/name", content: "Fred Bloggs")
50
+ assert_xpath("//feed/author/uri", content: "http://fredbloggs.com")
51
+ assert_xpath("//feed/author/email", content: "fred@fredbloggs.com")
52
52
  end
53
53
 
54
54
  describe "for article" do
@@ -58,81 +58,84 @@ describe "atom feed" do
58
58
  @category = create_category
59
59
  11.times do |i|
60
60
  @articles << create_article(
61
- :heading => "Article #{i + 1}",
62
- :path => "article-#{i + 1}",
63
- :metadata => {
61
+ heading: "Article #{i + 1}",
62
+ path: "article-#{i + 1}",
63
+ metadata: {
64
64
  "categories" => @category.path,
65
65
  "date" => "#{i + 1} January 2009"
66
66
  },
67
- :content => "Blah blah\n\n## #{@heading}\n\n[link](/foo)"
67
+ content: "Blah blah\n\n## #{@heading}\n\n[link](/foo)"
68
68
  )
69
69
  end
70
70
  @article = @articles.last
71
71
  get "/articles.xml"
72
72
  end
73
-
73
+
74
74
  it "should set title" do
75
- body.should have_tag("entry/title", "Article 11")
75
+ assert_xpath("//entry/title", content: "Article 11")
76
76
  end
77
-
77
+
78
78
  it "should link to the HTML version" do
79
79
  url = "http://example.org/#{@article.path}"
80
- body.should have_tag(
81
- "entry/link[@href='#{url}'][@rel=alternate][@type='text/html']")
80
+ assert_xpath(
81
+ "//entry/link[@href='#{url}'][@rel='alternate'][@type='text/html']")
82
82
  end
83
-
83
+
84
84
  it "should define unique ID" do
85
- body.should have_tag(
86
- "entry/id", "tag:example.org,2009-01-11:#{@article.abspath}")
85
+ assert_xpath(
86
+ "//entry/id",
87
+ content: "tag:example.org,2009-01-11:#{@article.abspath}"
88
+ )
87
89
  end
88
-
90
+
89
91
  it "should specify date published" do
90
- body.should have_tag("entry/published", "2009-01-11T00:00:00+00:00")
92
+ assert_xpath("//entry/published", content: "2009-01-11T00:00:00+00:00")
91
93
  end
92
94
 
93
95
  it "should specify article categories" do
94
- body.should have_tag("category[@term=#{@category.permalink}]")
96
+ assert_xpath("//category[@term='#{@category.permalink}']")
95
97
  end
96
98
 
97
99
  it "should have article content" do
98
- body.should have_tag(
99
- "entry/content[@type=html]", /<h2[^>]*>#{@heading}<\/h2>/)
100
+ assert_xpath "//entry/content[@type='html']" do |a|
101
+ a.should contain "<h2>#{@heading}</h2>"
102
+ end
100
103
  end
101
-
104
+
102
105
  it "should include hostname in URLs" do
103
- body.should have_tag("entry/content",
104
- Regexp.new('href=.+http:\/\/example.org\/foo'))
106
+ assert_xpath("//entry/content") do |c|
107
+ c.should contain 'http://example.org/foo'
108
+ end
105
109
  end
106
-
110
+
107
111
  it "should not include article heading in content" do
108
- body.should_not have_tag("entry/summary", /#{@article.heading}/)
112
+ body.should_not have_selector("summary:contains('#{@article.heading}')")
109
113
  end
110
-
114
+
111
115
  it "should list the latest 10 articles" do
112
- body.should have_tag("entry", :count => 10)
113
- body.should_not have_tag("entry/title", @articles.first.heading)
116
+ assert_selector("entry", count: 10)
114
117
  end
115
118
  end
116
-
119
+
117
120
  describe "page with no date" do
118
121
  before(:each) do
119
- create_category(:path => "no-date")
122
+ create_category(path: "no-date")
120
123
  get "/articles.xml"
121
124
  end
122
125
 
123
126
  it "should not appear in feed" do
124
- body.should_not have_tag("entry/id", /tag.*no-date/)
127
+ body.should_not have_selector("entry id:contains('no-date')")
125
128
  end
126
129
  end
127
-
130
+
128
131
  describe "article with atom ID" do
129
132
  it "should use pre-defined ID" do
130
- create_article(:metadata => {
133
+ create_article(metadata: {
131
134
  "date" => "1 January 2009",
132
135
  "atom id" => "use-this-id"
133
136
  })
134
137
  get "/articles.xml"
135
- body.should have_tag("entry/id", "use-this-id")
138
+ assert_xpath("//entry/id", content: "use-this-id")
136
139
  end
137
140
  end
138
141
  end
@@ -63,7 +63,7 @@ describe "nesta" do
63
63
  describe "--git" do
64
64
  before(:each) do
65
65
  @command = Nesta::Commands::New.new(@project_path, 'git' => '')
66
- @command.stub!(:system)
66
+ @command.stub(:system)
67
67
  end
68
68
 
69
69
  it "should create a .gitignore file" do
@@ -111,13 +111,13 @@ describe "nesta" do
111
111
  before(:each) do
112
112
  @config_path = project_path('config/config.yml')
113
113
  FileUtils.mkdir_p(File.dirname(@config_path))
114
- Nesta::Config.stub!(:yaml_path).and_return(@config_path)
114
+ Nesta::Config.stub(:yaml_path).and_return(@config_path)
115
115
  create_config_yaml('content: path/to/content')
116
- Nesta::App.stub!(:root).and_return(@project_path)
116
+ Nesta::App.stub(:root).and_return(@project_path)
117
117
  @repo_url = 'git://github.com/gma/nesta-demo-content.git'
118
118
  @demo_path = project_path('content-demo')
119
119
  @command = Nesta::Commands::Demo::Content.new
120
- @command.stub!(:system)
120
+ @command.stub(:system)
121
121
  end
122
122
 
123
123
  it "should clone the repository" do
@@ -169,10 +169,10 @@ describe "nesta" do
169
169
 
170
170
  describe "edit" do
171
171
  before(:each) do
172
- Nesta::Config.stub!(:content_path).and_return('content')
172
+ Nesta::Config.stub(:content_path).and_return('content')
173
173
  @page_path = 'path/to/page.mdown'
174
174
  @command = Nesta::Commands::Edit.new(@page_path)
175
- @command.stub!(:system)
175
+ @command.stub(:system)
176
176
  end
177
177
 
178
178
  it "should launch the editor" do
@@ -185,7 +185,7 @@ describe "nesta" do
185
185
  it "should not try and launch an editor if environment not setup" do
186
186
  ENV.delete('EDITOR')
187
187
  @command.should_not_receive(:system)
188
- $stderr.stub!(:puts)
188
+ $stderr.stub(:puts)
189
189
  @command.execute
190
190
  end
191
191
  end
@@ -199,7 +199,7 @@ describe "nesta" do
199
199
  Dir.mkdir(@plugins_path)
200
200
  Dir.chdir(@plugins_path)
201
201
  @command = Nesta::Commands::Plugin::Create.new(@name)
202
- @command.stub!(:system)
202
+ @command.stub(:system)
203
203
  end
204
204
 
205
205
  after(:each) do
@@ -258,8 +258,8 @@ describe "nesta" do
258
258
  it "should specify plugin gem's dependencies" do
259
259
  @command.execute
260
260
  text = File.read(@gem_spec)
261
- text.should include('s.add_dependency("nesta", ">= 0.9.11")')
262
- text.should include('s.add_development_dependency("rake")')
261
+ text.should include('gem.add_dependency("nesta", ">= 0.9.11")')
262
+ text.should include('gem.add_development_dependency("rake")')
263
263
  end
264
264
  end
265
265
  end
@@ -270,8 +270,8 @@ describe "nesta" do
270
270
  @theme_dir = 'themes/mine'
271
271
  FileUtils.mkdir_p(File.join(@theme_dir, '.git'))
272
272
  @command = Nesta::Commands::Theme::Install.new(@repo_url)
273
- @command.stub!(:enable)
274
- @command.stub!(:system)
273
+ @command.stub(:enable)
274
+ @command.stub(:system)
275
275
  end
276
276
 
277
277
  after(:each) do
@@ -301,7 +301,7 @@ describe "nesta" do
301
301
  @other_theme_dir = 'themes/mytheme'
302
302
  FileUtils.mkdir_p(File.join(@other_theme_dir, '.git'))
303
303
  @command = Nesta::Commands::Theme::Install.new(@repo_url)
304
- @command.stub!(:enable)
304
+ @command.stub(:enable)
305
305
  end
306
306
 
307
307
  after(:each) do
@@ -319,7 +319,7 @@ describe "nesta" do
319
319
  describe "theme:enable" do
320
320
  before(:each) do
321
321
  config = temp_path('config.yml')
322
- Nesta::Config.stub!(:yaml_path).and_return(config)
322
+ Nesta::Config.stub(:yaml_path).and_return(config)
323
323
  @name = 'mytheme'
324
324
  @command = Nesta::Commands::Theme::Enable.new(@name)
325
325
  end
@@ -362,7 +362,7 @@ describe "nesta" do
362
362
  end
363
363
 
364
364
  before(:each) do
365
- Nesta::App.stub!(:root).and_return(TempFileHelper::TEMP_DIR)
365
+ Nesta::App.stub(:root).and_return(TempFileHelper::TEMP_DIR)
366
366
  @name = 'my-new-theme'
367
367
  Nesta::Commands::Theme::Create.new(@name).execute
368
368
  end
@@ -381,9 +381,15 @@ describe "nesta" do
381
381
  should_exist('app.rb')
382
382
  end
383
383
 
384
- it "should create public and view directories" do
384
+ it "should create public and views directories" do
385
385
  should_exist("public/#{@name}")
386
386
  should_exist('views')
387
387
  end
388
+
389
+ it "should copy the default view templates into views" do
390
+ %w(layout.haml page.haml master.sass).each do |file|
391
+ should_exist("views/#{file}")
392
+ end
393
+ end
388
394
  end
389
395
  end