stormy 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +3 -0
- data/.travis.yml +7 -0
- data/Gemfile +3 -0
- data/Gemfile.lock +65 -0
- data/README.md +64 -0
- data/Rakefile +4 -0
- data/lib/stormy.rb +34 -0
- data/lib/stormy/caches/base.rb +46 -0
- data/lib/stormy/caches/dummy_cache.rb +12 -0
- data/lib/stormy/caches/file_cache.rb +47 -0
- data/lib/stormy/caches/memory_cache.rb +24 -0
- data/lib/stormy/chunk.rb +63 -0
- data/lib/stormy/content.rb +21 -0
- data/lib/stormy/content_list.rb +18 -0
- data/lib/stormy/engines/base.rb +7 -0
- data/lib/stormy/engines/erb.rb +8 -0
- data/lib/stormy/engines/haml.rb +9 -0
- data/lib/stormy/engines/html.rb +6 -0
- data/lib/stormy/engines/markdown.rb +8 -0
- data/lib/stormy/engines/sass.rb +12 -0
- data/lib/stormy/layout.rb +21 -0
- data/lib/stormy/page.rb +32 -0
- data/lib/stormy/static.rb +20 -0
- data/lib/stormy/stores/base.rb +52 -0
- data/lib/stormy/stores/file_store.rb +70 -0
- data/lib/stormy/template.rb +67 -0
- data/lib/stormy/version.rb +3 -0
- data/lib/stormy_app.rb +40 -0
- data/lib/stormy_server.rb +41 -0
- data/spec/fixtures/dummy_site/config.yml +1 -0
- data/spec/fixtures/dummy_site/content/blog/blog-post-1.md +5 -0
- data/spec/fixtures/dummy_site/content/blog/blog-post-2.md +5 -0
- data/spec/fixtures/dummy_site/layouts/main.haml +2 -0
- data/spec/fixtures/dummy_site/public/assets/storm.jpg +0 -0
- data/spec/fixtures/dummy_site/public/blog.haml +12 -0
- data/spec/fixtures/dummy_site/public/blog_desc.haml +13 -0
- data/spec/fixtures/dummy_site/public/hardcoded_blog_post.haml +12 -0
- data/spec/fixtures/dummy_site/public/missing.haml +1 -0
- data/spec/fixtures/dummy_site/public/pathtest/:permalink.haml +16 -0
- data/spec/fixtures/dummy_site/public/redirecto.haml +1 -0
- data/spec/fixtures/dummy_site/public/redirects/:permalink.haml +1 -0
- data/spec/fixtures/dummy_site/public/subdir/index.haml +1 -0
- data/spec/fixtures/dummy_site/public/tester.haml +4 -0
- data/spec/fixtures/dummy_site/public/tester_invalid_layout.haml +4 -0
- data/spec/fixtures/dummy_site/tester.haml +1 -0
- data/spec/spec_helper.rb +14 -0
- data/spec/stormy/caches/caches_spec.rb +50 -0
- data/spec/stormy/engines/erb_spec.rb +24 -0
- data/spec/stormy/engines/sass_spec.rb +24 -0
- data/spec/stormy/page_spec.rb +73 -0
- data/spec/stormy/stores/file_store_spec.rb +66 -0
- data/spec/stormy_app_spec.rb +37 -0
- data/spec/stormy_server_spec.rb +41 -0
- data/stormy.gemspec +33 -0
- data/tasks/rspec.rake +4 -0
- metadata +263 -0
@@ -0,0 +1 @@
|
|
1
|
+
%h1 Missing Page Yo!
|
@@ -0,0 +1 @@
|
|
1
|
+
- meta[:redirect] = "/tester"
|
@@ -0,0 +1 @@
|
|
1
|
+
= meta[:redirect] = "/new-location/" + meta[:permalink]
|
@@ -0,0 +1 @@
|
|
1
|
+
Index file
|
@@ -0,0 +1 @@
|
|
1
|
+
%h1 Tester
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
require "simplecov"
|
2
|
+
SimpleCov.start do
|
3
|
+
add_filter '/spec/'
|
4
|
+
end
|
5
|
+
|
6
|
+
require "codeclimate-test-reporter"
|
7
|
+
CodeClimate::TestReporter.start
|
8
|
+
|
9
|
+
require 'stormy'
|
10
|
+
|
11
|
+
Dir[File.expand_path('spec/support/**/*.rb')].each(&method(:require))
|
12
|
+
|
13
|
+
FIXTURE_ROOT = File.join(File.dirname(__FILE__),"fixtures")
|
14
|
+
|
@@ -0,0 +1,50 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
shared_examples "a stormy cache" do
|
4
|
+
|
5
|
+
let(:app) { StormyApp.new(root: FIXTURE_ROOT + "/dummy_site/",
|
6
|
+
cache: described_class) }
|
7
|
+
|
8
|
+
context "#page" do
|
9
|
+
|
10
|
+
it "stores returns the item in the block" do
|
11
|
+
result = app.cache.page("tester") do
|
12
|
+
"My Val"
|
13
|
+
end
|
14
|
+
|
15
|
+
expect(result).to eq "My Val"
|
16
|
+
end
|
17
|
+
|
18
|
+
it "doesn't call the block after it's stored it in the cache" do
|
19
|
+
app.cache.page("tester") do
|
20
|
+
"Dummy Val"
|
21
|
+
end
|
22
|
+
|
23
|
+
result = app.cache.page("tester") do
|
24
|
+
raise "Error"
|
25
|
+
end
|
26
|
+
|
27
|
+
expect(result).to eq "Dummy Val"
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
describe Stormy::Caches::MemoryCache do
|
34
|
+
it_behaves_like "a stormy cache"
|
35
|
+
end
|
36
|
+
|
37
|
+
describe Stormy::Caches::FileCache do
|
38
|
+
it_behaves_like "a stormy cache"
|
39
|
+
|
40
|
+
it "creates the necessary directory" do
|
41
|
+
cache_dir = FIXTURE_ROOT + "/dummy_site/tmp/cache"
|
42
|
+
FileUtils.rm_r(cache_dir) rescue nil
|
43
|
+
|
44
|
+
expect(File.directory?(cache_dir)).to eq false
|
45
|
+
StormyApp.new(root: FIXTURE_ROOT + "/dummy_site/",
|
46
|
+
cache: described_class)
|
47
|
+
|
48
|
+
expect(File.directory?(cache_dir)).to eq true
|
49
|
+
end
|
50
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
|
4
|
+
describe Stormy::Engines::Erb do
|
5
|
+
|
6
|
+
let(:app) { StormyApp.new({ root: FIXTURE_ROOT + "/dummy_site/" }) }
|
7
|
+
let(:engine) { Stormy::Engines::Erb.new(app) }
|
8
|
+
|
9
|
+
let(:body) do
|
10
|
+
<<-DOC
|
11
|
+
The answer is <%= 1+2 %>.
|
12
|
+
The word is <%= meta[:title] %>
|
13
|
+
DOC
|
14
|
+
end
|
15
|
+
|
16
|
+
context "#render" do
|
17
|
+
it "renders erbs" do
|
18
|
+
result = engine.render(body,{ meta: { title: "Yay!" }})
|
19
|
+
expect(result).to include "The answer is 3"
|
20
|
+
expect(result).to include "The word is Yay!"
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
|
4
|
+
describe Stormy::Engines::Sass do
|
5
|
+
|
6
|
+
let(:app) { StormyApp.new({ root: FIXTURE_ROOT + "/dummy_site/" }) }
|
7
|
+
let(:engine) { Stormy::Engines::Sass.new(app) }
|
8
|
+
|
9
|
+
let(:body) do
|
10
|
+
<<-DOC
|
11
|
+
.stuff {
|
12
|
+
.interior { color:red; }
|
13
|
+
}
|
14
|
+
DOC
|
15
|
+
end
|
16
|
+
|
17
|
+
context "#render" do
|
18
|
+
it "renders sass" do
|
19
|
+
result = engine.render(body,{})
|
20
|
+
expect(result).to include(".stuff .interior")
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
@@ -0,0 +1,73 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe Stormy::Page do
|
4
|
+
|
5
|
+
let!(:app) { StormyApp.new(root: FIXTURE_ROOT + "/dummy_site") }
|
6
|
+
|
7
|
+
describe "#resolve_content" do
|
8
|
+
|
9
|
+
it "resolves the content from the blog category for hardcoded content" do
|
10
|
+
page = app.page("hardcoded_blog_post", {})
|
11
|
+
page.resolve_content
|
12
|
+
|
13
|
+
expect(page.content[:content][:title]).to eq "Super post"
|
14
|
+
expect(page.content[:content][:author]).to eq "Svend Karlson"
|
15
|
+
expect(page.content[:content][:body]).to include "This is the content of the blog post yo!"
|
16
|
+
end
|
17
|
+
|
18
|
+
it "resolves content from permalinks" do
|
19
|
+
page = app.page("pathtest/blog-post-1", {})
|
20
|
+
page.resolve_content
|
21
|
+
expect(page.content[:post][:title]).to eq "Super post"
|
22
|
+
expect(page.content[:post][:author]).to eq "Svend Karlson"
|
23
|
+
end
|
24
|
+
|
25
|
+
it "resolves a content list" do
|
26
|
+
page = app.page("blog")
|
27
|
+
page.resolve_content
|
28
|
+
expect(page.content[:blog].length).to eq 2
|
29
|
+
expect(page.content[:blog][0][:title]).to eq "Super post"
|
30
|
+
expect(page.content[:blog][1][:title]).to eq "Super post 2"
|
31
|
+
end
|
32
|
+
|
33
|
+
it "correctly orders a content list" do
|
34
|
+
page = app.page("blog_desc")
|
35
|
+
page.resolve_content
|
36
|
+
expect(page.content[:blog].length).to eq 2
|
37
|
+
expect(page.content[:blog][0][:title]).to eq "Super post 2"
|
38
|
+
expect(page.content[:blog][1][:title]).to eq "Super post"
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
describe "#render" do
|
43
|
+
it "renders the output of a page" do
|
44
|
+
page = app.page("tester")
|
45
|
+
output = page.render
|
46
|
+
expect(output[0]).to eq 200
|
47
|
+
expect(output[1]['Content-Type']).to eq "text/html"
|
48
|
+
expect(output[2][0]).to include "Tester"
|
49
|
+
end
|
50
|
+
|
51
|
+
it "renders the output of content in a page" do
|
52
|
+
page = app.page("blog")
|
53
|
+
output = page.render
|
54
|
+
expect(output[2][0]).to include "Svend Karlson"
|
55
|
+
expect(output[2][0]).to include "Bob Johnson"
|
56
|
+
end
|
57
|
+
|
58
|
+
it "does a redirect if redirect is set in the page" do
|
59
|
+
page = app.page("redirecto")
|
60
|
+
output = page.render
|
61
|
+
expect(output[0]).to eq 301
|
62
|
+
expect(output[1]["Location"]).to eq "/tester"
|
63
|
+
end
|
64
|
+
|
65
|
+
it "can dynamicaly set the redirect from a path key" do
|
66
|
+
page = app.page("redirects/something-awesome")
|
67
|
+
output = page.render
|
68
|
+
expect(output[0]).to eq 301
|
69
|
+
expect(output[1]["Location"]).to eq "/new-location/something-awesome"
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
end
|
@@ -0,0 +1,66 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe Stormy::Stores::FileStore do
|
4
|
+
|
5
|
+
|
6
|
+
let!(:app) { StormyApp.new(root: FIXTURE_ROOT + "/dummy_site",
|
7
|
+
store: Stormy::Stores::FileStore ) }
|
8
|
+
let!(:store) { app.store }
|
9
|
+
|
10
|
+
|
11
|
+
describe "#lookup_filename" do
|
12
|
+
|
13
|
+
it "returns a filename even if the extension is missing" do
|
14
|
+
file,meta = store.lookup_filename("public","tester")
|
15
|
+
expect(file).to include "tester.haml"
|
16
|
+
end
|
17
|
+
|
18
|
+
it "returns nil if we try to force the engine extension" do
|
19
|
+
file,meta = store.lookup_filename("public","tester.haml")
|
20
|
+
expect(file).to eq nil
|
21
|
+
end
|
22
|
+
|
23
|
+
it "returns the index file if the path is a directory" do
|
24
|
+
file,meta = store.lookup_filename("public","subdir/")
|
25
|
+
expect(file).to include "index.haml"
|
26
|
+
end
|
27
|
+
|
28
|
+
it "returns the index file without the trailing slash" do
|
29
|
+
file,meta = store.lookup_filename("public","subdir")
|
30
|
+
expect(file).to include "index.haml"
|
31
|
+
end
|
32
|
+
|
33
|
+
it "returns a file with path metadata" do
|
34
|
+
file,meta = store.lookup_filename("public","pathtest/this-is-a-test")
|
35
|
+
expect(file).to include ":permalink.haml"
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
|
40
|
+
describe "#page" do
|
41
|
+
it "returns a valid page in public and extracts the meta data" do
|
42
|
+
details = store.page("tester")
|
43
|
+
expect(details[:path]).to include("tester.haml")
|
44
|
+
expect(details[:title]).to eq "The Testerama"
|
45
|
+
expect(details[:key]).to eq "tester"
|
46
|
+
expect(details[:body]).to include "Tester"
|
47
|
+
end
|
48
|
+
|
49
|
+
it "returns a segmented path with the valid meta data" do
|
50
|
+
details = store.page("pathtest/this-is-a-test")
|
51
|
+
expect(details[:path]).to include("permalink.haml")
|
52
|
+
expect(details[:body]).to include "some random body copy"
|
53
|
+
expect(details[:permalink]).to eq "this-is-a-test"
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
describe "#content" do
|
58
|
+
it "returns a pieces of content" do
|
59
|
+
details = store.content("blog","blog-post-1")
|
60
|
+
expect(details[:title]).to eq "Super post"
|
61
|
+
expect(details[:author]).to eq "Svend Karlson"
|
62
|
+
expect(details[:key]).to eq "blog-post-1"
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe StormyApp do
|
4
|
+
|
5
|
+
context "options" do
|
6
|
+
|
7
|
+
it "raises an error without a root option set" do
|
8
|
+
expect do
|
9
|
+
StormyApp.new({})
|
10
|
+
end.to raise_error
|
11
|
+
|
12
|
+
end
|
13
|
+
|
14
|
+
context "with root set" do
|
15
|
+
let(:app) { StormyApp.new(root: FIXTURE_ROOT + "/dummy_site/") }
|
16
|
+
|
17
|
+
it "sets the root with a root set" do
|
18
|
+
app = StormyApp.new(root: "/dummy_site")
|
19
|
+
expect(app.root).to eq "/dummy_site"
|
20
|
+
end
|
21
|
+
|
22
|
+
it "creates a dummy cache by default" do
|
23
|
+
expect(app.cache).to be_instance_of Stormy::Caches::DummyCache
|
24
|
+
end
|
25
|
+
|
26
|
+
it "creates a file store by default" do
|
27
|
+
expect(app.store).to be_instance_of Stormy::Stores::FileStore
|
28
|
+
end
|
29
|
+
|
30
|
+
it "loads the defaults.yml file" do
|
31
|
+
expect(app.defaults[:layout]).to eq "main"
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|
36
|
+
|
37
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe StormyServer do
|
4
|
+
|
5
|
+
let(:server) { StormyServer.new(root: FIXTURE_ROOT + "/dummy_site/") }
|
6
|
+
|
7
|
+
describe "#call" do
|
8
|
+
|
9
|
+
it "returns 404 with an invalid page" do
|
10
|
+
result = server.call("PATH_INFO" => "/afdsa")
|
11
|
+
expect(result[0]).to eq 404
|
12
|
+
end
|
13
|
+
|
14
|
+
it "returns a 200 with a valid page and valid layout" do
|
15
|
+
expect {
|
16
|
+
server.call("PATH_INFO" => "/tester_invalid_layout")
|
17
|
+
}. to raise_error
|
18
|
+
end
|
19
|
+
|
20
|
+
it "returns a 200 with a valid page and valid layout" do
|
21
|
+
result = server.call("PATH_INFO" => "/tester")
|
22
|
+
expect(result[0]).to eq 200
|
23
|
+
end
|
24
|
+
|
25
|
+
it "returns an image if it's an asset" do
|
26
|
+
result = server.call("PATH_INFO" => "/assets/storm.jpg")
|
27
|
+
expect(result[0]).to eq 200
|
28
|
+
expect(result[1]["Content-Type"]).to eq "image/jpeg"
|
29
|
+
end
|
30
|
+
|
31
|
+
it "renders a custom 404 page" do
|
32
|
+
custom_server = StormyServer.new(root: FIXTURE_ROOT + "/dummy_site/",
|
33
|
+
page_not_found: "/missing")
|
34
|
+
result = custom_server.call("PATH_INFO" => "/asgddasgasgsafd")
|
35
|
+
expect(result[0]).to eq 404
|
36
|
+
expect(result[2][0]).to include "Missing Page Yo!"
|
37
|
+
|
38
|
+
end
|
39
|
+
|
40
|
+
end
|
41
|
+
end
|
data/stormy.gemspec
ADDED
@@ -0,0 +1,33 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'stormy/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "stormy"
|
8
|
+
spec.version = Stormy::VERSION
|
9
|
+
spec.authors = ["Pascal Rettig"]
|
10
|
+
spec.email = ["pascal@cykod.com"]
|
11
|
+
spec.summary = %q{Minimal Static CMS}
|
12
|
+
spec.description = %q{Still Minimal}
|
13
|
+
spec.homepage = ""
|
14
|
+
spec.license = "MIT"
|
15
|
+
|
16
|
+
spec.files = `git ls-files -z`.split("\x0")
|
17
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
|
+
spec.require_paths = ["lib"]
|
20
|
+
|
21
|
+
spec.add_development_dependency "bundler", "~> 1.6"
|
22
|
+
spec.add_development_dependency "rake"
|
23
|
+
spec.add_development_dependency 'rspec'
|
24
|
+
spec.add_development_dependency "codeclimate-test-reporter"
|
25
|
+
|
26
|
+
|
27
|
+
spec.add_dependency "rack"
|
28
|
+
spec.add_dependency "tilt"
|
29
|
+
spec.add_dependency "haml"
|
30
|
+
spec.add_dependency "kramdown"
|
31
|
+
spec.add_dependency "sass"
|
32
|
+
spec.add_dependency "activesupport"
|
33
|
+
end
|