utopia 2.0.3 → 2.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: f8a91aed5e157e184b1b589dfc8889ac51f2e3c1
4
- data.tar.gz: d0f25b2d877416986be490f54d18d342b559f217
3
+ metadata.gz: f0f3495be3876412f9a11d21c4b836197905a1f4
4
+ data.tar.gz: cf908f69663dd5ed3319d3197445008b1afa4068
5
5
  SHA512:
6
- metadata.gz: bbfb18198ef48f6b26823fc756792db596a1e46baa57e596ab563f22346c6e38a1eb8f39b68f8d3c73cb1a1c2aced1f11f31796f648f32a8d97e1cce3d92defe
7
- data.tar.gz: 259cab3cc8b147a0729e63ea154ef04d220673ef3394271dbe4f1949ece0534560ee54c53c736b120a02e9a61bbb976bb0fcc1fb265944bdb57e6d5c0956c4fe
6
+ metadata.gz: c8e165f8e46e805d86abdbaeb91188b62e1d6ee900b41184741912c32b88c00085cc90e36f4494048d0d02c705b3a1729059571c9c7ffd16ded1f3e75e39f689
7
+ data.tar.gz: a032b62905906e418ad36d946725208cf07080332050cb78fa655624700d5e47d9be65513e9eaa4364ab532bae9383f7b52cc564870b929afd956269686d5966
data/.rspec CHANGED
@@ -1,4 +1,3 @@
1
- --color
2
1
  --format documentation
3
2
  --backtrace
4
3
  --require spec_helper
data/.travis.yml CHANGED
@@ -6,16 +6,16 @@ before_install:
6
6
  # For testing purposes:
7
7
  - git config --global user.email "samuel@oriontransfer.net"
8
8
  - git config --global user.name "Samuel Williams"
9
+ # https://github.com/rubygems/rubygems/issues/1448
10
+ - gem update --system
9
11
  rvm:
10
- - 2.2.4
11
- - 2.3.2
12
- - 2.4.0
12
+ - 2.2
13
+ - 2.3
14
+ - 2.4
13
15
  - jruby-head
14
16
  - ruby-head
15
- - rbx-3.65
16
17
  env: COVERAGE=true BENCHMARK=true
17
18
  matrix:
18
19
  allow_failures:
19
- - rvm: rbx-3.65
20
20
  - rvm: ruby-head
21
21
  - rvm: jruby-head
data/README.md CHANGED
@@ -54,12 +54,18 @@ There is an excellent documentation wiki included with the source code. Simply c
54
54
  - [Trenni](https://github.com/ioquatix/trenni) — Template and markup parsers, markup generation.
55
55
  - [Trenni::Formatters](https://github.com/ioquatix/trenni-formatters) — Helpers for HTML generation including views and forms.
56
56
  - [Utopia::Gallery](https://github.com/ioquatix/utopia-gallery) — A fast photo gallery based on [libvips](https://github.com/jcupitt/libvips).
57
+ - [Utopia::Analytics](https://github.com/ioquatix/utopia-analytics) — Simple integration with Google Analytics.
57
58
  - [Rack::Freeze](https://github.com/ioquatix/rack-freeze) — Multi-thread safety in Rack.
58
59
  - [HTTP::Accept](https://github.com/ioquatix/http-accept) — RFC compliant header parser.
59
60
  - [Samovar](https://github.com/ioquatix/samovar) — Command line parser used by Utopia.
60
61
  - [Mapping](https://github.com/ioquatix/mapping) — Provide structured conversions for web interfaces.
61
62
  - [Rack::Test::Body](https://github.com/ioquatix/rack-test-body) — Provide convenient helpers for testing web interfaces.
62
63
 
64
+ ### Applications
65
+
66
+ - [Financier](https://github.com/ioquatix/financier) — A small business management platform.
67
+ - [mail.oriontransfer.net](https://github.com/oriontransfer/mail.oriontransfer.net) - Mail server account management.
68
+
63
69
  ## License
64
70
 
65
71
  Released under the MIT license.
data/bin/utopia CHANGED
@@ -22,4 +22,4 @@
22
22
 
23
23
  require 'utopia/command'
24
24
 
25
- Utopia::Command::Top.parse(ARGV).invoke
25
+ Utopia::Command.parse(ARGV).invoke
@@ -12,8 +12,7 @@ gem "kramdown"
12
12
 
13
13
  group :development do
14
14
  # For `rake server`:
15
- gem "puma"
16
- gem "guard-puma"
15
+ gem "guard-falcon"
17
16
 
18
17
  # For `rake console`:
19
18
  gem "pry"
@@ -22,8 +21,6 @@ group :development do
22
21
  # For `rspec` testing:
23
22
  gem "rspec"
24
23
  gem "simplecov"
25
-
26
- gem "launchy"
27
24
  end
28
25
 
29
26
  group :production do
@@ -1,20 +1,21 @@
1
1
 
2
2
  group :development do
3
- guard :puma, port: 4000 do
3
+ guard :falcon do
4
4
  watch('Gemfile.lock')
5
5
  watch('config.ru')
6
6
  watch(%r{^config|lib|pages/.*})
7
+ notification :off
7
8
  end
8
9
 
9
- # Open the documentation website when the command is run, once puma has started:
10
- require 'launchy'
11
- $first_time = true
12
-
13
- url_path = 'run/url.txt'
14
- watch(url_path) do
15
- if $first_time
16
- $first_time = false
17
- Launchy.open(File.read(url_path))
18
- end
19
- end
10
+ # # Open the documentation website when the command is run, once puma has started:
11
+ # require 'launchy'
12
+ # $first_time = true
13
+ #
14
+ # url_path = 'run/url.txt'
15
+ # watch(url_path) do
16
+ # if $first_time
17
+ # $first_time = false
18
+ # Launchy.open(File.read(url_path))
19
+ # end
20
+ # end
20
21
  end
@@ -18,8 +18,6 @@ end
18
18
 
19
19
  use Rack::Sendfile
20
20
 
21
- use Utopia::ContentLength
22
-
23
21
  use Utopia::Redirection::Rewrite,
24
22
  '/' => '/wiki/index'
25
23
 
@@ -9,8 +9,6 @@
9
9
  <title>Utopia</title>
10
10
  <?r end ?>
11
11
 
12
- <base href="#{first.node.uri_path}"/>
13
-
14
12
  <link href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet" integrity="sha384-wvfXpqpZZVQGK6TAh5PVlGOfQNHSoD2xbE+QkPxCAFlNEevoEH3Sl0sibVcOQVnN" crossorigin="anonymous" />
15
13
 
16
14
  <link rel="icon" type="image/png" href="/_static/icon.png" />
@@ -6,7 +6,7 @@ Utopia provides a model for both local development (`utopia site create`) and de
6
6
 
7
7
  Utopia as a framework introduces changes and versions change according to semantic versioning.
8
8
 
9
- ### Controller Update 1.9.x to 2.0.0
9
+ ### Controller Update 1.9.x to 2.x
10
10
 
11
11
  The controller layer no longer automatically prepends the `Actions` layer. The following program does a best effort attempt to update existing controllers:
12
12
 
@@ -43,6 +43,14 @@ paths.each do |path|
43
43
  end
44
44
  ```
45
45
 
46
+ ### View Update 1.9.x to 2.x
47
+
48
+ Dynamic tags in 2.x require namespaces. This affects all `.xnode` files, in particular the following 3 cases:
49
+
50
+ 1. Rewrite `<(/?)(NAME)(\W)` to `<$1content:$2$3` where NAME is a tag which would expand using a `_NAME.xnode` file.
51
+ 2. Rewrite `<content/>` to `<utopia:content/>`. This affects `<node>`, `<deferred>`, `<environment>` tags.
52
+ 3. Rewrite `partial 'NAME'` to be `partial 'content:NAME'`.
53
+
46
54
  ## Server Update
47
55
 
48
56
  The utopia server git hooks are updated occasionally to improve the deployment process or to handle changes in the underlying process.
@@ -25,6 +25,10 @@ require_relative 'command/server'
25
25
 
26
26
  module Utopia
27
27
  module Command
28
+ def self.parse(*args)
29
+ Top.parse(*args)
30
+ end
31
+
28
32
  # The top level utopia command.
29
33
  class Top < Samovar::Command
30
34
  self.description = "A website development and deployment framework."
@@ -104,11 +104,11 @@ module Utopia
104
104
 
105
105
  # Check if the request is to a non-specific index. This only works for requests with a given name:
106
106
  basename = path.basename
107
- directory_path = File.join(@root, path.dirname.components, basename.name)
107
+ directory_path = File.join(@root, path.dirname.components, basename)
108
108
 
109
- # If the request for /foo/bar{extensions} is actually a directory, rewrite it to /foo/bar/index{extensions}:
109
+ # If the request for /foo/bar is actually a directory, rewrite it to /foo/bar/index:
110
110
  if File.directory? directory_path
111
- index_path = [basename.name, basename.rename(INDEX)]
111
+ index_path = [basename, INDEX]
112
112
 
113
113
  return [307, {HTTP::LOCATION => path.dirname.join(index_path).to_s}, []]
114
114
  end
@@ -24,7 +24,7 @@ require_relative 'markup'
24
24
 
25
25
  module Utopia
26
26
  class Content
27
- # This error is thrown if a tag doesn't match up when parsing the
27
+ # This error is raised if a tag doesn't match up when parsing.
28
28
  class UnbalancedTagError < StandardError
29
29
  def initialize(tag)
30
30
  @tag = tag
@@ -58,7 +58,7 @@ module Utopia
58
58
 
59
59
  def href
60
60
  @href ||= @info.fetch(:uri) do
61
- (@path.dirname + @path.basename.parts[0]).to_s if @path
61
+ (@path.dirname + @path.basename).to_s if @path
62
62
  end
63
63
  end
64
64
 
data/lib/utopia/path.rb CHANGED
@@ -19,52 +19,6 @@
19
19
  # THE SOFTWARE.
20
20
 
21
21
  module Utopia
22
- class Basename
23
- # A basename represents a file name with an optional extension. You can specify a specific extension to identify or specify true to select any extension after the last trailing dot.
24
- def initialize(name, extension = false)
25
- if extension
26
- if extension == true
27
- offset = name.rindex('.')
28
- else
29
- offset = name.rindex(extension) - 1
30
- end
31
-
32
- @name = name[0...offset]
33
- @extension = name[offset+1..-1]
34
- else
35
- @name = name
36
- @extension = nil
37
- end
38
- end
39
-
40
- def rename(name)
41
- copy = self.dup
42
-
43
- copy.send(:instance_variable_set, :@name, name)
44
-
45
- return copy
46
- end
47
-
48
- attr :name
49
- attr :extension
50
-
51
- def parts
52
- @parts ||= @name.split('.')
53
- end
54
-
55
- def locale
56
- parts.last if parts.size > 1
57
- end
58
-
59
- def to_str
60
- "#{name}#{extension}"
61
- end
62
-
63
- def to_s
64
- to_str
65
- end
66
- end
67
-
68
22
  # Represents a path as an array of path components. Useful for efficient URL manipulation.
69
23
  class Path
70
24
  include Comparable
@@ -143,6 +97,14 @@ module Utopia
143
97
  self.new(unescape(string).split(SEPARATOR, -1))
144
98
  end
145
99
 
100
+ def self.load(value)
101
+ from_string(value) if value
102
+ end
103
+
104
+ def self.dump(instance)
105
+ instance.to_s if instance
106
+ end
107
+
146
108
  def self.create(path)
147
109
  case path
148
110
  when Path
@@ -155,7 +117,11 @@ module Utopia
155
117
  return self.new([path])
156
118
  end
157
119
  end
158
-
120
+
121
+ def replace(other_path)
122
+ @components = other_path.components.dup
123
+ end
124
+
159
125
  def include?(*args)
160
126
  @components.include?(*args)
161
127
  end
@@ -200,9 +166,7 @@ module Utopia
200
166
  end
201
167
  end
202
168
 
203
- def to_s
204
- to_str
205
- end
169
+ alias to_s to_str
206
170
 
207
171
  def to_a
208
172
  @components
@@ -267,8 +231,8 @@ module Utopia
267
231
  return self.class.new(result)
268
232
  end
269
233
 
270
- def basename(*args)
271
- Basename.new(@components.last, *args)
234
+ def basename
235
+ @components.last
272
236
  end
273
237
 
274
238
  def dirname(count = 1)
@@ -52,10 +52,16 @@ module Utopia
52
52
  super
53
53
  end
54
54
 
55
+ CONTENT_TYPE = 'Content-Type'.freeze
56
+
57
+ def unhandled_error?(response)
58
+ response[0] >= 400 && !response[1].include?(CONTENT_TYPE)
59
+ end
60
+
55
61
  def call(env)
56
62
  response = @app.call(env)
57
63
 
58
- if response[0] >= 400 and location = @codes[response[0]]
64
+ if unhandled_error?(response) && location = @codes[response[0]]
59
65
  error_request = env.merge(Rack::PATH_INFO => location, Rack::REQUEST_METHOD => Rack::GET)
60
66
  error_response = @app.call(error_request)
61
67
 
@@ -19,5 +19,5 @@
19
19
  # THE SOFTWARE.
20
20
 
21
21
  module Utopia
22
- VERSION = "2.0.3"
22
+ VERSION = "2.1.0"
23
23
  end
data/setup/site/.rspec CHANGED
@@ -1,4 +1,3 @@
1
- --color
2
1
  --format documentation
3
2
  --backtrace
4
3
  --warnings
data/setup/site/Gemfile CHANGED
@@ -3,7 +3,7 @@ source "https://rubygems.org"
3
3
 
4
4
  gem "utopia", "~> $UTOPIA_VERSION"
5
5
  # gem "utopia-gallery"
6
- # gem "utopia-google-analytics"
6
+ # gem "utopia-analytics"
7
7
 
8
8
  gem "rake"
9
9
  gem "bundler"
@@ -12,8 +12,7 @@ gem "rack-freeze", "~> 1.2"
12
12
 
13
13
  group :development do
14
14
  # For `rake server`:
15
- gem "puma"
16
- gem "guard-puma", require: false
15
+ gem "guard-falcon", require: false
17
16
  gem 'guard-rspec', require: false
18
17
 
19
18
  # For `rake console`:
data/setup/site/Guardfile CHANGED
@@ -1,17 +1,29 @@
1
1
 
2
2
  group :development do
3
- guard :puma, port: 9292 do
3
+ guard :falcon, bind: "tcp://localhost:8080" do
4
4
  watch('Gemfile.lock')
5
5
  watch('config.ru')
6
6
  watch(%r{^config|lib|pages/.*})
7
+
8
+ notification :off
7
9
  end
8
10
  end
9
11
 
10
12
  group :test do
11
13
  guard :rspec, cmd: 'rspec' do
14
+ # Notifications can get a bit tedious:
15
+ # notification :off
16
+
17
+ # Re-run specs if they are changed:
12
18
  watch(%r{^spec/.+_spec\.rb$})
13
- watch(%r{^lib/(.+)\.rb$}) { |m| 'spec/lib/#{m[1]}_spec.rb' }
14
- watch('spec/spec_helper.rb') { 'spec' }
15
- watch(%r{^pages/.*}) { 'spec/website_spec.rb' }
19
+ watch('spec/spec_helper.rb') {'spec'}
20
+
21
+ # Run relevent specs if files in `lib/` or `pages/` are changed:
22
+ watch(%r{^lib/(.+)\.rb$}) {|match| "spec/lib/#{match[1]}_spec.rb" }
23
+ watch(%r{^pages/(.+)\.(rb|xnode)$}) {|match| "spec/pages/#{match[1]}_spec.rb"}
24
+ watch(%r{^pages/(.+)controller\.rb$}) {|match| Dir.glob("spec/pages/#{match[1]}*_spec.rb")}
25
+
26
+ # If any files in pages changes, ensure the website still works:
27
+ watch(%r{^pages/.*}) {'spec/website_spec.rb'}
16
28
  end
17
29
  end
@@ -51,7 +51,7 @@ body > header img {
51
51
  height: 4rem;
52
52
  }
53
53
 
54
- p {
54
+ p, ul, ol {
55
55
  color: #555;
56
56
  }
57
57
 
@@ -88,6 +88,10 @@ p, ul, ol, dl, h3 {
88
88
  margin: 2rem;
89
89
  }
90
90
 
91
+ li {
92
+ margin: 0.2rem;
93
+ }
94
+
91
95
  li > ul, li > ol {
92
96
  margin: 0;
93
97
  }
@@ -138,5 +138,25 @@ module Utopia::Controller::RespondSpec
138
138
  expect(last_response.headers['Content-Type']).to be == 'application/json; charset=utf-8'
139
139
  expect(last_response.body).to be == '{}'
140
140
  end
141
+
142
+ it "should give record as JSON" do
143
+ header 'Accept', 'application/json'
144
+
145
+ get '/rewrite/2/show'
146
+
147
+ expect(last_response.status).to be == 200
148
+ expect(last_response.headers['Content-Type']).to be == 'application/json; charset=utf-8'
149
+ expect(last_response.body).to be == '{"id":2,"foo":"bar"}'
150
+ end
151
+
152
+ it "should give error as JSON" do
153
+ header 'Accept', 'application/json'
154
+
155
+ get '/rewrite/1/show'
156
+
157
+ expect(last_response.status).to be == 404
158
+ expect(last_response.headers['Content-Type']).to be == 'application/json; charset=utf-8'
159
+ expect(last_response.body).to be == '{"message":"Could not find record"}'
160
+ end
141
161
  end
142
162
  end
@@ -1,4 +1,7 @@
1
1
 
2
+ use Utopia::Redirection::Errors,
3
+ 404 => '/fail'
4
+
2
5
  use Utopia::Controller,
3
6
  root: File.expand_path('respond_spec', __dir__)
4
7
 
@@ -0,0 +1,12 @@
1
+
2
+ prepend Respond, Rewrite, Actions
3
+
4
+ respond.with_json
5
+
6
+ rewrite.extract_prefix id: Integer do |request|
7
+ fail! :not_found, message: "Could not find record" if @id == 1
8
+ end
9
+
10
+ on 'show' do
11
+ succeed! content: {id: @id, foo: 'bar'}
12
+ end
@@ -22,131 +22,121 @@
22
22
 
23
23
  require 'utopia/path'
24
24
 
25
- module Utopia::PathSpec
26
- describe Utopia::Path do
27
- it "should be root path" do
28
- root = Utopia::Path["/"]
29
-
30
- expect(root.components).to be == ['', '']
31
- expect(root.to_local_path).to be == '/'
32
- end
25
+ RSpec.describe Utopia::Path do
26
+ context "coder" do
27
+ subject {"foo/bar/baz"}
28
+ let(:instance) {described_class.load(subject)}
33
29
 
34
- it "should concatenate absolute paths" do
35
- root = Utopia::Path["/"]
36
-
37
- expect(root).to be_absolute
38
- expect(root + Utopia::Path["foo/bar"]).to be == Utopia::Path["/foo/bar"]
30
+ it "loads a string" do
31
+ expect(instance).to be_a described_class
39
32
  end
40
33
 
41
- it "should compute all descendant paths" do
42
- root = Utopia::Path["/foo/bar"]
43
-
44
- descendants = root.descend.to_a
45
-
46
- expect(descendants[0].components).to be == [""]
47
- expect(descendants[1].components).to be == ["", "foo"]
48
- expect(descendants[2].components).to be == ["", "foo", "bar"]
49
-
50
- ascendants = root.ascend.to_a
51
-
52
- expect(descendants.reverse).to be == ascendants
34
+ it "dump generates the original string" do
35
+ expect(described_class.dump(instance)).to be == subject
53
36
  end
37
+ end
38
+
39
+ it "should be root path" do
40
+ root = Utopia::Path["/"]
54
41
 
55
- it "should be able to remove relative path entries" do
56
- path = Utopia::Path["/foo/bar/../baz/."]
57
- expect(path.simplify.components).to be == ['', 'foo', 'baz']
58
-
59
- path = Utopia::Path["/foo/bar/../baz/./"]
60
- expect(path.simplify.components).to be == ['', 'foo', 'baz', '']
61
- end
42
+ expect(root.components).to be == ['', '']
43
+ expect(root.to_local_path).to be == '/'
44
+ end
45
+
46
+ it "should concatenate absolute paths" do
47
+ root = Utopia::Path["/"]
62
48
 
63
- it "should remove the extension from the basename" do
64
- path = Utopia::Path["dir/foo.html"]
65
-
66
- basename = path.basename("html")
67
-
68
- expect(basename.name).to be == 'foo'
69
- expect(basename.extension).to be == 'html'
70
- end
49
+ expect(root).to be_absolute
50
+ expect(root + Utopia::Path["foo/bar"]).to be == Utopia::Path["/foo/bar"]
51
+ end
52
+
53
+ it "should compute all descendant paths" do
54
+ root = Utopia::Path["/foo/bar"]
71
55
 
72
- it "should be able to convert into a directory" do
73
- path = Utopia::Path["foo/bar"]
74
-
75
- expect(path).to_not be_directory
76
-
77
- expect(path.to_directory).to be_directory
78
-
79
- dir_path = path.to_directory
80
- expect(dir_path.to_directory).to be == dir_path
81
- end
56
+ descendants = root.descend.to_a
82
57
 
83
- it "should start with the given path" do
84
- path = Utopia::Path["/a/b/c/d/e"]
85
-
86
- expect(path.start_with?(path.dirname)).to be true
87
- end
58
+ expect(descendants[0].components).to be == [""]
59
+ expect(descendants[1].components).to be == ["", "foo"]
60
+ expect(descendants[2].components).to be == ["", "foo", "bar"]
88
61
 
89
- it "should split at the specified point" do
90
- path = Utopia::Path["/a/b/c/d/e"]
91
-
92
- expect(path.split('c')).to be == [Utopia::Path['/a/b'], Utopia::Path['d/e']]
93
- end
62
+ ascendants = root.ascend.to_a
94
63
 
95
- it "shouldn't be able to modify frozen paths" do
96
- path = Utopia::Path["dir/foo.html"]
97
-
98
- path.freeze
99
-
100
- expect(path.frozen?).to be true
101
-
102
- expect{path[0] = 'bob'}.to raise_exception(RuntimeError)
103
- end
64
+ expect(descendants.reverse).to be == ascendants
65
+ end
66
+
67
+ it "should be able to remove relative path entries" do
68
+ path = Utopia::Path["/foo/bar/../baz/."]
69
+ expect(path.simplify.components).to be == ['', 'foo', 'baz']
104
70
 
105
- it "should give the correct locale" do
106
- path = Utopia::Path["foo.en"]
107
-
108
- expect(path.basename.locale).to be == 'en'
109
- end
71
+ path = Utopia::Path["/foo/bar/../baz/./"]
72
+ expect(path.simplify.components).to be == ['', 'foo', 'baz', '']
73
+ end
74
+
75
+ it "should be able to convert into a directory" do
76
+ path = Utopia::Path["foo/bar"]
110
77
 
111
- it "should give no locale" do
112
- path = Utopia::Path["foo"]
113
-
114
- expect(path.basename.locale).to be == nil
115
- end
78
+ expect(path).to_not be_directory
116
79
 
117
- it "should expand relative paths" do
118
- root = Utopia::Path['/root']
119
- path = Utopia::Path["dir/foo.html"]
120
-
121
- expect(path.expand(root)).to be == (root + path)
122
- end
80
+ expect(path.to_directory).to be_directory
123
81
 
124
- it "shouldn't expand absolute paths" do
125
- root = Utopia::Path['/root']
126
-
127
- expect(root.expand(root)).to be == root
128
- end
82
+ dir_path = path.to_directory
83
+ expect(dir_path.to_directory).to be == dir_path
84
+ end
85
+
86
+ it "should start with the given path" do
87
+ path = Utopia::Path["/a/b/c/d/e"]
129
88
 
130
- it "should give the shortest path for outer paths" do
131
- input = Utopia::Path.create("/a/b/c/index")
132
- output = Utopia::Path.create("/a/b/c/d/e/")
133
-
134
- short = input.shortest_path(output)
135
-
136
- expect(short.components).to be == ["..", "..", "index"]
137
-
138
- expect((output + short).simplify).to be == input
139
- end
89
+ expect(path.start_with?(path.dirname)).to be true
90
+ end
91
+
92
+ it "should split at the specified point" do
93
+ path = Utopia::Path["/a/b/c/d/e"]
140
94
 
141
- it "should give the shortest path for inner paths" do
142
- input = Utopia::Path.create("/a/b/c/index")
143
- output = Utopia::Path.create("/a/")
144
-
145
- short = input.shortest_path(output)
146
-
147
- expect(short.components).to be == ["b", "c", "index"]
148
-
149
- expect((output + short).simplify).to be == input
150
- end
95
+ expect(path.split('c')).to be == [Utopia::Path['/a/b'], Utopia::Path['d/e']]
96
+ end
97
+
98
+ it "shouldn't be able to modify frozen paths" do
99
+ path = Utopia::Path["dir/foo.html"]
100
+
101
+ path.freeze
102
+
103
+ expect(path.frozen?).to be true
104
+
105
+ expect{path[0] = 'bob'}.to raise_exception(RuntimeError)
106
+ end
107
+
108
+ it "should expand relative paths" do
109
+ root = Utopia::Path['/root']
110
+ path = Utopia::Path["dir/foo.html"]
111
+
112
+ expect(path.expand(root)).to be == (root + path)
113
+ end
114
+
115
+ it "shouldn't expand absolute paths" do
116
+ root = Utopia::Path['/root']
117
+
118
+ expect(root.expand(root)).to be == root
119
+ end
120
+
121
+ it "should give the shortest path for outer paths" do
122
+ input = Utopia::Path.create("/a/b/c/index")
123
+ output = Utopia::Path.create("/a/b/c/d/e/")
124
+
125
+ short = input.shortest_path(output)
126
+
127
+ expect(short.components).to be == ["..", "..", "index"]
128
+
129
+ expect((output + short).simplify).to be == input
130
+ end
131
+
132
+ it "should give the shortest path for inner paths" do
133
+ input = Utopia::Path.create("/a/b/c/index")
134
+ output = Utopia::Path.create("/a/")
135
+
136
+ short = input.shortest_path(output)
137
+
138
+ expect(short.components).to be == ["b", "c", "index"]
139
+
140
+ expect((output + short).simplify).to be == input
151
141
  end
152
142
  end
@@ -22,6 +22,8 @@ require 'fileutils'
22
22
  require 'tmpdir'
23
23
  require 'yaml'
24
24
 
25
+ require 'open3'
26
+
25
27
  RSpec.describe "utopia executable" do
26
28
  let(:utopia) {File.expand_path("../../bin/utopia", __dir__)}
27
29
  let(:gemspec) {Gem::Specification.load File.expand_path("../../utopia.gemspec", __dir__)}
@@ -37,6 +39,9 @@ RSpec.describe "utopia executable" do
37
39
 
38
40
  around(:each) do |example|
39
41
  Bundler.with_clean_env do
42
+ # If we don't delete this, when running on travis, it will try submit the coverage report.
43
+ ENV.delete('COVERAGE')
44
+
40
45
  # This allows the utopia command to load the correct library:
41
46
  ENV['RUBYLIB'] = File.expand_path("../../lib", __dir__)
42
47
 
@@ -45,14 +50,11 @@ RSpec.describe "utopia executable" do
45
50
  end
46
51
 
47
52
  def sh_status(*args)
48
- puts args.join(' ')
49
- system(*args)
50
- return $?
53
+ system(*args) ? 0 : false
51
54
  end
52
55
 
53
56
  def sh_stdout(*args)
54
- puts args.join(' ')
55
- output = %x[#{args.join ' '}]
57
+ output, status = Open3.capture2(*args)
56
58
  return output
57
59
  end
58
60
 
data/utopia.gemspec CHANGED
@@ -14,6 +14,7 @@ Gem::Specification.new do |spec|
14
14
  EOF
15
15
  spec.summary = %q{Utopia is a framework for building dynamic content-driven websites.}
16
16
  spec.homepage = 'https://github.com/ioquatix/utopia'
17
+ spec.license = "MIT"
17
18
 
18
19
  spec.files = `git ls-files`.split($/)
19
20
  spec.executables = spec.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
@@ -37,7 +38,7 @@ Gem::Specification.new do |spec|
37
38
  spec.add_dependency 'concurrent-ruby', '~> 1.0'
38
39
 
39
40
  spec.add_development_dependency 'bundler', '~> 1.3'
40
- spec.add_development_dependency 'rspec', '~> 3.4'
41
+ spec.add_development_dependency 'rspec', '~> 3.6'
41
42
  spec.add_development_dependency 'puma'
42
43
  spec.add_development_dependency 'rake'
43
44
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: utopia
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.3
4
+ version: 2.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Samuel Williams
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-03-29 00:00:00.000000000 Z
11
+ date: 2017-06-16 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: trenni
@@ -142,14 +142,14 @@ dependencies:
142
142
  requirements:
143
143
  - - "~>"
144
144
  - !ruby/object:Gem::Version
145
- version: '3.4'
145
+ version: '3.6'
146
146
  type: :development
147
147
  prerelease: false
148
148
  version_requirements: !ruby/object:Gem::Requirement
149
149
  requirements:
150
150
  - - "~>"
151
151
  - !ruby/object:Gem::Version
152
- version: '3.4'
152
+ version: '3.6'
153
153
  - !ruby/object:Gem::Dependency
154
154
  name: puma
155
155
  requirement: !ruby/object:Gem::Requirement
@@ -211,7 +211,6 @@ files:
211
211
  - documentation/config.ru
212
212
  - documentation/config/README.md
213
213
  - documentation/config/environment.rb
214
- - documentation/config/puma.rb
215
214
  - documentation/lib/readme.txt
216
215
  - documentation/pages/_editor.xnode
217
216
  - documentation/pages/_heading.xnode
@@ -486,6 +485,7 @@ files:
486
485
  - spec/utopia/controller/respond_spec/api/controller.rb
487
486
  - spec/utopia/controller/respond_spec/errors/controller.rb
488
487
  - spec/utopia/controller/respond_spec/errors/file-not-found.xnode
488
+ - spec/utopia/controller/respond_spec/rewrite/controller.rb
489
489
  - spec/utopia/controller/rewrite_spec.rb
490
490
  - spec/utopia/controller/sequence_spec.rb
491
491
  - spec/utopia/controller/variables_spec.rb
@@ -530,7 +530,8 @@ files:
530
530
  - spec/utopia/static_spec/test.txt
531
531
  - utopia.gemspec
532
532
  homepage: https://github.com/ioquatix/utopia
533
- licenses: []
533
+ licenses:
534
+ - MIT
534
535
  metadata: {}
535
536
  post_install_message:
536
537
  rdoc_options: []
@@ -608,6 +609,7 @@ test_files:
608
609
  - spec/utopia/controller/respond_spec/api/controller.rb
609
610
  - spec/utopia/controller/respond_spec/errors/controller.rb
610
611
  - spec/utopia/controller/respond_spec/errors/file-not-found.xnode
612
+ - spec/utopia/controller/respond_spec/rewrite/controller.rb
611
613
  - spec/utopia/controller/rewrite_spec.rb
612
614
  - spec/utopia/controller/sequence_spec.rb
613
615
  - spec/utopia/controller/variables_spec.rb
@@ -1,20 +0,0 @@
1
-
2
- # Configure "min" to be the minimum number of threads to use to answer
3
- # requests and "max" the maximum.
4
- threads 0,4
5
-
6
- # Preload the application before starting the workers; this conflicts with
7
- # phased restart feature. (off by default)
8
- preload_app!
9
-
10
- # This writes run/url.txt which allows us to watch and load the URL once puma has started.
11
- get(:binds).tap do |binds|
12
- urls = binds.grep(/tcp:\/\/0.0.0.0:(\d+)/).collect do
13
- "http://localhost:#{$1}"
14
- end
15
-
16
- run_path = File.expand_path('../run', __dir__)
17
-
18
- FileUtils.mkdir_p run_path
19
- File.write(File.join(run_path, 'url.txt'), urls.first)
20
- end