klipp 0.0.1 → 0.2.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/.gitignore +2 -1
- data/.travis.yml +5 -0
- data/README.md +13 -26
- data/bin/klipp +1 -1
- data/klipp.gemspec +11 -6
- data/lib/klipp/configuration.rb +0 -4
- data/lib/klipp/creator.rb +78 -0
- data/lib/klipp/parameter_list.rb +3 -3
- data/lib/klipp/version.rb +1 -1
- data/lib/klipp.rb +148 -92
- data/lib/template/spec.rb +231 -0
- data/lib/template/token.rb +81 -0
- data/lib/template.rb +59 -0
- data/spec/fixtures/ambiguous-repo/Ambiguous/Ambiguous.klippspec +5 -0
- data/spec/fixtures/projects/Klippfile +26 -0
- data/spec/fixtures/projects/Klippfile-after-prepare +27 -0
- data/spec/fixtures/projects/Klippfile-ambiguous +1 -0
- data/spec/fixtures/projects/Klippfile-bad-ruby +3 -0
- data/spec/fixtures/projects/Klippfile-minimal +1 -0
- data/spec/fixtures/projects/Klippfile-unambiguous +1 -0
- data/spec/fixtures/template-repository/Ambiguous/Ambiguous.klippspec +5 -0
- data/spec/fixtures/template-repository/Another-Template/Another-Template.klippspec +20 -0
- data/spec/fixtures/template-repository/BadExample/BadExample.klippspec +35 -0
- data/spec/fixtures/template-repository/Empty/Empty.klippspec +20 -0
- data/spec/fixtures/template-repository/Example/.gitignore +10 -0
- data/spec/fixtures/template-repository/Example/Example.klippspec +40 -0
- data/spec/fixtures/template-repository/Example/Podfile +10 -0
- data/spec/fixtures/template-repository/Example/XXBLANKXX.hidden +10 -0
- data/spec/fixtures/template-repository/Example/XXPROJECT_IDXX/Config/Base.xcconfig +8 -0
- data/spec/fixtures/template-repository/Example/XXPROJECT_IDXX/Images/Default-568h@2x.png +0 -0
- data/spec/fixtures/template-repository/Example/XXPROJECT_IDXX/Images/Default.png +0 -0
- data/spec/fixtures/template-repository/Example/XXPROJECT_IDXX/Images/Default@2x.png +0 -0
- data/spec/fixtures/template-repository/Example/XXPROJECT_IDXX/Source/XXCLASS_PREFIXXXAppDelegate.h +13 -0
- data/spec/fixtures/template-repository/Example/XXPROJECT_IDXX/Source/XXCLASS_PREFIXXXAppDelegate.m +30 -0
- data/spec/fixtures/template-repository/Example/XXPROJECT_IDXX/Source/XXCLASS_PREFIXXXRootViewController.h +11 -0
- data/spec/fixtures/template-repository/Example/XXPROJECT_IDXX/Source/XXCLASS_PREFIXXXRootViewController.m +30 -0
- data/spec/fixtures/template-repository/Example/XXPROJECT_IDXX/XXPROJECT_TITLEXX-Info.plist +38 -0
- data/spec/fixtures/template-repository/Example/XXPROJECT_IDXX/XXPROJECT_TITLEXX-Prefix.pch +14 -0
- data/spec/fixtures/template-repository/Example/XXPROJECT_IDXX/en.lproj/Localizable.strings +1 -0
- data/spec/fixtures/template-repository/Example/XXPROJECT_IDXX/main.m +17 -0
- data/spec/fixtures/template-repository/Example/XXPROJECT_IDXX/nl.lproj/Localizable.strings +1 -0
- data/spec/fixtures/template-repository/Example/XXPROJECT_IDXX.xcodeproj/project.pbxproj +466 -0
- data/spec/fixtures/template-repository/Example/XXPROJECT_IDXX.xcodeproj/project.xcworkspace/contents.xcworkspacedata +7 -0
- data/spec/fixtures/template-repository/Example/XXPROJECT_IDXXTests/XXPROJECT_TITLEXXTests.m +22 -0
- data/spec/fixtures/template-repository/Interactive/Interactive.klippspec +15 -0
- data/spec/fixtures/template-repository/Interactive/XXSUBJECT_UNDER_TESTXXTests.m +15 -0
- data/spec/klipp/configuration_spec.rb +8 -0
- data/spec/klipp/creator_spec.rb +120 -0
- data/spec/klipp_spec.rb +80 -85
- data/spec/spec_helper.rb +8 -2
- data/spec/template/spec_spec.rb +225 -0
- data/spec/template/token_spec.rb +100 -0
- data/spec/template_spec.rb +82 -0
- metadata +118 -43
- data/lib/klipp/buffered_output.rb +0 -17
- data/lib/klipp/project.rb +0 -46
- data/lib/klipp/template.rb +0 -50
- data/lib/klipp/token.rb +0 -35
- data/spec/fixtures/klipps/Example.klippfile +0 -4
- data/spec/fixtures/klipps/ExcessiveExample.klippfile +0 -5
- data/spec/fixtures/klipps/Generated.klippfile +0 -11
- data/spec/fixtures/klipps/LackingExample.klippfile +0 -3
- data/spec/fixtures/klipps/MalformedExample.klippfile +0 -4
- data/spec/fixtures/klipps/single-token.yml +0 -5
- data/spec/fixtures/templates/Example/RegularFileWithContents.txt +0 -3
- data/spec/fixtures/templates/Example/XXCLASS_PREFIXXXPrefixedFile.txt +0 -3
- data/spec/fixtures/templates/Example/XXPROJECT_IDXX/BinaryFile.png +0 -0
- data/spec/fixtures/templates/Example/XXPROJECT_IDXX/XXCLASS_PREFIXXXPrefixedFileInDirectory.txt +0 -3
- data/spec/fixtures/templates/Example.yml +0 -29
- data/spec/klipp/project_spec.rb +0 -46
- data/spec/klipp/template_spec.rb +0 -80
- data/spec/klipp/token_spec.rb +0 -86
@@ -0,0 +1,120 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
require 'spec_helper'
|
3
|
+
|
4
|
+
describe Klipp::Creator do
|
5
|
+
|
6
|
+
it 'stores values for template tokens' do
|
7
|
+
creator = Klipp::Creator.new()
|
8
|
+
creator.tokens[:PROJECT_ID] = 'A project id'
|
9
|
+
creator.tokens[:PROJECT_ID].should eq 'A project id'
|
10
|
+
end
|
11
|
+
|
12
|
+
context 'concerning klippfiles' do
|
13
|
+
|
14
|
+
before do
|
15
|
+
Klipp::Configuration.stubs(:root_dir).returns(File.join(File.dirname(__dir__), 'fixtures'))
|
16
|
+
File.directory?(Klipp::Configuration.root_dir).should be true
|
17
|
+
end
|
18
|
+
|
19
|
+
context 'from file' do
|
20
|
+
|
21
|
+
context 'a minimal klippfile' do
|
22
|
+
|
23
|
+
it 'validates' do
|
24
|
+
creator = Klipp::Creator.new()
|
25
|
+
creator.expects(:invalidate).never
|
26
|
+
|
27
|
+
path = fixture_path('Klippfile-minimal')
|
28
|
+
string = read_fixture('Klippfile-minimal')
|
29
|
+
creator.eval_string(string, path)
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
33
|
+
|
34
|
+
context 'an invalid klippfile' do
|
35
|
+
|
36
|
+
it "raises an error if it's bad ruby" do
|
37
|
+
creator = Klipp::Creator.new()
|
38
|
+
creator.expects(:invalidate).never
|
39
|
+
|
40
|
+
path = fixture_path('Klippfile-bad-ruby')
|
41
|
+
string = read_fixture('Klippfile-bad-ruby')
|
42
|
+
expect { creator.eval_string(string, path) }.to raise_error RuntimeError
|
43
|
+
end
|
44
|
+
|
45
|
+
it "raises an error the Klippfile doesn't exist" do
|
46
|
+
File.stubs(:exists?).returns false
|
47
|
+
expect { Klipp::Creator.from_file ('anywhere/Klippfile') }.to raise_error RuntimeError
|
48
|
+
end
|
49
|
+
|
50
|
+
it 'warns about unambiguous templates' do
|
51
|
+
creator = Klipp::Creator.new()
|
52
|
+
path = fixture_path('Klippfile-unambiguous')
|
53
|
+
string = read_fixture('Klippfile-unambiguous')
|
54
|
+
expect { creator.eval_string(string, path) }.to raise_error Klipp::Hint
|
55
|
+
end
|
56
|
+
|
57
|
+
it 'raises an error for unknown templates' do
|
58
|
+
creator = Klipp::Creator.new()
|
59
|
+
expect { creator.eval_string("create 'Amnesia'", 'fictional-klippspec.rb') }.to raise_error RuntimeError
|
60
|
+
end
|
61
|
+
|
62
|
+
it 'raises an error for empty templates' do
|
63
|
+
creator = Klipp::Creator.new()
|
64
|
+
expect { creator.eval_string("create ''", 'fictional-klippspec.rb') }.to raise_error RuntimeError
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
context 'a valid klippfile' do
|
69
|
+
|
70
|
+
it 'initializes from a klippfile' do
|
71
|
+
Klipp::Creator.from_file(fixture_path('Klippfile')).should be_an_instance_of Klipp::Creator
|
72
|
+
end
|
73
|
+
|
74
|
+
it 'validates ambiguous templates' do
|
75
|
+
creator = Klipp::Creator.new()
|
76
|
+
creator.expects(:invalidate).never
|
77
|
+
path = fixture_path('Klippfile-ambiguous')
|
78
|
+
string = read_fixture('Klippfile-ambiguous')
|
79
|
+
creator.eval_string(string, path)
|
80
|
+
end
|
81
|
+
|
82
|
+
end
|
83
|
+
|
84
|
+
end
|
85
|
+
|
86
|
+
context 'from user input' do
|
87
|
+
|
88
|
+
before do
|
89
|
+
@input = StringIO.new
|
90
|
+
@output = StringIO.new
|
91
|
+
@highline = HighLine.new(@input, @output)
|
92
|
+
end
|
93
|
+
|
94
|
+
it 'validates' do
|
95
|
+
creator = Klipp::Creator.new()
|
96
|
+
creator.expects(:invalidate).never
|
97
|
+
|
98
|
+
@input << "Object\ny\n"
|
99
|
+
@input.rewind
|
100
|
+
|
101
|
+
creator.ask_user_input('Interactive', @highline)
|
102
|
+
end
|
103
|
+
|
104
|
+
it 'invalidates booleans and asks again' do
|
105
|
+
creator = Klipp::Creator.new()
|
106
|
+
creator.expects(:invalidate).never
|
107
|
+
|
108
|
+
@input << "Object\nja\ny\n"
|
109
|
+
@input.rewind
|
110
|
+
|
111
|
+
creator.ask_user_input('Interactive', @highline)
|
112
|
+
p @output.string
|
113
|
+
end
|
114
|
+
|
115
|
+
end
|
116
|
+
|
117
|
+
end
|
118
|
+
|
119
|
+
|
120
|
+
end
|
data/spec/klipp_spec.rb
CHANGED
@@ -3,137 +3,132 @@ require 'spec_helper'
|
|
3
3
|
|
4
4
|
describe Klipp do
|
5
5
|
|
6
|
-
|
7
|
-
@output = Klipp.output = StringIO.new
|
8
|
-
end
|
9
|
-
|
10
|
-
describe 'when routing' do
|
6
|
+
context 'capturing stdout' do
|
11
7
|
|
12
|
-
it '
|
13
|
-
|
14
|
-
|
8
|
+
it 'matches stdout' do
|
9
|
+
capture_stdout {
|
10
|
+
puts "I'm out"
|
11
|
+
}.should eq "I'm out\n"
|
15
12
|
end
|
16
13
|
|
17
|
-
it '
|
18
|
-
|
19
|
-
|
14
|
+
it 'matches formatador stdout' do
|
15
|
+
capture_stdout {
|
16
|
+
Formatador.display_line "I'm [green]green[/]"
|
17
|
+
}.should include "green"
|
20
18
|
end
|
21
19
|
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
end
|
20
|
+
end
|
21
|
+
|
22
|
+
context 'when routing commands' do
|
26
23
|
|
27
|
-
it '
|
28
|
-
|
29
|
-
|
24
|
+
it 'returns exit code 1 without any commands and displays a hint' do
|
25
|
+
(capture_stdout do
|
26
|
+
Klipp.route(*%w[]).should eq 1
|
27
|
+
end).should include '[?]'
|
30
28
|
end
|
31
29
|
|
32
|
-
it '
|
33
|
-
|
34
|
-
|
30
|
+
it 'returns exit code 1 with an unknown command and displays the error' do
|
31
|
+
(capture_stdout do
|
32
|
+
Klipp.route(*%w[magic]).should eq 1
|
33
|
+
end).should include '[!]'
|
35
34
|
end
|
36
35
|
|
37
|
-
it 'routes
|
38
|
-
Klipp.expects(:
|
39
|
-
Klipp.route
|
36
|
+
it 'routes prepare' do
|
37
|
+
Klipp.expects(:cli_prepare).with(['Example'])
|
38
|
+
Klipp.route(*%w[prepare Example])
|
40
39
|
end
|
41
40
|
|
42
|
-
it 'routes
|
43
|
-
Klipp.expects(:
|
44
|
-
Klipp.route
|
41
|
+
it 'routes create' do
|
42
|
+
Klipp.expects(:cli_create).with(['-f'])
|
43
|
+
Klipp.route(*%w[create -f])
|
45
44
|
end
|
46
45
|
|
47
|
-
it 'routes
|
48
|
-
|
49
|
-
Klipp.route
|
46
|
+
it 'routes template with exit code 0' do
|
47
|
+
Template.expects(:route)
|
48
|
+
Klipp.route(*%w[template]).should eq 0
|
50
49
|
end
|
51
50
|
|
52
51
|
end
|
53
52
|
|
54
|
-
|
53
|
+
context 'prepare' do
|
55
54
|
|
56
55
|
before do
|
57
|
-
Klipp::Configuration.stubs(:root_dir).returns
|
56
|
+
Klipp::Configuration.stubs(:root_dir).returns(File.join(__dir__, 'fixtures'))
|
58
57
|
end
|
59
58
|
|
60
|
-
it '
|
61
|
-
expect { Klipp.
|
59
|
+
it 'without template name raises error' do
|
60
|
+
expect { Klipp.cli_prepare([]) }.to raise_error Klipp::Hint
|
62
61
|
end
|
63
62
|
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
63
|
+
context 'without an existing Klippfile' do
|
64
|
+
before do
|
65
|
+
File.stubs(:exists?).returns(false)
|
66
|
+
end
|
68
67
|
|
69
|
-
|
70
|
-
|
68
|
+
it 'write a new Klippfile' do
|
69
|
+
klippfile = read_fixture 'Klippfile-after-prepare'
|
70
|
+
File.expects(:write).with('Klippfile', klippfile)
|
71
|
+
Klipp.cli_prepare(%w[Example])
|
72
|
+
end
|
71
73
|
end
|
72
74
|
|
73
|
-
it 'raises an error when a .klippfile for the template already exists' do
|
74
|
-
File.stubs(:exists?).with(anything).returns true
|
75
|
-
expect { Klipp.prepare 'Example' }.to raise_error RuntimeError
|
76
|
-
end
|
77
75
|
|
78
|
-
|
76
|
+
context 'with an existing Klippfile' do
|
79
77
|
|
80
|
-
|
78
|
+
before do
|
79
|
+
File.stubs(:exists?).returns(true)
|
80
|
+
end
|
81
81
|
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
82
|
+
it 'will not overwrite' do
|
83
|
+
File.expects(:write).never
|
84
|
+
expect { Klipp.cli_prepare(%w[Example]) }.to raise_error RuntimeError
|
85
|
+
end
|
86
|
+
|
87
|
+
it 'will overwrite when forced' do
|
88
|
+
klippfile = read_fixture 'Klippfile-after-prepare'
|
89
|
+
File.expects(:write).with('Klippfile', klippfile)
|
90
|
+
Klipp.cli_prepare(%w[Example -f])
|
91
|
+
end
|
87
92
|
|
88
|
-
it 'raises an error when there are no templates' do
|
89
|
-
Klipp.expects(:template_files).returns([])
|
90
|
-
expect { Klipp.list }.to raise_error RuntimeError
|
91
93
|
end
|
92
94
|
|
93
95
|
end
|
94
96
|
|
95
|
-
|
97
|
+
context 'create' do
|
96
98
|
|
97
|
-
|
98
|
-
Klipp.
|
99
|
-
|
99
|
+
before do
|
100
|
+
Klipp::Configuration.stubs(:root_dir).returns(File.join(__dir__, 'fixtures'))
|
101
|
+
Dir.stubs(:pwd).returns(Dir.mktmpdir)
|
102
|
+
|
103
|
+
maker = Klipp::Creator.new
|
104
|
+
maker.eval_string(read_fixture('Klippfile'), fixture_path('Klippfile'))
|
105
|
+
Klipp::Creator.stubs(:from_file).returns(maker)
|
100
106
|
end
|
101
107
|
|
102
|
-
|
108
|
+
it 'creates files from a Klippfile' do
|
103
109
|
|
104
|
-
|
110
|
+
Klipp.cli_create([])
|
111
|
+
File.exists?(File.join Dir.pwd, 'Podfile').should be true
|
112
|
+
File.exists?(File.join Dir.pwd, '.gitignore').should be true
|
113
|
+
File.exists?(File.join Dir.pwd, 'AmazingApp').should be true
|
114
|
+
File.exists?(File.join Dir.pwd, 'Example.klippspec').should be false
|
105
115
|
|
106
|
-
before do
|
107
|
-
Klipp::Configuration.stubs(:root_dir).returns File.join(__dir__, 'fixtures')
|
108
|
-
@example_klippfile_contents = File.read(File.join(__dir__, 'fixtures', 'klipps', 'Example.klippfile'))
|
109
116
|
end
|
110
117
|
|
111
|
-
it '
|
112
|
-
mock_project = mock
|
113
|
-
mock_project.expects(:create)
|
114
|
-
Klipp::Project.expects(:new).with(is_a(Klipp::Template)).returns(mock_project)
|
115
|
-
File.stubs(:read).with(anything).returns( @example_klippfile_contents )
|
116
|
-
Klipp.create('Example')
|
117
|
-
end
|
118
|
+
it 'creates files interactively' do
|
118
119
|
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
mock_project.expects(:create)
|
123
|
-
Klipp::Project.expects(:new).with(is_a(Klipp::Template)).returns(mock_project)
|
124
|
-
File.stubs(:read).with(anything).returns( @example_klippfile_contents )
|
125
|
-
Klipp.create nil
|
126
|
-
end
|
120
|
+
input = StringIO.new
|
121
|
+
output = StringIO.new
|
122
|
+
highline = HighLine.new(input, output)
|
127
123
|
|
128
|
-
|
129
|
-
|
130
|
-
expect { Klipp.create nil }.to raise_error RuntimeError
|
131
|
-
end
|
124
|
+
input << "KLPObject\nN\n"
|
125
|
+
input.rewind
|
132
126
|
|
133
|
-
|
127
|
+
Klipp.cli_create(%w(Interactive), highline)
|
128
|
+
File.exists?(File.join Dir.pwd, 'KLPObjectTests.m').should be true
|
129
|
+
|
130
|
+
end
|
134
131
|
|
135
|
-
def subject
|
136
|
-
@output.string
|
137
132
|
end
|
138
133
|
|
139
134
|
end
|
data/spec/spec_helper.rb
CHANGED
@@ -7,11 +7,17 @@ SimpleCov.formatter = SimpleCov::Formatter::HTMLFormatter
|
|
7
7
|
|
8
8
|
require 'klipp'
|
9
9
|
|
10
|
+
def fixture_path fixture_name
|
11
|
+
Dir.glob(File.join(__dir__, 'fixtures', '**', fixture_name)).first
|
12
|
+
end
|
13
|
+
|
10
14
|
def read_fixture fixture_name
|
11
|
-
File.read(
|
15
|
+
File.read(fixture_path fixture_name)
|
12
16
|
end
|
13
17
|
|
14
18
|
RSpec.configure do |config|
|
15
19
|
config.mock_framework = :mocha
|
16
20
|
config.order = 'random'
|
17
|
-
end
|
21
|
+
end
|
22
|
+
|
23
|
+
Klipp.env = StringInquirer.new('test')
|
@@ -0,0 +1,225 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Template::Spec do
|
4
|
+
|
5
|
+
context 'identifier methods' do
|
6
|
+
|
7
|
+
before do
|
8
|
+
Klipp::Configuration.stubs(:root_dir).returns(File.join(File.dirname(__dir__), 'fixtures'))
|
9
|
+
end
|
10
|
+
|
11
|
+
it 'finds the path to a template name' do
|
12
|
+
path = Template::Spec.spec_path_for_identifier('Example')
|
13
|
+
path.should eq File.join(File.dirname(__dir__), 'fixtures', 'template-repository', 'Example', 'Example.klippspec')
|
14
|
+
end
|
15
|
+
|
16
|
+
it 'raises error if a template doesn\'t exist' do
|
17
|
+
expect { Template::Spec.spec_path_for_identifier('Non-existing') }.to raise_error RuntimeError
|
18
|
+
end
|
19
|
+
|
20
|
+
it 'knows about unambiguous specs' do
|
21
|
+
Template::Spec.identifier_is_ambiguous('Ambiguous').should eq false
|
22
|
+
end
|
23
|
+
|
24
|
+
it 'raises error if a template is unambiguous' do
|
25
|
+
expect { Template::Spec.spec_path_for_identifier('Ambiguous') }.to raise_error RuntimeError, /Found multiple templates/
|
26
|
+
end
|
27
|
+
|
28
|
+
it 'finds the path to a template in a specific repo' do
|
29
|
+
path = Template::Spec.spec_path_for_identifier('template-repository/Ambiguous')
|
30
|
+
path.should eq File.join(File.dirname(__dir__), 'fixtures', 'template-repository', 'Ambiguous', 'Ambiguous.klippspec')
|
31
|
+
end
|
32
|
+
|
33
|
+
it 'deducts the template identifier from an unambiguous template name' do
|
34
|
+
path = Template::Spec.spec_path_for_identifier 'Example'
|
35
|
+
hash = Template::Spec.hash_for_spec_path path
|
36
|
+
Template::Spec.hash_to_identifier(hash).should eq 'template-repository/Example'
|
37
|
+
end
|
38
|
+
|
39
|
+
end
|
40
|
+
|
41
|
+
context 'with validation disabled' do
|
42
|
+
before do
|
43
|
+
Template::Spec.any_instance.stubs(:invalidate)
|
44
|
+
end
|
45
|
+
|
46
|
+
it 'yields on initialize' do
|
47
|
+
expect { |probe| Template::Spec.new().spec 'Example', &probe }.to yield_control
|
48
|
+
end
|
49
|
+
|
50
|
+
it 'passes itself as a parameter on yield' do
|
51
|
+
expect { |probe| Template::Spec.new().spec('Example', &probe) }.to yield_with_args(be_an_instance_of(Template::Spec))
|
52
|
+
end
|
53
|
+
|
54
|
+
it 'validates the spec after configuration' do
|
55
|
+
spec = Template::Spec.new
|
56
|
+
spec.expects(:validate_spec)
|
57
|
+
spec.spec('')
|
58
|
+
end
|
59
|
+
|
60
|
+
it 'raises an error when overwriting tokens, like the BLANK token' do
|
61
|
+
(expect do
|
62
|
+
Template::Spec.new().spec 'Example' do |spec|
|
63
|
+
spec.token :BLANK do |t|
|
64
|
+
t.comment = "You can't overwrite tokens"
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end).to raise_error RuntimeError
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
context 'with an invalid spec' do
|
72
|
+
|
73
|
+
before do
|
74
|
+
@spec = Template::Spec.new
|
75
|
+
end
|
76
|
+
|
77
|
+
it 'invalidates' do
|
78
|
+
@spec.expects(:invalidate)
|
79
|
+
@spec.spec('')
|
80
|
+
end
|
81
|
+
|
82
|
+
it 'raises an error when invalidating' do
|
83
|
+
expect { @spec.spec('') }.to raise_error RuntimeError
|
84
|
+
end
|
85
|
+
|
86
|
+
it 'rescues and re-raises errors from the config block' do
|
87
|
+
expect { @spec.spec('Example') { |s| s.lala = 5 } }.to raise_error RuntimeError, /Invalid klippspec configuration/
|
88
|
+
end
|
89
|
+
|
90
|
+
it 'raises errors from klippspec string' do
|
91
|
+
expect { @spec.from_string('lalala', 'fake/path') }.to raise_error RuntimeError, /Error evaluating spec/
|
92
|
+
end
|
93
|
+
|
94
|
+
end
|
95
|
+
|
96
|
+
context 'with a valid spec' do
|
97
|
+
|
98
|
+
before do
|
99
|
+
@template = Template::Spec.new
|
100
|
+
@template.spec('Example') {}
|
101
|
+
end
|
102
|
+
|
103
|
+
it 'has a name' do
|
104
|
+
@template.identifier = 'repo/ProjectX'
|
105
|
+
@template.identifier.should eq 'repo/ProjectX'
|
106
|
+
end
|
107
|
+
|
108
|
+
it 'has a post-action setter' do
|
109
|
+
@template.post_action = 'pod install'
|
110
|
+
@template.post_actions.should eq ['pod install']
|
111
|
+
end
|
112
|
+
|
113
|
+
it 'has a post-actions setter' do
|
114
|
+
@template.post_actions = ['git init', 'git add .', 'git commit -m "Initial commit."', 'pod install']
|
115
|
+
@template.post_actions.should eq ['git init', 'git add .', 'git commit -m "Initial commit."', 'pod install']
|
116
|
+
end
|
117
|
+
it 'has a token hash' do
|
118
|
+
@template[:PROJECT_ID] = Template::Token.new
|
119
|
+
@template[:PROJECT_ID].should be_an_instance_of(Template::Token)
|
120
|
+
end
|
121
|
+
|
122
|
+
it 'creates a token' do
|
123
|
+
yielded_token = :not_a_token
|
124
|
+
@template.token(:PROJECT_ID) { |t| yielded_token = t }
|
125
|
+
yielded_token.should be_an_instance_of Template::Token
|
126
|
+
end
|
127
|
+
|
128
|
+
it 'has a blank token' do
|
129
|
+
@template[:BLANK].hidden.should eq true
|
130
|
+
@template[:BLANK].value.should eq ''
|
131
|
+
end
|
132
|
+
|
133
|
+
it 'has a date token' do
|
134
|
+
@template[:DATE].hidden.should eq true
|
135
|
+
@template[:DATE].value.should eq DateTime.now.strftime('%F')
|
136
|
+
end
|
137
|
+
|
138
|
+
it 'has a year token' do
|
139
|
+
@template[:YEAR].hidden.should eq true
|
140
|
+
@template[:YEAR].value.should eq '2013'
|
141
|
+
end
|
142
|
+
|
143
|
+
end
|
144
|
+
|
145
|
+
context 'when loading a klippspec' do
|
146
|
+
|
147
|
+
before do
|
148
|
+
Klipp::Configuration.stubs(:root_dir).returns(File.join(File.dirname(__dir__), 'fixtures'))
|
149
|
+
end
|
150
|
+
|
151
|
+
context 'with an invalid klippspec' do
|
152
|
+
|
153
|
+
it 'raises an error when loading an invalid klippspec' do
|
154
|
+
klippspec = File.join(Klipp::Configuration.root_dir, 'template-repository', 'BadExample', 'BadExample.klippspec')
|
155
|
+
File.exists?(klippspec).should be true
|
156
|
+
expect { Template::Spec.from_file(klippspec) }.to raise_error RuntimeError
|
157
|
+
end
|
158
|
+
|
159
|
+
end
|
160
|
+
|
161
|
+
context 'with a valid klippspec' do
|
162
|
+
|
163
|
+
before do
|
164
|
+
@path = File.join(Klipp::Configuration.root_dir, 'template-repository', 'Example', 'Example.klippspec')
|
165
|
+
File.exists?(@path).should be true
|
166
|
+
|
167
|
+
@spec = Template::Spec.from_file(@path)
|
168
|
+
end
|
169
|
+
|
170
|
+
it 'loads a spec from a file' do
|
171
|
+
@spec.should be_an_instance_of Template::Spec
|
172
|
+
end
|
173
|
+
|
174
|
+
it 'generates a project specific Klippfile' do
|
175
|
+
fixture = read_fixture 'Klippfile-after-prepare'
|
176
|
+
@spec.klippfile.should eq fixture
|
177
|
+
end
|
178
|
+
|
179
|
+
it 'references the repo in the Klippfile' do
|
180
|
+
@spec.klippfile.should include 'template-repository/Example'
|
181
|
+
end
|
182
|
+
|
183
|
+
context 'with a values hash' do
|
184
|
+
before do
|
185
|
+
@values = Hash.new
|
186
|
+
@values[:PROJECT_ID] = "Klipp"
|
187
|
+
@values[:PROJECT_TITLE] = "Templates for the rest of us"
|
188
|
+
@values[:BUNDLE_ID] = "com.epologee.klipp"
|
189
|
+
@values[:ORGANIZATION_NAME] = "epologee"
|
190
|
+
@values[:CLASS_PREFIX] = "KLP"
|
191
|
+
@values[:SECRET_TOGGLE] = true
|
192
|
+
end
|
193
|
+
|
194
|
+
it 'validates token values' do
|
195
|
+
@spec.set_token_values @values
|
196
|
+
end
|
197
|
+
|
198
|
+
it 'replaces delimited tokens with its values' do
|
199
|
+
@spec.set_token_values @values
|
200
|
+
source = 'XXPROJECT_IDXX - XXPROJECT_TITLEXX - XXBUNDLE_IDXX - XXORGANIZATION_NAMEXX - XXCLASS_PREFIXXX - XXSECRET_TOGGLEXX - [XXBLANKXX]'
|
201
|
+
target = 'Klipp - Templates for the rest of us - com.epologee.klipp - epologee - KLP - YES - []'
|
202
|
+
@spec.replace_tokens(source).should eq target
|
203
|
+
end
|
204
|
+
end
|
205
|
+
|
206
|
+
|
207
|
+
end
|
208
|
+
|
209
|
+
end
|
210
|
+
|
211
|
+
context 'when creating a klippspec' do
|
212
|
+
|
213
|
+
before do
|
214
|
+
Klipp::Configuration.stubs(:root_dir).returns(File.join(File.dirname(__dir__), 'fixtures'))
|
215
|
+
end
|
216
|
+
|
217
|
+
it 'generates the klippspec' do
|
218
|
+
spec = Template::Spec.new
|
219
|
+
spec.identifier = 'Another-Template'
|
220
|
+
spec.klippspec.should eq read_fixture('Another-Template.klippspec')
|
221
|
+
end
|
222
|
+
|
223
|
+
end
|
224
|
+
|
225
|
+
end
|
@@ -0,0 +1,100 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Template::Token do
|
4
|
+
|
5
|
+
before do
|
6
|
+
@token = Template::Token.new
|
7
|
+
end
|
8
|
+
|
9
|
+
it 'has a default string type' do
|
10
|
+
@token.type.should eq :string
|
11
|
+
end
|
12
|
+
|
13
|
+
it 'will not allow an unknown type' do
|
14
|
+
expect { @token.type = :invalid_type }.to raise_error RuntimeError
|
15
|
+
end
|
16
|
+
|
17
|
+
context 'with type string' do
|
18
|
+
|
19
|
+
it 'has a hidden property' do
|
20
|
+
@token.hidden = true
|
21
|
+
@token.hidden.should eq true
|
22
|
+
end
|
23
|
+
|
24
|
+
it 'is not hidden by default' do
|
25
|
+
@token.hidden.should eq false
|
26
|
+
end
|
27
|
+
|
28
|
+
it 'has a comment' do
|
29
|
+
@token.comment = 'Comment'
|
30
|
+
@token.comment.should eq 'Comment'
|
31
|
+
end
|
32
|
+
|
33
|
+
it 'has a validation' do
|
34
|
+
@token.validation = /^[A-Z][A-Za-z0-9]{2,}$/
|
35
|
+
@token.validation.should eq /^[A-Z][A-Za-z0-9]{2,}$/
|
36
|
+
end
|
37
|
+
|
38
|
+
it 'has a default validation hint' do
|
39
|
+
@token.validation = /^[A-Z][A-Za-z0-9]{2,}$/
|
40
|
+
@token.validation_hint.should include '(no custom validation_hint given)'
|
41
|
+
end
|
42
|
+
|
43
|
+
it 'accepts custom validation hints' do
|
44
|
+
@token.validation_hint = 'Hint'
|
45
|
+
@token.validation_hint.should eq 'Hint'
|
46
|
+
end
|
47
|
+
|
48
|
+
it 'invalidates booleans assigned' do
|
49
|
+
expect { @token.value = true }.to raise_error RuntimeError
|
50
|
+
end
|
51
|
+
|
52
|
+
end
|
53
|
+
|
54
|
+
context 'with type bool' do
|
55
|
+
|
56
|
+
before do
|
57
|
+
@token.type = :bool
|
58
|
+
end
|
59
|
+
|
60
|
+
it 'accepts boolean values' do
|
61
|
+
@token.value = true
|
62
|
+
@token.value.should eq true
|
63
|
+
|
64
|
+
@token.value = false
|
65
|
+
@token.value.should eq false
|
66
|
+
end
|
67
|
+
|
68
|
+
it 'accepts booleans as strings' do
|
69
|
+
@token.value = 'true'
|
70
|
+
@token.value.should eq true
|
71
|
+
|
72
|
+
@token.value = 'yes'
|
73
|
+
@token.value.should eq true
|
74
|
+
|
75
|
+
@token.value = 'Yes'
|
76
|
+
@token.value.should eq true
|
77
|
+
|
78
|
+
@token.value = 'y'
|
79
|
+
@token.value.should eq true
|
80
|
+
|
81
|
+
@token.value = 'false'
|
82
|
+
@token.value.should eq false
|
83
|
+
|
84
|
+
@token.value = 'no'
|
85
|
+
@token.value.should eq false
|
86
|
+
|
87
|
+
@token.value = 'No'
|
88
|
+
@token.value.should eq false
|
89
|
+
|
90
|
+
@token.value = 'n'
|
91
|
+
@token.value.should eq false
|
92
|
+
end
|
93
|
+
|
94
|
+
it 'invalidates other strings' do
|
95
|
+
expect { @token.value = 'ja' }.to raise_error RuntimeError
|
96
|
+
end
|
97
|
+
|
98
|
+
end
|
99
|
+
|
100
|
+
end
|