singer 1.0.0 → 2.0.0
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 +47 -0
- data/exe/singer +1 -2
- data/lib/singer/configuration.rb +13 -1
- data/lib/singer/name_transformation.rb +26 -0
- data/lib/singer/option_parsing.rb +57 -17
- data/lib/singer/paths.rb +6 -2
- data/lib/singer/template.rb +9 -1
- data/lib/singer/version.rb +1 -1
- data/lib/singer.rb +28 -7
- data/templates/sinatra_app/config/config.ru +1 -1
- data/templates/sinatra_app/exe/server.rb +1 -1
- data/templates/sinatra_app/lib/{__SNAKECASE_NAME__ → __PROJECT_NAME_SNAKECASE__}/hello.rb +1 -1
- data/templates/sinatra_app/lib/{__SNAKECASE_NAME__ → __PROJECT_NAME_SNAKECASE__}/server.rb +1 -1
- data/templates/sinatra_app/test/server/test_server.rb +1 -1
- data/templates/sinatra_app/test/server/test_server_error_dumping.rb +1 -1
- data/templates/sinatra_app/test/test_hello.rb +1 -1
- data/templates/sinatra_app/views/layout.haml +1 -1
- data/templates/tdd/lib/{__SNAKECASE_NAME__.rb → __PROJECT_NAME_SNAKECASE__.rb} +2 -2
- data/templates/tdd/test/test___PROJECT_NAME_SNAKECASE__.rb +16 -0
- metadata +8 -7
- data/templates/tdd/test/test___SNAKECASE_NAME__.rb +0 -16
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: b91934a916b675cfddecdac26f48673a77e9e2f014ae94a7db7623df0adaac67
|
|
4
|
+
data.tar.gz: f8a8384bdbba9f096d303e91fbd68a2b1063239d89e5f072d1e8e551cee1b7d2
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 5a0d34e3e4ba0b18a55151f796f30d8b0bad715f74a084f37456a4cdebb74d8f66543db90003dc84877a19ef295f0664f1e5ba190cd137d67a670f8819802d01
|
|
7
|
+
data.tar.gz: d9245c0f2fcbc5671a078daf5bcf71977ba2ec661c1b599e0aedaa2e679948bc4d9ebad738a6302daefe515dae253a5d8d59d6b12b0779b7796b6c9bf52b35d2
|
data/README.md
CHANGED
|
@@ -17,6 +17,53 @@ Run `singer --list-templates` to see available templates' names, both shipped wi
|
|
|
17
17
|
|
|
18
18
|
For `PROJECT_NAME`, using `snake_case` is best, although an attempt will be made to understand `CamelCase`, too.
|
|
19
19
|
|
|
20
|
+
## Writing your own templates
|
|
21
|
+
|
|
22
|
+
Many features of Singer will become clearer when seeing actual usage - please feel encouraged to examine the templates shipped with the gem (you can find them in `templates_from_gem` shown by the `singer --show-paths`).
|
|
23
|
+
|
|
24
|
+
### Template location
|
|
25
|
+
|
|
26
|
+
User-provided templates should be placed in the directory named `templates_from_user` in the `singer --show-paths` output.
|
|
27
|
+
Each template resides in a subdirectory - the subdirectory's name becomes the template's name, and is not included in the generated paths (Singer will only replicate the directory structure _inside_ it).
|
|
28
|
+
|
|
29
|
+
### Variables available to templates
|
|
30
|
+
|
|
31
|
+
Templates written in ERB or other templating mechanisms that execute Ruby code will have access to `Singer.configuration` object and its accessors. For example, the following code in a `my_template`'s file:
|
|
32
|
+
```ruby
|
|
33
|
+
class <%= Singer.configuration.project_name_camelcase %>
|
|
34
|
+
```
|
|
35
|
+
will, when Singer is called with `singer my_template foo_bar_baz`, result in this written to output file:
|
|
36
|
+
```ruby
|
|
37
|
+
class FooBarBaz
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
To see an up-to-date list of available variables, run `singer --list-variables`.
|
|
41
|
+
|
|
42
|
+
### Using --dashes option
|
|
43
|
+
|
|
44
|
+
Since Ruby treats the `-` character in snakecased name as corresponding to module nesting in camelcased name, Singer also treats it in a special way. You can control this behavior with the `--dashes` option. This is how different values will affect `project_name_camelcase`:
|
|
45
|
+
|
|
46
|
+
```bash
|
|
47
|
+
singer foo_bar-baz --dashes modularize # results in FooBar::Baz (default)
|
|
48
|
+
singer foo_bar-baz --dashes preserve # results in FooBar-baz
|
|
49
|
+
singer foo_bar-baz --dashes delete # results in FooBarbaz
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
### Special segments in template paths
|
|
53
|
+
|
|
54
|
+
Any of the variables above can be also used in paths/filenames of template files, capitalized and surrounded by double underscores.
|
|
55
|
+
So, if `my_template` has a file at this path:
|
|
56
|
+
```
|
|
57
|
+
docs_for___PROJECT_NAME_SNAKECASE__/__PROJECT_NAME_CAMELCASE__ - humble beginnings.txt
|
|
58
|
+
```
|
|
59
|
+
and you run `singer my_template alpha_beta`, a file named like this will be created:
|
|
60
|
+
```
|
|
61
|
+
docs_for_alpha_beta/AlphaBeta - humble beginnings.txt
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
Tiny caveat for completeness - while `template_file_name_actual` can be used inside template files, the `__TEMPLATE_FILE_NAME_ACTUAL__` will not be substituted in paths.
|
|
65
|
+
"Stack level too deep" and all that ;)
|
|
66
|
+
|
|
20
67
|
## Development
|
|
21
68
|
|
|
22
69
|
```bash
|
data/exe/singer
CHANGED
data/lib/singer/configuration.rb
CHANGED
|
@@ -1,4 +1,16 @@
|
|
|
1
|
+
# main module, has `.configuration` reader
|
|
1
2
|
module Singer
|
|
2
3
|
# holds settings
|
|
3
|
-
|
|
4
|
+
Configuration = Struct.new(
|
|
5
|
+
'Configuration',
|
|
6
|
+
:template_name,
|
|
7
|
+
:project_name_original, :project_name_camelcase, :project_name_snakecase,
|
|
8
|
+
:template_file_name_original, :template_file_name_actual,
|
|
9
|
+
:dashes,
|
|
10
|
+
)
|
|
11
|
+
CONFIGURATION_VARIABLES_FORBIDDEN_IN_PATHS = %w[template_file_name_actual].freeze
|
|
12
|
+
|
|
13
|
+
def self.configuration
|
|
14
|
+
@configuration ||= Configuration.new
|
|
15
|
+
end
|
|
4
16
|
end
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
module Singer
|
|
2
|
+
# transform between snakecase and camelcase, with some special rules
|
|
3
|
+
class NameTransformation
|
|
4
|
+
DASHES_OPTIONS = %w[modularize delete preserve].freeze
|
|
5
|
+
|
|
6
|
+
def self.encase_name(name)
|
|
7
|
+
Singer.configuration.project_name_original = name
|
|
8
|
+
Singer.configuration.project_name_snakecase = name.gsub(/(\w)([A-Z])/){ "#{$1}_#{$2}" }.gsub(/_+/, '_').downcase
|
|
9
|
+
camelcase = Singer.configuration.project_name_snakecase.split('_').map(&:capitalize).join
|
|
10
|
+
Singer.configuration.project_name_camelcase = treat_dashes_in_name(camelcase)
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def self.treat_dashes_in_name(camelcase)
|
|
14
|
+
case Singer.configuration.dashes
|
|
15
|
+
when 'modularize'
|
|
16
|
+
camelcase.gsub(/([[:alnum:]])-+([[:alnum:]])/){ "#{$1}::#{$2.upcase}" }
|
|
17
|
+
when 'delete'
|
|
18
|
+
camelcase.delete('-')
|
|
19
|
+
when 'preserve'
|
|
20
|
+
camelcase
|
|
21
|
+
else
|
|
22
|
+
raise ParameterValueUnsupported, "Unsupported value #{Singer.configuration.dashes.inspect} for --dashes option"
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
@@ -1,40 +1,80 @@
|
|
|
1
1
|
module Singer
|
|
2
2
|
# extracts what we need from ARGV
|
|
3
3
|
class OptionParsing
|
|
4
|
-
DEFAULT_TEMPLATE_NAME = 'tdd'.freeze
|
|
5
|
-
|
|
6
4
|
def self.configure(argvies) # rubocop:disable Metrics/MethodLength
|
|
7
5
|
options = {}
|
|
6
|
+
Singer.configuration.dashes = NameTransformation::DASHES_OPTIONS.first
|
|
7
|
+
|
|
8
8
|
OptionParser.new do |parser|
|
|
9
|
+
parser.program_name = 'singer'
|
|
10
|
+
parser.version = Singer::VERSION
|
|
9
11
|
parser.banner = <<~USAGE
|
|
10
|
-
Usage: #{
|
|
12
|
+
Usage: #{parser.program_name} [OPTION]... [TEMPLATE_NAME] PROJECT_NAME
|
|
11
13
|
Generates a project from a multi-file template.
|
|
12
14
|
PROJECT_NAME can be in snake_case or CamelCase.
|
|
13
15
|
|
|
14
16
|
Options:
|
|
15
17
|
USAGE
|
|
16
|
-
parser
|
|
17
|
-
|
|
18
|
-
Kernel.exit
|
|
19
|
-
end
|
|
18
|
+
add_options_functional(parser)
|
|
19
|
+
add_options_listing(parser)
|
|
20
20
|
end.parse!(argvies, into: options)
|
|
21
|
+
end
|
|
21
22
|
|
|
22
|
-
|
|
23
|
+
def self.add_options_functional(parser) # rubocop:disable Metrics/MethodLength
|
|
24
|
+
parser.on(
|
|
25
|
+
'-t', '--template-path=PATH', 'load a template from a given path - use instead of [TEMPLATE_NAME]',
|
|
26
|
+
) do |path|
|
|
27
|
+
Template.load_one_from_path(path)
|
|
28
|
+
end
|
|
29
|
+
parser.on('--dashes DASHES', NameTransformation::DASHES_OPTIONS, <<~DESCRIPTION) do |dashes|
|
|
30
|
+
what to do with "-" in PROJECT_NAME when converting to Singer.configuration.project_name_camelcase:
|
|
31
|
+
"modularize": convert to "::", following Ruby convention of mapping dashes to module nesting, or
|
|
32
|
+
"delete": remove entirely, or
|
|
33
|
+
"preserve": leave as-is
|
|
34
|
+
(default is "#{Singer.configuration.dashes}" if `--dashes` isn't given)
|
|
35
|
+
DESCRIPTION
|
|
36
|
+
Singer.configuration.dashes = dashes
|
|
37
|
+
end
|
|
38
|
+
end
|
|
23
39
|
|
|
24
|
-
|
|
25
|
-
|
|
40
|
+
def self.add_options_listing(parser) # rubocop:disable Metrics/MethodLength
|
|
41
|
+
parser.on('--list-templates', 'list all available templates') do
|
|
42
|
+
list_all_templates
|
|
43
|
+
Kernel.exit
|
|
44
|
+
end
|
|
45
|
+
parser.on('--list-paths', 'list paths used to load files') do
|
|
46
|
+
list_paths
|
|
47
|
+
Kernel.exit
|
|
48
|
+
end
|
|
49
|
+
parser.on('--list-variables', 'list all variables available to templates and in paths') do
|
|
50
|
+
list_variables
|
|
51
|
+
Kernel.exit
|
|
52
|
+
end
|
|
26
53
|
end
|
|
27
54
|
|
|
28
55
|
def self.list_all_templates
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
56
|
+
columnize_hash(Template.all.transform_values(&:path))
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
def self.list_paths
|
|
60
|
+
columnize_hash(%w[singer_config_dir templates_from_user templates_from_gem].map{ [_1, Paths.send(_1)] })
|
|
33
61
|
end
|
|
34
62
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
63
|
+
NOT_AVAILABLE = '(not available in paths)'.freeze
|
|
64
|
+
def self.list_variables
|
|
65
|
+
columnize_hash(Singer.configuration.members.map do |var|
|
|
66
|
+
[
|
|
67
|
+
var,
|
|
68
|
+
CONFIGURATION_VARIABLES_FORBIDDEN_IN_PATHS.include?(var.to_s) ? NOT_AVAILABLE : "__#{var.upcase}__",
|
|
69
|
+
]
|
|
70
|
+
end)
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
def self.columnize_hash(hash_or_array)
|
|
74
|
+
first_column_width = hash_or_array.map{ |k, _v| k.length }.max
|
|
75
|
+
hash_or_array.each do |k, v|
|
|
76
|
+
puts "#{k.to_s.ljust(first_column_width)} #{v}"
|
|
77
|
+
end
|
|
38
78
|
end
|
|
39
79
|
end
|
|
40
80
|
end
|
data/lib/singer/paths.rb
CHANGED
|
@@ -21,12 +21,16 @@ module Singer
|
|
|
21
21
|
File.join(...).gsub(/__([[:alpha:]][[:word:]]+)__/) do |match|
|
|
22
22
|
potential_config = $1.downcase
|
|
23
23
|
|
|
24
|
-
if
|
|
25
|
-
|
|
24
|
+
if variable_name_can_be_substituted?(potential_config)
|
|
25
|
+
Singer.configuration.send(potential_config)
|
|
26
26
|
else
|
|
27
27
|
match
|
|
28
28
|
end
|
|
29
29
|
end
|
|
30
30
|
end
|
|
31
|
+
|
|
32
|
+
def self.variable_name_can_be_substituted?(name)
|
|
33
|
+
Singer.configuration.respond_to?(name) && !CONFIGURATION_VARIABLES_FORBIDDEN_IN_PATHS.include?(name)
|
|
34
|
+
end
|
|
31
35
|
end
|
|
32
36
|
end
|
data/lib/singer/template.rb
CHANGED
|
@@ -19,6 +19,11 @@ module Singer
|
|
|
19
19
|
end
|
|
20
20
|
end
|
|
21
21
|
|
|
22
|
+
def self.load_one_from_path(path)
|
|
23
|
+
Singer.configuration.template_name = File.basename(path)
|
|
24
|
+
all[Singer.configuration.template_name] = new(path)
|
|
25
|
+
end
|
|
26
|
+
|
|
22
27
|
attr_reader :path, :files
|
|
23
28
|
|
|
24
29
|
def initialize(path)
|
|
@@ -31,9 +36,12 @@ module Singer
|
|
|
31
36
|
|
|
32
37
|
def generate(output_path)
|
|
33
38
|
files.each do |file|
|
|
34
|
-
|
|
39
|
+
Singer.configuration.template_file_name_original = file
|
|
35
40
|
target_file = Paths.output_path(output_path, file)
|
|
41
|
+
Singer.configuration.template_file_name_actual = target_file
|
|
42
|
+
|
|
36
43
|
FileUtils.mkdir_p(File.dirname(target_file))
|
|
44
|
+
source_file = File.join(path, file)
|
|
37
45
|
TemplatingMethods.send(:erb, source_file, target_file)
|
|
38
46
|
end
|
|
39
47
|
end
|
data/lib/singer/version.rb
CHANGED
data/lib/singer.rb
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
require_relative 'singer/version'
|
|
2
2
|
require_relative 'singer/configuration'
|
|
3
|
+
require_relative 'singer/name_transformation'
|
|
3
4
|
require_relative 'singer/option_parsing'
|
|
4
5
|
require_relative 'singer/paths'
|
|
5
6
|
require_relative 'singer/template'
|
|
@@ -10,14 +11,34 @@ require 'optparse'
|
|
|
10
11
|
# Singer, which generates Sinatra apps etc. from templates
|
|
11
12
|
module Singer
|
|
12
13
|
class Error < StandardError; end
|
|
13
|
-
class NameMissingError <
|
|
14
|
-
class TemplateUnknown <
|
|
14
|
+
class NameMissingError < Error; end
|
|
15
|
+
class TemplateUnknown < Error; end
|
|
16
|
+
class ParameterValueUnsupported < Error; end
|
|
15
17
|
|
|
16
|
-
def self.
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
18
|
+
def self.configure_and_generate(argvies)
|
|
19
|
+
Singer::OptionParsing.configure(argvies)
|
|
20
|
+
configure_project_name(argvies)
|
|
21
|
+
configure_template(argvies)
|
|
22
|
+
Singer.generate
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def self.configure_project_name(argvies)
|
|
26
|
+
raise NameMissingError, 'Missing mandatory argument PROJECT_NAME' if argvies.empty?
|
|
27
|
+
|
|
28
|
+
NameTransformation.encase_name(argvies.pop)
|
|
29
|
+
end
|
|
20
30
|
|
|
21
|
-
|
|
31
|
+
DEFAULT_TEMPLATE_NAME = 'tdd'.freeze
|
|
32
|
+
def self.configure_template(argvies)
|
|
33
|
+
return if configuration.template_name # must have been set via --template-directory
|
|
34
|
+
|
|
35
|
+
configuration.template_name = argvies.pop || DEFAULT_TEMPLATE_NAME
|
|
36
|
+
return if Template.all.key?(configuration.template_name)
|
|
37
|
+
|
|
38
|
+
raise TemplateUnknown, "Template #{configuration.template_name.inspect} not found"
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def self.generate
|
|
42
|
+
Template.all[configuration.template_name].generate('.')
|
|
22
43
|
end
|
|
23
44
|
end
|
|
@@ -3,7 +3,7 @@ require 'haml'
|
|
|
3
3
|
require 'sassc'
|
|
4
4
|
require 'colorize'
|
|
5
5
|
|
|
6
|
-
module <%= Singer
|
|
6
|
+
module <%= Singer.configuration.project_name_camelcase %>
|
|
7
7
|
# Sinatra app with routes
|
|
8
8
|
class Server < Sinatra::Base
|
|
9
9
|
set :root, '.' # to make directory structure with views/ work
|
|
@@ -10,7 +10,7 @@ class TestServerErrorDumping < Minitest::Test
|
|
|
10
10
|
refute message.lines.any?{ _1.include?('/vendor/') } # now you don't
|
|
11
11
|
end
|
|
12
12
|
|
|
13
|
-
app = <%= Singer
|
|
13
|
+
app = <%= Singer.configuration.project_name_camelcase %>::Server.new! # .new! returns real instance without Sinatra::Wrapper
|
|
14
14
|
app.dump_errors!(exc, log)
|
|
15
15
|
end
|
|
16
16
|
|
|
@@ -3,6 +3,6 @@ require 'minitest_helper'
|
|
|
3
3
|
# TODO: remove
|
|
4
4
|
class TestHello < Minitest::Test
|
|
5
5
|
def test_greet_with_a_param_generates_a_greeting_string
|
|
6
|
-
assert_equal 'Hello, stranger.', <%= Singer
|
|
6
|
+
assert_equal 'Hello, stranger.', <%= Singer.configuration.project_name_camelcase %>::Hello.greet(:stranger)
|
|
7
7
|
end
|
|
8
8
|
end
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
require 'colorize'
|
|
2
2
|
# require 'awesome_print'
|
|
3
3
|
|
|
4
|
-
class <%= Singer
|
|
4
|
+
class <%= Singer.configuration.project_name_camelcase %>
|
|
5
5
|
def hello(who:)
|
|
6
6
|
"Hello, #{who}."
|
|
7
7
|
end
|
|
8
8
|
end
|
|
9
9
|
|
|
10
10
|
if File.expand_path($PROGRAM_NAME) == File.expand_path(__FILE__)
|
|
11
|
-
ciastka = <%= Singer
|
|
11
|
+
ciastka = <%= Singer.configuration.project_name_camelcase %>.new
|
|
12
12
|
puts "Testing testing: #{ciastka.hello(who: :world).green}"
|
|
13
13
|
end
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
require 'minitest/rg'
|
|
2
|
+
require 'minitest/autorun' if File.expand_path($PROGRAM_NAME) == File.expand_path(__FILE__)
|
|
3
|
+
|
|
4
|
+
require_relative '../lib/<%= Singer.configuration.project_name_snakecase %>'
|
|
5
|
+
|
|
6
|
+
class Test<%= Singer.configuration.project_name_camelcase %> < Minitest::Test
|
|
7
|
+
# TEST_INPUT = File.read('input_mini.txt').lines(chomp: true)
|
|
8
|
+
|
|
9
|
+
def setup
|
|
10
|
+
@<%= Singer.configuration.project_name_snakecase %> = <%= Singer.configuration.project_name_camelcase %>.new
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def test_hello_interpolates_into_string
|
|
14
|
+
assert_equal 'Hello, world.', @<%= Singer.configuration.project_name_snakecase %>.hello(who: :world)
|
|
15
|
+
end
|
|
16
|
+
end
|
metadata
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: singer
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version:
|
|
4
|
+
version: 2.0.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Emil Chludziński
|
|
8
8
|
bindir: exe
|
|
9
9
|
cert_chain: []
|
|
10
|
-
date:
|
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
|
11
11
|
dependencies:
|
|
12
12
|
- !ruby/object:Gem::Dependency
|
|
13
13
|
name: erb
|
|
@@ -38,6 +38,7 @@ files:
|
|
|
38
38
|
- exe/singer
|
|
39
39
|
- lib/singer.rb
|
|
40
40
|
- lib/singer/configuration.rb
|
|
41
|
+
- lib/singer/name_transformation.rb
|
|
41
42
|
- lib/singer/option_parsing.rb
|
|
42
43
|
- lib/singer/paths.rb
|
|
43
44
|
- lib/singer/template.rb
|
|
@@ -48,8 +49,8 @@ files:
|
|
|
48
49
|
- templates/sinatra_app/config/config.ru
|
|
49
50
|
- templates/sinatra_app/config/puma.rb
|
|
50
51
|
- templates/sinatra_app/exe/server.rb
|
|
51
|
-
- templates/sinatra_app/lib/
|
|
52
|
-
- templates/sinatra_app/lib/
|
|
52
|
+
- templates/sinatra_app/lib/__PROJECT_NAME_SNAKECASE__/hello.rb
|
|
53
|
+
- templates/sinatra_app/lib/__PROJECT_NAME_SNAKECASE__/server.rb
|
|
53
54
|
- templates/sinatra_app/lib/zeitwerk_setup.rb
|
|
54
55
|
- templates/sinatra_app/test/minitest_helper.rb
|
|
55
56
|
- templates/sinatra_app/test/server/test_server.rb
|
|
@@ -60,8 +61,8 @@ files:
|
|
|
60
61
|
- templates/sinatra_app/views/layout.haml
|
|
61
62
|
- templates/sinatra_app/views/style.sass
|
|
62
63
|
- templates/tdd/Gemfile
|
|
63
|
-
- templates/tdd/lib/
|
|
64
|
-
- templates/tdd/test/
|
|
64
|
+
- templates/tdd/lib/__PROJECT_NAME_SNAKECASE__.rb
|
|
65
|
+
- templates/tdd/test/test___PROJECT_NAME_SNAKECASE__.rb
|
|
65
66
|
homepage: https://gitlab.com/tanstaafl/singer/
|
|
66
67
|
licenses:
|
|
67
68
|
- MIT
|
|
@@ -83,7 +84,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
83
84
|
- !ruby/object:Gem::Version
|
|
84
85
|
version: '0'
|
|
85
86
|
requirements: []
|
|
86
|
-
rubygems_version: 3.6.
|
|
87
|
+
rubygems_version: 3.6.7
|
|
87
88
|
specification_version: 4
|
|
88
89
|
summary: Singer generates code (such as Sinatra apps) from templates.
|
|
89
90
|
test_files: []
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
require 'minitest/rg'
|
|
2
|
-
require 'minitest/autorun' if $PROGRAM_NAME == __FILE__
|
|
3
|
-
|
|
4
|
-
require_relative '../lib/<%= Singer::CONFIGURATION.snakecase_name %>'
|
|
5
|
-
|
|
6
|
-
class Test<%= Singer::CONFIGURATION.camelcase_name %> < Minitest::Test
|
|
7
|
-
# TEST_INPUT = File.read('input_mini.txt').lines(chomp: true)
|
|
8
|
-
|
|
9
|
-
def setup
|
|
10
|
-
@<%= Singer::CONFIGURATION.snakecase_name %> = <%= Singer::CONFIGURATION.camelcase_name %>.new
|
|
11
|
-
end
|
|
12
|
-
|
|
13
|
-
def test_hello_interpolates_into_string
|
|
14
|
-
assert_equal 'Hello, world.', @<%= Singer::CONFIGURATION.snakecase_name %>.hello(who: :world)
|
|
15
|
-
end
|
|
16
|
-
end
|