klipp 0.0.1 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|