@@ -8,25 +8,220 @@ module Generators
8
8
class DevcontainerGeneratorTest < Rails ::Generators ::TestCase
9
9
include GeneratorsTestHelper
10
10
11
- def test_generates_devcontainer_files
11
+ def test_creates_devcontainer_files
12
12
run_generator
13
13
14
14
assert_file ".devcontainer/compose.yaml"
15
15
assert_file ".devcontainer/Dockerfile"
16
16
assert_file ".devcontainer/devcontainer.json"
17
+ test_common_config
17
18
end
18
19
19
- def test_default_json_has_no_mounts
20
+ def test_active_storage_option_default
20
21
run_generator
21
22
22
- assert_devcontainer_json_file do |devcontainer_config |
23
- assert_nil devcontainer_config [ "mounts" ]
23
+ assert_devcontainer_json_file do |devcontainer_json |
24
+ assert_includes devcontainer_json [ "features" ] . keys , "ghcr.io/rails/devcontainer/features/activestorage"
25
+ end
26
+ end
27
+
28
+ def test_active_storage_option_skip
29
+ run_generator [ "--skip-active-storage" ]
30
+
31
+ test_common_config
32
+ assert_devcontainer_json_file do |devcontainer_json |
33
+ assert_nil devcontainer_json [ "features" ] [ "ghcr.io/rails/devcontainer/features/activestorage" ]
34
+ end
35
+ end
36
+
37
+ def test_app_name_option_default
38
+ run_generator
39
+
40
+ assert_devcontainer_json_file do |devcontainer_json |
41
+ assert_equal "rails_app" , devcontainer_json [ "name" ]
42
+ end
43
+
44
+ assert_compose_file do |compose |
45
+ assert_equal "rails_app" , compose [ "name" ]
46
+ end
47
+ end
48
+
49
+ def test_app_name_option
50
+ run_generator [ "--app-name" , "my-TestApp_name" ]
51
+
52
+ test_common_config
53
+ assert_devcontainer_json_file do |devcontainer_json |
54
+ assert_equal "my-TestApp_name" , devcontainer_json [ "name" ]
55
+ end
56
+
57
+ assert_compose_file do |compose |
58
+ assert_equal "my-TestApp_name" , compose [ "name" ]
59
+ end
60
+ end
61
+
62
+ def test_database_default_sqlite3
63
+ run_generator
64
+
65
+ assert_no_file "config/database.yml"
66
+ assert_devcontainer_json_file do |devcontainer_json |
67
+ assert_includes devcontainer_json [ "features" ] . keys , "ghcr.io/rails/devcontainer/features/sqlite3"
68
+ end
69
+ end
70
+
71
+ def test_database_mariadb_mysql
72
+ run_generator [ "--database" , "mariadb-mysql" ]
73
+
74
+ test_common_config
75
+ assert_no_file "config/database.yml"
76
+ assert_compose_file do |compose |
77
+ expected_mariadb_config = {
78
+ "image" => "mariadb:10.5" ,
79
+ "restart" => "unless-stopped" ,
80
+ "networks" => [ "default" ] ,
81
+ "volumes" => [ "mariadb-data:/var/lib/mysql" ] ,
82
+ "environment" => {
83
+ "MARIADB_ALLOW_EMPTY_ROOT_PASSWORD" => "true" ,
84
+ } ,
85
+ }
86
+ assert_equal expected_mariadb_config , compose [ "services" ] [ "mariadb" ]
87
+ assert_includes compose [ "volumes" ] . keys , "mariadb-data"
88
+ assert_includes compose [ "services" ] [ "rails-app" ] [ "depends_on" ] , "mariadb"
89
+ end
90
+
91
+ assert_devcontainer_json_file do |devcontainer_json |
92
+ assert_equal "mariadb" , devcontainer_json [ "containerEnv" ] [ "DB_HOST" ]
93
+ assert_includes devcontainer_json [ "features" ] . keys , "ghcr.io/rails/devcontainer/features/mysql-client"
94
+ assert_includes devcontainer_json [ "forwardPorts" ] , 3306
95
+ end
96
+ end
97
+
98
+ def test_database_mariadb_trilogy
99
+ run_generator [ "--database" , "mariadb-trilogy" ]
100
+
101
+ test_common_config
102
+ assert_no_file "config/database.yml"
103
+ assert_compose_file do |compose |
104
+ expected_mariadb_config = {
105
+ "image" => "mariadb:10.5" ,
106
+ "restart" => "unless-stopped" ,
107
+ "networks" => [ "default" ] ,
108
+ "volumes" => [ "mariadb-data:/var/lib/mysql" ] ,
109
+ "environment" => {
110
+ "MARIADB_ALLOW_EMPTY_ROOT_PASSWORD" => "true" ,
111
+ } ,
112
+ }
113
+ assert_equal expected_mariadb_config , compose [ "services" ] [ "mariadb" ]
114
+ assert_includes compose [ "volumes" ] . keys , "mariadb-data"
115
+ assert_includes compose [ "services" ] [ "rails-app" ] [ "depends_on" ] , "mariadb"
116
+ end
117
+
118
+ assert_devcontainer_json_file do |devcontainer_json |
119
+ assert_equal "mariadb" , devcontainer_json [ "containerEnv" ] [ "DB_HOST" ]
120
+ assert_includes devcontainer_json [ "forwardPorts" ] , 3306
121
+ end
122
+ end
123
+
124
+ def test_database_mysql
125
+ run_generator [ "--database" , "mysql" ]
126
+
127
+ test_common_config
128
+ assert_no_file "config/database.yml"
129
+ assert_compose_file do |compose |
130
+ expected_mysql_config = {
131
+ "image" => "mysql/mysql-server:8.0" ,
132
+ "restart" => "unless-stopped" ,
133
+ "environment" => {
134
+ "MYSQL_ALLOW_EMPTY_PASSWORD" => "true" ,
135
+ "MYSQL_ROOT_HOST" => "%"
136
+ } ,
137
+ "volumes" => [ "mysql-data:/var/lib/mysql" ] ,
138
+ "networks" => [ "default" ] ,
139
+ }
140
+ assert_equal expected_mysql_config , compose [ "services" ] [ "mysql" ]
141
+ assert_includes compose [ "volumes" ] . keys , "mysql-data"
142
+ assert_includes compose [ "services" ] [ "rails-app" ] [ "depends_on" ] , "mysql"
143
+ end
144
+
145
+ assert_devcontainer_json_file do |devcontainer_json |
146
+ assert_equal "mysql" , devcontainer_json [ "containerEnv" ] [ "DB_HOST" ]
147
+ assert_includes devcontainer_json [ "features" ] . keys , "ghcr.io/rails/devcontainer/features/mysql-client"
148
+ assert_includes devcontainer_json [ "forwardPorts" ] , 3306
24
149
end
25
150
end
26
151
27
- def test_dev_option_devcontainer_json_mounts_local_rails
152
+ def test_database_postgresql
153
+ run_generator [ "--database" , "postgresql" ]
154
+
155
+ test_common_config
156
+
157
+ assert_file ( "config/database.yml" ) do |db_config |
158
+ assert_match ( /host: <%= ENV\[ "DB_HOST"\] %>/ , db_config )
159
+ assert_match ( /username: postgres/ , db_config )
160
+ assert_match ( /password: postgres/ , db_config )
161
+ end
162
+
163
+ assert_compose_file do |compose |
164
+ expected_postgres_config = {
165
+ "image" => "postgres:16.1" ,
166
+ "restart" => "unless-stopped" ,
167
+ "networks" => [ "default" ] ,
168
+ "volumes" => [ "postgres-data:/var/lib/postgresql/data" ] ,
169
+ "environment" => {
170
+ "POSTGRES_USER" => "postgres" ,
171
+ "POSTGRES_PASSWORD" => "postgres"
172
+ }
173
+ }
174
+ assert_equal expected_postgres_config , compose [ "services" ] [ "postgres" ]
175
+ assert_includes compose [ "volumes" ] . keys , "postgres-data"
176
+ assert_includes compose [ "services" ] [ "rails-app" ] [ "depends_on" ] , "postgres"
177
+ end
178
+
179
+ assert_devcontainer_json_file do |devcontainer_json |
180
+ assert_equal "postgres" , devcontainer_json [ "containerEnv" ] [ "DB_HOST" ]
181
+ assert_includes devcontainer_json [ "features" ] . keys , "ghcr.io/rails/devcontainer/features/postgres-client"
182
+ assert_includes devcontainer_json [ "forwardPorts" ] , 5432
183
+ end
184
+ end
185
+
186
+ def test_database_trilogy
187
+ run_generator [ "--database" , "trilogy" ]
188
+
189
+ test_common_config
190
+ assert_no_file "config/database.yml"
191
+ assert_compose_file do |compose |
192
+ expected_mysql_config = {
193
+ "image" => "mysql/mysql-server:8.0" ,
194
+ "restart" => "unless-stopped" ,
195
+ "environment" => {
196
+ "MYSQL_ALLOW_EMPTY_PASSWORD" => "true" ,
197
+ "MYSQL_ROOT_HOST" => "%"
198
+ } ,
199
+ "volumes" => [ "mysql-data:/var/lib/mysql" ] ,
200
+ "networks" => [ "default" ] ,
201
+ }
202
+ assert_equal expected_mysql_config , compose [ "services" ] [ "mysql" ]
203
+ assert_includes compose [ "volumes" ] . keys , "mysql-data"
204
+ assert_includes compose [ "services" ] [ "rails-app" ] [ "depends_on" ] , "mysql"
205
+ end
206
+
207
+ assert_devcontainer_json_file do |content |
208
+ assert_equal "mysql" , content [ "containerEnv" ] [ "DB_HOST" ]
209
+ assert_includes content [ "forwardPorts" ] , 3306
210
+ end
211
+ end
212
+
213
+ def test_dev_option_default
214
+ run_generator
215
+
216
+ assert_devcontainer_json_file do |devcontainer_json |
217
+ assert_nil devcontainer_json [ "mounts" ]
218
+ end
219
+ end
220
+
221
+ def test_dev_option
28
222
run_generator [ "--dev" ]
29
223
224
+ test_common_config
30
225
assert_devcontainer_json_file do |devcontainer_json |
31
226
mounts = devcontainer_json [ "mounts" ] . sole
32
227
@@ -35,6 +230,124 @@ def test_dev_option_devcontainer_json_mounts_local_rails
35
230
assert_equal Rails ::Generators ::RAILS_DEV_PATH , mounts [ "target" ]
36
231
end
37
232
end
233
+
234
+ def test_node_option_default
235
+ run_generator
236
+
237
+ assert_devcontainer_json_file do |devcontainer_json |
238
+ assert_not_includes devcontainer_json [ "features" ] . keys , "ghcr.io/devcontainers/features/node:1"
239
+ end
240
+ end
241
+
242
+ def test_node_option
243
+ run_generator [ "--node" ]
244
+
245
+ test_common_config
246
+ assert_devcontainer_json_file do |devcontainer_json |
247
+ assert_includes devcontainer_json [ "features" ] . keys , "ghcr.io/devcontainers/features/node:1"
248
+ end
249
+ end
250
+
251
+ def test_redis_option_default
252
+ run_generator
253
+
254
+ assert_compose_file do |compose |
255
+ assert_includes compose [ "services" ] [ "rails-app" ] [ "depends_on" ] , "redis"
256
+ expected_redis_config = {
257
+ "image" => "redis:7.2" ,
258
+ "restart" => "unless-stopped" ,
259
+ "volumes" => [ "redis-data:/data" ]
260
+ }
261
+ assert_equal expected_redis_config , compose [ "services" ] [ "redis" ]
262
+ assert_equal [ "redis-data" ] , compose [ "volumes" ] . keys
263
+ end
264
+
265
+ assert_devcontainer_json_file do |devcontainer_json |
266
+ assert_equal "redis://redis:6379/1" , devcontainer_json [ "containerEnv" ] [ "REDIS_URL" ]
267
+ assert_includes devcontainer_json [ "forwardPorts" ] , 6379
268
+ end
269
+ end
270
+
271
+ def test_redis_option_skip
272
+ run_generator [ "--skip-redis" ]
273
+
274
+ test_common_config
275
+ assert_compose_file do |compose |
276
+ assert_not_includes compose [ "services" ] [ "rails-app" ] [ "depends_on" ] , "redis"
277
+ assert_nil compose [ "services" ] [ "redis" ]
278
+ assert_nil compose [ "volumes" ]
279
+ end
280
+
281
+ assert_devcontainer_json_file do |devcontainer_json |
282
+ assert_not_includes devcontainer_json [ "forwardPorts" ] , 6379
283
+ end
284
+ end
285
+
286
+ def test_system_test_option_default
287
+ copy_application_system_test_case
288
+
289
+ run_generator
290
+
291
+ assert_devcontainer_json_file do |devcontainer_json |
292
+ assert_equal "45678" , devcontainer_json [ "containerEnv" ] [ "CAPYBARA_SERVER_PORT" ]
293
+ assert_equal "selenium" , devcontainer_json [ "containerEnv" ] [ "SELENIUM_HOST" ]
294
+ end
295
+
296
+ assert_file ( "test/application_system_test_case.rb" ) do |system_test_case |
297
+ assert_match ( /^ if ENV\[ "CAPYBARA_SERVER_PORT"\] / , system_test_case )
298
+ assert_match ( /^ served_by host: "rails-app", port: ENV\[ "CAPYBARA_SERVER_PORT"\] / , system_test_case )
299
+ assert_match ( /^ driven_by :selenium, using: :headless_chrome, screen_size: \[ 1400, 1400 \] , options: {$/ , system_test_case )
300
+ assert_match ( /^ browser: :remote,$/ , system_test_case )
301
+ assert_match ( /^ url: "http:\/ \/ \# {ENV\[ "SELENIUM_HOST"\] }:4444"$/ , system_test_case )
302
+ end
303
+ end
304
+
305
+ def test_system_test_option_does_not_create_new_file
306
+ run_generator [ "--system-test" ]
307
+
308
+ test_common_config
309
+ assert_no_file "test/application_system_test_case.rb"
310
+ end
311
+
312
+ def test_system_test_option_skip
313
+ copy_application_system_test_case
314
+
315
+ run_generator [ "--skip-system-test" , "--force" ]
316
+
317
+ test_common_config
318
+ assert_compose_file do |compose |
319
+ assert_not_includes compose [ "services" ] [ "rails-app" ] [ "depends_on" ] , "selenium"
320
+ assert_not_includes compose [ "services" ] . keys , "selenium"
321
+ end
322
+ assert_devcontainer_json_file do |devcontainer_json |
323
+ assert_nil devcontainer_json [ "containerEnv" ] [ "CAPYBARA_SERVER_PORT" ]
324
+ end
325
+ end
326
+
327
+ private
328
+ def test_common_config
329
+ assert_file ( ".devcontainer/Dockerfile" ) do |dockerfile |
330
+ assert_match ( /ARG RUBY_VERSION=#{ RUBY_VERSION } / , dockerfile )
331
+ end
332
+
333
+ assert_devcontainer_json_file do |devcontainer_json |
334
+ assert_includes devcontainer_json [ "features" ] . keys , "ghcr.io/devcontainers/features/github-cli:1"
335
+ assert_includes devcontainer_json [ "forwardPorts" ] , 3000
336
+ end
337
+
338
+ assert_compose_file do |compose |
339
+ expected_app_config = {
340
+ "build" => {
341
+ "context" => ".." ,
342
+ "dockerfile" => ".devcontainer/Dockerfile"
343
+ } ,
344
+ "volumes" => [ "../..:/workspaces:cached" ] ,
345
+ "command" => "sleep infinity"
346
+ }
347
+ actual_independent_config = compose [ "services" ] [ "rails-app" ] . except ( "depends_on" )
348
+ assert_equal expected_app_config , actual_independent_config
349
+ end
350
+ end
38
351
end
39
352
end
40
353
end
0 commit comments