dry-web-web_pipe 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +37 -0
- data/.rspec +2 -0
- data/.travis.yml +31 -0
- data/CHANGELOG.md +283 -0
- data/CONTRIBUTING.md +29 -0
- data/Gemfile +36 -0
- data/LICENSE +22 -0
- data/README.md +72 -0
- data/Rakefile +6 -0
- data/dry-web-web_pipe.gemspec +33 -0
- data/exe/dry-web-web_pipe +6 -0
- data/lib/dry/web/web_pipe/cli/generate.rb +18 -0
- data/lib/dry/web/web_pipe/cli.rb +26 -0
- data/lib/dry/web/web_pipe/generate.rb +52 -0
- data/lib/dry/web/web_pipe/generators/abstract_generator.rb +54 -0
- data/lib/dry/web/web_pipe/generators/abstract_project.rb +116 -0
- data/lib/dry/web/web_pipe/generators/flat_project.rb +43 -0
- data/lib/dry/web/web_pipe/generators/inflections.rb +21 -0
- data/lib/dry/web/web_pipe/generators/sub_app.rb +68 -0
- data/lib/dry/web/web_pipe/generators/umbrella_project.rb +29 -0
- data/lib/dry/web/web_pipe/templates/.env.test.tt +1 -0
- data/lib/dry/web/web_pipe/templates/.env.tt +2 -0
- data/lib/dry/web/web_pipe/templates/.gitignore.tt +11 -0
- data/lib/dry/web/web_pipe/templates/.keep +0 -0
- data/lib/dry/web/web_pipe/templates/.rspec +2 -0
- data/lib/dry/web/web_pipe/templates/Gemfile +47 -0
- data/lib/dry/web/web_pipe/templates/README.md.tt +15 -0
- data/lib/dry/web/web_pipe/templates/Rakefile.tt +109 -0
- data/lib/dry/web/web_pipe/templates/application.html.slim +3 -0
- data/lib/dry/web/web_pipe/templates/config.ru.tt +7 -0
- data/lib/dry/web/web_pipe/templates/console.tt +7 -0
- data/lib/dry/web/web_pipe/templates/container.rb.tt +17 -0
- data/lib/dry/web/web_pipe/templates/flat_project/boot.rb.tt +12 -0
- data/lib/dry/web/web_pipe/templates/flat_project/root.rb.tt +16 -0
- data/lib/dry/web/web_pipe/templates/flat_project/router.rb.tt +8 -0
- data/lib/dry/web/web_pipe/templates/flat_project/web.rb.tt +52 -0
- data/lib/dry/web/web_pipe/templates/import.rb.tt +5 -0
- data/lib/dry/web/web_pipe/templates/monitor.rb.tt +10 -0
- data/lib/dry/web/web_pipe/templates/operation.rb.tt +11 -0
- data/lib/dry/web/web_pipe/templates/persistence.rb.tt +36 -0
- data/lib/dry/web/web_pipe/templates/repository.rb.tt +11 -0
- data/lib/dry/web/web_pipe/templates/sample_data.rb +1 -0
- data/lib/dry/web/web_pipe/templates/seed.rb +1 -0
- data/lib/dry/web/web_pipe/templates/settings.rb.tt +10 -0
- data/lib/dry/web/web_pipe/templates/setup +7 -0
- data/lib/dry/web/web_pipe/templates/spec/db_spec_helper.rb.tt +23 -0
- data/lib/dry/web/web_pipe/templates/spec/factories/example.rb +9 -0
- data/lib/dry/web/web_pipe/templates/spec/spec_helper.rb.tt +61 -0
- data/lib/dry/web/web_pipe/templates/spec/support/db/factory.rb +8 -0
- data/lib/dry/web/web_pipe/templates/spec/support/db/helpers.rb.tt +13 -0
- data/lib/dry/web/web_pipe/templates/spec/support/web/helpers.rb.tt +9 -0
- data/lib/dry/web/web_pipe/templates/spec/web_spec_helper.rb +37 -0
- data/lib/dry/web/web_pipe/templates/subapp/boot.rb.tt +5 -0
- data/lib/dry/web/web_pipe/templates/subapp/container.rb.tt +21 -0
- data/lib/dry/web/web_pipe/templates/subapp/import.rb.tt +7 -0
- data/lib/dry/web/web_pipe/templates/subapp/root.rb.tt +18 -0
- data/lib/dry/web/web_pipe/templates/subapp/router.rb.tt +10 -0
- data/lib/dry/web/web_pipe/templates/subapp/view.rb.tt +17 -0
- data/lib/dry/web/web_pipe/templates/subapp/view_context.rb.tt +8 -0
- data/lib/dry/web/web_pipe/templates/subapp/web.rb.tt +54 -0
- data/lib/dry/web/web_pipe/templates/subapp/welcome.rb.tt +13 -0
- data/lib/dry/web/web_pipe/templates/types.rb +6 -0
- data/lib/dry/web/web_pipe/templates/umbrella_project/boot.rb.tt +18 -0
- data/lib/dry/web/web_pipe/templates/umbrella_project/router.rb.tt +8 -0
- data/lib/dry/web/web_pipe/templates/view.rb.tt +15 -0
- data/lib/dry/web/web_pipe/templates/view_context.rb.tt +31 -0
- data/lib/dry/web/web_pipe/templates/welcome.html.slim +1 -0
- data/lib/dry/web/web_pipe/templates/welcome.rb.tt +11 -0
- data/lib/dry/web/web_pipe/version.rb +7 -0
- data/lib/dry-web-web_pipe.rb +1 -0
- data/script/ci +67 -0
- data/script/setup +47 -0
- data/script/teardown +42 -0
- data/spec/integration/new_app_spec.rb +21 -0
- data/spec/spec_helper.rb +22 -0
- data/spec/support/app.rb +64 -0
- data/spec/support/bundler.rb +113 -0
- data/spec/support/cli.rb +47 -0
- data/spec/support/directories.rb +37 -0
- data/spec/support/env.rb +84 -0
- data/spec/support/files.rb +59 -0
- data/spec/support/project.rb +60 -0
- data/spec/support/requests.rb +5 -0
- data/spec/support/silently.rb +28 -0
- data/spec/unit/generators/inflections_spec.rb +33 -0
- metadata +268 -0
data/script/teardown
ADDED
@@ -0,0 +1,42 @@
|
|
1
|
+
#!/bin/bash
|
2
|
+
set -euo pipefail
|
3
|
+
IFS=$'\n\t'
|
4
|
+
|
5
|
+
remove_bundler_cache() {
|
6
|
+
local pwd=$PWD
|
7
|
+
local cache="$pwd/vendor/cache"
|
8
|
+
|
9
|
+
rm -rf $cache
|
10
|
+
}
|
11
|
+
|
12
|
+
# We may need something like this in future if we use github checkouts of gems
|
13
|
+
# (see `uninstall_hanami_gems()` in hanami/hanami's teardown script)
|
14
|
+
#
|
15
|
+
# uninstall_gems_from_checkouts() { }
|
16
|
+
|
17
|
+
bundle_install() {
|
18
|
+
bundle install > /dev/null
|
19
|
+
}
|
20
|
+
|
21
|
+
advertise_start() {
|
22
|
+
echo -en "Cleaning up.."
|
23
|
+
}
|
24
|
+
|
25
|
+
advertise_end() {
|
26
|
+
echo " done"
|
27
|
+
}
|
28
|
+
|
29
|
+
main() {
|
30
|
+
local ci=${CI:-false}
|
31
|
+
|
32
|
+
if [ "$ci" = true ] ; then
|
33
|
+
echo "Running on CI, skipping cleanup"
|
34
|
+
else
|
35
|
+
advertise_start &&
|
36
|
+
remove_bundler_cache &&
|
37
|
+
bundle_install &&
|
38
|
+
advertise_end
|
39
|
+
fi
|
40
|
+
}
|
41
|
+
|
42
|
+
main
|
@@ -0,0 +1,21 @@
|
|
1
|
+
RSpec.describe "new app", type: :cli do
|
2
|
+
describe "umbrella project" do
|
3
|
+
it "boots and displays a welcome page" do
|
4
|
+
with_project do
|
5
|
+
run_app do |app|
|
6
|
+
expect(app.get("/")).to eq "<html><body><h1>Welcome to dry-web-web_pipe!</h1></body></html>"
|
7
|
+
end
|
8
|
+
end
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
describe "flat project" do
|
13
|
+
it "boots and displays a welcome page" do
|
14
|
+
with_project arch: "flat" do
|
15
|
+
run_app do |app|
|
16
|
+
expect(app.get("/")).to eq "<html><body><h1>Welcome to dry-web-web_pipe!</h1></body></html>"
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
require "pry-byebug"
|
2
|
+
|
3
|
+
SPEC_ROOT = Pathname(__dir__)
|
4
|
+
TEST_APP_NAME = "test_app".freeze
|
5
|
+
|
6
|
+
Dir[SPEC_ROOT.join("support/*.rb").to_s].each { |f| require f }
|
7
|
+
|
8
|
+
RSpec.configure do |config|
|
9
|
+
config.disable_monkey_patching!
|
10
|
+
|
11
|
+
config.example_status_persistence_file_path = "spec/examples.txt"
|
12
|
+
|
13
|
+
config.filter_run :focus
|
14
|
+
config.run_all_when_everything_filtered = true
|
15
|
+
|
16
|
+
config.default_formatter = "doc" if config.files_to_run.one?
|
17
|
+
|
18
|
+
config.profile_examples = 10
|
19
|
+
|
20
|
+
config.order = :random
|
21
|
+
Kernel.srand config.seed
|
22
|
+
end
|
data/spec/support/app.rb
ADDED
@@ -0,0 +1,64 @@
|
|
1
|
+
require "net/http"
|
2
|
+
require "uri"
|
3
|
+
require "waitutil"
|
4
|
+
require_relative "silently"
|
5
|
+
|
6
|
+
module RSpec
|
7
|
+
module Support
|
8
|
+
module App
|
9
|
+
private
|
10
|
+
|
11
|
+
class RunningApp
|
12
|
+
attr_reader :port
|
13
|
+
|
14
|
+
def initialize(port)
|
15
|
+
@port = port
|
16
|
+
end
|
17
|
+
|
18
|
+
def get(path)
|
19
|
+
Net::HTTP.get(uri(path))
|
20
|
+
end
|
21
|
+
|
22
|
+
private
|
23
|
+
|
24
|
+
def uri(path)
|
25
|
+
URI("http://0.0.0.0:#{port}#{path}")
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def run_app(host: "0.0.0.0", port: "30333", timeout: 10)
|
30
|
+
cmd = "bundle exec rackup -o 0.0.0.0 -p #{port} config.ru"
|
31
|
+
out = Tempfile.new("dry-web-web_pipe-out")
|
32
|
+
|
33
|
+
pid = fork {
|
34
|
+
Bundler.with_clean_env do
|
35
|
+
exec cmd, out: out.path, err: out.path
|
36
|
+
end
|
37
|
+
}
|
38
|
+
|
39
|
+
WaitUtil.wait_for_condition "app available on #{host}:#{port}", timeout_sec: timeout do
|
40
|
+
begin
|
41
|
+
result = WaitUtil.send(:is_tcp_port_open, host, port, WaitUtil::DEFAULT_DELAY_SEC)
|
42
|
+
|
43
|
+
result || begin
|
44
|
+
out.rewind
|
45
|
+
[false, "#{cmd} failed:\n#{out.read}"]
|
46
|
+
end
|
47
|
+
rescue SocketError
|
48
|
+
out.rewind
|
49
|
+
[false, "#{cmd} failed:\n#{out.read}"]
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
yield RunningApp.new(port)
|
54
|
+
ensure
|
55
|
+
Process.kill "TERM", pid
|
56
|
+
Process.wait pid
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
RSpec.configure do |config|
|
63
|
+
config.include RSpec::Support::App, type: :cli
|
64
|
+
end
|
@@ -0,0 +1,113 @@
|
|
1
|
+
require 'open3'
|
2
|
+
require 'pathname'
|
3
|
+
require_relative 'env'
|
4
|
+
require_relative 'silently'
|
5
|
+
require_relative 'files'
|
6
|
+
|
7
|
+
module RSpec
|
8
|
+
module Support
|
9
|
+
module Bundler
|
10
|
+
def self.root
|
11
|
+
Pathname.new(__dir__).join("..", "..")
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.cache
|
15
|
+
root.join("vendor", "cache")
|
16
|
+
end
|
17
|
+
|
18
|
+
def self.setup
|
19
|
+
return if cache.exist?
|
20
|
+
|
21
|
+
with_clean_env do
|
22
|
+
RSpec::Support.silently "./script/setup"
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def self.with_clean_env(&blk)
|
27
|
+
::Bundler.with_clean_env(&blk)
|
28
|
+
end
|
29
|
+
|
30
|
+
private
|
31
|
+
|
32
|
+
attr_reader :out, :err, :exitstatus
|
33
|
+
|
34
|
+
def setup_gemfile(gems: [], exclude_gems: [], path: "Gemfile")
|
35
|
+
filtered_content = ::File.readlines(path).
|
36
|
+
drop(1).
|
37
|
+
reject { |l| exclude_gems.any? { |g| l.include?(g) } }
|
38
|
+
|
39
|
+
content = ["source 'file://#{cache}'\n"] + filtered_content + gems.map { |g| "gem #{g}\n" }
|
40
|
+
|
41
|
+
rewrite(path, content)
|
42
|
+
end
|
43
|
+
|
44
|
+
def bundle_install
|
45
|
+
bundle "install --local --no-cache --retry 0 --no-color"
|
46
|
+
end
|
47
|
+
|
48
|
+
def bundle_exec(cmd, env: nil, &blk)
|
49
|
+
bundle("exec #{cmd}", env: env, &blk)
|
50
|
+
end
|
51
|
+
|
52
|
+
def bundle(cmd, env: nil, &blk)
|
53
|
+
ruby_bin = which("ruby")
|
54
|
+
bundle_bin = which("bundle")
|
55
|
+
rack_env = "RACK_ENV=#{env} " unless env.nil?
|
56
|
+
|
57
|
+
system_exec("#{rack_env}#{ruby_bin} -I#{load_paths} #{bundle_bin} #{cmd}", &blk)
|
58
|
+
end
|
59
|
+
|
60
|
+
# Adapted from Bundler source code
|
61
|
+
#
|
62
|
+
# Bundler is released under MIT license
|
63
|
+
# https://github.com/bundler/bundler/blob/master/LICENSE.md
|
64
|
+
#
|
65
|
+
# A special "thank you" goes to Bundler maintainers and contributors.
|
66
|
+
#
|
67
|
+
# rubocop:disable Metrics/AbcSize
|
68
|
+
# rubocop:disable Metrics/MethodLength
|
69
|
+
def system_exec(cmd)
|
70
|
+
Open3.popen3(RSpec::Support::Env.env, cmd) do |stdin, stdout, stderr, wait_thr|
|
71
|
+
yield stdin, stdout, wait_thr if block_given?
|
72
|
+
stdin.close
|
73
|
+
|
74
|
+
@exitstatus = wait_thr && wait_thr.value.exitstatus
|
75
|
+
@out = Thread.new { stdout.read }.value.strip
|
76
|
+
@err = Thread.new { stderr.read }.value.strip
|
77
|
+
end
|
78
|
+
|
79
|
+
(@all_output ||= "") << [
|
80
|
+
"$ #{cmd.to_s.strip}",
|
81
|
+
out,
|
82
|
+
err,
|
83
|
+
@exitstatus ? "# $? => #{@exitstatus}" : "",
|
84
|
+
"\n"
|
85
|
+
].reject(&:empty?).join("\n")
|
86
|
+
|
87
|
+
@out
|
88
|
+
end
|
89
|
+
# rubocop:enable Metrics/MethodLength
|
90
|
+
# rubocop:enable Metrics/AbcSize
|
91
|
+
|
92
|
+
def load_paths
|
93
|
+
[root.join('lib'), root.join('spec')].join(':')
|
94
|
+
end
|
95
|
+
|
96
|
+
def root
|
97
|
+
RSpec::Support::Bundler.root
|
98
|
+
end
|
99
|
+
|
100
|
+
def cache
|
101
|
+
RSpec::Support::Bundler.cache
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
RSpec.configure do |config|
|
108
|
+
config.include RSpec::Support::Bundler, type: :cli
|
109
|
+
|
110
|
+
config.before(:all, type: :cli) do
|
111
|
+
RSpec::Support::Bundler.setup
|
112
|
+
end
|
113
|
+
end
|
data/spec/support/cli.rb
ADDED
@@ -0,0 +1,47 @@
|
|
1
|
+
require "aruba"
|
2
|
+
require "aruba/api"
|
3
|
+
require "pathname"
|
4
|
+
|
5
|
+
module RSpec
|
6
|
+
module Support
|
7
|
+
module Cli
|
8
|
+
def self.included(spec)
|
9
|
+
spec.before do
|
10
|
+
aruba = Pathname.new(Dir.pwd).join('tmp', 'aruba')
|
11
|
+
aruba.rmtree if aruba.exist?
|
12
|
+
|
13
|
+
setup_aruba
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
private
|
18
|
+
|
19
|
+
def run_command(cmd, output = nil, exit_status: 0)
|
20
|
+
run_simple "bundle exec #{cmd}", fail_on_error: false
|
21
|
+
|
22
|
+
match_output(output)
|
23
|
+
expect(last_command_started).to have_exit_status(exit_status)
|
24
|
+
end
|
25
|
+
|
26
|
+
def match_output(output)
|
27
|
+
case output
|
28
|
+
when String
|
29
|
+
expect(all_output).to include(output)
|
30
|
+
when Regexp
|
31
|
+
expect(all_output).to match(output)
|
32
|
+
when Array
|
33
|
+
output.each { |o| match_output(o) }
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def all_output
|
38
|
+
all_commands.map(&:output).join("\n")
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
RSpec.configure do |config|
|
45
|
+
config.include Aruba::Api, type: :cli
|
46
|
+
config.include RSpec::Support::Cli, type: :cli
|
47
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
require "fileutils"
|
2
|
+
|
3
|
+
module RSpec
|
4
|
+
module Support
|
5
|
+
module Directory
|
6
|
+
private
|
7
|
+
|
8
|
+
def with_directory(directory)
|
9
|
+
current = Dir.pwd
|
10
|
+
target = Pathname.new(Dir.pwd).join(directory)
|
11
|
+
|
12
|
+
Dir.chdir(target)
|
13
|
+
yield
|
14
|
+
ensure
|
15
|
+
Dir.chdir(current)
|
16
|
+
end
|
17
|
+
|
18
|
+
def with_tmp_directory
|
19
|
+
dir = Pathname.new("tmp").join("aruba")
|
20
|
+
|
21
|
+
with_directory(dir) do
|
22
|
+
yield
|
23
|
+
end
|
24
|
+
ensure
|
25
|
+
FileUtils.rm_rf(dir)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
RSpec.configure do |config|
|
32
|
+
config.include RSpec::Support::Directory, type: :cli
|
33
|
+
|
34
|
+
config.before :suite do
|
35
|
+
Pathname.new(Dir.pwd).join("tmp").mkpath
|
36
|
+
end
|
37
|
+
end
|
data/spec/support/env.rb
ADDED
@@ -0,0 +1,84 @@
|
|
1
|
+
require 'singleton'
|
2
|
+
require 'thread'
|
3
|
+
|
4
|
+
module RSpec
|
5
|
+
module Support
|
6
|
+
class Env
|
7
|
+
include Singleton
|
8
|
+
|
9
|
+
def self.setup
|
10
|
+
instance.__send__(:setup)
|
11
|
+
end
|
12
|
+
|
13
|
+
def self.reset
|
14
|
+
instance.__send__(:setup)
|
15
|
+
end
|
16
|
+
|
17
|
+
def self.env
|
18
|
+
instance.to_h
|
19
|
+
end
|
20
|
+
|
21
|
+
def self.[](key)
|
22
|
+
instance[key]
|
23
|
+
end
|
24
|
+
|
25
|
+
def self.[]=(key, value)
|
26
|
+
instance[key] = value
|
27
|
+
end
|
28
|
+
|
29
|
+
def self.fetch_from_original(key)
|
30
|
+
instance.__send__(:original).fetch(key)
|
31
|
+
end
|
32
|
+
|
33
|
+
def initialize
|
34
|
+
@original = ENV.to_hash
|
35
|
+
@mutex = Mutex.new
|
36
|
+
setup
|
37
|
+
end
|
38
|
+
|
39
|
+
def [](key)
|
40
|
+
synchronize do
|
41
|
+
env[key]
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
def []=(key, value)
|
46
|
+
synchronize do
|
47
|
+
env[key] = value
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
def to_h
|
52
|
+
env.dup
|
53
|
+
end
|
54
|
+
|
55
|
+
private
|
56
|
+
|
57
|
+
attr_reader :original, :env
|
58
|
+
|
59
|
+
def setup
|
60
|
+
synchronize do
|
61
|
+
@env = {}
|
62
|
+
end
|
63
|
+
|
64
|
+
self["GEM_ROOT"] = original["GEM_ROOT"]
|
65
|
+
self["GEM_HOME"] = original["GEM_HOME"]
|
66
|
+
self["GEM_PATH"] = original["GEM_PATH"]
|
67
|
+
end
|
68
|
+
|
69
|
+
def synchronize(&blk)
|
70
|
+
@mutex.synchronize(&blk)
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
RSpec.configure do |config|
|
77
|
+
config.before(:suite) do
|
78
|
+
RSpec::Support::Env.setup
|
79
|
+
end
|
80
|
+
|
81
|
+
config.after do
|
82
|
+
RSpec::Support::Env.reset
|
83
|
+
end
|
84
|
+
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
module RSpec
|
2
|
+
module Support
|
3
|
+
module Files
|
4
|
+
private
|
5
|
+
|
6
|
+
def write(path, *content)
|
7
|
+
Pathname.new(path).dirname.mkpath
|
8
|
+
open(path, ::File::CREAT | ::File::WRONLY, *content)
|
9
|
+
end
|
10
|
+
|
11
|
+
def rewrite(path, *content)
|
12
|
+
open(path, ::File::TRUNC | ::File::WRONLY, *content)
|
13
|
+
end
|
14
|
+
|
15
|
+
def replace(path, target, replacement)
|
16
|
+
content = ::File.readlines(path)
|
17
|
+
content[index(content, path, target)] = "#{replacement}\n"
|
18
|
+
|
19
|
+
rewrite(path, content)
|
20
|
+
end
|
21
|
+
|
22
|
+
def replace_last(path, target, replacement)
|
23
|
+
content = ::File.readlines(path)
|
24
|
+
content[-index(content.reverse, path, target) - 1] = "#{replacement}\n"
|
25
|
+
|
26
|
+
rewrite(path, content)
|
27
|
+
end
|
28
|
+
|
29
|
+
def unshift(path, line)
|
30
|
+
content = ::File.readlines(path)
|
31
|
+
content.unshift("#{line}\n")
|
32
|
+
|
33
|
+
rewrite(path, content)
|
34
|
+
end
|
35
|
+
|
36
|
+
def append(path, contents)
|
37
|
+
content = ::File.readlines(path)
|
38
|
+
content << "#{contents}\n"
|
39
|
+
|
40
|
+
rewrite(path, content)
|
41
|
+
end
|
42
|
+
|
43
|
+
def open(path, mode, *content)
|
44
|
+
::File.open(path, mode) do |file|
|
45
|
+
file.write(Array(content).flatten.join)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def index(content, path, target)
|
50
|
+
content.index { |l| l.include?(target) } or
|
51
|
+
raise ArgumentError.new("Cannot find `#{target}' inside `#{path}'.")
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
RSpec.configure do |config|
|
58
|
+
config.include RSpec::Support::Files, type: :cli
|
59
|
+
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
require "waitutil"
|
2
|
+
require_relative 'env'
|
3
|
+
require_relative 'silently'
|
4
|
+
require_relative 'bundler'
|
5
|
+
require_relative 'directories'
|
6
|
+
|
7
|
+
module RSpec
|
8
|
+
module Support
|
9
|
+
module Project
|
10
|
+
private
|
11
|
+
|
12
|
+
KNOWN_ARGUMENTS = [:arch].freeze
|
13
|
+
|
14
|
+
def with_project(name = "sandbox", **args)
|
15
|
+
with_tmp_directory do
|
16
|
+
create_project name, args
|
17
|
+
|
18
|
+
within_project_directory(name) do
|
19
|
+
setup_gemfile gems: ["'dry-web-web_pipe', path: '#{root}'"], exclude_gems: ['dry-web-web_pipe']
|
20
|
+
bundle_install
|
21
|
+
yield
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def within_project_directory(project)
|
27
|
+
cd(project.to_s) do
|
28
|
+
# Aruba resets ENV and its API to set new env vars is broken.
|
29
|
+
#
|
30
|
+
# We need to manually setup the following env vars:
|
31
|
+
#
|
32
|
+
# ENV["PATH"] is required by Capybara's selenium/poltergeist drivers
|
33
|
+
ENV["PATH"] = RSpec::Support::Env.fetch_from_original("PATH")
|
34
|
+
# Bundler on CI can't find HOME and it fails to run Hanami commands
|
35
|
+
ENV["HOME"] = RSpec::Support::Env.fetch_from_original("HOME")
|
36
|
+
|
37
|
+
yield
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def create_project(name, args)
|
42
|
+
silently "dry-web-web_pipe new #{name} #{_create_project_args(args)}"
|
43
|
+
end
|
44
|
+
|
45
|
+
def _create_project_args(args)
|
46
|
+
return if args.empty?
|
47
|
+
|
48
|
+
flags = args.dup.keep_if { |k, _| KNOWN_ARGUMENTS.include?(k) }
|
49
|
+
|
50
|
+
flags.map { |arg, value|
|
51
|
+
"--#{arg}=#{value}"
|
52
|
+
}.join(" ")
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
RSpec.configure do |config|
|
59
|
+
config.include RSpec::Support::Project, type: :cli
|
60
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
require "tempfile"
|
2
|
+
|
3
|
+
module RSpec
|
4
|
+
module Support
|
5
|
+
def self.silently(cmd, via: :system)
|
6
|
+
out = Tempfile.new("dry-web-web_pipe-out")
|
7
|
+
# RSpec::Support::Env.env
|
8
|
+
result = ::Kernel.__send__(via, cmd, out: out.path, err: out.path)
|
9
|
+
|
10
|
+
return if result
|
11
|
+
|
12
|
+
out.rewind
|
13
|
+
fail "#{cmd} failed:\n#{out.read}" # rubocop:disable Style/SignalException
|
14
|
+
end
|
15
|
+
|
16
|
+
module Silently
|
17
|
+
private
|
18
|
+
|
19
|
+
def silently(*args)
|
20
|
+
Support.silently(*args)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
RSpec.configure do |config|
|
27
|
+
config.include RSpec::Support::Silently, type: :cli
|
28
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
require "dry/web/web_pipe/generators/inflections"
|
2
|
+
|
3
|
+
RSpec.describe Dry::Web::WebPipe::Generators::Inflections do
|
4
|
+
subject(:inflections) { described_class }
|
5
|
+
|
6
|
+
describe ".underscored_name" do
|
7
|
+
it "leaves an already underscored name" do
|
8
|
+
expect(inflections.underscored_name("my_app")).to eq "my_app"
|
9
|
+
end
|
10
|
+
|
11
|
+
it "leaves a name without any sort of delimiters" do
|
12
|
+
expect(inflections.underscored_name("myapp")).to eq "myapp"
|
13
|
+
end
|
14
|
+
|
15
|
+
it "converts a dashed name" do
|
16
|
+
expect(inflections.underscored_name("my-app")).to eq "my_app"
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
describe ".camel_cased_name" do
|
21
|
+
it "leaves an already camel cased name" do
|
22
|
+
expect(inflections.camel_cased_name("MyApp")).to eq "MyApp"
|
23
|
+
end
|
24
|
+
|
25
|
+
it "converts a dashed name" do
|
26
|
+
expect(inflections.camel_cased_name("my-app")).to eq "MyApp"
|
27
|
+
end
|
28
|
+
|
29
|
+
it "converts an underscored name" do
|
30
|
+
expect(inflections.camel_cased_name("my_app")).to eq "MyApp"
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|