sandals 0.1.0 → 0.1.1
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 +4 -4
- data/README.md +51 -1
- data/lib/sandals/cli.rb +86 -5
- data/lib/sandals/version.rb +1 -1
- metadata +15 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 729bdd148836e2e4876915282f45c5dfb13e5ac040a45ab973a40824d4a02e09
|
|
4
|
+
data.tar.gz: b4ce94253c0bb8d5a8e7026e2c8dc5f873d748ee572756a98b240ff02e3a1f64
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 1298a4d2d07e5ff4d0a09dbc446fa2f32858a043f9ea68bcd76c0be4543aceaa0292e4f469bde1048ce63d4932eee26da0eae88a715f9dffd5a7328832ec8fbf
|
|
7
|
+
data.tar.gz: e09f3194ff8c72a2c0dbab9f00f73ea7916deaca101427c617b6c5d04a307c50a95563805a2094a895288a7ae6874753f5cf45d61039b4435e216cdaabf5a9c5
|
data/README.md
CHANGED
|
@@ -19,12 +19,62 @@ Sandals requires Ruby 3.1 or later.
|
|
|
19
19
|
|
|
20
20
|
```sh
|
|
21
21
|
gem install sandals
|
|
22
|
-
sandals
|
|
22
|
+
sandals new hello
|
|
23
|
+
sandals run hello.rb
|
|
23
24
|
```
|
|
24
25
|
|
|
25
26
|
The server listens on `127.0.0.1`. All required assets are included in the gem,
|
|
26
27
|
so a local app does not need an internet connection.
|
|
27
28
|
|
|
29
|
+
## Quickstart
|
|
30
|
+
|
|
31
|
+
Create your first application:
|
|
32
|
+
|
|
33
|
+
```sh
|
|
34
|
+
sandals new hello
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
This creates two files:
|
|
38
|
+
|
|
39
|
+
```text
|
|
40
|
+
hello.rb
|
|
41
|
+
hello_test.rb
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
`hello.rb` is a small application with a text field and a greeting. Run it:
|
|
45
|
+
|
|
46
|
+
```sh
|
|
47
|
+
sandals run hello.rb
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
Keep Sandals running and open `hello.rb` in your editor. Change:
|
|
51
|
+
|
|
52
|
+
```ruby
|
|
53
|
+
title "Hello"
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
to:
|
|
57
|
+
|
|
58
|
+
```ruby
|
|
59
|
+
title "Hello from Ruby"
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
Save the file. The browser reloads automatically and shows the change.
|
|
63
|
+
|
|
64
|
+
If the file contains a syntax or load error, Sandals keeps the last valid
|
|
65
|
+
version running and reports the error with its location. Fix the file and save
|
|
66
|
+
it again; the application recovers automatically.
|
|
67
|
+
|
|
68
|
+
The generated test interacts with the application through visible labels and
|
|
69
|
+
text. Run it with:
|
|
70
|
+
|
|
71
|
+
```sh
|
|
72
|
+
ruby hello_test.rb
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
The test fills in `"Your name"` and verifies that the greeting appears. It uses
|
|
76
|
+
Minitest, which is installed with Sandals.
|
|
77
|
+
|
|
28
78
|
## The experience
|
|
29
79
|
|
|
30
80
|
An application should normally fit in a single file:
|
data/lib/sandals/cli.rb
CHANGED
|
@@ -15,9 +15,11 @@ module Sandals
|
|
|
15
15
|
|
|
16
16
|
def run
|
|
17
17
|
command = @arguments.shift
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
18
|
+
case command
|
|
19
|
+
when "run" then run_app
|
|
20
|
+
when "new" then new_app
|
|
21
|
+
else usage
|
|
22
|
+
end
|
|
21
23
|
rescue Interrupt
|
|
22
24
|
0
|
|
23
25
|
rescue StandardError => error
|
|
@@ -27,6 +29,42 @@ module Sandals
|
|
|
27
29
|
|
|
28
30
|
private
|
|
29
31
|
|
|
32
|
+
def new_app
|
|
33
|
+
name = @arguments.shift
|
|
34
|
+
raise ArgumentError, "missing app name" unless name
|
|
35
|
+
raise ArgumentError, "unexpected arguments: #{@arguments.join(' ')}" unless @arguments.empty?
|
|
36
|
+
|
|
37
|
+
base_name = name.delete_suffix(".rb")
|
|
38
|
+
unless base_name.match?(/\A[a-zA-Z0-9][a-zA-Z0-9_-]*\z/)
|
|
39
|
+
raise ArgumentError, "app name must contain only letters, numbers, underscores, or hyphens"
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
app_path = "#{base_name}.rb"
|
|
43
|
+
test_path = "#{base_name}_test.rb"
|
|
44
|
+
existing_path = [app_path, test_path].find { |path| File.exist?(path) }
|
|
45
|
+
raise ArgumentError, "#{existing_path} already exists" if existing_path
|
|
46
|
+
|
|
47
|
+
title = base_name.split(/[_-]+/).map(&:capitalize).join(" ")
|
|
48
|
+
File.open(app_path, File::WRONLY | File::CREAT | File::EXCL, 0o644) do |file|
|
|
49
|
+
file.write(app_template(title))
|
|
50
|
+
end
|
|
51
|
+
File.open(test_path, File::WRONLY | File::CREAT | File::EXCL, 0o644) do |file|
|
|
52
|
+
file.write(test_template(base_name))
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
puts "Created #{app_path}"
|
|
56
|
+
puts "Created #{test_path}"
|
|
57
|
+
puts
|
|
58
|
+
puts "Run the app:"
|
|
59
|
+
puts " sandals run #{app_path}"
|
|
60
|
+
puts
|
|
61
|
+
puts "Run the test:"
|
|
62
|
+
puts " ruby #{test_path}"
|
|
63
|
+
0
|
|
64
|
+
rescue Errno::EEXIST
|
|
65
|
+
raise ArgumentError, "could not create app because a generated file already exists"
|
|
66
|
+
end
|
|
67
|
+
|
|
30
68
|
def run_app
|
|
31
69
|
options = { open: true, port: 0 }
|
|
32
70
|
parser = OptionParser.new do |opts|
|
|
@@ -40,7 +78,7 @@ module Sandals
|
|
|
40
78
|
server = Server.new(application, port: options[:port], reload_path: path)
|
|
41
79
|
|
|
42
80
|
trap("INT") { server.stop }
|
|
43
|
-
puts "Sandals
|
|
81
|
+
puts "Sandals is running #{path}"
|
|
44
82
|
puts server.url
|
|
45
83
|
open_browser(server.url) if options[:open]
|
|
46
84
|
server.start
|
|
@@ -67,8 +105,51 @@ module Sandals
|
|
|
67
105
|
system(*command, out: File::NULL, err: File::NULL)
|
|
68
106
|
end
|
|
69
107
|
|
|
108
|
+
def app_template(title)
|
|
109
|
+
<<~RUBY
|
|
110
|
+
require "sandals"
|
|
111
|
+
|
|
112
|
+
Sandals.app title: "#{title}" do
|
|
113
|
+
@name = ""
|
|
114
|
+
|
|
115
|
+
view do
|
|
116
|
+
stack do
|
|
117
|
+
title "#{title}"
|
|
118
|
+
|
|
119
|
+
text_field "Your name", value: @name do |value|
|
|
120
|
+
@name = value
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
para "Hello, \#{@name}!" unless @name.empty?
|
|
124
|
+
end
|
|
125
|
+
end
|
|
126
|
+
end
|
|
127
|
+
RUBY
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
def test_template(base_name)
|
|
131
|
+
<<~RUBY
|
|
132
|
+
require "minitest/autorun"
|
|
133
|
+
require_relative "#{base_name}"
|
|
134
|
+
|
|
135
|
+
class GeneratedAppTest < Minitest::Test
|
|
136
|
+
def test_greets_the_user
|
|
137
|
+
session = Sandals.test(Sandals.application)
|
|
138
|
+
|
|
139
|
+
session.field("Your name").fill("Ada")
|
|
140
|
+
|
|
141
|
+
assert session.text?("Hello, Ada!")
|
|
142
|
+
end
|
|
143
|
+
end
|
|
144
|
+
RUBY
|
|
145
|
+
end
|
|
146
|
+
|
|
70
147
|
def usage
|
|
71
|
-
warn
|
|
148
|
+
warn <<~USAGE
|
|
149
|
+
Usage:
|
|
150
|
+
sandals new NAME
|
|
151
|
+
sandals run APP [--no-open] [--port PORT]
|
|
152
|
+
USAGE
|
|
72
153
|
1
|
|
73
154
|
end
|
|
74
155
|
end
|
data/lib/sandals/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: sandals
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.1.
|
|
4
|
+
version: 0.1.1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Benito Serna
|
|
@@ -9,6 +9,20 @@ bindir: bin
|
|
|
9
9
|
cert_chain: []
|
|
10
10
|
date: 1980-01-02 00:00:00.000000000 Z
|
|
11
11
|
dependencies:
|
|
12
|
+
- !ruby/object:Gem::Dependency
|
|
13
|
+
name: minitest
|
|
14
|
+
requirement: !ruby/object:Gem::Requirement
|
|
15
|
+
requirements:
|
|
16
|
+
- - "~>"
|
|
17
|
+
- !ruby/object:Gem::Version
|
|
18
|
+
version: '6.0'
|
|
19
|
+
type: :runtime
|
|
20
|
+
prerelease: false
|
|
21
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
22
|
+
requirements:
|
|
23
|
+
- - "~>"
|
|
24
|
+
- !ruby/object:Gem::Version
|
|
25
|
+
version: '6.0'
|
|
12
26
|
- !ruby/object:Gem::Dependency
|
|
13
27
|
name: webrick
|
|
14
28
|
requirement: !ruby/object:Gem::Requirement
|