frontman-ssg 0.0.2

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 (141) hide show
  1. checksums.yaml +7 -0
  2. data/.circleci/config.yml +42 -0
  3. data/.github/CODE_OF_CONDUCT.md +9 -0
  4. data/.github/ISSUE_TEMPLATE/bug_report.md +25 -0
  5. data/.github/ISSUE_TEMPLATE/feature_request.md +22 -0
  6. data/.github/PULL_REQUEST_TEMPLATE.md +22 -0
  7. data/.gitignore +5 -0
  8. data/.rubocop.yml +88 -0
  9. data/CHANGELOG.md +11 -0
  10. data/CONTRIBUTING.md +42 -0
  11. data/Gemfile +5 -0
  12. data/LICENSE.md +21 -0
  13. data/Rakefile +94 -0
  14. data/SECURITY.md +6 -0
  15. data/bin/frontman +6 -0
  16. data/frontman-ssg.gemspec +48 -0
  17. data/frontman.svg +2 -0
  18. data/lib/frontman.rb +15 -0
  19. data/lib/frontman/app.rb +175 -0
  20. data/lib/frontman/bootstrapper.rb +70 -0
  21. data/lib/frontman/builder/asset_pipeline.rb +55 -0
  22. data/lib/frontman/builder/builder.rb +193 -0
  23. data/lib/frontman/builder/file.rb +55 -0
  24. data/lib/frontman/builder/mapping.rb +54 -0
  25. data/lib/frontman/builder/statistics_collector.rb +37 -0
  26. data/lib/frontman/cli.rb +6 -0
  27. data/lib/frontman/commands/build.rb +76 -0
  28. data/lib/frontman/commands/init.rb +58 -0
  29. data/lib/frontman/commands/serve.rb +110 -0
  30. data/lib/frontman/concerns/dispatch_events.rb +56 -0
  31. data/lib/frontman/concerns/forward_calls_to_app.rb +28 -0
  32. data/lib/frontman/config.rb +52 -0
  33. data/lib/frontman/context.rb +125 -0
  34. data/lib/frontman/custom_struct.rb +44 -0
  35. data/lib/frontman/data_store.rb +106 -0
  36. data/lib/frontman/data_store_file.rb +60 -0
  37. data/lib/frontman/helpers/app_helper.rb +18 -0
  38. data/lib/frontman/helpers/link_helper.rb +35 -0
  39. data/lib/frontman/helpers/render_helper.rb +76 -0
  40. data/lib/frontman/helpers/url_helper.rb +11 -0
  41. data/lib/frontman/iterator.rb +48 -0
  42. data/lib/frontman/process/chain.rb +43 -0
  43. data/lib/frontman/process/processor.rb +11 -0
  44. data/lib/frontman/renderers/erb_renderer.rb +21 -0
  45. data/lib/frontman/renderers/haml_renderer.rb +22 -0
  46. data/lib/frontman/renderers/markdown_renderer.rb +26 -0
  47. data/lib/frontman/renderers/renderer.rb +26 -0
  48. data/lib/frontman/renderers/renderer_resolver.rb +26 -0
  49. data/lib/frontman/resource.rb +279 -0
  50. data/lib/frontman/sitemap_tree.rb +211 -0
  51. data/lib/frontman/toolbox/timer.rb +49 -0
  52. data/lib/frontman/version.rb +6 -0
  53. data/project-templates/default/.gitignore +2 -0
  54. data/project-templates/default/Gemfile +3 -0
  55. data/project-templates/default/config.rb +17 -0
  56. data/project-templates/default/data/site.yml +4 -0
  57. data/project-templates/default/helpers/site_helper.rb +7 -0
  58. data/project-templates/default/public/code.css +77 -0
  59. data/project-templates/default/public/frontman-logo.svg +2 -0
  60. data/project-templates/default/public/main.css +27 -0
  61. data/project-templates/default/public/main.js +1 -0
  62. data/project-templates/default/source/index.html.md.erb +7 -0
  63. data/project-templates/default/source/sitemap.xml.erb +11 -0
  64. data/project-templates/default/views/layouts/main.erb +19 -0
  65. data/project-templates/default/views/layouts/main.haml +15 -0
  66. data/project-templates/default/views/partials/menu.erb +7 -0
  67. data/project-templates/webpack/.gitignore +4 -0
  68. data/project-templates/webpack/Gemfile +3 -0
  69. data/project-templates/webpack/README.md +54 -0
  70. data/project-templates/webpack/assets/css/code.css +77 -0
  71. data/project-templates/webpack/assets/css/style.css +27 -0
  72. data/project-templates/webpack/assets/images/.gitkeep +0 -0
  73. data/project-templates/webpack/assets/images/frontman_logo.svg +2 -0
  74. data/project-templates/webpack/assets/js/index.js +1 -0
  75. data/project-templates/webpack/config.rb +24 -0
  76. data/project-templates/webpack/data/site.yml +4 -0
  77. data/project-templates/webpack/helpers/assets_helper.rb +24 -0
  78. data/project-templates/webpack/helpers/site_helper.rb +7 -0
  79. data/project-templates/webpack/package-lock.json +7603 -0
  80. data/project-templates/webpack/package.json +34 -0
  81. data/project-templates/webpack/source/index.html.md.erb +7 -0
  82. data/project-templates/webpack/source/sitemap.xml.erb +11 -0
  83. data/project-templates/webpack/views/layouts/main.erb +20 -0
  84. data/project-templates/webpack/views/layouts/main.haml +14 -0
  85. data/project-templates/webpack/views/partials/menu.erb +7 -0
  86. data/project-templates/webpack/views/partials/script_with_vendors.haml +5 -0
  87. data/project-templates/webpack/webpack/base.config.js +51 -0
  88. data/project-templates/webpack/webpack/dev.config.js +6 -0
  89. data/project-templates/webpack/webpack/prod.config.js +30 -0
  90. data/readme.md +80 -0
  91. data/sorbet/config +2 -0
  92. data/sorbet/rbi/hidden-definitions/errors.txt +27259 -0
  93. data/sorbet/rbi/hidden-definitions/hidden.rbi +45122 -0
  94. data/sorbet/rbi/sorbet-typed/lib/rainbow/all/rainbow.rbi +276 -0
  95. data/sorbet/rbi/todo.rbi +6 -0
  96. data/spec/frontman/app_spec.rb +48 -0
  97. data/spec/frontman/bootstrapper_spec.rb +26 -0
  98. data/spec/frontman/builder/builder_spec.rb +79 -0
  99. data/spec/frontman/builder/file_spec.rb +45 -0
  100. data/spec/frontman/builder/mapping_spec.rb +8 -0
  101. data/spec/frontman/concerns/dispatch_events_spec.rb +70 -0
  102. data/spec/frontman/concerns/forward_calls_to_app_spec.rb +21 -0
  103. data/spec/frontman/config_spec.rb +54 -0
  104. data/spec/frontman/context_spec.rb +48 -0
  105. data/spec/frontman/custom_struct_spec.rb +51 -0
  106. data/spec/frontman/data_store_file_spec.rb +9 -0
  107. data/spec/frontman/data_store_spec.rb +36 -0
  108. data/spec/frontman/frontman_ssg_spec.rb +7 -0
  109. data/spec/frontman/helpers/app_helper_spec.rb +24 -0
  110. data/spec/frontman/helpers/link_helper_spec.rb +37 -0
  111. data/spec/frontman/helpers/render_helper_spec.rb +55 -0
  112. data/spec/frontman/helpers/url_helper_spec.rb +21 -0
  113. data/spec/frontman/iterator_spec.rb +47 -0
  114. data/spec/frontman/mocks/asset.css +3 -0
  115. data/spec/frontman/mocks/config.rb +0 -0
  116. data/spec/frontman/mocks/helpers/formatting_helper.rb +5 -0
  117. data/spec/frontman/mocks/helpers/language_helper.rb +5 -0
  118. data/spec/frontman/mocks/helpers/link_helper.rb +5 -0
  119. data/spec/frontman/mocks/helpers/test_command.rb +5 -0
  120. data/spec/frontman/mocks/html_file.html +8 -0
  121. data/spec/frontman/mocks/html_file.html.md.erb +9 -0
  122. data/spec/frontman/mocks/html_file.md.html +8 -0
  123. data/spec/frontman/mocks/info.yml +4 -0
  124. data/spec/frontman/mocks/layouts/raw_without_body.haml +1 -0
  125. data/spec/frontman/mocks/nested/data.yml +4 -0
  126. data/spec/frontman/mocks/nested/more_data.yml +4 -0
  127. data/spec/frontman/mocks/partials/paragraph.haml +2 -0
  128. data/spec/frontman/mocks/snippet/html_file.html +8 -0
  129. data/spec/frontman/mocks/snippet/html_file.yml +670 -0
  130. data/spec/frontman/mocks/test.html +8 -0
  131. data/spec/frontman/mocks/wrap.haml +3 -0
  132. data/spec/frontman/process/chain_spec.rb +56 -0
  133. data/spec/frontman/renderers/erb_renderer_spec.rb +22 -0
  134. data/spec/frontman/renderers/haml_renderer_spec.rb +12 -0
  135. data/spec/frontman/renderers/markdown_renderer_spec.rb +12 -0
  136. data/spec/frontman/renderers/renderer_spec.rb +16 -0
  137. data/spec/frontman/resource_spec.rb +151 -0
  138. data/spec/frontman/sitemap_tree_spec.rb +128 -0
  139. data/spec/frontman/toolbox/timer_spec.rb +34 -0
  140. data/spec/spec_setup.rb +19 -0
  141. metadata +507 -0
@@ -0,0 +1,8 @@
1
+ # typed: false
2
+ # frozen_string_literal: true
3
+
4
+ require './spec/spec_setup'
5
+ require 'frontman/builder/mapping'
6
+
7
+ describe Frontman::Builder::Mapping do
8
+ end
@@ -0,0 +1,70 @@
1
+ # typed: false
2
+ # frozen_string_literal: true
3
+
4
+ require './spec/spec_setup'
5
+ require 'frontman/concerns/dispatch_events'
6
+
7
+ describe Frontman::DispatchEvents do
8
+ let(:subject) do
9
+ Class.new do
10
+ include Frontman::DispatchEvents
11
+ end.new
12
+ end
13
+
14
+ it 'should register events properly' do
15
+ subject.on('test_event', lambda {
16
+ 'logic here'
17
+ })
18
+
19
+ expect(subject.listeners.length).to eq 1
20
+ expect(subject.listeners['test_event'.to_sym].length).to eq 1
21
+ end
22
+
23
+ it 'should register multiple events properly' do
24
+ subject.on('event1, event2', lambda {
25
+ 'logic here'
26
+ })
27
+
28
+ expect(subject.listeners.length).to eq 2
29
+ expect(subject.listeners['event1'.to_sym].length).to eq 1
30
+ expect(subject.listeners['event2'.to_sym].length).to eq 1
31
+ end
32
+
33
+ it 'should fire multiple events at once' do
34
+ first = false
35
+ second = false
36
+ subject.on('event1', lambda {
37
+ first = true
38
+ }).on('event2', lambda {
39
+ second = true
40
+ })
41
+
42
+ subject.emit 'event1, event2'
43
+
44
+ expect(first).to eq true
45
+ expect(second).to eq true
46
+ end
47
+
48
+ it 'should fire events properly and pass parameters when sending events' do
49
+ value = false
50
+ test_value = 'foo'
51
+ subject.on('event', lambda { |parameter|
52
+ value = parameter
53
+ })
54
+
55
+ subject.emit 'event', test_value
56
+
57
+ expect(value).to eq test_value
58
+ end
59
+
60
+ it 'remove event listeners' do
61
+ subject.on('test_event', lambda {
62
+ 'logic here'
63
+ })
64
+
65
+ subject.off('test_event')
66
+
67
+ expect(subject.listeners.length).to eq 1
68
+ expect(subject.listeners['test_event'.to_sym].length).to eq 0
69
+ end
70
+ end
@@ -0,0 +1,21 @@
1
+ # typed: false
2
+ # frozen_string_literal: true
3
+
4
+ require './spec/spec_setup'
5
+ require 'frontman/app'
6
+ require 'frontman/concerns/forward_calls_to_app'
7
+
8
+ describe Frontman::ForwardCallsToApp do
9
+ let(:subject) do
10
+ Class.new do
11
+ include Frontman::ForwardCallsToApp
12
+ end.new
13
+ end
14
+
15
+ it 'should forward missing method calls to App' do
16
+ app = Frontman::App.instance
17
+ expect(app).to receive(:non_existent_method)
18
+
19
+ subject.non_existent_method
20
+ end
21
+ end
@@ -0,0 +1,54 @@
1
+ # typed: false
2
+ # frozen_string_literal: true
3
+
4
+ require './spec/spec_setup'
5
+ require 'frontman/config'
6
+
7
+ describe Frontman::Config do
8
+ before(:each) do
9
+ Frontman::Config.all.keys.each do |key|
10
+ Frontman::Config.delete(key)
11
+ end
12
+ end
13
+
14
+ it 'should hold the correct value' do
15
+ Frontman::Config.set(:foo, 'bar')
16
+
17
+ expect(Frontman::Config.get('foo')).to eq 'bar'
18
+ end
19
+
20
+ it 'should not return the default if the set value is falsy' do
21
+ Frontman::Config.set(:foo, nil)
22
+
23
+ expect(Frontman::Config.get('foo', fallback: 'baz')).to eq nil
24
+ end
25
+
26
+ it 'should return the default value if the key is not set' do
27
+ expect(Frontman::Config.get('foo', fallback: 'baz')).to eq 'baz'
28
+ end
29
+
30
+ it 'should indicate whether the key exists' do
31
+ Frontman::Config.set(:foo, nil)
32
+
33
+ expect(Frontman::Config.has?('foo')).to eq true
34
+ expect(Frontman::Config.has?('bar')).to eq false
35
+ end
36
+
37
+ it 'should delete the config' do
38
+ expect(Frontman::Config.has?('foo')).to eq false
39
+ Frontman::Config.set(:foo, nil)
40
+ expect(Frontman::Config.has?('foo')).to eq true
41
+ Frontman::Config.delete(:foo)
42
+ expect(Frontman::Config.has?('foo')).to eq false
43
+ end
44
+
45
+ it 'should return all the config values' do
46
+ Frontman::Config.set(:foo, nil)
47
+ Frontman::Config.set('bar', 'baz')
48
+ expected = {
49
+ foo: nil,
50
+ bar: 'baz'
51
+ }
52
+ expect(Frontman::Config.all).to eq expected
53
+ end
54
+ end
@@ -0,0 +1,48 @@
1
+ # typed: false
2
+ # frozen_string_literal: true
3
+
4
+ require './spec/spec_setup'
5
+ require 'frontman/context'
6
+ require 'frontman/resource'
7
+
8
+ describe Frontman::Context do
9
+ subject { Frontman::Context.new }
10
+ let(:resource) { Frontman::Resource.from_path('spec/frontman/mocks/html_file.html') }
11
+
12
+ it 'should correctly handle attached methods' do
13
+ subject.singleton_class.send(:define_method, 'testing') { 'value' }
14
+ expect(subject.testing).to eq 'value'
15
+ end
16
+
17
+ it 'should correctly respond to attached methods' do
18
+ subject.singleton_class.send(:define_method, 'testing') { 'value' }
19
+ expect(subject.respond_to?('testing')).to eq true
20
+ end
21
+
22
+ context 'content' do
23
+ it 'should return nil for unknown content' do
24
+ expect(subject.yield_content('unknown content')).to eq nil
25
+ end
26
+
27
+ it 'should return not react to unknown content' do
28
+ expect(subject.content_for?('unknown content')).to eq false
29
+ end
30
+
31
+ it 'should return content when it\'s set' do
32
+ Frontman::App.instance.current_page = resource
33
+ subject.content_for('my-key', 'myvalue')
34
+ expect(subject.yield_content('my-key')).to eq 'myvalue'
35
+ end
36
+
37
+ it 'should react to known content' do
38
+ Frontman::App.instance.current_page = resource
39
+ subject.content_for('my-key', 'myvalue')
40
+ expect(subject.content_for?('my-key')).to eq true
41
+ end
42
+
43
+ it 'should wrap the layout properly' do
44
+ Frontman::Config.set(:layout_dir, 'spec/frontman/mocks/layouts')
45
+ expect(Frontman::Resource.from_path('spec/frontman/mocks/wrap.haml').render).to eq "<h1>This is a test!</h1>\n\n"
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,51 @@
1
+ # typed: false
2
+ # frozen_string_literal: true
3
+
4
+ require './spec/spec_setup'
5
+ require 'frontman/custom_struct'
6
+
7
+ describe CustomStruct do
8
+ context 'hash to ostruct' do
9
+ subject do
10
+ { merge: 'merge', test: 'test', test1: ['test1', { test2: 'test2' }] }.to_ostruct
11
+ end
12
+
13
+ it 'should allow access with method syntax' do
14
+ expect(subject.test).to eq 'test'
15
+ expect(subject.test1.class).to eq Array
16
+ expect(subject.test1[1].class).to eq described_class
17
+ expect(subject.test1[1].test2).to eq 'test2'
18
+ end
19
+
20
+ it 'should allow hash syntax ' do
21
+ expect(subject[:test]).to eq 'test'
22
+ expect(subject['test1'].class).to eq Array
23
+ end
24
+
25
+ it 'should allow hash syntax in combination with method syntax' do
26
+ expect(subject['test1'][1].class).to eq described_class
27
+ expect(subject['test1'][1].test2).to eq 'test2'
28
+ end
29
+
30
+ it 'should disallow keys named like hash methods' do
31
+ expect(subject.merge({})).not_to eq 'merge'
32
+ end
33
+
34
+ it 'should forward hash methods' do
35
+ expect(subject.size).to eq 3
36
+ end
37
+ end
38
+
39
+ context 'array to ostruct' do
40
+ subject { ['a_test', { test: 'test', test1: ['test1', { test2: 'test2' }] }].to_ostruct }
41
+
42
+ it 'should allow method syntax' do
43
+ expect(subject[0]).to eq 'a_test'
44
+
45
+ expect(subject[1].test).to eq 'test'
46
+ expect(subject[1].test1.class).to be Array
47
+ expect(subject[1].test1[1].class).to eq described_class
48
+ expect(subject[1].test1[1].test2).to eq 'test2'
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,9 @@
1
+ # typed: false
2
+ # frozen_string_literal: true
3
+
4
+ require './spec/spec_setup'
5
+ require 'lib/frontman/data_store_file'
6
+
7
+ describe Frontman::DataStoreFile do
8
+ # TODO: determine best tests
9
+ end
@@ -0,0 +1,36 @@
1
+ # typed: false
2
+ # frozen_string_literal: true
3
+
4
+ require './spec/spec_setup'
5
+ require 'lib/frontman/data_store'
6
+
7
+ describe Frontman::DataStore do
8
+ subject { Frontman::DataStore.new("#{__dir__}/mocks") }
9
+
10
+ it 'should ignore non-processable files' do
11
+ expect(subject.asset).to eq nil
12
+ end
13
+
14
+ it 'should flatten' do
15
+ expect(subject.flatten.size).to eq 4
16
+ expect(subject.nested.flatten.size).to eq 2
17
+ end
18
+
19
+ it 'should access data correctly' do
20
+ expect(subject.info.name).to eq 'test'
21
+ expect(subject.info.types).to be_a Array
22
+ end
23
+
24
+ it 'should return nil when accessing nonexistent files' do
25
+ expect(subject.non_existant).to eq nil
26
+ end
27
+
28
+ it 'should access parent folder' do
29
+ expect(subject.nested.more_data.parent.base_file_name).to eq 'nested'
30
+ end
31
+
32
+ it 'should have name and path' do
33
+ expect(subject.nested.base_file_name).to eq 'nested'
34
+ expect(subject.nested.path).to eq "#{__dir__}/mocks/nested"
35
+ end
36
+ end
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ require './spec/spec_setup'
4
+ require './lib/frontman'
5
+
6
+ describe Frontman do
7
+ end
@@ -0,0 +1,24 @@
1
+ # typed: false
2
+ # frozen_string_literal: true
3
+
4
+ require './spec/spec_setup'
5
+ require 'lib/frontman/helpers/app_helper'
6
+ require 'lib/frontman/config'
7
+
8
+ describe AppHelper do
9
+ subject do
10
+ Class.new do
11
+ include AppHelper
12
+ end.new
13
+ end
14
+
15
+ it 'should be in build mode if :mode config is set to build' do
16
+ Frontman::Config.set(:mode, 'build')
17
+ expect(subject.build?).to eq true
18
+ end
19
+
20
+ it 'should be in serve mode if :mode config by default' do
21
+ Frontman::Config.set(:mode, nil)
22
+ expect(subject.serve?).to eq true
23
+ end
24
+ end
@@ -0,0 +1,37 @@
1
+ # typed: false
2
+ # frozen_string_literal: true
3
+
4
+ require './spec/spec_setup'
5
+ require 'lib/frontman/helpers/link_helper'
6
+
7
+ describe LinkHelper do
8
+ subject do
9
+ Class.new do
10
+ include LinkHelper
11
+ end.new
12
+ end
13
+
14
+ before(:each) do
15
+ subject.reset_ids_generation
16
+ end
17
+
18
+ it 'should properly slugify a string' do
19
+ expect(subject.slugify('Hello world')).to eq 'hello-world'
20
+ end
21
+
22
+ it 'should generate an id' do
23
+ expect(subject.generate_id('Hello world')).to eq 'hello-world'
24
+ end
25
+
26
+ it 'should append numbers if an id is created multiple times' do
27
+ expect(subject.generate_id('Hello world')).to eq 'hello-world'
28
+ expect(subject.generate_id('Hello world')).to eq 'hello-world-2'
29
+ end
30
+
31
+ it 'should reset appended numbers' do
32
+ expect(subject.generate_id('Hello world')).to eq 'hello-world'
33
+ expect(subject.generate_id('Hello world')).to eq 'hello-world-2'
34
+ subject.reset_ids_generation
35
+ expect(subject.generate_id('Hello world')).to eq 'hello-world'
36
+ end
37
+ end
@@ -0,0 +1,55 @@
1
+ # typed: false
2
+ # frozen_string_literal: true
3
+
4
+ require './spec/spec_setup'
5
+ require 'lib/frontman/helpers/render_helper'
6
+ require 'lib/frontman/config'
7
+ require 'lib/frontman/resource'
8
+
9
+ describe RenderHelper do
10
+ subject do
11
+ Class.new do
12
+ include RenderHelper
13
+ end.new
14
+ end
15
+
16
+ context 'templating languages' do
17
+ it 'should render markdown' do
18
+ markdown = '# Hello world!'
19
+ html = "<h1 id=\"hello-world\">Hello world!</h1>\n"
20
+ expect(subject.render_markdown(markdown)).to eq html
21
+ end
22
+
23
+ it 'should render ERB' do
24
+ erb = '<h1><%= "Hello" %> <%= talk_to %>!</h1>'
25
+ html = '<h1>Hello world!</h1>'
26
+ expect(subject.render_erb(erb, talk_to: 'world')).to eq html
27
+ end
28
+ end
29
+
30
+ context 'partials' do
31
+ it 'should throw an error for a non existing partial' do
32
+ expect { subject.partial('fake_partial') }.to raise_error RuntimeError
33
+ end
34
+
35
+ it 'should render an existing partial' do
36
+ Frontman::Config.set(:partial_dir, 'spec/frontman/mocks/partials')
37
+
38
+ expect(subject.partial('paragraph.haml', text: 'Testing'))
39
+ .to eq("<p>\nThe passed text: Testing\n</p>\n")
40
+ end
41
+ end
42
+
43
+ context 'render page' do
44
+ let(:resource) { Frontman::Resource.from_path('spec/frontman/mocks/html_file.html') }
45
+
46
+ it 'should render the current page' do
47
+ Frontman::App.instance.current_page = resource
48
+ expect(subject.render_current_page).to eq resource.render(nil, layout: nil, ignore_page: nil)
49
+ end
50
+
51
+ it 'should render a page' do
52
+ expect(subject.render_page(resource)).to eq resource.render(nil, layout: nil, ignore_page: nil)
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,21 @@
1
+ # typed: false
2
+ # frozen_string_literal: true
3
+
4
+ require './spec/spec_setup'
5
+ require 'lib/frontman/helpers/url_helper'
6
+
7
+ describe UrlHelper do
8
+ subject do
9
+ Class.new do
10
+ include UrlHelper
11
+ end.new
12
+ end
13
+
14
+ it 'should properly format a URL' do
15
+ improperly_formatted = %w[hello-world/index.html /hello-world/index.html /hello-world hello-world/]
16
+
17
+ improperly_formatted.each do |url|
18
+ expect(subject.format_url(url)).to eq '/hello-world/'
19
+ end
20
+ end
21
+ end