middleman-apps 0.1.0 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (83) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +3 -0
  3. data/.rubocop.yml +2 -1
  4. data/Gemfile +4 -0
  5. data/{LICENSE.txt → LICENSE} +0 -0
  6. data/README.md +166 -40
  7. data/features/e_asset_hash.feature +17 -0
  8. data/features/{directory_indexes.feature → e_directory_indexes.feature} +14 -16
  9. data/features/e_relative_assets.feature +17 -0
  10. data/features/f_code_reloading.feature +134 -0
  11. data/features/f_metadata.feature +25 -0
  12. data/features/{not_found_rack.feature → f_not_found.feature} +12 -22
  13. data/features/f_options.feature +39 -0
  14. data/features/step_definitions/capybara_steps.rb +18 -0
  15. data/features/step_definitions/mechanize_steps.rb +19 -0
  16. data/features/step_definitions/rack_app_steps.rb +4 -2
  17. data/features/support/aruba.rb +22 -0
  18. data/features/support/env.rb +0 -14
  19. data/features/support/helpers.rb +11 -0
  20. data/features/support/mechanize.rb +32 -0
  21. data/features/support/poltegeist.rb +35 -0
  22. data/features/v_activating.feature +74 -0
  23. data/features/v_building.feature +31 -0
  24. data/features/v_inheriting_from.feature +38 -0
  25. data/fixtures/asset_hash/apps/ignored_app.rb +10 -0
  26. data/fixtures/asset_hash/apps/test_app.rb +11 -0
  27. data/fixtures/asset_hash/config.rb +2 -0
  28. data/fixtures/asset_hash/source/error.html.erb +2 -0
  29. data/fixtures/{complex-app → asset_hash}/source/index.html.erb +0 -0
  30. data/fixtures/asset_hash/source/layouts/layout.erb +12 -0
  31. data/fixtures/asset_hash/source/layouts/page.erb +6 -0
  32. data/fixtures/asset_hash/source/stylesheets/style.css.scss.erb +5 -0
  33. data/fixtures/dir_index/apps/ignored_app.rb +10 -0
  34. data/fixtures/dir_index/apps/test_app.rb +10 -0
  35. data/fixtures/dir_index/config.rb +2 -0
  36. data/fixtures/{simple-app → dir_index}/source/index.html.erb +0 -0
  37. data/fixtures/mount_path/apps/test_app.rb +10 -0
  38. data/fixtures/mount_path/config.rb +1 -0
  39. data/fixtures/{complex-app/build/index.html → mount_path/source/index.html.erb} +0 -0
  40. data/fixtures/real_world/apps/awesome_api.rb +40 -0
  41. data/fixtures/{complex-app → real_world}/apps/child_app.rb +15 -2
  42. data/fixtures/{complex-app/apps/test_app.rb → real_world/apps/ignored_app.rb} +2 -2
  43. data/fixtures/real_world/apps/no_namespace.rb +8 -0
  44. data/fixtures/real_world/apps/test_app.rb +16 -0
  45. data/fixtures/real_world/config.rb +13 -0
  46. data/fixtures/real_world/source/apps.html.erb +14 -0
  47. data/fixtures/real_world/source/custom.html.erb +1 -0
  48. data/fixtures/{simple-app/build/index.html → real_world/source/index.html.erb} +0 -0
  49. data/fixtures/real_world/source/layouts/_partial.erb +1 -0
  50. data/fixtures/real_world/source/layouts/layout.erb +11 -0
  51. data/fixtures/real_world/source/layouts/page.erb +6 -0
  52. data/fixtures/real_world/source/layouts/test.html.markdown.erb +3 -0
  53. data/fixtures/relative_assets/apps/ignored_app.rb +10 -0
  54. data/fixtures/relative_assets/apps/test_app.rb +11 -0
  55. data/fixtures/relative_assets/config.rb +2 -0
  56. data/fixtures/relative_assets/source/error.html.erb +2 -0
  57. data/fixtures/relative_assets/source/index.html.erb +2 -0
  58. data/fixtures/relative_assets/source/layouts/layout.erb +12 -0
  59. data/fixtures/relative_assets/source/layouts/page.erb +6 -0
  60. data/fixtures/relative_assets/source/stylesheets/style.css.scss.erb +5 -0
  61. data/fixtures/simple/apps/ignored_app.rb +10 -0
  62. data/fixtures/simple/apps/test_app.rb +10 -0
  63. data/fixtures/simple/config.rb +1 -0
  64. data/fixtures/simple/source/index.html.erb +2 -0
  65. data/lib/middleman/apps.rb +26 -7
  66. data/lib/middleman/apps/base.rb +71 -15
  67. data/lib/middleman/apps/extension.rb +34 -158
  68. data/lib/middleman/apps/version.rb +2 -1
  69. data/lib/middleman/sitemap/app_collection.rb +225 -0
  70. data/lib/middleman/sitemap/app_resource.rb +61 -0
  71. metadata +77 -31
  72. data/features/activation.feature +0 -53
  73. data/features/build.feature +0 -20
  74. data/features/child_app.feature +0 -18
  75. data/features/complex_app.feature +0 -66
  76. data/features/not_found_server.feature +0 -8
  77. data/features/verbose.feature +0 -23
  78. data/fixtures/complex-app/apps/awesome_api.rb +0 -11
  79. data/fixtures/complex-app/build/error.html +0 -1
  80. data/fixtures/complex-app/config.rb +0 -1
  81. data/fixtures/simple-app/apps/test_app.rb +0 -8
  82. data/fixtures/simple-app/build/error.html +0 -1
  83. data/fixtures/simple-app/config.rb +0 -1
@@ -0,0 +1,25 @@
1
+ Feature: Setting metadata from Child App
2
+
3
+ Background:
4
+ Given successfully built app is running at "real_world"
5
+
6
+ Scenario: Default Metadata
7
+ When I go to "/test/metadata"
8
+ Then I should see metadata for "title" to be "Real World/Test App"
9
+ And I should see metadata for "description" to be empty
10
+ And I should see metadata for "html_description" to be empty
11
+ And I should see metadata for "routes" to be "[]"
12
+ And I should see metadata for "url" to be "/test"
13
+ And I should see metadata for "klass" to be "RealWorld::TestApp"
14
+
15
+ Scenario: Allow access to metadata and setting title and description
16
+ When I go to "/api/metadata"
17
+ Then the status code should be "200"
18
+ And I should see metadata for "title" to be "Awesome API"
19
+ And I should see metadata for "description" to have "## Awesome API v3"
20
+ And I should see metadata for "html_description" to have "<h2>Awesome API v3</h2>"
21
+
22
+ Scenario: Set routes and arbitrary information as metadata
23
+ When I go to "/api/metadata"
24
+ Then I should see metadata for "arbitrary" to be "defined"
25
+ And I should see metadata for "routes" to have "#GET /ping"
@@ -1,17 +1,18 @@
1
- Feature: 404 error pages using Rack and MiddlemanApps
1
+ Feature: 404 error pages with MiddlemanApps
2
2
 
3
3
  # Rack::NotFound's default response
4
+ @production
4
5
  Scenario: Default 404 response from Built app
5
- Given a fixture app "simple-app"
6
- And app is running
6
+ Given successfully built app is running at "simple"
7
7
  When I go to "/unknown-app"
8
8
  Then the status code should be "404"
9
9
  And I should see "Not found"
10
10
 
11
11
  # Use default 404 error page for `middleman-apps`:
12
12
  # Serve 404 pages from file: build/404.html
13
+ @production
13
14
  Scenario: 404 response from Built app when `404.html` exists
14
- Given a fixture app "simple-app"
15
+ Given a fixture app "simple"
15
16
  And a file named "source/404.html.erb" with:
16
17
  """
17
18
  <h1><%= (400+4).to_s + ' - Not Found' %></h1>
@@ -22,32 +23,21 @@ Feature: 404 error pages using Rack and MiddlemanApps
22
23
  And I should see "<h1>404 - Not Found</h1>"
23
24
 
24
25
  # Use custom error page for `middleman-apps`:
26
+ @production
25
27
  Scenario: With a custom error page
26
- Given a fixture app "simple-app"
28
+ Given a fixture app "real_world"
27
29
  And a file named "source/custom.html.erb" with:
28
30
  """
29
31
  <h2><%= 404 %> Custom Not Found!</h2>
30
32
  """
31
- And app is running with config:
32
- """
33
- activate :apps, not_found: "custom.html"
34
- """
33
+ And app is running
35
34
  When I go to "/unknown-app"
36
35
  Then the status code should be "404"
37
36
  And I should see "<h2>404 Custom Not Found!</h2>"
38
37
 
39
- # Use custom error page for `middleman-apps`:
40
- # Ensure that `build/404.html` is not being used for 404 pages now.
41
- Scenario: No default 404 with custom error page
42
- Given a fixture app "simple-app"
43
- And a file named "source/404.html.erb" with:
44
- """
45
- <h1>Not Found</h1>
46
- """
47
- And app is running with config:
48
- """
49
- activate :apps, not_found: "custom.html"
50
- """
38
+ @development
39
+ Scenario: Fixed 404 response with Server
40
+ Given the Server is running at "simple"
51
41
  When I go to "/unknown-app"
52
42
  Then the status code should be "404"
53
- And I should see "Not found"
43
+ And I should see "<h1>File Not Found</h1>"
@@ -0,0 +1,39 @@
1
+ Feature: Various options that can be provided to this extension
2
+
3
+ Scenario: Allows namespacing applications
4
+ Given successfully built app is running at "real_world"
5
+ When I go to "/child-app"
6
+ Then the status code should be "200"
7
+ And I should see "hello my world"
8
+
9
+ Scenario: Ignores modular apps that have no direct mapping
10
+ Given successfully built app is running at "real_world"
11
+ When I go to "/ignored-app"
12
+ Then the status code should be "404"
13
+
14
+ Scenario: Allows specifying different mount URL for an app
15
+ Given successfully built app is running at "real_world"
16
+ When I go to "/test"
17
+ Then the status code should be "200"
18
+ And I should see "fail"
19
+
20
+ Scenario: Allows specifying URL path for application
21
+ Given successfully built app is running at "real_world"
22
+ When I go to "/test-app?test=1"
23
+ Then the status code should be "404"
24
+ When I go to "/test?test=1"
25
+ Then the status code should be "200"
26
+ And I should see "pass"
27
+ When I go to "/awesome-api/ping"
28
+ Then the status code should be "404"
29
+ When I go to "/api/ping"
30
+ Then the status code should be "200"
31
+ And I should see "pong"
32
+
33
+ Scenario: Allows specifying mount point for all child apps
34
+ Given successfully built app is running at "mount_path"
35
+ When I go to "/test-app?test=1"
36
+ Then the status code should be "404"
37
+ When I go to "/a/b/c/d/test-app?test=1"
38
+ Then the status code should be "200"
39
+ And I should see "pass"
@@ -0,0 +1,18 @@
1
+ Then(/^I should see text "([^\"]*)"$/) do |text|
2
+ expect(page).to have_text(text)
3
+ end
4
+ Then(/^I should not see text "([^\"]*)"$/) do |text|
5
+ expect(page).to have_no_text(text)
6
+ end
7
+
8
+ Then(/^I should see metadata for "([^\"]*)" to be "([^\"]*)"$/) do |key, val|
9
+ expect(page.body).to include("#{key} => #{val}")
10
+ end
11
+
12
+ Then(/^I should see metadata for "([^\"]*)" to have "([^\"]*)"$/) do |key, val|
13
+ expect(page.body).to match(/^#{key} => .*#{Regexp.escape val}/)
14
+ end
15
+
16
+ Then(/^I should see metadata for "([^\"]*)" to be empty$/) do |key|
17
+ expect(page.body).to match(/^#{key} =>\s*$/)
18
+ end
@@ -0,0 +1,19 @@
1
+ Given(/^server is running in background$/) do
2
+ if development?
3
+ step %(I run `middleman server -p #{Capybara.server_port}` in background)
4
+ elsif production?
5
+ step %(I run `middleman build --clean`) ## trigger generation of config.ru
6
+ step %(I run `rackup -p #{Capybara.server_port}` in background)
7
+ else
8
+ raise 'You must set @development or @production tag before using this step'
9
+ end
10
+ sleep 8
11
+
12
+ # TODO: match partial output from background process in aruba?
13
+ # step %(I wait for stdout to contain "View your site at")
14
+ end
15
+
16
+ When(/^I go to "([^\"]*)" on local server$/) do |path|
17
+ sleep 5 # wait to ensure path has reloaded if required
18
+ visit "http://#{Capybara.server_host}:#{Capybara.server_port}#{path}"
19
+ end
@@ -1,5 +1,5 @@
1
- Given(/app is running(?: with config:)?/) do |*args|
2
- step %(I overwrite the file named "config.rb" with:), args[0] if args.any?
1
+ Given(/^(?:|successfully built )?app is running(?:| at "([^\"]*)")?$/) do |*args|
2
+ step %(a fixture app "#{args[0]}") if args.any?
3
3
  step %(I run `middleman build --verbose`)
4
4
  step %(was successfully built)
5
5
 
@@ -11,5 +11,7 @@ Given(/app is running(?: with config:)?/) do |*args|
11
11
  app, = Rack::Builder.parse_file('config.ru')
12
12
  end
13
13
 
14
+ # a built app that is running is always in production mode
15
+ ENV['RACK_ENV'] = 'production'
14
16
  Capybara.app = app.to_app
15
17
  end
@@ -0,0 +1,22 @@
1
+ Aruba.configure do |config|
2
+ config.activate_announcer_on_command_failure = [:stderr, :stdout, :command]
3
+ end
4
+
5
+ Before do
6
+ delete_environment_variable 'MM_ROOT'
7
+ end
8
+
9
+ After do
10
+ delete_environment_variable 'MM_ROOT'
11
+ ENV['MM_ROOT'] = nil
12
+ end
13
+
14
+ module Aruba
15
+ module Platforms
16
+ # Turn off deprecation warnings from Aruba,
17
+ # atleast on my current system :)
18
+ class UnixPlatform
19
+ def deprecated(*_args); end
20
+ end
21
+ end
22
+ end
@@ -2,17 +2,3 @@ PROJECT_ROOT_PATH = File.dirname(File.dirname(File.dirname(__FILE__)))
2
2
  require 'middleman-core'
3
3
  require 'middleman-core/step_definitions'
4
4
  require File.join(PROJECT_ROOT_PATH, 'lib', 'middleman/apps')
5
-
6
- Before do
7
- delete_environment_variable 'MM_ROOT'
8
- end
9
-
10
- module Aruba
11
- module Platforms
12
- # Turn off deprecation warnings from Aruba,
13
- # atleast on my current system :)
14
- class UnixPlatform
15
- def deprecated(*_args); end
16
- end
17
- end
18
- end
@@ -0,0 +1,11 @@
1
+ module CucumberHelpers
2
+ def development?
3
+ ENV['RACK_ENV'] == 'development'
4
+ end
5
+
6
+ def production?
7
+ ENV['RACK_ENV'] == 'production'
8
+ end
9
+ end
10
+
11
+ World(CucumberHelpers)
@@ -0,0 +1,32 @@
1
+ # FIXME: Remove this and figure out a way to reload Capybara app?
2
+ #
3
+ require 'capybara/mechanize'
4
+ require 'capybara/mechanize/cucumber'
5
+
6
+ After do
7
+ ENV['RACK_ENV'] = nil
8
+ end
9
+
10
+ Before '@development' do
11
+ ENV['RACK_ENV'] = 'development'
12
+ end
13
+
14
+ Before '@production' do
15
+ ENV['RACK_ENV'] = 'production'
16
+ end
17
+
18
+ Around '@mechanize' do |_scenario, block|
19
+ current_app = Capybara.app
20
+ Capybara.app = ->(_env) { [200, {}, []] }
21
+ Capybara.app_host = 'localhost:13579'
22
+ Capybara.server_port = 13_579
23
+ Capybara.run_server = true
24
+ Capybara.raise_server_errors = false
25
+
26
+ block.call
27
+
28
+ Capybara.app = current_app
29
+ Capybara.app_host = nil
30
+ Capybara.server_port = nil
31
+ Capybara.run_server = false
32
+ end
@@ -0,0 +1,35 @@
1
+ require 'capybara/poltergeist'
2
+
3
+ Capybara.default_driver = :rack_test
4
+ Capybara.register_driver :poltergeist do |app|
5
+ options = {
6
+ js_errors: true,
7
+ timeout: 120,
8
+ debug: false,
9
+ phantomjs_options: ['--load-images=no', '--disk-cache=false'],
10
+ inspector: true
11
+ }
12
+ Capybara::Poltergeist::Driver.new(app, options)
13
+ end
14
+ Capybara.javascript_driver = :poltergeist
15
+
16
+ After do
17
+ ENV['RACK_ENV'] = nil
18
+ end
19
+
20
+ Before '@development' do
21
+ ENV['RACK_ENV'] = 'development'
22
+ end
23
+
24
+ Before '@production' do
25
+ ENV['RACK_ENV'] = 'production'
26
+ end
27
+
28
+ Before '@reload' do
29
+ $LOADED_FEATURES.reject! { |f| f =~ %r{/tmp/aruba/} }
30
+ $LOADED_FEATURES.reject! { |f| f =~ %r{middleman/apps/base\.rb} }
31
+
32
+ %i[RealWorld OtherNamespace Simple].each do |const|
33
+ Object.send :remove_const, const if Object.const_defined? const
34
+ end
35
+ end
@@ -0,0 +1,74 @@
1
+ Feature: When Activating Middleman::Apps
2
+
3
+ Scenario: Without `middleman-apps`
4
+ Given a fixture app "simple"
5
+ And a file named "config.rb" with:
6
+ """
7
+ """
8
+ And the Server is running at "simple"
9
+ When I go to "/"
10
+ Then I should see "<h1>Middleman</h1>"
11
+ When I go to "/test-app"
12
+ Then the status code should be "404"
13
+ And I should see "<h1>File Not Found</h1>"
14
+
15
+ Scenario: Without `middleman-apps` but with Rack
16
+ Given a fixture app "simple"
17
+ And a file named "config.rb" with:
18
+ """
19
+ require 'sinatra'
20
+ require_relative 'apps/test_app'
21
+ map("/test-app") { run Simple::TestApp }
22
+ """
23
+ And the Server is running at "simple"
24
+ When I go to "/"
25
+ Then I should see "<h1>Middleman</h1>"
26
+ When I go to "/test-app"
27
+ Then I should see "fail"
28
+ When I go to "/test-app/?test=1"
29
+ Then I should see "pass"
30
+
31
+ Scenario: With `middleman-apps`
32
+ Given the Server is running at "simple"
33
+ When I go to "/"
34
+ Then I should see "<h1>Middleman</h1>"
35
+ When I go to "/test-app"
36
+ Then I should see "fail"
37
+ When I go to "/test-app/?test=1"
38
+ Then I should see "pass"
39
+
40
+ Scenario: Adds a `config.ru`
41
+ Given a fixture app "simple"
42
+ Then the file "config.ru" should not exist
43
+ When the Server is running at "simple"
44
+ Then the file "config.ru" should exist
45
+
46
+ Scenario: Allows changing path to apps directory
47
+ Given a fixture app "simple"
48
+ And I move the file named "apps/test_app.rb" to "other/test_app.rb"
49
+ And a file named "config.rb" with:
50
+ """
51
+ activate :apps, app_dir: 'other', namespace: 'Simple'
52
+ """
53
+ And the Server is running at "simple"
54
+ When I go to "/test-app/?test=1"
55
+ Then I should see "pass"
56
+
57
+ @production @slow
58
+ Scenario: Display list of child apps which were ignored
59
+ Given a fixture app "simple"
60
+ And I overwrite the file named "config.rb" with:
61
+ """
62
+ activate :apps, namespace: 'Simple', verbose: true
63
+ """
64
+ And I run `middleman build --verbose`
65
+ And the aruba exit timeout is 4 seconds
66
+ And I run `rackup -p 17283` in background
67
+ Then the output should match:
68
+ """
69
+ Ignored child app:.*apps\/ignored_app\.rb
70
+ """
71
+ And the output should not match:
72
+ """
73
+ Ignored child app:.*apps\/test_app\.rb
74
+ """
@@ -0,0 +1,31 @@
1
+ Feature: When building Middleman or after it
2
+
3
+ Scenario: Builds successfully
4
+ Given a fixture app "simple"
5
+ Then the file "config.ru" should not exist
6
+ Given a successfully built app at "simple"
7
+ Then the file "config.ru" should exist
8
+ And the file "build/index.html" should exist
9
+ And the file "build/apps/test_app.rb" should not exist
10
+
11
+ @production
12
+ Scenario: Running built app
13
+ Given successfully built app is running at "simple"
14
+ When I go to "/"
15
+ Then I should see "<h1>Middleman</h1>"
16
+ When I go to "/test-app"
17
+ Then I should see "fail"
18
+ When I go to "/test-app?test=1"
19
+ Then I should see "pass"
20
+
21
+ Scenario: Running built inherited app
22
+ Given successfully built app is running at "real_world"
23
+ When I go to "/"
24
+ Then I should see "<h1>Middleman</h1>"
25
+ When I go to "/child-app"
26
+ Then I should see "hello my world"
27
+ When I go to "/child-app/page/anystring"
28
+ Then I should see "<h3>rendered partial</h3>"
29
+ And I should see "<h3>via layout</h3>"
30
+ And I should see "<h3>via page</h3>"
31
+ And I should see "anystring"
@@ -0,0 +1,38 @@
1
+ Feature: Child apps inheriting from Middleman::Apps::Base
2
+
3
+ # Scenario: 404 response is same as Middleman app
4
+ # Given successfully built app is running at "real_world"
5
+ # When I go to "/test-app"
6
+ # Then I should see "Not found"
7
+ # When I go to "/child-app"
8
+ # Then I should see "hello my world"
9
+ # When I go to "/child-app/unknown"
10
+ # Then the status code should be "404"
11
+ # And I should see "Not found"
12
+
13
+ Scenario: Custom 404 response is same as Middleman app
14
+ Given a fixture app "real_world"
15
+ And a file named "source/custom.html.erb" with:
16
+ """
17
+ <h2><%= 404 %> Custom Not Found!</h2>
18
+ """
19
+ Given app is running
20
+ When I go to "/child-app"
21
+ Then I should see "hello my world"
22
+ When I go to "/child-app/unknown"
23
+ Then the status code should be "404"
24
+ And I should see "<h2>404 Custom Not Found!</h2>"
25
+
26
+ Scenario: Multiple renderers are handled correctly in MM layouts
27
+ Given successfully built app is running at "real_world"
28
+ When I go to "/child-app/test"
29
+ Then I should see "<h1>Heading L1</h1>"
30
+ And I should see "<h2>Heading L2</h2>"
31
+
32
+ Scenario: Middleman template helpers can be used
33
+ Given successfully built app is running at "real_world"
34
+ When I go to "/child-app/page/somestr"
35
+ Then I should see "<h3>rendered partial</h3>"
36
+ And I should see "<h3>via layout</h3>"
37
+ And I should see "somestr"
38
+ And I should see "<h3>via page</h3>"