Skip to content

Commit 13ed094

Browse files
WIP: Introduce suspenders:install:web generator and application template
Create generator to invoke all necessary generators. We add it to the `install` namespace to provide flexibility should we add other installation options, such as ones for API Only applications. We manually invoke generators rather than using `generate "suspenders:generator"`. This is because in those cases, the generator is actually run, which slows down the test suite dramatically. More importantly, this allows us to use [Mocha][] to mock generators in an effort to improve testing. By mocking the generators, we ensure they're not actually invoked, which would result in a slow test. Also, it would mean we would need to build up extensive `prepare_destination` and `restore_destination` method declarations. [Mocha]: https://github.com/freerange/mocha
1 parent 7866a7b commit 13ed094

File tree

6 files changed

+158
-1
lines changed

6 files changed

+158
-1
lines changed

NEWS.md

+1
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ Unreleased
1515
* Introduce `suspenders:db:migrate` task
1616
* Introduce `suspenders:email` generator
1717
* Introduce `suspenders:testing` generator
18+
* Introduce `suspenders:install:web` generator
1819

1920
20230113.0 (January, 13, 2023)
2021

README.md

+11-1
Original file line numberDiff line numberDiff line change
@@ -9,14 +9,24 @@ if you like missing deadlines.
99

1010
## Usage
1111

12+
### Existing Rails Applications
13+
1214
```
1315
group :development, :test do
1416
gem "suspenders"
1517
end
1618
```
1719

1820
```
19-
bin/rails g suspenders:all
21+
bin/rails g suspenders:install:web
22+
```
23+
24+
### New Rails Applications
25+
26+
```
27+
rails new my_app \
28+
-d=postgresql \
29+
-m=https://raw.githubusercontent.com/thoughtbot/suspenders/lib/install/web.rb
2030
```
2131

2232
## Generators
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
require "generators/suspenders/accessibility_generator"
2+
require "generators/suspenders/styles_generator"
3+
require "generators/suspenders/advisories_generator"
4+
require "generators/suspenders/inline_svg_generator"
5+
require "generators/suspenders/factories_generator"
6+
require "generators/suspenders/jobs_generator"
7+
require "generators/suspenders/lint_generator"
8+
require "generators/suspenders/rake_generator"
9+
require "generators/suspenders/views_generator"
10+
require "generators/suspenders/setup_generator"
11+
require "generators/suspenders/tasks_generator"
12+
require "generators/suspenders/email_generator"
13+
require "generators/suspenders/testing_generator"
14+
15+
module Suspenders
16+
module Generators
17+
module Install
18+
class WebGenerator < Rails::Generators::Base
19+
include Suspenders::Generators::APIAppUnsupported
20+
21+
def invoke_generators
22+
Suspenders::Generators::AccessibilityGenerator.new.invoke_all
23+
Suspenders::Generators::StylesGenerator.new.invoke_all
24+
Suspenders::Generators::AdvisoriesGenerator.new.invoke_all
25+
Suspenders::Generators::InlineSvgGenerator.new.invoke_all
26+
Suspenders::Generators::FactoriesGenerator.new.invoke_all
27+
Suspenders::Generators::JobsGenerator.new.invoke_all
28+
Suspenders::Generators::RakeGenerator.new.invoke_all
29+
Suspenders::Generators::ViewsGenerator.new.invoke_all
30+
Suspenders::Generators::SetupGenerator.new.invoke_all
31+
Suspenders::Generators::TasksGenerator.new.invoke_all
32+
Suspenders::Generators::EmailGenerator.new.invoke_all
33+
Suspenders::Generators::TestingGenerator.new.invoke_all
34+
35+
# Needs to be invoked last, since it fixes any liting violations
36+
# caused by the previous generators.
37+
Suspenders::Generators::LintGenerator.new.invoke_all
38+
end
39+
end
40+
end
41+
end
42+
end

lib/install/web.rb

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
after_bundle do
2+
gem_group :development, :test do
3+
gem "suspenders", github: "thoughtbot/suspenders", branch: "suspenders-3-0-0-web-generator"
4+
end
5+
6+
run "bundle install"
7+
8+
generate "suspenders:install:web"
9+
end

lib/suspenders/generators.rb

+3
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@
22

33
module Suspenders
44
module Generators
5+
6+
CSS_OPTIONS = %w[tailwind postcss].freeze
7+
58
module Helpers
69
def default_test_suite?
710
File.exist? Rails.root.join("test")
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
require "test_helper"
2+
require "generators/suspenders/install/web_generator"
3+
4+
module Suspenders
5+
module Generators
6+
module Install
7+
class WebGeneratorTest < Rails::Generators::TestCase
8+
include Suspenders::TestHelpers
9+
10+
tests Suspenders::Generators::Install::WebGenerator
11+
destination Rails.root
12+
setup :prepare_destination
13+
teardown :restore_destination
14+
15+
test "raises if API only application" do
16+
within_api_only_app do
17+
assert_raises Suspenders::Generators::APIAppUnsupported::Error do
18+
run_generator
19+
end
20+
end
21+
end
22+
23+
test "invokes generators" do
24+
accessibility_generator_mock = mock("accessibility_generator")
25+
Suspenders::Generators::AccessibilityGenerator.stubs(:new).returns(accessibility_generator_mock)
26+
27+
styles_generator_mock = mock("styles_generator")
28+
Suspenders::Generators::StylesGenerator.stubs(:new).returns(styles_generator_mock)
29+
30+
advisories_generator_mock = mock("advisories_generator")
31+
Suspenders::Generators::AdvisoriesGenerator.stubs(:new).returns(advisories_generator_mock)
32+
33+
inline_svg_generator_mock = mock("inline_svg_generator")
34+
Suspenders::Generators::InlineSvgGenerator.stubs(:new).returns(inline_svg_generator_mock)
35+
36+
facories_generator_mock = mock("facories_generator")
37+
Suspenders::Generators::FactoriesGenerator.stubs(:new).returns(facories_generator_mock)
38+
39+
jobs_generator_mock = mock("jobs_generator")
40+
Suspenders::Generators::JobsGenerator.stubs(:new).returns(jobs_generator_mock)
41+
42+
lint_generator_mock = mock("lint_generator")
43+
Suspenders::Generators::LintGenerator.stubs(:new).returns(lint_generator_mock)
44+
45+
rake_generator_mock = mock("rake_generator")
46+
Suspenders::Generators::RakeGenerator.stubs(:new).returns(rake_generator_mock)
47+
48+
views_generator_mock = mock("views_generator")
49+
Suspenders::Generators::ViewsGenerator.stubs(:new).returns(views_generator_mock)
50+
51+
setup_generator_mock = mock("setup_generator")
52+
Suspenders::Generators::SetupGenerator.stubs(:new).returns(setup_generator_mock)
53+
54+
tasks_generator_mock = mock("tasks_generator")
55+
Suspenders::Generators::TasksGenerator.stubs(:new).returns(tasks_generator_mock)
56+
57+
email_generator_mock = mock("email_generator")
58+
Suspenders::Generators::EmailGenerator.stubs(:new).returns(email_generator_mock)
59+
60+
testing_generator_mock = mock("testing_generator")
61+
Suspenders::Generators::TestingGenerator.stubs(:new).returns(testing_generator_mock)
62+
63+
accessibility_generator_mock.expects(:invoke_all).once
64+
styles_generator_mock.expects(:invoke_all).once
65+
advisories_generator_mock.expects(:invoke_all).once
66+
inline_svg_generator_mock.expects(:invoke_all).once
67+
facories_generator_mock.expects(:invoke_all).once
68+
jobs_generator_mock.expects(:invoke_all).once
69+
lint_generator_mock.expects(:invoke_all).once
70+
rake_generator_mock.expects(:invoke_all).once
71+
views_generator_mock.expects(:invoke_all).once
72+
setup_generator_mock.expects(:invoke_all).once
73+
tasks_generator_mock.expects(:invoke_all).once
74+
email_generator_mock.expects(:invoke_all).once
75+
testing_generator_mock.expects(:invoke_all).once
76+
77+
generator_class.new([], css: "tailwind").invoke_generators
78+
end
79+
80+
private
81+
82+
def prepare_destination
83+
touch "Gemfile"
84+
end
85+
86+
def restore_destination
87+
remove_file_if_exists "Gemfile"
88+
end
89+
end
90+
end
91+
end
92+
end

0 commit comments

Comments
 (0)