hyperloop 0.0.4 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (73) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +41 -16
  3. data/LICENSE +21 -0
  4. data/hyperloop.gemspec +29 -30
  5. data/lib/generators/hyper/component_generator.rb +20 -0
  6. data/lib/generators/hyper/router_generator.rb +19 -0
  7. data/lib/generators/hyper/templates/component_template.rb +41 -0
  8. data/lib/generators/hyper/templates/router_template.rb +44 -0
  9. data/lib/generators/hyperloop/install_generator.rb +46 -0
  10. data/lib/hyperloop.rb +16 -8
  11. data/lib/hyperloop/version.rb +1 -1
  12. metadata +63 -222
  13. data/.ruby-version +0 -1
  14. data/.travis.yml +0 -4
  15. data/Gemfile +0 -4
  16. data/LICENSE.txt +0 -22
  17. data/README.md +0 -107
  18. data/Rakefile +0 -6
  19. data/bin/hyperloop +0 -7
  20. data/lib/hyperloop/application.rb +0 -103
  21. data/lib/hyperloop/cli.rb +0 -11
  22. data/lib/hyperloop/generators/site.rb +0 -47
  23. data/lib/hyperloop/generators/site/Gemfile +0 -3
  24. data/lib/hyperloop/generators/site/_partial.html.erb +0 -1
  25. data/lib/hyperloop/generators/site/about.html.erb +0 -3
  26. data/lib/hyperloop/generators/site/app.css +0 -2
  27. data/lib/hyperloop/generators/site/app.js +0 -2
  28. data/lib/hyperloop/generators/site/application.html.erb +0 -23
  29. data/lib/hyperloop/generators/site/bootstrap.css +0 -6805
  30. data/lib/hyperloop/generators/site/config.ru +0 -4
  31. data/lib/hyperloop/generators/site/current-time.coffee +0 -3
  32. data/lib/hyperloop/generators/site/index.html.erb +0 -11
  33. data/lib/hyperloop/generators/site/jquery.js +0 -8829
  34. data/lib/hyperloop/generators/site/main.scss +0 -7
  35. data/lib/hyperloop/generators/site/socool.jpg +0 -0
  36. data/lib/hyperloop/response.rb +0 -10
  37. data/lib/hyperloop/view.rb +0 -73
  38. data/lib/hyperloop/view/registry.rb +0 -90
  39. data/lib/hyperloop/view/scope.rb +0 -23
  40. data/spec/application_spec.rb +0 -300
  41. data/spec/fixtures/assets/app/assets/images/my-gif.gif +0 -0
  42. data/spec/fixtures/assets/app/assets/images/my-jpg.jpg +0 -0
  43. data/spec/fixtures/assets/app/assets/images/my-png.png +0 -0
  44. data/spec/fixtures/assets/app/assets/javascripts/app.js +0 -1
  45. data/spec/fixtures/assets/app/assets/javascripts/my-scripts.coffee +0 -1
  46. data/spec/fixtures/assets/app/assets/shouldfail/shouldfail.css +0 -3
  47. data/spec/fixtures/assets/app/assets/stylesheets/app.css +0 -1
  48. data/spec/fixtures/assets/app/assets/stylesheets/my-styles.scss +0 -3
  49. data/spec/fixtures/assets/app/views/index.html.erb +0 -7
  50. data/spec/fixtures/assets/app/views/layouts/application.html.erb +0 -15
  51. data/spec/fixtures/assets/vendor/assets/javascripts/vendored.js +0 -1
  52. data/spec/fixtures/assets/vendor/assets/stylesheets/vendored.css +0 -3
  53. data/spec/fixtures/erb/app/views/about.html.erb +0 -10
  54. data/spec/fixtures/erb/app/views/index.html.erb +0 -10
  55. data/spec/fixtures/layouts/app/views/index.html.erb +0 -3
  56. data/spec/fixtures/layouts/app/views/layouts/application.html.erb +0 -12
  57. data/spec/fixtures/layouts/app/views/subdir/index.html.erb +0 -3
  58. data/spec/fixtures/partials/app/views/index.html.erb +0 -3
  59. data/spec/fixtures/partials/app/views/layouts/application.html.erb +0 -12
  60. data/spec/fixtures/partials/app/views/subdir/_partial.html.erb +0 -1
  61. data/spec/fixtures/partials/app/views/subdir/index.html.erb +0 -3
  62. data/spec/fixtures/partials/app/views/subdir/nonroot.html.erb +0 -3
  63. data/spec/fixtures/simple/app/views/about.html +0 -10
  64. data/spec/fixtures/simple/app/views/index.html +0 -10
  65. data/spec/fixtures/subdirectories/app/views/about.html +0 -10
  66. data/spec/fixtures/subdirectories/app/views/index.html +0 -10
  67. data/spec/fixtures/subdirectories/app/views/subdir1/index.html +0 -10
  68. data/spec/fixtures/subdirectories/app/views/subdir1/kanye.html +0 -10
  69. data/spec/response_spec.rb +0 -8
  70. data/spec/spec_helper.rb +0 -139
  71. data/spec/view/registry_spec.rb +0 -56
  72. data/spec/view/scope_spec.rb +0 -21
  73. data/spec/view_spec.rb +0 -93
@@ -1,7 +0,0 @@
1
- nav {
2
- background-color: #ddd;
3
-
4
- li {
5
- background-color: #bbb;
6
- }
7
- }
@@ -1,10 +0,0 @@
1
- require "rack"
2
-
3
- module Hyperloop
4
- class Response < Rack::Response
5
- def initialize(*)
6
- super
7
- headers["Content-Type"] ||= "text/html"
8
- end
9
- end
10
- end
@@ -1,73 +0,0 @@
1
- require "erb"
2
- require "tilt"
3
-
4
- module Hyperloop
5
- class View
6
- def initialize(view_registry, full_path, layout_path=nil)
7
- @view_registry = view_registry
8
- @full_path = full_path
9
- @data = File.read(@full_path)
10
-
11
- # Only load layout data if all of these things are true:
12
- #
13
- # 1. We're not in a partial
14
- # 2. A layout path was provided
15
- # 3. There's a file at the provided layout path
16
- if !partial? && layout_path && File.file?(layout_path)
17
- @layout_data = File.read(layout_path)
18
- end
19
- end
20
-
21
- # Public: The format of the view. Derived from the view's extension.
22
- #
23
- # Returns a string.
24
- def format
25
- @format ||= File.extname(@full_path)[1..-1].intern
26
- end
27
-
28
- # Public: The name of the view. Derived from the view's filename without
29
- # any extensions or leading underscores. Not guaranteed to be unique amongst
30
- # other views in an app.
31
- #
32
- # Returns a string.
33
- def name
34
- @name ||= filename.split(".").first.sub(/^_/, "")
35
- end
36
-
37
- # Public: Is this view a partial?
38
- #
39
- # Returns a boolean.
40
- def partial?
41
- @partial ||= filename.start_with?("_")
42
- end
43
-
44
- # Public: Render the view.
45
- #
46
- # request - Rack request object that the view is being rendered in response
47
- # to.
48
- #
49
- # Returns a string.
50
- def render(request)
51
- case format
52
- when :html
53
- @data
54
- when :erb
55
- scope = Scope.new(request, @view_registry)
56
- view_html = Tilt["erb"].new { @data }.render(scope)
57
-
58
- if @layout_data
59
- layout_template = Tilt["erb"].new { @layout_data }
60
- layout_template.render(scope) { view_html }
61
- else
62
- view_html
63
- end
64
- end
65
- end
66
-
67
- private
68
-
69
- def filename
70
- @filename ||= File.basename(@full_path)
71
- end
72
- end
73
- end
@@ -1,90 +0,0 @@
1
- module Hyperloop
2
- class View
3
- class Registry
4
- def initialize(root)
5
- views_root = File.join([root, "app/views"].compact)
6
- layout_path = views_root + "/layouts/application.html.erb"
7
-
8
- # Get all the view paths. These look like:
9
- #
10
- # some/path/app/views/whatever.html.erb
11
- # some/path/app/views/subdir/whatever.html.erb
12
- # some/path/app/views/subdir/_partial.html.erb
13
- view_paths = Dir.glob(views_root + "/**/*").reject {|fn| File.directory?(fn)}
14
- view_paths -= [layout_path]
15
-
16
- @template_views = {}
17
- @partial_views = {}
18
-
19
- view_paths.each do |path|
20
- view = View.new(self, path, layout_path)
21
-
22
- # The path under app/views. This will be something like:
23
- #
24
- # /whatever.html.erb
25
- # /subdir/whatever.html.erb
26
- # /subdir/_partial.html.erb
27
- relative_path = path.sub(views_root, "")
28
-
29
- # The path under app/views without a file extension (and without the
30
- # starting _ for partials). This will be something like:
31
- #
32
- # /whatever
33
- # /subdir/whatever
34
- # /subdir/partial
35
- request_dir = File.dirname(relative_path)
36
- request_path = File.join(request_dir, view.name)
37
-
38
- if view.partial?
39
- # Chop off the leading forward slash for partials.
40
- @partial_views[request_path.sub(/^\//, "")] = view
41
- else
42
- @template_views[request_path] = view
43
- @template_views[request_dir] = view if view.name == "index"
44
- end
45
- end
46
- end
47
-
48
- # Public: Get the template view for the specified path.
49
- #
50
- # path - Relative path for the view. Should start under the app/views
51
- # directory and not include file extensions. Should start with a forward
52
- # slash.
53
- #
54
- # Example:
55
- #
56
- # Assuming there's a file at path/to/yoursite/app/views/subdir/whatever.html.erb
57
- #
58
- # bad: registry.find_template_view("/app/views/subdir/whatever.html.erb")
59
- # bad: registry.find_template_view("/subdir/whatever.html.erb")
60
- # bad: registry.find_template_view("subdir/whatever")
61
- # good: registry.find_template_view("/subdir/whatever")
62
- #
63
- # Returns a Hyperloop::View or nil if no view was found.
64
- def find_template_view(path)
65
- @template_views[path]
66
- end
67
-
68
- # Public: Get the partial view for the specified path.
69
- #
70
- # path - Relative path for the view. Should start under the app/views
71
- # directory and not include file extensions, leading underscores, or
72
- # leading forward slashes.
73
- #
74
- # Example:
75
- #
76
- # Assuming there's a file at path/to/yoursite/app/views/subdir/_partial.html.erb
77
- #
78
- # bad: registry.find_partial_view("app/views/subdir/_partial.html.erb")
79
- # bad: registry.find_partial_view("subdir/_partial.html.erb")
80
- # bad: registry.find_partial_view("subdir/_partial")
81
- # bad: registry.find_partial_view("/subdir/partial")
82
- # good: registry.find_partial_view("subdir/partial")
83
- #
84
- # Returns a Hyperloop::View or nil if no view was found.
85
- def find_partial_view(path)
86
- @partial_views[path]
87
- end
88
- end
89
- end
90
- end
@@ -1,23 +0,0 @@
1
- require "tilt"
2
-
3
- module Hyperloop
4
- class View
5
- class Scope
6
- attr_reader :request
7
-
8
- def initialize(request, view_registry)
9
- @request = request
10
- @view_registry = view_registry
11
- end
12
-
13
- # Public: Render the specified partial.
14
- #
15
- # path - Path to look for the partial at.
16
- #
17
- # Returns a string.
18
- def render(path)
19
- @view_registry.find_partial_view(path).render(request)
20
- end
21
- end
22
- end
23
- end
@@ -1,300 +0,0 @@
1
- require File.expand_path("../spec_helper", __FILE__)
2
-
3
- describe Hyperloop::Application do
4
- describe "with a flat views directory" do
5
- before :each do
6
- @app = Hyperloop::Application.new(prepare_fixture(:simple))
7
- end
8
-
9
- it "responds successfully to a request for root" do
10
- response = mock_request(@app).get("/")
11
-
12
- expect(response).to be_ok
13
- expect(response.content_type).to eql("text/html")
14
- expect(text_in(response.body, "h1")).to eql("Simple")
15
- end
16
-
17
- it "responds successfully to a request for a different page" do
18
- response = mock_request(@app).get("/about")
19
-
20
- expect(response).to be_ok
21
- expect(text_in(response.body, "h1")).to eql("About")
22
- end
23
-
24
- it "responds successfully to a request with a trailing slash" do
25
- response = mock_request(@app).get("/about/")
26
-
27
- expect(response).to be_ok
28
- expect(text_in(response.body, "h1")).to eql("About")
29
- end
30
-
31
- it "404s on a request for a nonexistent page" do
32
- response = mock_request(@app).get("/nonexistent")
33
-
34
- expect(response).to be_not_found
35
- end
36
- end
37
-
38
- describe "with subdirectories" do
39
- before :each do
40
- @app = Hyperloop::Application.new(prepare_fixture(:subdirectories))
41
- end
42
-
43
- it "responds successfully to a request for the subdirectory root" do
44
- response = mock_request(@app).get("/subdir1")
45
-
46
- expect(response).to be_ok
47
- expect(text_in(response.body, "h1")).to eql("Subdirectory Index")
48
- end
49
-
50
- it "responds successfully to a request for a different page in the subdirectory" do
51
- response = mock_request(@app).get("/subdir1/kanye")
52
-
53
- expect(response).to be_ok
54
- expect(text_in(response.body, "h1")).to eql("Hurry up with my damn croissant")
55
- end
56
- end
57
-
58
- describe "with ERB" do
59
- before :each do
60
- @app = Hyperloop::Application.new(prepare_fixture(:erb))
61
- end
62
-
63
- it "renders embedded Ruby in the root page" do
64
- response = mock_request(@app).get("/")
65
-
66
- expect(response).to be_ok
67
- expect(text_in(response.body, "h1")).to eql("WE ARE USING ERB")
68
- end
69
- end
70
-
71
- describe "with a layout" do
72
- before :each do
73
- @app = Hyperloop::Application.new(prepare_fixture(:layouts))
74
- end
75
-
76
- it "renders the root view within the layout" do
77
- response = mock_request(@app).get("/")
78
-
79
- expect(response).to be_ok
80
- expect(text_in(response.body, "h1")).to eql("Layout Header")
81
- expect(text_in(response.body, "h2")).to eql("This is the root page!")
82
- end
83
-
84
- it "renders subdirectory views within the layout" do
85
- response = mock_request(@app).get("/subdir")
86
-
87
- expect(response).to be_ok
88
- expect(text_in(response.body, "h1")).to eql("Layout Header")
89
- expect(text_in(response.body, "h2")).to eql("This is a page in a subdirectory!")
90
- end
91
- end
92
-
93
- describe "with assets" do
94
- before :each do
95
- @app = Hyperloop::Application.new(prepare_fixture(:assets))
96
- end
97
-
98
- it "responds successfully to a request for root" do
99
- response = mock_request(@app).get("/")
100
-
101
- expect(response).to be_ok
102
- expect(text_in(response.body, "h1")).to eql("This app has so many assets")
103
- end
104
-
105
- it "responds successfully to a request for the css app bundle" do
106
- response = mock_request(@app).get("/assets/stylesheets/app.css")
107
-
108
- expect(response).to be_ok
109
- expect(response.content_type).to eql("text/css")
110
- expect(response.body).to match(/display: ?block/)
111
- end
112
-
113
- it "responds successfully to a request for the javascript app bundle" do
114
- response = mock_request(@app).get("/assets/javascripts/app.js")
115
-
116
- expect(response).to be_ok
117
- expect(response.content_type).to eql("application/javascript")
118
- expect(response.body).to match(/alert\("such javascript wow"\)/)
119
- end
120
-
121
- it "responds successfully to a request for a vendored css file" do
122
- response = mock_request(@app).get("/assets/stylesheets/vendored.css")
123
-
124
- expect(response).to be_ok
125
- expect(response.content_type).to eql("text/css")
126
- expect(response.body).to match(/margin: ?0/)
127
- end
128
-
129
- it "responds successfully to a request for a vendored javascript bundle" do
130
- response = mock_request(@app).get("/assets/javascripts/vendored.js")
131
-
132
- expect(response).to be_ok
133
- expect(response.content_type).to eql("application/javascript")
134
- expect(response.body).to match(/alert\("i am vendored"\)/)
135
- end
136
-
137
- it "responds successfully to a request for a gif" do
138
- response = mock_request(@app).get("/assets/images/my-gif.gif")
139
-
140
- expect(response).to be_ok
141
- expect(response.content_type).to eql("image/gif")
142
- expect(Digest::SHA1.hexdigest(response.body)).to eql("bcbc6e6fc1eb77b2ca676e17425df93a56495bb2")
143
- end
144
-
145
- it "responds successfully to a request for a jpg" do
146
- response = mock_request(@app).get("/assets/images/my-jpg.jpg")
147
-
148
- expect(response).to be_ok
149
- expect(response.content_type).to eql("image/jpeg")
150
- expect(Digest::SHA1.hexdigest(response.body)).to eql("ae6a26b513d6648446da1395ee73e9cf32c8c668")
151
- end
152
-
153
- it "responds successfully to a request for a png" do
154
- response = mock_request(@app).get("/assets/images/my-png.png")
155
-
156
- expect(response).to be_ok
157
- expect(response.content_type).to eql("image/png")
158
- expect(Digest::SHA1.hexdigest(response.body)).to eql("adf65c25a8e3e39c49ecf581433278d7eac4d1a2")
159
- end
160
-
161
- it "404s on a request for an asset without namespacing by type" do
162
- response = mock_request(@app).get("/assets/app.js")
163
- expect(response).to be_not_found
164
- end
165
-
166
- it "404s on a request for an asset namespaced by the wrong type" do
167
- response = mock_request(@app).get("/assets/stylesheets/app.js")
168
- expect(response).to be_not_found
169
- end
170
-
171
- it "404s on a request for an asset namespaced by an unknown type" do
172
- response = mock_request(@app).get("/assets/shouldfail/shouldfail.css")
173
- expect(response).to be_not_found
174
- end
175
-
176
- it "404s on a request for a nonexistent asset" do
177
- response = mock_request(@app).get("/assets/javascripts/nonexistent.js")
178
-
179
- expect(response).to be_not_found
180
- end
181
- end
182
-
183
- describe "live reloading" do
184
- context "with assets" do
185
- before :each do
186
- @root = prepare_fixture(:assets)
187
- @app = Hyperloop::Application.new(@root)
188
- end
189
-
190
- it "reloads changed assets" do
191
- # On the first request, stylesheet should have `display: block` and not
192
- # `display: inline`.
193
- response = mock_request(@app).get("/assets/stylesheets/app.css")
194
- expect(response).to be_ok
195
- expect(response.body).to match(/display: ?block/)
196
- expect(response.body).not_to match(/display: ?inline/)
197
-
198
- change_fixture(@root, "app/assets/stylesheets/my-styles.scss",
199
- :pattern => "display: block",
200
- :replacement => "display: inline"
201
- )
202
-
203
- # On the second request, stylesheet should have `display: inline` and not
204
- # `display: block`.
205
- response = mock_request(@app).get("/assets/stylesheets/app.css")
206
- expect(response).to be_ok
207
- expect(response.body).to match(/display: ?inline/)
208
- expect(response.body).not_to match(/display: ?block/)
209
- end
210
- end
211
-
212
- context "with views" do
213
- before :each do
214
- @root = prepare_fixture(:partials)
215
- @app = Hyperloop::Application.new(@root)
216
- end
217
-
218
- it "reloads changed layouts" do
219
- # On the first request, <title> text should not be "Changed"
220
- response = mock_request(@app).get("/")
221
- expect(response).to be_ok
222
- expect(text_in(response.body, "title")).not_to eql("Changed")
223
-
224
- change_fixture(@root, "app/views/layouts/application.html.erb",
225
- :pattern => /<title>[^<]*<\/title>/,
226
- :replacement => "<title>Changed</title>"
227
- )
228
-
229
- # On the second request, <title> text should be "Changed"
230
- response = mock_request(@app).get("/")
231
- expect(response).to be_ok
232
- expect(text_in(response.body, "title")).to eql("Changed")
233
- end
234
-
235
- it "reloads changed partials" do
236
- # On the first request, <p> text should not be "Changed"
237
- response = mock_request(@app).get("/")
238
- expect(response).to be_ok
239
- expect(text_in(response.body, "p.spec-in-partial")).not_to eql("Changed")
240
-
241
- change_fixture(@root, "app/views/subdir/_partial.html.erb",
242
- :pattern => /<p class="spec-in-partial">[^<]*<\/p>/,
243
- :replacement => "<p class=\"spec-in-partial\">Changed</p>"
244
- )
245
-
246
- # On the second request, <p> text should be "Changed"
247
- response = mock_request(@app).get("/")
248
- expect(response).to be_ok
249
- expect(text_in(response.body, "p.spec-in-partial")).to eql("Changed")
250
- end
251
-
252
- it "reloads changed views" do
253
- # On the first request, <h2> text should not be "Changed"
254
- response = mock_request(@app).get("/")
255
- expect(response).to be_ok
256
- expect(text_in(response.body, "h2")).not_to eql("Changed")
257
-
258
- change_fixture(@root, "app/views/index.html.erb",
259
- :pattern => /<h2>[^<]*<\/h2>/,
260
- :replacement => "<h2>Changed</h2>"
261
- )
262
-
263
- # On the second request, <h2> text should be "Changed"
264
- response = mock_request(@app).get("/")
265
- expect(response).to be_ok
266
- expect(text_in(response.body, "h2")).to eql("Changed")
267
- end
268
- end
269
-
270
- context "in production" do
271
- before :each do
272
- set_rack_env :production
273
- end
274
-
275
- after :each do
276
- reset_rack_env
277
- end
278
-
279
- it "doesn't reload changed views" do
280
- root = prepare_fixture(:erb)
281
- app = Hyperloop::Application.new(root)
282
-
283
- # On the first request, <title> text should be "ERB"
284
- response = mock_request(app).get("/")
285
- expect(response).to be_ok
286
- expect(text_in(response.body, "title")).to eql("ERB")
287
-
288
- change_fixture(root, "app/views/index.html.erb",
289
- :pattern => "<title>ERB</title>",
290
- :replacement => "<title>Changed</title>"
291
- )
292
-
293
- # On the second request, <title> text should still be "ERB"
294
- response = mock_request(app).get("/")
295
- expect(response).to be_ok
296
- expect(text_in(response.body, "title")).to eql("ERB")
297
- end
298
- end
299
- end
300
- end