vitae 0.0.2 → 0.1.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.
- data/.autotest +10 -0
- data/.gitignore +2 -0
- data/Gemfile.lock +29 -0
- data/README.rdoc +59 -2
- data/bin/vitae +67 -0
- data/config.ru +4 -0
- data/lib/vitae.rb +2 -3
- data/lib/vitae/cv.rb +40 -0
- data/lib/vitae/server/.gitignore +4 -0
- data/lib/vitae/server/helpers.rb +37 -0
- data/lib/vitae/server/server.rb +31 -0
- data/lib/vitae/server/views/index.haml +3 -0
- data/lib/vitae/server/views/layout.haml +10 -0
- data/lib/vitae/server/views/show.haml +1 -0
- data/lib/vitae/templates/cvs/arthur_gunn.yaml +5 -0
- data/lib/vitae/templates/cvs/default.yaml.tt +5 -0
- data/lib/vitae/templates/themes/default/application.css +226 -0
- data/lib/vitae/templates/themes/default/application.js +1 -0
- data/lib/vitae/version.rb +1 -1
- data/test/active_server_test.rb +36 -0
- data/test/basic_server_test.rb +10 -0
- data/test/tag_helpers_test.rb +24 -0
- data/test/test_helper.rb +78 -0
- data/test/vitae_executable_test.rb +52 -0
- data/vitae.gemspec +6 -0
- metadata +88 -9
data/.autotest
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
vitae (0.0.2)
|
5
|
+
haml
|
6
|
+
sinatra
|
7
|
+
thor
|
8
|
+
|
9
|
+
GEM
|
10
|
+
remote: http://rubygems.org/
|
11
|
+
specs:
|
12
|
+
haml (3.0.24)
|
13
|
+
nokogiri (1.4.4)
|
14
|
+
rack (1.2.1)
|
15
|
+
sinatra (1.1.0)
|
16
|
+
rack (~> 1.1)
|
17
|
+
tilt (~> 1.1)
|
18
|
+
thor (0.14.6)
|
19
|
+
tilt (1.1)
|
20
|
+
|
21
|
+
PLATFORMS
|
22
|
+
ruby
|
23
|
+
|
24
|
+
DEPENDENCIES
|
25
|
+
haml
|
26
|
+
nokogiri
|
27
|
+
sinatra
|
28
|
+
thor
|
29
|
+
vitae!
|
data/README.rdoc
CHANGED
@@ -1,5 +1,62 @@
|
|
1
|
-
|
1
|
+
= Vitae
|
2
2
|
|
3
3
|
Vitae is to CVs what rubygems is to ruby code.
|
4
4
|
|
5
|
-
|
5
|
+
It's also very under development right now, and not very useful yet. Come back soon!
|
6
|
+
|
7
|
+
|
8
|
+
=== Usage
|
9
|
+
First install the vitae gem:
|
10
|
+
$: sudo gem i vitae
|
11
|
+
|
12
|
+
Now lets create a new project called my_cv_project, with some named CVs:
|
13
|
+
$: vitae create my_cv_project arthur_gunn sajal_shah
|
14
|
+
creating my_cv_project...
|
15
|
+
create cvs/arthur_gunn.yaml
|
16
|
+
create cvs/sajal_shah.yaml
|
17
|
+
create themes/default/application.js
|
18
|
+
create themes/default/application.css
|
19
|
+
|
20
|
+
Great, it's created our two named CVs in the my_cv_project/cvs directory from a basic yaml template. Edit these yaml files with your own info (note: currently data is not actually read from these, that will change soon).
|
21
|
+
|
22
|
+
Once your done editing, start up the server:
|
23
|
+
$: cd my_cv_project
|
24
|
+
$: vitae server
|
25
|
+
Serving CVs at 0.0.0.0:3141
|
26
|
+
|
27
|
+
Enjoy!
|
28
|
+
|
29
|
+
=== Future plans
|
30
|
+
1. Data should actually be read from the yaml files.
|
31
|
+
2. Vitae should com bundled with better default templates - CSS, JS and YAML.
|
32
|
+
3. Support for multiple themes.
|
33
|
+
4. The clever stuff
|
34
|
+
|
35
|
+
=== The clever stuff
|
36
|
+
Much like rubygems or git
|
37
|
+
|
38
|
+
Push a CV:
|
39
|
+
$: vitae push vitae.gunn.co.nz arthur_gunn
|
40
|
+
pushing...
|
41
|
+
1 CV pushed
|
42
|
+
CV available at http://vitae.gunn.co.nz/arthur_gunn
|
43
|
+
|
44
|
+
Pull a CV:
|
45
|
+
$: vitae pull vitae.gunn.co.nz sajal_shah
|
46
|
+
pulling...
|
47
|
+
1 CV pulled
|
48
|
+
2 themes pulled
|
49
|
+
CV pulled to cvs/sajal_shah
|
50
|
+
Theme pulled to themes/darkness
|
51
|
+
Theme pulled to themes/espresso
|
52
|
+
|
53
|
+
=== Want to help?
|
54
|
+
Just the github usual for development - fork, commit, pull request, bonus points for tests.
|
55
|
+
Have a play and report bugs, request features via the issue tracker.
|
56
|
+
|
57
|
+
Feel free to email me at arthur@gunn.co.nz
|
58
|
+
|
59
|
+
=== Credits
|
60
|
+
Development by Arthur Gunn.
|
61
|
+
|
62
|
+
Thanks to Maxim Chernyak and Juriy Zaytsev for CSS used in the default theme.
|
data/bin/vitae
ADDED
@@ -0,0 +1,67 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
require "rubygems"
|
3
|
+
require "thor"
|
4
|
+
|
5
|
+
require File.expand_path('../../lib/vitae', __FILE__)
|
6
|
+
|
7
|
+
module Vitae
|
8
|
+
class CLI < Thor
|
9
|
+
include Thor::Actions
|
10
|
+
|
11
|
+
def self.source_root
|
12
|
+
File.expand_path('../../lib/vitae/templates', __FILE__)
|
13
|
+
end
|
14
|
+
|
15
|
+
|
16
|
+
default_task :create
|
17
|
+
|
18
|
+
desc "create [project_name]", "Create a new vitae project"
|
19
|
+
def create(name, *cv_names)
|
20
|
+
self.destination_root = name
|
21
|
+
puts "creating #{name}..."
|
22
|
+
|
23
|
+
if cv_names.size > 0
|
24
|
+
cv_names.each do |cv_name|
|
25
|
+
@name = cv_name
|
26
|
+
template "cvs/default.yaml.tt", "cvs/#{cv_name}.yaml"
|
27
|
+
end
|
28
|
+
else
|
29
|
+
templates = Dir.glob(File.join(CLI.source_root, "cvs/*.yaml*")).
|
30
|
+
map{|f| File.basename(f)} -["default.yaml.tt"]
|
31
|
+
|
32
|
+
templates.each do |template_name|
|
33
|
+
template "cvs/#{template_name}", "cvs/#{template_name.sub(/\.tt$/, '')}"
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
themes = Dir.glob(File.join(CLI.source_root, "themes/*")).map{|f| File.basename(f)}
|
38
|
+
themes.each do |theme_name|
|
39
|
+
copy_file "themes/#{theme_name}/application.js"
|
40
|
+
copy_file "themes/#{theme_name}/application.css"
|
41
|
+
end
|
42
|
+
|
43
|
+
end
|
44
|
+
|
45
|
+
desc "server [-p 3000]", "Start the vitae server."
|
46
|
+
def server
|
47
|
+
require "rack"
|
48
|
+
|
49
|
+
just_pretend = ARGV.delete "--pretend"
|
50
|
+
port_set_by_user = ARGV.any? { |a| %w[-p --port].include?( a ) }
|
51
|
+
|
52
|
+
server = Rack::Server.new.tap do |s|
|
53
|
+
s.options[:config] = File.join(File.dirname(__FILE__), "../config.ru")
|
54
|
+
s.options[:Port] = 3141 unless port_set_by_user
|
55
|
+
end
|
56
|
+
|
57
|
+
require "vitae/server/server"
|
58
|
+
Server.project_root = Dir.pwd
|
59
|
+
|
60
|
+
say "Serving CVs at #{server.options[:Host]}:#{server.options[:Port]}", :green
|
61
|
+
server.start unless just_pretend
|
62
|
+
end
|
63
|
+
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
Vitae::CLI.start
|
data/config.ru
ADDED
data/lib/vitae.rb
CHANGED
@@ -1,3 +1,2 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
end
|
1
|
+
$:.unshift File.dirname(File.expand_path(__FILE__))
|
2
|
+
require "vitae/cv"
|
data/lib/vitae/cv.rb
ADDED
@@ -0,0 +1,40 @@
|
|
1
|
+
class CV
|
2
|
+
|
3
|
+
def self.all
|
4
|
+
cvs = Dir.glob(File.join(Server.project_root, "cvs/*.yaml"))
|
5
|
+
cvs.map do |cv|
|
6
|
+
CV.new(cv)
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
def self.find name
|
11
|
+
all.find do |cv|
|
12
|
+
cv.name == name
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def initialize yaml_file
|
17
|
+
@name = File.basename(yaml_file, '.yaml')
|
18
|
+
end
|
19
|
+
|
20
|
+
def name
|
21
|
+
@name
|
22
|
+
end
|
23
|
+
|
24
|
+
def human_name
|
25
|
+
name.split("_").map{|w|w.capitalize}.join(" ")
|
26
|
+
end
|
27
|
+
|
28
|
+
def to_s
|
29
|
+
human_name
|
30
|
+
end
|
31
|
+
|
32
|
+
def link
|
33
|
+
"/#{name}"
|
34
|
+
end
|
35
|
+
|
36
|
+
def theme
|
37
|
+
"default"
|
38
|
+
end
|
39
|
+
|
40
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
module Helpers
|
2
|
+
def current_theme
|
3
|
+
@cv && @cv.theme || "default"
|
4
|
+
end
|
5
|
+
|
6
|
+
def include_theme_assets
|
7
|
+
html = content_tag(:script, nil, :type => "text/javascript", :src => "/#{current_theme}/application.js")
|
8
|
+
html << "\n"+tag(:link, nil, :type => "text/css", :media => "screen", :rel => "stylesheet", :href => "/#{current_theme}/application.css")
|
9
|
+
html
|
10
|
+
end
|
11
|
+
|
12
|
+
def link_to(text, link=nil, options={})
|
13
|
+
link ||= text.split(/\s+/).join('_').downcase
|
14
|
+
content_tag :a, text, options.merge({:href => link})
|
15
|
+
end
|
16
|
+
|
17
|
+
def content_tag(*args, &block)
|
18
|
+
args.last[:double_tag] = true if args.last.is_a?(Hash)
|
19
|
+
tag(*args, &block)
|
20
|
+
end
|
21
|
+
|
22
|
+
def tag(*args, &block)
|
23
|
+
name = args.first
|
24
|
+
|
25
|
+
options = args.last.is_a?(Hash) ? args.pop : {}
|
26
|
+
double_tag = options.delete(:double_tag)
|
27
|
+
|
28
|
+
attrs = if options.size>0
|
29
|
+
" "+options.map { |k,v| "#{k}='#{v}'" }.join(" ")
|
30
|
+
else
|
31
|
+
""
|
32
|
+
end
|
33
|
+
tag_html = block_given? ? capture_html(&block) : args[1]
|
34
|
+
|
35
|
+
"<#{name}#{attrs}"+(tag_html||double_tag ? ">#{tag_html}</#{name}>" : "/>")
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
require 'sinatra/base'
|
2
|
+
require 'haml'
|
3
|
+
require "vitae/server/helpers"
|
4
|
+
|
5
|
+
class Server < Sinatra::Base
|
6
|
+
helpers Helpers
|
7
|
+
set :views, File.dirname(__FILE__) + '/views'
|
8
|
+
|
9
|
+
get '/' do
|
10
|
+
@cvs = CV.all
|
11
|
+
haml :index
|
12
|
+
end
|
13
|
+
|
14
|
+
get '/:name' do
|
15
|
+
@cv = CV.find( params[:name] )
|
16
|
+
haml :show
|
17
|
+
end
|
18
|
+
|
19
|
+
|
20
|
+
|
21
|
+
@@project_root = nil
|
22
|
+
def self.project_root
|
23
|
+
@@project_root
|
24
|
+
end
|
25
|
+
|
26
|
+
def self.project_root= root
|
27
|
+
set :public, File.join(root, "themes")
|
28
|
+
@@project_root = root
|
29
|
+
end
|
30
|
+
|
31
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
=link_to "Vitae Home", "/"
|
@@ -0,0 +1,226 @@
|
|
1
|
+
/* CSS by Maxim Chernyak and Juriy Zaytsev - https://github.com/maxim/maxim.github.com */
|
2
|
+
body {
|
3
|
+
font-family: Garamond, "Hoefler Text", "Times New Roman", Times, serif;
|
4
|
+
font-size: 1.1em;
|
5
|
+
line-height: 1.3;
|
6
|
+
}
|
7
|
+
|
8
|
+
abbr { border: none; cursor: help; }
|
9
|
+
|
10
|
+
h1, h2, h3, h4 {
|
11
|
+
font-family: Garamond, "Hoefler Text", Palatino, "Palatino Linotype", serif;
|
12
|
+
}
|
13
|
+
|
14
|
+
h1 { font-size: 2em; }
|
15
|
+
h2 { font-size: 1.8em; }
|
16
|
+
|
17
|
+
h3 {
|
18
|
+
margin-bottom: 0;
|
19
|
+
font-size: 1.2em;
|
20
|
+
font-weight: normal;
|
21
|
+
}
|
22
|
+
|
23
|
+
img {
|
24
|
+
border: 0;
|
25
|
+
}
|
26
|
+
|
27
|
+
#left-ribbon {
|
28
|
+
position: absolute;
|
29
|
+
top: 0;
|
30
|
+
left: 0;
|
31
|
+
border: 0;
|
32
|
+
}
|
33
|
+
|
34
|
+
#download-links {
|
35
|
+
position: absolute;
|
36
|
+
top: 160px;
|
37
|
+
right: 0;
|
38
|
+
padding: 5px;
|
39
|
+
padding-top: 15px;
|
40
|
+
background-color: #ffd;
|
41
|
+
}
|
42
|
+
|
43
|
+
#download-links a {
|
44
|
+
display: block;
|
45
|
+
}
|
46
|
+
|
47
|
+
ul {
|
48
|
+
list-style-type: none;
|
49
|
+
padding-left: 0;
|
50
|
+
}
|
51
|
+
|
52
|
+
.tags-header {
|
53
|
+
margin-bottom: 0.5em;
|
54
|
+
}
|
55
|
+
|
56
|
+
.tags {
|
57
|
+
font-size: 0.85em;
|
58
|
+
font-family: "Courier New", Courier, monospace;
|
59
|
+
margin-top: 0;
|
60
|
+
margin-bottom: 2em;
|
61
|
+
}
|
62
|
+
|
63
|
+
.tags li {
|
64
|
+
display: inline;
|
65
|
+
margin-right: 0.5em;
|
66
|
+
vertical-align: middle;
|
67
|
+
}
|
68
|
+
|
69
|
+
.tags li {
|
70
|
+
-moz-box-shadow: 0px 1px 2px #777;
|
71
|
+
-webkit-box-shadow: 1px 1px 2px #777;
|
72
|
+
box-shadow: 0px 1px 2px #777;
|
73
|
+
|
74
|
+
-moz-border-radius: 0.25em;
|
75
|
+
-webkit-border-radius: 0.25em;
|
76
|
+
border-radius: 0.25em;
|
77
|
+
|
78
|
+
border: 1px solid #eee;
|
79
|
+
background-color: #efefef;
|
80
|
+
padding: 0.40em;
|
81
|
+
line-height: 2.8em;
|
82
|
+
}
|
83
|
+
|
84
|
+
.tags .weak {
|
85
|
+
color: #333;
|
86
|
+
font-size: 0.9em;
|
87
|
+
}
|
88
|
+
|
89
|
+
.tags .strong {
|
90
|
+
font-weight: normal;
|
91
|
+
font-size: 1.2em;
|
92
|
+
}
|
93
|
+
|
94
|
+
.tags .prefer {
|
95
|
+
font-size: 1.4em;
|
96
|
+
font-weight: bold;
|
97
|
+
}
|
98
|
+
|
99
|
+
.tags .dislike {
|
100
|
+
font-size: 0.9em;
|
101
|
+
}
|
102
|
+
|
103
|
+
#title, #title-clone {
|
104
|
+
text-align: center;
|
105
|
+
font-size: 4em;
|
106
|
+
color: #777;
|
107
|
+
margin-top: 0;
|
108
|
+
}
|
109
|
+
|
110
|
+
#quick-links {
|
111
|
+
list-style-type: none;
|
112
|
+
padding-left: 0.5em;
|
113
|
+
width: 25em;
|
114
|
+
margin: 2em auto;
|
115
|
+
color: #666;
|
116
|
+
font-size: 0.9em;
|
117
|
+
}
|
118
|
+
|
119
|
+
#quick-links li a {
|
120
|
+
text-decoration: none;
|
121
|
+
font-size: 1.1em;
|
122
|
+
}
|
123
|
+
|
124
|
+
.label {
|
125
|
+
color: #888;
|
126
|
+
display: inline-block;
|
127
|
+
width: 6em;
|
128
|
+
padding-right: 1em;
|
129
|
+
text-align: right;
|
130
|
+
}
|
131
|
+
|
132
|
+
#quick-links li a:hover, #quick-links li a:focus {
|
133
|
+
text-decoration: underline;
|
134
|
+
}
|
135
|
+
|
136
|
+
#content {
|
137
|
+
width: 960px;
|
138
|
+
margin: 3em auto;
|
139
|
+
}
|
140
|
+
|
141
|
+
.spaced-out {
|
142
|
+
line-height: 1.5;
|
143
|
+
}
|
144
|
+
|
145
|
+
.column-wrapper {
|
146
|
+
overflow: hidden;
|
147
|
+
width: 100%;
|
148
|
+
margin-bottom: 2em;
|
149
|
+
}
|
150
|
+
|
151
|
+
.column {
|
152
|
+
float: left;
|
153
|
+
width: 30%;
|
154
|
+
padding-right: 30px;
|
155
|
+
}
|
156
|
+
|
157
|
+
em {
|
158
|
+
font-style: inherit;
|
159
|
+
background-color: #ffd;
|
160
|
+
padding: 2px 5px 2px 5px;
|
161
|
+
color: #444;
|
162
|
+
}
|
163
|
+
|
164
|
+
.dtrange {
|
165
|
+
text-shadow: none;
|
166
|
+
font-weight: normal;
|
167
|
+
font-size: 15px;
|
168
|
+
margin-left: 0.5em;
|
169
|
+
color: #777;
|
170
|
+
}
|
171
|
+
|
172
|
+
#printio-experience-intro {
|
173
|
+
margin-top: -1em;
|
174
|
+
margin-bottom: 2em;
|
175
|
+
}
|
176
|
+
|
177
|
+
#bitsonnet-experience-intro {
|
178
|
+
margin-top: -1em;
|
179
|
+
margin-bottom: 2em;
|
180
|
+
}
|
181
|
+
|
182
|
+
.jobs-list li {
|
183
|
+
padding: 0.75em 0.5em 0.75em 1em;
|
184
|
+
margin-bottom: 1em;
|
185
|
+
}
|
186
|
+
|
187
|
+
.jobs-list li h3 {
|
188
|
+
margin-top: 0;
|
189
|
+
}
|
190
|
+
|
191
|
+
.job-description {
|
192
|
+
margin: 0.25em 0 0 1em;
|
193
|
+
color: #333;
|
194
|
+
}
|
195
|
+
|
196
|
+
#summarize { color: #555; position: absolute; top: 1em; right: 1em; width: 10em; }
|
197
|
+
|
198
|
+
#projects-contributed-to { margin-left: 1em; }
|
199
|
+
#projects-contributed-to li { display: inline; margin-right: 0.5em; line-height: 1.5; }
|
200
|
+
#projects-contributed-to li a { margin-right: 0.5em; }
|
201
|
+
|
202
|
+
/* PRINT MEDIA */
|
203
|
+
|
204
|
+
@media print {
|
205
|
+
body { color: #000; font-family: Cambria, Georgia, Times, "Times New Roman", serif; font-size: 1.3em; }
|
206
|
+
em { font-weight: bold; }
|
207
|
+
a:link, a:visited { color: #007; text-decoration: none; }
|
208
|
+
.tags li { color: #000; }
|
209
|
+
#title { margin-top: -0.5em; font-size: 3em; }
|
210
|
+
#left-ribbon { display: none; }
|
211
|
+
#summarize { display: none; }
|
212
|
+
#download-links { display: none; }
|
213
|
+
}
|
214
|
+
|
215
|
+
/* SMALL SCREEN DEVICES */
|
216
|
+
|
217
|
+
@media only screen and (max-device-width: 480px) {
|
218
|
+
body { margin: 0; }
|
219
|
+
.column { width: auto; padding-right: 0; }
|
220
|
+
#title, #title-clone { font-size: 3em; margin-top: 0; }
|
221
|
+
#content { width: auto; padding: 0 0.5em 0.5em 0.5em; }
|
222
|
+
#left-ribbon { display: none; }
|
223
|
+
#quick-links { width: auto; }
|
224
|
+
#quick-links li { margin-bottom: 0.25em; padding: 0.25em; }
|
225
|
+
#quick-links .label { width: 5em; }
|
226
|
+
}
|
@@ -0,0 +1 @@
|
|
1
|
+
// I'm javascript!
|
data/lib/vitae/version.rb
CHANGED
@@ -0,0 +1,36 @@
|
|
1
|
+
require "test_helper"
|
2
|
+
require "nokogiri"
|
3
|
+
|
4
|
+
class ActiveServerTest < VitaeServerTestCase
|
5
|
+
|
6
|
+
test "the homepage contains lists the cvs we're hosting" do
|
7
|
+
clear_test_dir
|
8
|
+
vitae_create "resumes derek arthur sajal"
|
9
|
+
|
10
|
+
get '/'
|
11
|
+
assert last_response.ok?
|
12
|
+
assert_matches %w[Derek Arthur Sajal]
|
13
|
+
assert_select "a[href='/sajal']", "Sajal"
|
14
|
+
|
15
|
+
check_includes_standard_assets
|
16
|
+
end
|
17
|
+
|
18
|
+
test "a CV gets its own show page" do
|
19
|
+
clear_test_dir
|
20
|
+
vitae_create "resumes arthur_gunn"
|
21
|
+
|
22
|
+
get '/arthur_gunn'
|
23
|
+
assert last_response.ok?
|
24
|
+
|
25
|
+
assert_select "h1", "Arthur Gunn"
|
26
|
+
assert_select "a[href='/']"
|
27
|
+
|
28
|
+
check_includes_standard_assets
|
29
|
+
end
|
30
|
+
|
31
|
+
def check_includes_standard_assets theme="default"
|
32
|
+
assert_select "script[src='/#{theme}/application.js'][type='text/javascript']"
|
33
|
+
assert_select "link[href='/#{theme}/application.css'][rel='stylesheet'][type='text/css']"
|
34
|
+
end
|
35
|
+
|
36
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
require "test_helper"
|
2
|
+
require 'vitae/server/helpers'
|
3
|
+
|
4
|
+
class VitaeExecutableTest < VitaeTestCase
|
5
|
+
module Help
|
6
|
+
extend Helpers
|
7
|
+
end
|
8
|
+
|
9
|
+
test "link_to helper produces well formed links" do
|
10
|
+
assert_equal "<a href='about_us'>About Us</a>", Help.link_to("About Us")
|
11
|
+
assert_equal "<a href='http://google.com'>Search Time!</a>", Help.link_to("Search Time!", "http://google.com")
|
12
|
+
end
|
13
|
+
|
14
|
+
test "content_tag helper produces well formed tags" do
|
15
|
+
assert_equal "<h1>Title!</h1>", Help.content_tag(:h1, "Title!")
|
16
|
+
assert_equal "<script src='/fast.js'></script>", Help.content_tag(:script, :src => "/fast.js")
|
17
|
+
end
|
18
|
+
|
19
|
+
test "tag helper produces well formed tags" do
|
20
|
+
assert_equal "<br/>", Help.tag(:br)
|
21
|
+
assert_equal "<link href='/pretty.css'/>", Help.tag(:link, :href => "/pretty.css")
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
data/test/test_helper.rb
ADDED
@@ -0,0 +1,78 @@
|
|
1
|
+
require 'fileutils'
|
2
|
+
require 'test/unit'
|
3
|
+
|
4
|
+
require File.expand_path('../../lib/vitae', __FILE__)
|
5
|
+
require 'vitae/server/server'
|
6
|
+
require 'rack/test'
|
7
|
+
|
8
|
+
VITAE_TEST_DIR = ::File.expand_path('../../tmp', __FILE__)
|
9
|
+
VITAE_EXECUTABLE = ::File.expand_path('../../bin/vitae', __FILE__)
|
10
|
+
|
11
|
+
class VitaeTestCase < Test::Unit::TestCase
|
12
|
+
def self.test name, &block
|
13
|
+
name = "test #{name}"#.split(/[^a-z1-9]+/).compact.join("_")
|
14
|
+
define_method name, &block
|
15
|
+
end
|
16
|
+
|
17
|
+
test "tests working here" do
|
18
|
+
# assert(true, "Just to keep t/u happy.")
|
19
|
+
end
|
20
|
+
|
21
|
+
def vitae_test_dir
|
22
|
+
FileUtils.mkdir_p VITAE_TEST_DIR
|
23
|
+
end
|
24
|
+
|
25
|
+
def vitae_executable
|
26
|
+
VITAE_EXECUTABLE
|
27
|
+
end
|
28
|
+
|
29
|
+
%w[server].each do |command|
|
30
|
+
define_method "vitae_#{command}" do |*args|
|
31
|
+
args = args.first
|
32
|
+
FileUtils.cd vitae_test_dir
|
33
|
+
`#{vitae_executable} #{command} #{args} 2>&1`
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def vitae_create args=""
|
38
|
+
FileUtils.cd vitae_test_dir
|
39
|
+
project_name = args.split(/\s+/).first || ""
|
40
|
+
Server.project_root = File.join(vitae_test_dir, project_name)
|
41
|
+
`#{vitae_executable} create #{args} 2>&1`
|
42
|
+
end
|
43
|
+
|
44
|
+
def clear_test_dir
|
45
|
+
FileUtils.rm_r vitae_test_dir
|
46
|
+
end
|
47
|
+
|
48
|
+
def vitae_file? path
|
49
|
+
File.exist? ::File.expand_path(path, vitae_test_dir)
|
50
|
+
end
|
51
|
+
|
52
|
+
end
|
53
|
+
|
54
|
+
class VitaeServerTestCase < VitaeTestCase
|
55
|
+
include Rack::Test::Methods
|
56
|
+
|
57
|
+
def app
|
58
|
+
Server
|
59
|
+
end
|
60
|
+
|
61
|
+
def assert_matches matches, actual=last_response.body
|
62
|
+
matches.each do |match|
|
63
|
+
assert_match match, actual
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
def assert_select selector, content=nil, text=last_response.body
|
68
|
+
matches = Nokogiri::HTML.parse(text).css(selector)
|
69
|
+
assert(matches.size>0, "No matches for the selector '#{selector}'.")
|
70
|
+
if content
|
71
|
+
matches.each do |el|
|
72
|
+
return assert(true) if el.content.match content
|
73
|
+
end
|
74
|
+
assert(false, "No matches for '#{content}' with the selector '#{selector}'.")
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
require "test_helper"
|
2
|
+
|
3
|
+
class VitaeExecutableTest < VitaeTestCase
|
4
|
+
|
5
|
+
test "create gives help when called without args" do
|
6
|
+
output = vitae_create
|
7
|
+
assert_match('"create" was called incorrectly', output)
|
8
|
+
end
|
9
|
+
|
10
|
+
test "create generates a project" do
|
11
|
+
clear_test_dir
|
12
|
+
output = vitae_create("my_cvs")
|
13
|
+
|
14
|
+
files = %w[my_cvs/cvs/arthur_gunn.yaml
|
15
|
+
my_cvs/themes/default/application.js
|
16
|
+
my_cvs/themes/default/application.css]
|
17
|
+
|
18
|
+
files.each do |file|
|
19
|
+
assert(vitae_file?( file ), "#{file} should exist in #{vitae_test_dir}")
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
test "create generates a project with provided names" do
|
24
|
+
clear_test_dir
|
25
|
+
output = vitae_create("resume arthur_gunn derek sajal")
|
26
|
+
|
27
|
+
files = %w[resume/cvs/arthur_gunn.yaml
|
28
|
+
resume/cvs/derek.yaml
|
29
|
+
resume/cvs/sajal.yaml
|
30
|
+
resume/themes/default/application.js
|
31
|
+
resume/themes/default/application.css]
|
32
|
+
|
33
|
+
files.each do |file|
|
34
|
+
assert(vitae_file?( file ), "#{file} should exist in #{vitae_test_dir}")
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
test "the server responds well" do
|
39
|
+
assert_match("Serving CVs", vitae_server("--pretend"))
|
40
|
+
end
|
41
|
+
|
42
|
+
test "the server accepts a custom port" do
|
43
|
+
assert_match(":3141", vitae_server("--pretend"))
|
44
|
+
assert_match(":9292", vitae_server("--pretend -p 9292"))
|
45
|
+
assert_match(":1121", vitae_server("--pretend -p 1121"))
|
46
|
+
end
|
47
|
+
|
48
|
+
test "the server gives rackup help" do
|
49
|
+
assert_match("Usage: rackup", vitae_server("-h"))
|
50
|
+
end
|
51
|
+
|
52
|
+
end
|
data/vitae.gemspec
CHANGED
@@ -11,6 +11,12 @@ Gem::Specification.new do |s|
|
|
11
11
|
s.homepage = "https://github.com/gunn/vitae"
|
12
12
|
s.summary = %q{A structured CV publishing system.}
|
13
13
|
s.description = %q{Vitae is to CVs what rubygems is to ruby code. Now I just need to program it.}
|
14
|
+
|
15
|
+
s.add_dependency "sinatra"
|
16
|
+
s.add_dependency "haml"
|
17
|
+
s.add_dependency "thor"
|
18
|
+
|
19
|
+
s.add_development_dependency "nokogiri"
|
14
20
|
|
15
21
|
s.files = `git ls-files`.split("\n")
|
16
22
|
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
metadata
CHANGED
@@ -5,9 +5,9 @@ version: !ruby/object:Gem::Version
|
|
5
5
|
prerelease: false
|
6
6
|
segments:
|
7
7
|
- 0
|
8
|
+
- 1
|
8
9
|
- 0
|
9
|
-
|
10
|
-
version: 0.0.2
|
10
|
+
version: 0.1.0
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Arthur Gunn
|
@@ -15,26 +15,101 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2010-12-
|
18
|
+
date: 2010-12-04 00:00:00 +13:00
|
19
19
|
default_executable:
|
20
|
-
dependencies:
|
21
|
-
|
20
|
+
dependencies:
|
21
|
+
- !ruby/object:Gem::Dependency
|
22
|
+
name: sinatra
|
23
|
+
prerelease: false
|
24
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ">="
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
hash: 3
|
30
|
+
segments:
|
31
|
+
- 0
|
32
|
+
version: "0"
|
33
|
+
type: :runtime
|
34
|
+
version_requirements: *id001
|
35
|
+
- !ruby/object:Gem::Dependency
|
36
|
+
name: haml
|
37
|
+
prerelease: false
|
38
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
39
|
+
none: false
|
40
|
+
requirements:
|
41
|
+
- - ">="
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
hash: 3
|
44
|
+
segments:
|
45
|
+
- 0
|
46
|
+
version: "0"
|
47
|
+
type: :runtime
|
48
|
+
version_requirements: *id002
|
49
|
+
- !ruby/object:Gem::Dependency
|
50
|
+
name: thor
|
51
|
+
prerelease: false
|
52
|
+
requirement: &id003 !ruby/object:Gem::Requirement
|
53
|
+
none: false
|
54
|
+
requirements:
|
55
|
+
- - ">="
|
56
|
+
- !ruby/object:Gem::Version
|
57
|
+
hash: 3
|
58
|
+
segments:
|
59
|
+
- 0
|
60
|
+
version: "0"
|
61
|
+
type: :runtime
|
62
|
+
version_requirements: *id003
|
63
|
+
- !ruby/object:Gem::Dependency
|
64
|
+
name: nokogiri
|
65
|
+
prerelease: false
|
66
|
+
requirement: &id004 !ruby/object:Gem::Requirement
|
67
|
+
none: false
|
68
|
+
requirements:
|
69
|
+
- - ">="
|
70
|
+
- !ruby/object:Gem::Version
|
71
|
+
hash: 3
|
72
|
+
segments:
|
73
|
+
- 0
|
74
|
+
version: "0"
|
75
|
+
type: :development
|
76
|
+
version_requirements: *id004
|
22
77
|
description: Vitae is to CVs what rubygems is to ruby code. Now I just need to program it.
|
23
78
|
email:
|
24
79
|
- arthur@gunn.co.nz
|
25
|
-
executables:
|
26
|
-
|
80
|
+
executables:
|
81
|
+
- vitae
|
27
82
|
extensions: []
|
28
83
|
|
29
84
|
extra_rdoc_files: []
|
30
85
|
|
31
86
|
files:
|
87
|
+
- .autotest
|
32
88
|
- .gitignore
|
33
89
|
- Gemfile
|
90
|
+
- Gemfile.lock
|
34
91
|
- README.rdoc
|
35
92
|
- Rakefile
|
93
|
+
- bin/vitae
|
94
|
+
- config.ru
|
36
95
|
- lib/vitae.rb
|
96
|
+
- lib/vitae/cv.rb
|
97
|
+
- lib/vitae/server/.gitignore
|
98
|
+
- lib/vitae/server/helpers.rb
|
99
|
+
- lib/vitae/server/server.rb
|
100
|
+
- lib/vitae/server/views/index.haml
|
101
|
+
- lib/vitae/server/views/layout.haml
|
102
|
+
- lib/vitae/server/views/show.haml
|
103
|
+
- lib/vitae/templates/cvs/arthur_gunn.yaml
|
104
|
+
- lib/vitae/templates/cvs/default.yaml.tt
|
105
|
+
- lib/vitae/templates/themes/default/application.css
|
106
|
+
- lib/vitae/templates/themes/default/application.js
|
37
107
|
- lib/vitae/version.rb
|
108
|
+
- test/active_server_test.rb
|
109
|
+
- test/basic_server_test.rb
|
110
|
+
- test/tag_helpers_test.rb
|
111
|
+
- test/test_helper.rb
|
112
|
+
- test/vitae_executable_test.rb
|
38
113
|
- vitae.gemspec
|
39
114
|
has_rdoc: true
|
40
115
|
homepage: https://github.com/gunn/vitae
|
@@ -70,5 +145,9 @@ rubygems_version: 1.3.7
|
|
70
145
|
signing_key:
|
71
146
|
specification_version: 3
|
72
147
|
summary: A structured CV publishing system.
|
73
|
-
test_files:
|
74
|
-
|
148
|
+
test_files:
|
149
|
+
- test/active_server_test.rb
|
150
|
+
- test/basic_server_test.rb
|
151
|
+
- test/tag_helpers_test.rb
|
152
|
+
- test/test_helper.rb
|
153
|
+
- test/vitae_executable_test.rb
|