piano 0.9.0 → 0.10.1

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/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"