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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 8706dd760aa94d3533ea6c2fb18bf8d265272a3c49250e1539300e8f2d960740
4
- data.tar.gz: 87590e396a533c73abc3eb6689c90481f301d84c885e344bb21148845f602baf
3
+ metadata.gz: 729bdd148836e2e4876915282f45c5dfb13e5ac040a45ab973a40824d4a02e09
4
+ data.tar.gz: b4ce94253c0bb8d5a8e7026e2c8dc5f873d748ee572756a98b240ff02e3a1f64
5
5
  SHA512:
6
- metadata.gz: b5cf4873ca1ebc024b7f45c744b3d7747ace37a867b6a0c9dfb9e85861398e3bf2ff99d7a431c1e7c9d063f1df1b5a65684918fa581ab2bfcf94915e2201fe81
7
- data.tar.gz: 1e17469e4cb0a3bdf878ffafc07d45e083e620a8410704c012c2cd524268e2b22d3786a6c7cf0db04e1b28707fea3198b121dbe5e0cc5b6bf7323d6d039a3705
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 run app.rb
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
- return usage unless command == "run"
19
-
20
- run_app
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 está corriendo #{path}"
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 "Usage: sandals run APP [--no-open] [--port PORT]"
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
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Sandals
4
- VERSION = "0.1.0"
4
+ VERSION = "0.1.1"
5
5
  end
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.0
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