jeremylightsmith-actionsite 0.1 → 0.3

Sign up to get free protection for your applications and to get access to all the features.
data/Rakefile CHANGED
@@ -3,7 +3,7 @@ $LOAD_PATH << File.expand_path(File.dirname(__FILE__) + "/lib")
3
3
  require 'action_site'
4
4
  require 'spec/rake/spectask'
5
5
 
6
- task :default => [:spec, :example]
6
+ task :default => [:spec, :gemspec, :example]
7
7
 
8
8
  Spec::Rake::SpecTask.new(:spec) do |t|
9
9
  t.spec_files = FileList['spec/**/*_spec.rb']
data/lib/action_site.rb CHANGED
@@ -15,3 +15,8 @@ require 'yaml'
15
15
  require 'action_site/extensions/string'
16
16
 
17
17
  require 'action_site/site'
18
+ require 'action_site/link_checker'
19
+
20
+ module ActionSite
21
+ VERSION = 0.3
22
+ end
@@ -4,7 +4,7 @@ module ActionSite
4
4
  def process(context, content)
5
5
  builder = Markaby::Builder.new({}, context)
6
6
  builder.instance_eval content, context.file_name
7
- content = builder.to_s
7
+ builder.to_s
8
8
  end
9
9
  end
10
10
  end
@@ -3,7 +3,7 @@ module ActionSite
3
3
  class RedclothGenerator
4
4
  def process(context, content)
5
5
  redcloth = RedCloth.new(content)
6
- content = redcloth.to_html(:html, :textile)
6
+ redcloth.to_html(:html, :textile)
7
7
  end
8
8
  end
9
9
  end
@@ -2,7 +2,7 @@ module ActionSite
2
2
  module Generators
3
3
  class YamlGenerator
4
4
  def process(context, content)
5
- content = YAML::load(content) rescue raise("error reading #{context.file_name}: #{$!.message}")
5
+ YAML::load(content) rescue raise("error reading #{context.file_name}: #{$!.message}")
6
6
  end
7
7
  end
8
8
  end
@@ -4,8 +4,9 @@ module ActionSite
4
4
  class HtmlGenerator
5
5
  attr_reader :template_directory
6
6
 
7
- def initialize(site_context, template_directory)
8
- @site_context, @template_directory = site_context, template_directory
7
+ def initialize(site_context, template_directory, generators)
8
+ @site_context, @template_directory, @generators =
9
+ site_context, template_directory, generators
9
10
  end
10
11
 
11
12
  def process_file(file, context = new_context(file), apply_layout = true)
@@ -18,7 +19,7 @@ module ActionSite
18
19
  def process(file_name, context, content, apply_layout = true)
19
20
  file_name, extension = file_name.split_filename
20
21
 
21
- generator = ActionSite.generators[extension]
22
+ generator = @generators[extension]
22
23
  if generator
23
24
  content = generator.process(context, content)
24
25
 
@@ -0,0 +1,106 @@
1
+ require 'rubygems'
2
+ require 'hpricot'
3
+ require 'net/http'
4
+ require 'uri'
5
+
6
+ module ActionSite
7
+ class LinkChecker
8
+ def initialize(options = {})
9
+ @options = options
10
+ @checked_urls = []
11
+ end
12
+
13
+ def check(url, host = nil, indent = "")
14
+ url = url.sub(/\#.*/, '')
15
+ return if url.blank?
16
+ return if @options[:local] && host && !local?(host, url)
17
+ return if @checked_urls.include?(url)
18
+ @checked_urls << url
19
+
20
+ puts "#{indent}checking #{url}"
21
+
22
+ begin
23
+ url, html = fetch(url)
24
+ rescue
25
+ puts "#{url} not found"
26
+ raise
27
+ end
28
+
29
+ host ||= host_for(url)
30
+ doc = Hpricot(html)
31
+
32
+ if local?(host, url)
33
+ (doc / "a").each do |link|
34
+ if child_link = expand_link(url, link["href"])
35
+ begin
36
+ check child_link, host, indent + " "
37
+ rescue
38
+ puts "from #{url} as #{link}"
39
+ raise
40
+ end
41
+ end
42
+ end
43
+ end
44
+ end
45
+
46
+ def expand_link(from, to)
47
+ case to
48
+ when nil
49
+ nil
50
+ when /^mailto:.+\@.+\..+/
51
+ nil
52
+ when /^https?\:\/\//
53
+ to
54
+ when /^\//
55
+ File.join(host_for(from), to)
56
+ else
57
+ relative_link(from, to)
58
+ end
59
+ end
60
+
61
+ def relative_link(from, to)
62
+ from += "." if from.ends_with?("/")
63
+
64
+ from = from.split("/")
65
+ to = to.split("/")
66
+
67
+ from.pop
68
+
69
+ while to[0] == ".."
70
+ to.shift
71
+ from.pop
72
+ end
73
+
74
+ while to[0] == "."
75
+ to.shift
76
+ end
77
+
78
+ (from + to).join("/")
79
+ end
80
+
81
+ def fetch(url, limit = 10)
82
+ # You should choose better exception.
83
+ raise ArgumentError, 'HTTP redirect too deep' if limit == 0
84
+
85
+ response = Net::HTTP.get_response(URI.parse(url))
86
+ case response
87
+ when Net::HTTPSuccess then [url, response.body]
88
+ when Net::HTTPRedirection then fetch(response['location'], limit - 1)
89
+ else
90
+ response.error!
91
+ end
92
+ end
93
+
94
+ def host_for(url)
95
+ if url =~ /^(https?\:\/\/[^\/]+\/)/
96
+ $1
97
+ else
98
+ raise "don't know how to get the host for #{url}"
99
+ end
100
+ end
101
+
102
+ def local?(host, url)
103
+ url.starts_with?(host)
104
+ end
105
+ end
106
+ end
@@ -17,6 +17,7 @@ module ActionSite
17
17
  @html_generator, @global_context, @file_name =
18
18
  html_generator, global_context, file_name
19
19
  layout(:application) rescue nil
20
+ helper(:application, false)
20
21
  end
21
22
 
22
23
  def layout(name)
@@ -33,17 +34,18 @@ module ActionSite
33
34
  @html_generator.process_file(*args)
34
35
  end
35
36
 
36
- def helper(name)
37
+ def helper(name, assert_loaded = true)
37
38
  file_name = "#{name}_helper"
39
+ fully_qualified_file = File.join(@html_generator.template_directory, "helpers", file_name + ".rb")
40
+ return unless File.exist?(fully_qualified_file) || assert_loaded
41
+
38
42
  class_name = file_name.classify
39
- helper = begin
40
- class_name.constantize
41
- rescue NameError # this constant hasn't been loaded yet
42
- require File.join(@html_generator.template_directory, "helpers", file_name)
43
- class_name.constantize
43
+ if Object.const_defined?(class_name)
44
+ Object.send(:remove_const, class_name)
44
45
  end
45
-
46
- metaclass.send(:include, helper)
46
+
47
+ load fully_qualified_file
48
+ metaclass.send(:include, class_name.constantize)
47
49
  end
48
50
 
49
51
  def content_for(name)
@@ -9,30 +9,32 @@ require 'action_site/generators/yaml_generator'
9
9
 
10
10
  module ActionSite
11
11
  EXCLUDED_DIRECTORIES = %w(layouts helpers)
12
- RESOURCE_EXTENSIONS = %w(css ico gif jpg png js)
13
-
14
- def self.generators
15
- @generators ||= {
16
- "erb" => Generators::ErbGenerator.new,
17
- "mab" => Generators::MarkabyGenerator.new,
18
- "red" => Generators::RedclothGenerator.new,
19
- "yml" => Generators::YamlGenerator.new,
20
- "yaml" => Generators::YamlGenerator.new
21
- }
22
- end
23
-
12
+ RESOURCE_EXTENSIONS = %w(css ico gif jpg png js pdf)
13
+ DEFAULT_GENERATORS = {
14
+ "erb" => Generators::ErbGenerator.new,
15
+ "mab" => Generators::MarkabyGenerator.new,
16
+ "red" => Generators::RedclothGenerator.new,
17
+ "yml" => Generators::YamlGenerator.new,
18
+ "yaml" => Generators::YamlGenerator.new
19
+ }
20
+
24
21
  class Site
25
22
  attr_reader :context
26
-
23
+
27
24
  def initialize(in_dir, out_dir)
28
25
  @context = Context.new
29
- @generator = HtmlGenerator.new(@context, in_dir)
26
+ @generator = HtmlGenerator.new(@context, in_dir, generators)
30
27
  @in_dir, @out_dir = in_dir, out_dir
31
28
  puts "\nGENERATING #{File.basename(in_dir).upcase}\n\n"
32
29
  rm_rf out_dir
33
30
  mkdir_p out_dir
34
31
  end
35
32
 
33
+ # add / remove / change generators to change the behavior of the html generation
34
+ def generators
35
+ @generators ||= DEFAULT_GENERATORS.dup
36
+ end
37
+
36
38
  def generate(in_dir = @in_dir, out_dir = @out_dir)
37
39
  Dir[in_dir + "/*"].each do |in_file|
38
40
  out_file = in_file.gsub(in_dir, out_dir)
@@ -5,12 +5,14 @@ describe ActionSite::HtmlGenerator do
5
5
  attr_reader :generator
6
6
 
7
7
  before do
8
- @generator = ActionSite::HtmlGenerator.new(ActionSite::Context.new, sandbox.root)
8
+ @generator = ActionSite::HtmlGenerator.new(ActionSite::Context.new,
9
+ sandbox.root,
10
+ ActionSite::DEFAULT_GENERATORS)
9
11
  end
10
12
 
11
13
  describe "default generators" do
12
14
  it "should have erb, mab, yaml, red" do
13
- ActionSite.generators.keys.sort.should == %w(erb mab red yaml yml)
15
+ ActionSite::DEFAULT_GENERATORS.keys.sort.should == %w(erb mab red yaml yml)
14
16
  end
15
17
  end
16
18
 
@@ -55,6 +57,15 @@ describe ActionSite::HtmlGenerator do
55
57
  'hello world'
56
58
  end
57
59
  end"
60
+
61
+ sandbox.new :file => 'helpers/application_helper.rb',
62
+ :with_contents => "
63
+ module ApplicationHelper
64
+ def bob
65
+ 'the builder'
66
+ end
67
+ end"
68
+
58
69
  sandbox.new :file => "layouts/application.html.erb",
59
70
  :with_contents => "<%= content %>"
60
71
  end
@@ -63,6 +74,25 @@ describe ActionSite::HtmlGenerator do
63
74
  process("*.html.erb", "% helper 'test'\n<%= some_test_method %>").
64
75
  should == "hello world"
65
76
  end
77
+
78
+ it "should allow multiple helpers with same name between sites" do
79
+ process("*.html.erb", "<%= bob %>").should == "the builder"
80
+
81
+ sandbox.new :file => 'helpers/application_helper.rb',
82
+ :with_contents => "
83
+ module ApplicationHelper
84
+ def jack
85
+ 'the bricklayer'
86
+ end
87
+ end"
88
+
89
+ process("*.html.erb", "<%= jack %>").should == "the bricklayer"
90
+ proc {process("*.html.erb", "<%= bob %>")}.should raise_error
91
+ end
92
+
93
+ it "should include application_helper.rb if it is there" do
94
+ process("*.html.erb", "<%= bob %>").should == "the builder"
95
+ end
66
96
  end
67
97
 
68
98
  describe "content_for" do
@@ -0,0 +1,40 @@
1
+ require File.dirname(__FILE__) + '/../spec_helper'
2
+
3
+ describe ActionSite::LinkChecker do
4
+ attr_reader :links
5
+
6
+ before do
7
+ @links = ActionSite::LinkChecker.new
8
+ end
9
+
10
+ it "should calculate correct links" do
11
+ expand_link("http://localhost/bob", "http://google.com").should == "http://google.com"
12
+ expand_link("http://localhost/bob", "http://google.com").should == "http://google.com"
13
+ expand_link("http://localhost/bob", "george").should == "http://localhost/george"
14
+ expand_link("http://localhost/bob/", "george").should == "http://localhost/bob/george"
15
+ expand_link("http://localhost/bob/", ".").should == "http://localhost/bob"
16
+ expand_link("http://localhost/bob", ".").should == "http://localhost"
17
+ expand_link("http://localhost/bob", "..").should == "http:/"
18
+ expand_link("http://localhost/bob/", "..").should == "http://localhost"
19
+ expand_link("http://localhost/a/blues_hero/", "/register.html").should == "http://localhost/register.html"
20
+ end
21
+
22
+ it "should find get redirects" do
23
+ url, html = links.fetch("http://google.com")
24
+
25
+ url.should == "http://www.google.com/"
26
+ end
27
+
28
+ it "should find host for urls" do
29
+ links.host_for("http://foo.bar:3000/").should == "http://foo.bar:3000/"
30
+ links.host_for("http://google.com/").should == "http://google.com/"
31
+ links.host_for("https://google.com/").should == "https://google.com/"
32
+ links.host_for("http://google.com/a/b/c").should == "http://google.com/"
33
+ links.host_for("https://google.com/a/b/c").should == "https://google.com/"
34
+ proc {links.host_for("foo")}.should raise_error
35
+ end
36
+
37
+ def expand_link(from, to)
38
+ links.expand_link(from, to)
39
+ end
40
+ end
@@ -2,10 +2,14 @@ require File.dirname(__FILE__) + '/../spec_helper'
2
2
 
3
3
  module ActionSite
4
4
  describe PageContext do
5
+ include FileSandbox
5
6
  attr_reader :context
6
7
 
7
8
  before do
8
- @context = PageContext.new(nil, nil, nil)
9
+ @generator = ActionSite::HtmlGenerator.new(ActionSite::Context.new,
10
+ sandbox.root,
11
+ ActionSite::DEFAULT_GENERATORS)
12
+ @context = @generator.new_context(nil)
9
13
  end
10
14
 
11
15
  it "should allow setting new variables and accessing them" do
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: jeremylightsmith-actionsite
3
3
  version: !ruby/object:Gem::Version
4
- version: "0.1"
4
+ version: "0.3"
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jeremy Lightsmith
@@ -64,6 +64,7 @@ files:
64
64
  - lib/action_site/helpers/markaby_helper.rb
65
65
  - lib/action_site/helpers/url_helper.rb
66
66
  - lib/action_site/html_generator.rb
67
+ - lib/action_site/link_checker.rb
67
68
  - lib/action_site/page_context.rb
68
69
  - lib/action_site/site.rb
69
70
  - lib/action_site.rb
@@ -133,5 +134,6 @@ test_files:
133
134
  - spec/action_site/helpers/form_helper_spec.rb
134
135
  - spec/action_site/helpers/url_helper_spec.rb
135
136
  - spec/action_site/html_generator_spec.rb
137
+ - spec/action_site/link_checker_spec.rb
136
138
  - spec/action_site/page_context_spec.rb
137
139
  - spec/spec_helper.rb