piano 0.9.0 → 0.10.1

Sign up to get free protection for your applications and to get access to all the features.
data/bin/piano CHANGED
@@ -43,11 +43,11 @@ end
43
43
  require "piano"
44
44
 
45
45
  if args
46
- Piano.port = args[:port] if args[:port]
47
- Piano.environment = args[:environment] if args[:environment]
48
- Piano.etags = args[:etags] if args[:etags]
49
- Piano.views = File.expand_path(Dir.pwd) + "/" +args[:views] if args[:views]
50
- Piano.public = File.expand_path(Dir.pwd) + "/" + args[:public] if args[:public]
46
+ Piano::Base.port = args[:port] if args[:port]
47
+ Piano::Base.environment = args[:environment] if args[:environment]
48
+ Piano::Base.etags = args[:etags] if args[:etags]
49
+ Piano::Base.views = File.expand_path(Dir.pwd) + "/" +args[:views] if args[:views]
50
+ Piano::Base.public = File.expand_path(Dir.pwd) + "/" + args[:public] if args[:public]
51
51
  end
52
52
 
53
53
  def make_sample
@@ -61,7 +61,7 @@ def make_sample
61
61
  end
62
62
 
63
63
  self.extend Metafun::Delegator
64
- self.delegate Piano, :get, :patch, :put, :post, :delete,
64
+ self.delegate Piano::Base, :get, :patch, :put, :post, :delete,
65
65
  :head, :options, :template, :layout,
66
66
  :before, :after, :error, :not_found,
67
67
  :configure, :set, :mime_type, :enable,
@@ -73,14 +73,15 @@ self.helpers Sinatra::Piano
73
73
  $LOAD_PATH << Dir.pwd
74
74
 
75
75
  if File.exists?(File.expand_path(Dir.pwd) + "/Pianofile")
76
- piano_file = File.expand_path(Dir.pwd) + "/Pianofile"
77
76
  puts "Pianofile found, loading..."
78
- load piano_file
77
+ load File.expand_path(Dir.pwd) + "/Pianofile"
79
78
  end
80
- if File.exists?(File.expand_path(Dir.pwd) + "/.piano") # Deprecate soon
81
- load File.expand_path(Dir.pwd) + "/.piano"
79
+
80
+ if Dir.exist? "controllers"
81
+ puts "'controllers' directory found, loading '.controller' files"
82
+ Piano::ControllerLoader.folder "controllers"
82
83
  end
83
84
 
84
85
  require "piano/routes"
85
86
 
86
- Piano.play!
87
+ Piano::Base.play!
@@ -13,7 +13,13 @@ rescue Exception => error
13
13
  end
14
14
 
15
15
  module Sinatra
16
+
17
+ # Piano was originally though as a Sinatra extension
18
+ # That's why the code was defined here
16
19
  module Piano
20
+
21
+ # Like Sinatra's/Tilt's `haml`, but adds etags and
22
+ # returns a 404 with some hints if the haml is not found
17
23
  def try_haml(template)
18
24
  file_name = "#{pwd}/#{template}.haml"
19
25
  bad_luck file_name unless File.exists? file_name
@@ -26,6 +32,9 @@ module Sinatra
26
32
  haml template.to_sym
27
33
  end
28
34
 
35
+ # Loads and parses a `sass` template from the :views directory.
36
+ # Adds an etag if `etags?` is enabled and returns 404 and hints
37
+ # if it can't find the .sass file.
29
38
  def sass(template)
30
39
  file_name = "#{pwd}/#{template}.sass"
31
40
  bad_luck file_name unless File.exists? file_name
@@ -34,6 +43,10 @@ module Sinatra
34
43
  Sass.compile File.read(file_name), :syntax => :sass
35
44
  end
36
45
 
46
+ # Loads and parses a `coffee-script` template from the :views
47
+ # directory.
48
+ # Adds an etag if `etags?` is enabled and returns 404 and hints
49
+ # if it can't find the .coffee file.
37
50
  def coffee(template)
38
51
  file_name = "#{pwd}/#{template}.coffee"
39
52
  bad_luck file_name unless File.exists? file_name
@@ -42,23 +55,31 @@ module Sinatra
42
55
  CoffeeScript.compile(File.read(file_name))
43
56
  end
44
57
 
58
+ # Loads and parses the YAML data from the data directory
45
59
  def data_for(template)
46
60
  file_name = "#{pwd}/data/#{template}.yaml"
47
61
  YAML.load_file(file_name) if File.exists?(file_name)
48
62
  end
49
63
 
64
+ # Sugar: formats a css stylesheet <link /> tag with the input
50
65
  def style(path)
51
66
  "<link rel='stylesheet' type='text/css' href='#{path}' />"
52
67
  end
53
68
 
69
+ # Sugar: formats a javascript <script> tag with the input
54
70
  def script(path)
55
71
  "<script type='text/javascript' src='#{path}'></script>"
56
72
  end
57
73
 
74
+ # Returns the path to the :views directory
58
75
  def pwd
59
76
  settings.views
60
77
  end
61
78
 
79
+ # Fails. Shouts a 404 response and prints hints
80
+ #
81
+ # If Piano is running in production mode, prints a plain 404 html
82
+ # or, if a 404.haml exists in the :views directory, returns it
62
83
  def bad_luck(path)
63
84
  content_type :html
64
85
  if settings.environment == :production
@@ -73,16 +94,43 @@ module Sinatra
73
94
  end
74
95
  end
75
96
 
97
+ # Builds a hash for a file within the :views directory
98
+ # Note: I feel like this functionality should be private
76
99
  def hash_for(name, type)
77
100
  "#{name}.#{type} - " + File.mtime("#{pwd}/#{name}.#{type}").to_s
78
101
  end
79
102
 
103
+ # Makes an extract out of the given text with the default length
104
+ # of 80 words
105
+ #
106
+ # If an integer is passed as the second argument, the length
107
+ # of the result is adjusted properly:
108
+ #
109
+ # extract "Hello World! Too much text is inconvenient", 2
110
+ #
111
+ # returns
112
+ #
113
+ # => "Hello World!..."
114
+ #
80
115
  def extract(text, length = 80)
81
116
  words = text.gsub(/<.+?>/, "").split
82
117
  return text if words.length <= length
83
118
  words[0..(length-1)].join(" ") + "..."
84
119
  end
85
120
 
121
+ # Returns a url-friendly version of the given link, with a
122
+ # default maximum of 5 words.
123
+ # `link` strips any non-letter or special character, downcases the
124
+ # string and replaces whitespace with "-"
125
+ # For example:
126
+ #
127
+ # link "This is a special text! This won't be shown"
128
+ #
129
+ # returns
130
+ #
131
+ # => "this-is-a-special-text"
132
+ #
133
+ # You can specify a word length in the second argument.
86
134
  def link(text, length = 5)
87
135
  words = text
88
136
  .gsub(/<.+?>/, "")
@@ -93,6 +141,7 @@ module Sinatra
93
141
  words[0..(length-1)].join("-")
94
142
  end
95
143
 
144
+ # Shorthand to settings.etags == :on
96
145
  def etags?
97
146
  if settings.respond_to? :etags
98
147
  settings.etags == :on
@@ -101,6 +150,7 @@ module Sinatra
101
150
  end
102
151
  end
103
152
 
153
+ # Non implemented yet
104
154
  def t(key)
105
155
  I18n.translate key
106
156
  end
@@ -110,29 +160,30 @@ module Sinatra
110
160
  end
111
161
 
112
162
 
113
-
114
- class Piano < Sinatra::Base
115
- register Sinatra::Piano
116
-
117
- set :root, File.expand_path(Dir.pwd)
118
- set :views, File.expand_path(Dir.pwd)
119
- set :etags, :on
120
- set :i18n_path, File.expand_path(Dir.pwd) + "/config/locale"
121
-
122
- def self.i18n!
123
- return unless Dir.exists? self.i18n_path
124
- dir = Dir.new self.i18n_path
125
- i18n_files = []
126
- dir.each do |file|
127
- if file.end_with?(".yml") or file.end_with?(".yaml")
128
- i18n_files << "#{dir.path}/#{file}"
163
+ module Piano
164
+ class Base < Sinatra::Base
165
+ register Sinatra::Piano
166
+
167
+ set :root, File.expand_path(Dir.pwd)
168
+ set :views, File.expand_path(Dir.pwd)
169
+ set :etags, :on
170
+ set :i18n_path, File.expand_path(Dir.pwd) + "/config/locale"
171
+
172
+ def self.i18n!
173
+ return unless Dir.exists? self.i18n_path
174
+ dir = Dir.new self.i18n_path
175
+ i18n_files = []
176
+ dir.each do |file|
177
+ if file.end_with?(".yml") or file.end_with?(".yaml")
178
+ i18n_files << "#{dir.path}/#{file}"
179
+ end
129
180
  end
181
+ I18n.load_path = i18n_files
182
+ end
183
+
184
+ def self.play!
185
+ self.run!
130
186
  end
131
- I18n.load_path = i18n_files
132
- end
133
-
134
- def self.play!
135
- self.run!
136
187
  end
137
188
  end
138
189
 
@@ -1,11 +1,42 @@
1
1
  require "polyglot"
2
+ require "rspec"
2
3
 
3
- class Piano
4
- class ControllerLoader
4
+ include RSpec::Matchers
5
+
6
+ module Piano
7
+ # Controller loader especifically for polyglot
8
+ class PolyglotControllerLoader
9
+ # Loads the file, no more settings for the moment
5
10
  def self.load filename, options = nil, &block
6
11
  Kernel.eval File.read filename
7
12
  end
8
13
  end
14
+
15
+ # Handler of .controller files loading
16
+ class ControllerLoader
17
+ def self.folder path
18
+ $LOAD_PATH << Dir.pwd
19
+ recursive path do |item|
20
+ require item
21
+ end
22
+ end
23
+
24
+ # Iterates recursively over the path and calls the block
25
+ # with each newfound file
26
+ def self.recursive path, &block
27
+ files = []
28
+ Dir.new(File.expand_path(path)).each do |file|
29
+ if File.directory? "#{path}/#{file}"
30
+ recursive "#{path}/#{file}" do |item|
31
+ files << "#{item}"
32
+ end unless file == ".." or file == "."
33
+ elsif file.end_with? ".controller"
34
+ files << "#{path}/#{file[0..-12]}"
35
+ end
36
+ end
37
+ files.each { |item| block.call(item) }
38
+ end
39
+ end
9
40
  end
10
41
 
11
- Polyglot.register "controller", Piano::ControllerLoader
42
+ Polyglot.register "controller", Piano::PolyglotControllerLoader
@@ -1,22 +1,24 @@
1
- class Piano
2
- get "/" do
3
- @data = data_for "index"
4
- try_haml "index"
5
- end
6
-
7
- get %r{/(.+?).css$} do |something|
8
- content_type :css
9
- sass something
10
- end
11
-
12
- get %r{/(.+?).js$} do |something|
13
- content_type :js
14
- coffee something
15
- end
16
-
17
- get "/*" do
18
- something = request.path[1..(request.path.length-1)]
19
- @data = data_for something
20
- try_haml something
1
+ module Piano
2
+ class Base
3
+ get "/" do
4
+ @data = data_for "index"
5
+ try_haml "index"
6
+ end
7
+
8
+ get %r{/(.+?).css$} do |something|
9
+ content_type :css
10
+ sass something
11
+ end
12
+
13
+ get %r{/(.+?).js$} do |something|
14
+ content_type :js
15
+ coffee something
16
+ end
17
+
18
+ get "/*" do
19
+ something = request.path[1..(request.path.length-1)]
20
+ @data = data_for something
21
+ try_haml something
22
+ end
21
23
  end
22
24
  end
@@ -1,3 +1,3 @@
1
1
  module Piano
2
- VERSION = "0.9.0"
2
+ VERSION = "0.10.1"
3
3
  end
@@ -21,6 +21,8 @@ Gem::Specification.new do |s|
21
21
  s.add_dependency "polyglot", ">= 0.3.1"
22
22
  s.add_dependency "metafun"
23
23
 
24
+ s.add_development_dependency "rspec"
25
+
24
26
  s.files = `git ls-files`.split("\n")
25
27
  s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
26
28
  s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
@@ -0,0 +1,90 @@
1
+ require "piano/controllerloader"
2
+
3
+ describe Piano::ControllerLoader do
4
+ context "there are some files in the folder" do
5
+ before :all do
6
+ if Dir.exist? "controllers"
7
+ puts "#{File.expand_path('controllers')} should not exist for this to run"
8
+ Process.exit!
9
+ end
10
+
11
+ FileUtils.mkdir "controllers"
12
+ File.open "controllers/demo.controller", "w" do |file|
13
+ file.write <<-HOLA
14
+ def Piano.demo_was_loaded; true; end
15
+ HOLA
16
+ end
17
+
18
+ File.open "controllers/another.rb", "w" do |file|
19
+ file.write <<-HOLA2
20
+ def Piano.wrong!; true; end
21
+ HOLA2
22
+ end
23
+
24
+ FileUtils.mkdir "controllers/recursive"
25
+ FileUtils.mkdir "controllers/recursive/very"
26
+ File.open "controllers/recursive/very/demo2.controller", "w" do
27
+ |file|
28
+ file.write <<-HOLA3
29
+ def Piano.another_was_loaded; true; end
30
+ HOLA3
31
+ end
32
+ end
33
+
34
+ describe ".folder" do
35
+ context "files" do
36
+ before :all do
37
+ Piano::ControllerLoader.folder "controllers"
38
+ end
39
+
40
+ it "should include the demo file" do
41
+ Piano.demo_was_loaded.should be
42
+ end
43
+
44
+ it "should not include the .rb file" do
45
+ expect { Piano.wrong!
46
+ }.to raise_error(NoMethodError)
47
+ end
48
+
49
+ it "should include the in-folder file" do
50
+ Piano.another_was_loaded.should be
51
+ end
52
+ end
53
+
54
+ it "should not change $LOAD_PATH" do
55
+ expect { Piano::ControllerLoader.folder "controllers"
56
+ }.to change{ $LOAD_PATH.length }.by(1)
57
+ end
58
+ end
59
+
60
+ describe ".recursive" do
61
+ it "should contain the path to the demo file" do
62
+ flag = false
63
+ Piano::ControllerLoader.recursive "controllers" do |item|
64
+ flag = true if item == "controllers/demo"
65
+ end
66
+ flag.should be_true
67
+ end
68
+
69
+ it "should not contain the path to the .rb file" do
70
+ flag = false
71
+ Piano::ControllerLoader.recursive "controllers" do |item|
72
+ flag = true if item == "controllers/another"
73
+ end
74
+ flag.should_not be_true
75
+ end
76
+
77
+ it "should contain the path to the indented demo file" do
78
+ flag = false
79
+ Piano::ControllerLoader.recursive "controllers" do |item|
80
+ flag = true if item == "controllers/recursive/very/demo2"
81
+ end
82
+ flag.should be_true
83
+ end
84
+ end
85
+
86
+ after :all do
87
+ FileUtils.rm_r "controllers"
88
+ end
89
+ end
90
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: piano
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.9.0
4
+ version: 0.10.1
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,12 +9,12 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2011-10-12 00:00:00.000000000 -03:00
12
+ date: 2011-10-14 00:00:00.000000000 -03:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: sinatra
17
- requirement: &22896720 !ruby/object:Gem::Requirement
17
+ requirement: &22807344 !ruby/object:Gem::Requirement
18
18
  none: false
19
19
  requirements:
20
20
  - - ! '>='
@@ -22,10 +22,10 @@ dependencies:
22
22
  version: 1.2.6
23
23
  type: :runtime
24
24
  prerelease: false
25
- version_requirements: *22896720
25
+ version_requirements: *22807344
26
26
  - !ruby/object:Gem::Dependency
27
27
  name: haml
28
- requirement: &22896420 !ruby/object:Gem::Requirement
28
+ requirement: &22807044 !ruby/object:Gem::Requirement
29
29
  none: false
30
30
  requirements:
31
31
  - - ! '>='
@@ -33,10 +33,10 @@ dependencies:
33
33
  version: 3.1.1
34
34
  type: :runtime
35
35
  prerelease: false
36
- version_requirements: *22896420
36
+ version_requirements: *22807044
37
37
  - !ruby/object:Gem::Dependency
38
38
  name: sass
39
- requirement: &22896108 !ruby/object:Gem::Requirement
39
+ requirement: &22806768 !ruby/object:Gem::Requirement
40
40
  none: false
41
41
  requirements:
42
42
  - - ! '>='
@@ -44,10 +44,10 @@ dependencies:
44
44
  version: 3.1.1
45
45
  type: :runtime
46
46
  prerelease: false
47
- version_requirements: *22896108
47
+ version_requirements: *22806768
48
48
  - !ruby/object:Gem::Dependency
49
49
  name: coffee-script
50
- requirement: &22895832 !ruby/object:Gem::Requirement
50
+ requirement: &22806492 !ruby/object:Gem::Requirement
51
51
  none: false
52
52
  requirements:
53
53
  - - ! '>='
@@ -55,10 +55,10 @@ dependencies:
55
55
  version: 2.2.0
56
56
  type: :runtime
57
57
  prerelease: false
58
- version_requirements: *22895832
58
+ version_requirements: *22806492
59
59
  - !ruby/object:Gem::Dependency
60
60
  name: i18n
61
- requirement: &22895556 !ruby/object:Gem::Requirement
61
+ requirement: &22806216 !ruby/object:Gem::Requirement
62
62
  none: false
63
63
  requirements:
64
64
  - - ! '>='
@@ -66,10 +66,10 @@ dependencies:
66
66
  version: 0.6.0
67
67
  type: :runtime
68
68
  prerelease: false
69
- version_requirements: *22895556
69
+ version_requirements: *22806216
70
70
  - !ruby/object:Gem::Dependency
71
71
  name: polyglot
72
- requirement: &22895268 !ruby/object:Gem::Requirement
72
+ requirement: &22805940 !ruby/object:Gem::Requirement
73
73
  none: false
74
74
  requirements:
75
75
  - - ! '>='
@@ -77,10 +77,10 @@ dependencies:
77
77
  version: 0.3.1
78
78
  type: :runtime
79
79
  prerelease: false
80
- version_requirements: *22895268
80
+ version_requirements: *22805940
81
81
  - !ruby/object:Gem::Dependency
82
82
  name: metafun
83
- requirement: &22895016 !ruby/object:Gem::Requirement
83
+ requirement: &22805712 !ruby/object:Gem::Requirement
84
84
  none: false
85
85
  requirements:
86
86
  - - ! '>='
@@ -88,7 +88,18 @@ dependencies:
88
88
  version: '0'
89
89
  type: :runtime
90
90
  prerelease: false
91
- version_requirements: *22895016
91
+ version_requirements: *22805712
92
+ - !ruby/object:Gem::Dependency
93
+ name: rspec
94
+ requirement: &22805436 !ruby/object:Gem::Requirement
95
+ none: false
96
+ requirements:
97
+ - - ! '>='
98
+ - !ruby/object:Gem::Version
99
+ version: '0'
100
+ type: :development
101
+ prerelease: false
102
+ version_requirements: *22805436
92
103
  description: Out-of-the-box sinatra server for web site sketching using haml + sass
93
104
  + coffee-script
94
105
  email:
@@ -103,9 +114,6 @@ files:
103
114
  - README.rdoc
104
115
  - Rakefile
105
116
  - bin/piano
106
- - features/piano_i18n.feature
107
- - features/step_definitions/i18n_steps.rb
108
- - features/support/env.rb
109
117
  - lib/piano.rb
110
118
  - lib/piano/controllerloader.rb
111
119
  - lib/piano/routes.rb
@@ -115,6 +123,7 @@ files:
115
123
  - sample/data/index.yaml
116
124
  - sample/index.haml
117
125
  - sample/style.sass
126
+ - spec/controller_spec.rb
118
127
  has_rdoc: true
119
128
  homepage: http://github.com/xaviervia/piano
120
129
  licenses: []
@@ -1,28 +0,0 @@
1
- Feature: i18n
2
- In order to have internationalization in Piano
3
- As a Piano user
4
- I want to get it loaded and ready
5
-
6
- Scenario: Load the i18n
7
- Given I have installed the i18n gem
8
- When I require the i18n
9
- Then I have the I18n module in scope
10
-
11
- Scenario: Get an english translation
12
- Given I have the file "config/locale/en.yml"
13
- And I have the file "config/locale/es.yml"
14
- And the file "config/locale/en.yml" includes:
15
- """
16
- en:
17
- hello:
18
- world: 'Hello World!'
19
- """
20
- When I load the i18ns within "config/locale"
21
- And I set the locale as :en
22
- And I run the translation with "hello.world"
23
- Then I should get the translated "Hello World!"
24
-
25
- Scenario: Provide a helper
26
- Given everything is ok
27
- When execute instance.t "some.text"
28
- Then translation should match "translation missing"
@@ -1,52 +0,0 @@
1
- Given /I have installed the (.*?) gem$/ do |gem|
2
- Gem.available? gem
3
- end
4
-
5
- When /I require the (.*?)$/ do |file|
6
- Piano.should be_a(Class)
7
- end
8
-
9
- Then /I have the (.*?) module in scope/ do |class_name|
10
- klass = Module.const_get class_name
11
- klass.should be_a(Module)
12
- end
13
-
14
- Given /I have the file "([^"]*)"$/ do |file_path|
15
- @base_path = File.expand_path("../../../", __FILE__)
16
- file_name = "#{@base_path}/#{file_path}"
17
- File.should exist(file_name)
18
- end
19
-
20
- Given /the file "([^"]*)" includes:$/ do |file_path, content|
21
- file_content = File.read "#{@base_path}/#{file_path}"
22
- file_content.should == content
23
- end
24
-
25
- When /I load the i18ns within "([^"]*)"/ do |folder|
26
- Piano.i18n_path = folder
27
- Piano.i18n!
28
- end
29
-
30
- When /I set the locale as :(.*)/ do |locale_string|
31
- I18n.locale = locale_string.to_sym
32
- end
33
-
34
- When /I run the translation with "([^"]*)"/ do |key|
35
- @translation = I18n.translate key
36
- end
37
-
38
- Then /I should get the translated "([^"]*)"/ do |translated|
39
- @translation.should == translated
40
- end
41
-
42
- Given /everything is ok/ do; end
43
-
44
- When /execute instance.t "([^"]*)"/ do |text|
45
- obj = Object.new
46
- obj.extend Sinatra::Piano::Helpers
47
- @translation = obj.t text
48
- end
49
-
50
- Then /translation should match "([^"]*)"/ do |text|
51
- @translation.should match(Regexp.new(text))
52
- end
@@ -1,3 +0,0 @@
1
- $LOAD_PATH << File.expand_path("../../../lib", __FILE__)
2
-
3
- require "piano"