utopia 2.0.3 → 2.1.0

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.
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