danwrong-evil 0.1 → 0.1.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/CHANGELOG +1 -0
- data/LICENSE +22 -0
- data/Manifest +33 -7
- data/README.textile +20 -0
- data/Rakefile +21 -2
- data/assets/config.ru +10 -2
- data/assets/evil-lib.js +222 -0
- data/assets/evil.css +204 -10
- data/assets/evil.js +20 -0
- data/assets/logo.png +0 -0
- data/evil.gemspec +32 -19
- data/lib/evil/application.rb +85 -17
- data/lib/evil/extensions.rb +71 -0
- data/lib/evil/helpers.rb +62 -0
- data/lib/evil/models/config_pair.rb +7 -0
- data/lib/evil/models/template.rb +10 -9
- data/lib/evil/models.rb +0 -12
- data/lib/evil/open_id.rb +101 -0
- data/lib/evil/plugin/base.rb +56 -0
- data/lib/evil/plugin/configuration.rb +77 -0
- data/lib/evil/plugin/environment.rb +15 -0
- data/lib/evil/plugin/filesystem.rb +18 -0
- data/lib/evil/plugin/tag.rb +81 -0
- data/lib/evil/plugin.rb +21 -0
- data/lib/evil/setup/generator.rb +13 -1
- data/lib/evil/setup/migration.rb +4 -11
- data/lib/evil.rb +34 -1
- data/test/app/evil_test.rb +64 -0
- data/test/dev_env.rb +10 -0
- data/test/test_helper.rb +12 -0
- data/test/units/plugin/base_test.rb +47 -0
- data/test/units/plugin/tag_test.rb +108 -0
- data/views/_banner.haml +8 -0
- data/views/_errors.haml +9 -0
- data/views/index.haml +41 -0
- data/views/layout.haml +13 -0
- data/views/login.haml +5 -0
- data/views/plugins/_fields.haml +7 -0
- data/views/plugins/edit.haml +2 -0
- data/views/plugins/fields/_password.haml +3 -0
- data/views/plugins/fields/_text.haml +3 -0
- data/views/plugins/new.haml +6 -0
- data/views/templates/_fields.haml +23 -0
- data/views/templates/edit.haml +3 -0
- data/views/templates/new.haml +3 -0
- metadata +115 -13
- data/lib/evil/models/plugin.rb +0 -13
- data/test/harness/config.ru +0 -9
- data/test/harness/evil.db +0 -0
- data/test/harness/public/javascripts/evil.js +0 -0
- data/test/harness/public/stylesheets/evil.css +0 -24
- data/test/harness/tmp/restart.txt +0 -0
| @@ -0,0 +1,81 @@ | |
| 1 | 
            +
            module Evil
         | 
| 2 | 
            +
              module Plugin
         | 
| 3 | 
            +
                
         | 
| 4 | 
            +
                class TagExecution
         | 
| 5 | 
            +
                  
         | 
| 6 | 
            +
                  def initialize(tag, options, context, &block)
         | 
| 7 | 
            +
                    @options = evaluate(options, context)
         | 
| 8 | 
            +
                    @context = context
         | 
| 9 | 
            +
                    @tag = tag
         | 
| 10 | 
            +
                    @proc = block
         | 
| 11 | 
            +
                  end
         | 
| 12 | 
            +
                  
         | 
| 13 | 
            +
                  def body(locals={})
         | 
| 14 | 
            +
                    @context.stack do
         | 
| 15 | 
            +
                      locals.each { |k, v| @context[k.to_s] = v }
         | 
| 16 | 
            +
                      return @tag.render_body(@context).to_s
         | 
| 17 | 
            +
                    end
         | 
| 18 | 
            +
                  end
         | 
| 19 | 
            +
                  
         | 
| 20 | 
            +
                  def execute
         | 
| 21 | 
            +
                    self.instance_exec(@options, &@proc)
         | 
| 22 | 
            +
                  end
         | 
| 23 | 
            +
                  
         | 
| 24 | 
            +
                  def to_s
         | 
| 25 | 
            +
                    execute.to_s
         | 
| 26 | 
            +
                  end
         | 
| 27 | 
            +
                  
         | 
| 28 | 
            +
                  private
         | 
| 29 | 
            +
                  
         | 
| 30 | 
            +
                  def evaluate(options, context)
         | 
| 31 | 
            +
                    options.inject({}) do |evaluated, pair| 
         | 
| 32 | 
            +
                      opt, value = pair
         | 
| 33 | 
            +
                      evaluated[opt] = context[value]; evaluated
         | 
| 34 | 
            +
                    end
         | 
| 35 | 
            +
                  end
         | 
| 36 | 
            +
                end
         | 
| 37 | 
            +
                
         | 
| 38 | 
            +
                class Tag < Liquid::Block
         | 
| 39 | 
            +
                  Syntax = /((#{Liquid::TagAttributes}\s?,?\s?)*)/
         | 
| 40 | 
            +
                  
         | 
| 41 | 
            +
                  class << self
         | 
| 42 | 
            +
                    attr_accessor :tag_proc
         | 
| 43 | 
            +
                    attr_accessor :plugin
         | 
| 44 | 
            +
                    
         | 
| 45 | 
            +
                    def from(&block)
         | 
| 46 | 
            +
                      tag = Class.new(self)
         | 
| 47 | 
            +
                      tag.tag_proc = block; tag
         | 
| 48 | 
            +
                    end
         | 
| 49 | 
            +
                  end
         | 
| 50 | 
            +
             | 
| 51 | 
            +
                  def initialize(tag_name, markup, tokens)
         | 
| 52 | 
            +
                    super
         | 
| 53 | 
            +
                    
         | 
| 54 | 
            +
                    if markup =~ Syntax
         | 
| 55 | 
            +
                      @options = parse_options($1)
         | 
| 56 | 
            +
                    else
         | 
| 57 | 
            +
                      raise Liquid::SyntaxError.new("Syntax Error in tag '#{tagname}' - Valid syntax: #{tagname} [ opt : 'val', opt : 'val' ]")
         | 
| 58 | 
            +
                    end
         | 
| 59 | 
            +
                  end
         | 
| 60 | 
            +
                  
         | 
| 61 | 
            +
                  def render(context)
         | 
| 62 | 
            +
                    TagExecution.new(self, @options, context, &self.class.tag_proc).to_s
         | 
| 63 | 
            +
                  end
         | 
| 64 | 
            +
                  
         | 
| 65 | 
            +
                  def render_body(context)
         | 
| 66 | 
            +
                    render_all(@nodelist, context)
         | 
| 67 | 
            +
                  end
         | 
| 68 | 
            +
             | 
| 69 | 
            +
                  private
         | 
| 70 | 
            +
             | 
| 71 | 
            +
                  def parse_options(opt_string)
         | 
| 72 | 
            +
                    pairs = opt_string.split(',')
         | 
| 73 | 
            +
                    pairs.inject({}) do |opts, pair|
         | 
| 74 | 
            +
                      opt, value = pair.split(':')
         | 
| 75 | 
            +
                      opts[opt.strip.to_sym] = value.strip; opts
         | 
| 76 | 
            +
                    end
         | 
| 77 | 
            +
                  end
         | 
| 78 | 
            +
                end
         | 
| 79 | 
            +
                
         | 
| 80 | 
            +
              end
         | 
| 81 | 
            +
            end
         | 
    
        data/lib/evil/plugin.rb
    ADDED
    
    | @@ -0,0 +1,21 @@ | |
| 1 | 
            +
            module Evil
         | 
| 2 | 
            +
              module Plugin
         | 
| 3 | 
            +
                autoload :Base, 'evil/plugin/base'
         | 
| 4 | 
            +
                autoload :Tag, 'evil/plugin/tag'
         | 
| 5 | 
            +
                autoload :Environment, 'evil/plugin/environment'
         | 
| 6 | 
            +
                autoload :Filesystem, 'evil/plugin/filesystem'
         | 
| 7 | 
            +
                autoload :Configuration, 'evil/plugin/configuration'
         | 
| 8 | 
            +
                
         | 
| 9 | 
            +
                def self.evaluate(plugin_source)
         | 
| 10 | 
            +
                  Environment.module_eval plugin_source
         | 
| 11 | 
            +
                end
         | 
| 12 | 
            +
                
         | 
| 13 | 
            +
                def self.from_file(file)
         | 
| 14 | 
            +
                  evaluate(File.read(file))
         | 
| 15 | 
            +
                end
         | 
| 16 | 
            +
                
         | 
| 17 | 
            +
                def self.find_plugin(name)
         | 
| 18 | 
            +
                  Environment.plugins.find { |p| p.name == name }
         | 
| 19 | 
            +
                end
         | 
| 20 | 
            +
              end
         | 
| 21 | 
            +
            end
         | 
    
        data/lib/evil/setup/generator.rb
    CHANGED
    
    | @@ -1,6 +1,7 @@ | |
| 1 1 | 
             
            require 'fileutils'
         | 
| 2 2 | 
             
            require 'evil/models'
         | 
| 3 3 | 
             
            require 'evil/setup/migration'
         | 
| 4 | 
            +
            require 'digest/sha1'
         | 
| 4 5 |  | 
| 5 6 | 
             
            module Evil
         | 
| 6 7 | 
             
              module Setup
         | 
| @@ -14,11 +15,14 @@ module Evil | |
| 14 15 | 
             
                    public/images
         | 
| 15 16 | 
             
                    public/stylesheets
         | 
| 16 17 | 
             
                    public/javascripts
         | 
| 18 | 
            +
                    plugins
         | 
| 17 19 | 
             
                  }
         | 
| 18 20 |  | 
| 19 21 | 
             
                  ASSETS = [
         | 
| 20 22 | 
             
                    ['evil.css', 'public/stylesheets/evil.css'],
         | 
| 21 23 | 
             
                    ['evil.js', 'public/javascripts/evil.js'],
         | 
| 24 | 
            +
                    ['evil-lib.js', 'public/javascripts/evil-lib.js'],
         | 
| 25 | 
            +
                    ['logo.png', 'public/images/logo.png'],
         | 
| 22 26 | 
             
                    ['config.ru', 'config.ru']
         | 
| 23 27 | 
             
                  ]
         | 
| 24 28 |  | 
| @@ -30,12 +34,14 @@ module Evil | |
| 30 34 | 
             
                    puts "Generating Evil application..."
         | 
| 31 35 | 
             
                    create_dir_tree!
         | 
| 32 36 | 
             
                    copy_assets!
         | 
| 37 | 
            +
                    set_cookie_secret!
         | 
| 33 38 | 
             
                    puts "Initializing database..."
         | 
| 34 39 | 
             
                    create_database!
         | 
| 35 40 | 
             
                  end
         | 
| 36 41 |  | 
| 37 42 | 
             
                  def create_dir_tree!
         | 
| 38 43 | 
             
                    DIR_LAYOUT.each do |dir|
         | 
| 44 | 
            +
                      puts "Directory #{@path}/#{dir}"
         | 
| 39 45 | 
             
                      mkdir_p "#{@path}/#{dir}"
         | 
| 40 46 | 
             
                    end
         | 
| 41 47 | 
             
                  end
         | 
| @@ -51,10 +57,16 @@ module Evil | |
| 51 57 |  | 
| 52 58 | 
             
                  def copy_assets!
         | 
| 53 59 | 
             
                    ASSETS.each do |file, dest|
         | 
| 60 | 
            +
                      puts "File #{File.join(@path, dest)}"
         | 
| 54 61 | 
             
                      cp File.join(ASSET_PATH, file), File.join(@path, dest)
         | 
| 55 62 | 
             
                    end
         | 
| 56 63 | 
             
                  end
         | 
| 57 | 
            -
             | 
| 64 | 
            +
                  
         | 
| 65 | 
            +
                  def set_cookie_secret!
         | 
| 66 | 
            +
                    rackup = File.read(File.join(@path, 'config.ru'))
         | 
| 67 | 
            +
                    rackup.gsub!(/__SECRET__/, Digest::SHA1.hexdigest("__EVIL__#{Time.now.to_s}__#{rand(999999)}"))
         | 
| 68 | 
            +
                    File.open(File.join(@path, 'config.ru'), 'w') { |f| f.write(rackup) }
         | 
| 69 | 
            +
                  end
         | 
| 58 70 | 
             
                end
         | 
| 59 71 | 
             
              end
         | 
| 60 72 | 
             
            end
         | 
    
        data/lib/evil/setup/migration.rb
    CHANGED
    
    | @@ -8,27 +8,20 @@ module Evil | |
| 8 8 | 
             
                  def create_evil_tables
         | 
| 9 9 | 
             
                    create_table :evil_templates do |t|
         | 
| 10 10 | 
             
                      t.integer :ttl, :position
         | 
| 11 | 
            -
                      t.string  :title, :route
         | 
| 11 | 
            +
                      t.string  :title, :route, :content_type, :encoding
         | 
| 12 12 | 
             
                      t.text    :source
         | 
| 13 13 | 
             
                      t.timestamps
         | 
| 14 | 
            -
                    end unless Evil::Models::Template.table_exists?
         | 
| 15 | 
            -
                    
         | 
| 16 | 
            -
                    create_table :evil_plugins do |t|
         | 
| 17 | 
            -
                      t.string  :name, :description, :author
         | 
| 18 | 
            -
                      t.text    :source, :url
         | 
| 19 | 
            -
                      t.boolean :enabled
         | 
| 20 | 
            -
                      t.timestamps
         | 
| 21 | 
            -
                    end unless Evil::Models::Plugin.table_exists?
         | 
| 14 | 
            +
                    end unless Evil::Models::Template.table_exists? 
         | 
| 22 15 |  | 
| 23 16 | 
             
                    unless Evil::Models::ConfigPair.table_exists?
         | 
| 24 17 | 
             
                      create_table :evil_config_pairs do |t|
         | 
| 25 | 
            -
                        t. | 
| 18 | 
            +
                        t.string  :plugin
         | 
| 26 19 | 
             
                        t.string  :key
         | 
| 27 20 | 
             
                        t.text    :value
         | 
| 28 21 | 
             
                        t.timestamps
         | 
| 29 22 | 
             
                      end
         | 
| 30 23 |  | 
| 31 | 
            -
                      add_index :evil_config_pairs, : | 
| 24 | 
            +
                      add_index :evil_config_pairs, :plugin
         | 
| 32 25 | 
             
                    end
         | 
| 33 26 |  | 
| 34 27 | 
             
                    create_table :evil_whitelists do |t|
         | 
    
        data/lib/evil.rb
    CHANGED
    
    | @@ -1,3 +1,7 @@ | |
| 1 | 
            +
            require 'liquid'
         | 
| 2 | 
            +
            require 'liquid_inheritance'
         | 
| 3 | 
            +
            require 'httparty'
         | 
| 4 | 
            +
             | 
| 1 5 | 
             
            module Evil
         | 
| 2 6 | 
             
              module Setup
         | 
| 3 7 | 
             
                autoload :DbTool, 'evil/setup/db_tool'
         | 
| @@ -5,11 +9,40 @@ module Evil | |
| 5 9 | 
             
                autoload :Migration, 'evil/setup/migration'
         | 
| 6 10 | 
             
              end
         | 
| 7 11 |  | 
| 12 | 
            +
              autoload :OpenID, 'evil/open_id'
         | 
| 13 | 
            +
              autoload :Helpers, 'evil/helpers'
         | 
| 14 | 
            +
              autoload :Extensions, 'evil/extensions'
         | 
| 15 | 
            +
              
         | 
| 16 | 
            +
              autoload :Plugin, 'evil/plugin'
         | 
| 17 | 
            +
              
         | 
| 8 18 | 
             
              autoload :Application, 'evil/application'
         | 
| 9 19 |  | 
| 10 20 | 
             
              class << self
         | 
| 11 21 | 
             
                attr_accessor :gem_root, :app_root
         | 
| 22 | 
            +
                
         | 
| 23 | 
            +
                def heroku?
         | 
| 24 | 
            +
                  Object.const_defined?(:Heroku)
         | 
| 25 | 
            +
                end
         | 
| 12 26 | 
             
              end
         | 
| 13 27 | 
             
            end
         | 
| 14 28 |  | 
| 15 | 
            -
            Evil.gem_root = File.join(File.dirname(__FILE__), '..')
         | 
| 29 | 
            +
            Evil.gem_root = File.join(File.dirname(__FILE__), '..')
         | 
| 30 | 
            +
             | 
| 31 | 
            +
            class Proc 
         | 
| 32 | 
            +
              def bind(object)
         | 
| 33 | 
            +
                block, time = self, Time.now
         | 
| 34 | 
            +
                (class << object; self end).class_eval do
         | 
| 35 | 
            +
                  method_name = "__bind_#{time.to_i}_#{time.usec}"
         | 
| 36 | 
            +
                  define_method(method_name, &block)
         | 
| 37 | 
            +
                  method = instance_method(method_name)
         | 
| 38 | 
            +
                  remove_method(method_name)
         | 
| 39 | 
            +
                  method
         | 
| 40 | 
            +
                end.bind(object)
         | 
| 41 | 
            +
              end
         | 
| 42 | 
            +
            end
         | 
| 43 | 
            +
             | 
| 44 | 
            +
            class Object
         | 
| 45 | 
            +
              def instance_exec(*arguments, &block)
         | 
| 46 | 
            +
                block.bind(self)[*arguments]
         | 
| 47 | 
            +
              end
         | 
| 48 | 
            +
            end
         | 
| @@ -0,0 +1,64 @@ | |
| 1 | 
            +
            require File.join(File.dirname(__FILE__), '../test_helper')
         | 
| 2 | 
            +
            require 'evil/application'
         | 
| 3 | 
            +
             | 
| 4 | 
            +
            class EvilTest < Test::Unit::TestCase
         | 
| 5 | 
            +
              include Sinatra::Test
         | 
| 6 | 
            +
              
         | 
| 7 | 
            +
              context 'running the evil application' do
         | 
| 8 | 
            +
                setup do
         | 
| 9 | 
            +
                  @app = Evil::Application
         | 
| 10 | 
            +
                end
         | 
| 11 | 
            +
              
         | 
| 12 | 
            +
                context 'while not logged in' do
         | 
| 13 | 
            +
                  
         | 
| 14 | 
            +
                    context 'GET /admin' do
         | 
| 15 | 
            +
                      setup do
         | 
| 16 | 
            +
                        get '/admin'
         | 
| 17 | 
            +
                      end
         | 
| 18 | 
            +
                    
         | 
| 19 | 
            +
                      should 'not be authorized' do
         | 
| 20 | 
            +
                        assert_equal 401, response.status
         | 
| 21 | 
            +
                        assert_match /openid_url/, response.body
         | 
| 22 | 
            +
                      end
         | 
| 23 | 
            +
                    end
         | 
| 24 | 
            +
                  
         | 
| 25 | 
            +
                  end
         | 
| 26 | 
            +
                
         | 
| 27 | 
            +
                  context 'while logged in' do 
         | 
| 28 | 
            +
                    setup do
         | 
| 29 | 
            +
                      @env = { 'rack.session' => { :identity_url => 'www.danwebb.net' } }
         | 
| 30 | 
            +
                    end
         | 
| 31 | 
            +
                         
         | 
| 32 | 
            +
                    context 'GET /admin' do
         | 
| 33 | 
            +
                      setup do
         | 
| 34 | 
            +
                        get '/admin', {}, @env
         | 
| 35 | 
            +
                      end
         | 
| 36 | 
            +
             | 
| 37 | 
            +
                      should 'be successful' do
         | 
| 38 | 
            +
                        assert response.ok?
         | 
| 39 | 
            +
                      end
         | 
| 40 | 
            +
                    end
         | 
| 41 | 
            +
                    
         | 
| 42 | 
            +
                    context 'GET /admin/templates/1 with existing template' do
         | 
| 43 | 
            +
                      setup do
         | 
| 44 | 
            +
                        get '/admin/templates/1', {}, @env
         | 
| 45 | 
            +
                      end
         | 
| 46 | 
            +
                      
         | 
| 47 | 
            +
                      should 'be successful' do
         | 
| 48 | 
            +
                        assert response.ok?
         | 
| 49 | 
            +
                      end
         | 
| 50 | 
            +
                    end
         | 
| 51 | 
            +
                    
         | 
| 52 | 
            +
                    context 'GET /admin/templates/nothinghere with non-existing template' do
         | 
| 53 | 
            +
                      setup do
         | 
| 54 | 
            +
                        get '/admin/templates/nothinghere', {}, @env
         | 
| 55 | 
            +
                      end
         | 
| 56 | 
            +
                      
         | 
| 57 | 
            +
                      should 'be not found' do
         | 
| 58 | 
            +
                        assert_equal 404, response.status
         | 
| 59 | 
            +
                      end
         | 
| 60 | 
            +
                    end
         | 
| 61 | 
            +
                  end
         | 
| 62 | 
            +
                end
         | 
| 63 | 
            +
              
         | 
| 64 | 
            +
            end
         | 
    
        data/test/dev_env.rb
    ADDED
    
    
    
        data/test/test_helper.rb
    ADDED
    
    | @@ -0,0 +1,12 @@ | |
| 1 | 
            +
            $:.unshift(File.join(File.dirname(__FILE__), '../lib'))
         | 
| 2 | 
            +
            require 'rubygems'
         | 
| 3 | 
            +
            require 'evil'
         | 
| 4 | 
            +
            require 'test/unit'
         | 
| 5 | 
            +
            require 'shoulda'
         | 
| 6 | 
            +
            require 'sinatra/test'
         | 
| 7 | 
            +
            require 'mocha'
         | 
| 8 | 
            +
             | 
| 9 | 
            +
            require 'redgreen' rescue nil
         | 
| 10 | 
            +
             | 
| 11 | 
            +
            Sinatra::Default.set :environment, 'test'
         | 
| 12 | 
            +
            Evil.app_root = File.join(File.dirname(__FILE__), 'example')
         | 
| @@ -0,0 +1,47 @@ | |
| 1 | 
            +
            class BaseTest < Test::Unit::TestCase
         | 
| 2 | 
            +
              should 'initialize with a name and a block that recieves the new instance' do
         | 
| 3 | 
            +
                plugin = Evil::Plugin::Base.new 'Test Plugin' do |p|
         | 
| 4 | 
            +
                  assert_instance_of Evil::Plugin::Base, p
         | 
| 5 | 
            +
                end
         | 
| 6 | 
            +
                
         | 
| 7 | 
            +
                assert_equal 'Test Plugin', plugin.name
         | 
| 8 | 
            +
              end
         | 
| 9 | 
            +
              
         | 
| 10 | 
            +
              context 'given a plugin instance with a description and setup set' do
         | 
| 11 | 
            +
                setup do
         | 
| 12 | 
            +
                  @setup_proc = Proc.new {}
         | 
| 13 | 
            +
                  
         | 
| 14 | 
            +
                  @plugin = Evil::Plugin::Base.new 'Test Plugin' do |p|
         | 
| 15 | 
            +
                    p.description 'A plugin for testing plugins'
         | 
| 16 | 
            +
                    
         | 
| 17 | 
            +
                    p.setup &@setup_proc
         | 
| 18 | 
            +
             | 
| 19 | 
            +
                  end
         | 
| 20 | 
            +
                end
         | 
| 21 | 
            +
                
         | 
| 22 | 
            +
                should 'have a description set' do
         | 
| 23 | 
            +
                  assert_equal 'A plugin for testing plugins', @plugin.description
         | 
| 24 | 
            +
                end
         | 
| 25 | 
            +
                
         | 
| 26 | 
            +
                should 'call the setup proc when init called' do
         | 
| 27 | 
            +
                  @setup_proc.expects(:call)
         | 
| 28 | 
            +
                  
         | 
| 29 | 
            +
                  @plugin.init
         | 
| 30 | 
            +
                end
         | 
| 31 | 
            +
                
         | 
| 32 | 
            +
              end
         | 
| 33 | 
            +
              
         | 
| 34 | 
            +
              should 'create and register a tag instance when plugin initialize with a tag call' do
         | 
| 35 | 
            +
                Evil::Plugin::Tag.expects(:from).returns(t = Class.new(Liquid::Tag))
         | 
| 36 | 
            +
                Liquid::Template.expects(:register_tag).with(:thing, t)
         | 
| 37 | 
            +
                
         | 
| 38 | 
            +
                Evil::Plugin::Base.new 'Test Plugin' do |p|
         | 
| 39 | 
            +
                  p.tag :thing do 
         | 
| 40 | 
            +
                    'a tag'
         | 
| 41 | 
            +
                  end
         | 
| 42 | 
            +
                end
         | 
| 43 | 
            +
                
         | 
| 44 | 
            +
              end
         | 
| 45 | 
            +
              
         | 
| 46 | 
            +
              
         | 
| 47 | 
            +
            end
         | 
| @@ -0,0 +1,108 @@ | |
| 1 | 
            +
            require File.join(File.dirname(__FILE__), '../../test_helper')
         | 
| 2 | 
            +
            require 'liquid'
         | 
| 3 | 
            +
             | 
| 4 | 
            +
            class TagTest < Test::Unit::TestCase
         | 
| 5 | 
            +
              context 'with a custom tag defined that returns a string' do
         | 
| 6 | 
            +
                setup do
         | 
| 7 | 
            +
                  Liquid::Template.register_tag('test', Evil::Plugin::Tag.from { |params|
         | 
| 8 | 
            +
                    'hello'
         | 
| 9 | 
            +
                  })
         | 
| 10 | 
            +
                end
         | 
| 11 | 
            +
                
         | 
| 12 | 
            +
                should 'output the string' do
         | 
| 13 | 
            +
                  template = Liquid::Template.parse('{% test %}{% endtest %}')
         | 
| 14 | 
            +
             | 
| 15 | 
            +
                  assert_equal 'hello', template.render
         | 
| 16 | 
            +
                end
         | 
| 17 | 
            +
              end
         | 
| 18 | 
            +
              
         | 
| 19 | 
            +
              context 'with a custom tag defined that returns a parameter' do
         | 
| 20 | 
            +
                setup do
         | 
| 21 | 
            +
                  Liquid::Template.register_tag('test', Evil::Plugin::Tag.from { |params|
         | 
| 22 | 
            +
                    params[:a]
         | 
| 23 | 
            +
                  })
         | 
| 24 | 
            +
                end
         | 
| 25 | 
            +
                
         | 
| 26 | 
            +
                should 'output that parameter if passed as a constant' do
         | 
| 27 | 
            +
                  template = Liquid::Template.parse('{% test a: "thing" %}{% endtest %}')
         | 
| 28 | 
            +
                  
         | 
| 29 | 
            +
                  assert_equal 'thing', template.render
         | 
| 30 | 
            +
                end
         | 
| 31 | 
            +
                
         | 
| 32 | 
            +
                should 'output that parameter if passed as a variable' do
         | 
| 33 | 
            +
                  template = Liquid::Template.parse('{% test a: var %}{% endtest %}')
         | 
| 34 | 
            +
                  
         | 
| 35 | 
            +
                  assert_equal 'thing', template.render('var' => 'thing')
         | 
| 36 | 
            +
                end
         | 
| 37 | 
            +
              end
         | 
| 38 | 
            +
              
         | 
| 39 | 
            +
              context 'with a custom tag defined that uses the body method' do
         | 
| 40 | 
            +
                setup do
         | 
| 41 | 
            +
                  Liquid::Template.register_tag('test', Evil::Plugin::Tag.from { |params|
         | 
| 42 | 
            +
                    times = params[:times] || 1
         | 
| 43 | 
            +
                    out = ''
         | 
| 44 | 
            +
                    times.times { |i| out << body(:i => i) }
         | 
| 45 | 
            +
                    out
         | 
| 46 | 
            +
                  })
         | 
| 47 | 
            +
                end
         | 
| 48 | 
            +
                
         | 
| 49 | 
            +
                should 'output the contents of the tag' do
         | 
| 50 | 
            +
                  template = Liquid::Template.parse('{% test %}a{% endtest %}')
         | 
| 51 | 
            +
                  
         | 
| 52 | 
            +
                  assert_equal 'a', template.render
         | 
| 53 | 
            +
                end
         | 
| 54 | 
            +
                
         | 
| 55 | 
            +
                should 'remember the i variable passed to body' do
         | 
| 56 | 
            +
                  template = Liquid::Template.parse('{% test %}{{ i }}{% endtest %}')
         | 
| 57 | 
            +
                  
         | 
| 58 | 
            +
                  assert_equal '0', template.render
         | 
| 59 | 
            +
                end
         | 
| 60 | 
            +
                
         | 
| 61 | 
            +
                should 'be different value of i for each repetition of body' do
         | 
| 62 | 
            +
                  template = Liquid::Template.parse('{% test times: 10 %}{{ i }}{% endtest %}')
         | 
| 63 | 
            +
                  
         | 
| 64 | 
            +
                  assert_equal '0123456789', template.render
         | 
| 65 | 
            +
                end
         | 
| 66 | 
            +
              end
         | 
| 67 | 
            +
              
         | 
| 68 | 
            +
              context 'with 2 custom tags defined' do
         | 
| 69 | 
            +
                setup do
         | 
| 70 | 
            +
                  Liquid::Template.register_tag('test', Evil::Plugin::Tag.from { |params|
         | 
| 71 | 
            +
                    times = params[:times] || 1
         | 
| 72 | 
            +
                    out = ''
         | 
| 73 | 
            +
                    times.times { |i| out << body(:i => i) }
         | 
| 74 | 
            +
                    out
         | 
| 75 | 
            +
                  })
         | 
| 76 | 
            +
                  
         | 
| 77 | 
            +
                  Liquid::Template.register_tag('test2', Evil::Plugin::Tag.from { |params|
         | 
| 78 | 
            +
                    params[:a]
         | 
| 79 | 
            +
                  })
         | 
| 80 | 
            +
                end
         | 
| 81 | 
            +
                
         | 
| 82 | 
            +
                should 'be able to nest tags' do
         | 
| 83 | 
            +
                  template = Liquid::Template.parse("{% test times: 2 %}{% test2 a: 4 %}{% endtest2 %}{% endtest %}")
         | 
| 84 | 
            +
                  
         | 
| 85 | 
            +
                  assert_equal '44', template.render
         | 
| 86 | 
            +
                end
         | 
| 87 | 
            +
                
         | 
| 88 | 
            +
                should 'be able to use vars from outer tag in inner tag' do
         | 
| 89 | 
            +
                  template = Liquid::Template.parse("{% test times: 2 %}{% test2 a: i %}{% endtest2 %}{% endtest %}")
         | 
| 90 | 
            +
                  
         | 
| 91 | 
            +
                  assert_equal '01', template.render
         | 
| 92 | 
            +
                end
         | 
| 93 | 
            +
              end
         | 
| 94 | 
            +
              
         | 
| 95 | 
            +
              context 'with a custom tag with more than one parameter defined' do
         | 
| 96 | 
            +
                setup do
         | 
| 97 | 
            +
                  Liquid::Template.register_tag('test', Evil::Plugin::Tag.from { |params|
         | 
| 98 | 
            +
                    [params[:a], params[:b]].join('|')
         | 
| 99 | 
            +
                  })
         | 
| 100 | 
            +
                end
         | 
| 101 | 
            +
                
         | 
| 102 | 
            +
                should 'output both parameters' do
         | 
| 103 | 
            +
                  template = Liquid::Template.parse("{% test a: 'g', b: 'a' %}{% endtest %}")
         | 
| 104 | 
            +
                  
         | 
| 105 | 
            +
                  assert_equal 'g|a', template.render
         | 
| 106 | 
            +
                end
         | 
| 107 | 
            +
              end
         | 
| 108 | 
            +
            end
         | 
    
        data/views/_banner.haml
    ADDED
    
    | @@ -0,0 +1,8 @@ | |
| 1 | 
            +
            - if session[:identity_url]
         | 
| 2 | 
            +
              #banner
         | 
| 3 | 
            +
                %a{ :href => '/admin' }
         | 
| 4 | 
            +
                  %img#logo{ :src => '/images/logo.png', :alt => 'Evil' } 
         | 
| 5 | 
            +
                %form{ :method => 'post', :action => '/admin/openid/logout', :id => 'logout' }
         | 
| 6 | 
            +
                  Logged in as 
         | 
| 7 | 
            +
                  %em= session[:identity_url]
         | 
| 8 | 
            +
                  %input.submit{ :type => 'submit', :value => 'Log out' }
         | 
    
        data/views/_errors.haml
    ADDED
    
    
    
        data/views/index.haml
    ADDED
    
    | @@ -0,0 +1,41 @@ | |
| 1 | 
            +
            #overview
         | 
| 2 | 
            +
              %table#template-overview
         | 
| 3 | 
            +
                %thead
         | 
| 4 | 
            +
                  %tr.title
         | 
| 5 | 
            +
                    %th{ :colspan => 3 } Templates
         | 
| 6 | 
            +
                  %tr
         | 
| 7 | 
            +
                    %th Name
         | 
| 8 | 
            +
                    %th URL Pattern
         | 
| 9 | 
            +
                    %th TTL
         | 
| 10 | 
            +
                    %th 
         | 
| 11 | 
            +
                %tbody
         | 
| 12 | 
            +
                  - @templates.each_with_index do |template, i|
         | 
| 13 | 
            +
                    %tr{ :class => ('alt' if i % 2 == 1) }
         | 
| 14 | 
            +
                      %td= template.title
         | 
| 15 | 
            +
                      %td= template.route
         | 
| 16 | 
            +
                      %td= template.route.empty? ? 'N/A' : template.ttl
         | 
| 17 | 
            +
                      %td.tools
         | 
| 18 | 
            +
                        %a{ :href => "/admin/templates/#{template.id}"} Edit
         | 
| 19 | 
            +
                %tfoot
         | 
| 20 | 
            +
                  %tr
         | 
| 21 | 
            +
                    %td{ :colspan => 4 }
         | 
| 22 | 
            +
                      %a{ :href => '/admin/templates/new' } Add Template...
         | 
| 23 | 
            +
                  
         | 
| 24 | 
            +
              %table#plugin-overview
         | 
| 25 | 
            +
                %thead
         | 
| 26 | 
            +
                  %tr.title
         | 
| 27 | 
            +
                    %th{ :colspan => 3 } Plugin Configuration
         | 
| 28 | 
            +
                  %tr
         | 
| 29 | 
            +
                    %th Name
         | 
| 30 | 
            +
                    %th 
         | 
| 31 | 
            +
                %tbody
         | 
| 32 | 
            +
                  - @plugins.each_with_index do |plugin, i|
         | 
| 33 | 
            +
                    %tr{ :class => ('alt' if i % 2 == 1) }
         | 
| 34 | 
            +
                      %td= plugin
         | 
| 35 | 
            +
                      %td.tools
         | 
| 36 | 
            +
                        %a{ :href => "/admin/plugins/#{urlencode(plugin)}"} Edit
         | 
| 37 | 
            +
                %tfoot
         | 
| 38 | 
            +
                  %tr
         | 
| 39 | 
            +
                    %td{ :colspan => 3 }
         | 
| 40 | 
            +
                      %a{ :href => '/admin/plugins/new' } Add Configuration...
         | 
| 41 | 
            +
              
         | 
    
        data/views/layout.haml
    ADDED
    
    | @@ -0,0 +1,13 @@ | |
| 1 | 
            +
            !!!
         | 
| 2 | 
            +
            %html
         | 
| 3 | 
            +
              %head
         | 
| 4 | 
            +
                %title Evil Admin
         | 
| 5 | 
            +
                %link{ :rel => 'stylesheet', :href => '/stylesheets/evil.css', :type => 'text/css' }
         | 
| 6 | 
            +
              %body
         | 
| 7 | 
            +
                = partial(:banner)
         | 
| 8 | 
            +
                #content
         | 
| 9 | 
            +
                  = yield
         | 
| 10 | 
            +
                %script{ :type => 'text/javascript', :src => 'http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js' }
         | 
| 11 | 
            +
                %script{ :type => 'text/javascript', :src => '/javascripts/evil-lib.js' }
         | 
| 12 | 
            +
                %script{ :type => 'text/javascript', :src => '/javascripts/evil.js' }
         | 
| 13 | 
            +
                  
         | 
    
        data/views/login.haml
    ADDED
    
    
| @@ -0,0 +1,23 @@ | |
| 1 | 
            +
            %p
         | 
| 2 | 
            +
              %label{ :for => 'template_title' }
         | 
| 3 | 
            +
                Title *
         | 
| 4 | 
            +
              %input#template_title.text{ :name => 'template[title]', :value => @template.title }
         | 
| 5 | 
            +
            %p
         | 
| 6 | 
            +
              %label{ :for => 'template_route' }
         | 
| 7 | 
            +
                Route
         | 
| 8 | 
            +
              %input#template_route.text{ :name => 'template[route]', :value => @template.route }
         | 
| 9 | 
            +
            %p
         | 
| 10 | 
            +
              %label{ :for => 'template_source' }
         | 
| 11 | 
            +
                Source *
         | 
| 12 | 
            +
              %textarea#template_source{ :name => 'template[source]' }= @template.source
         | 
| 13 | 
            +
            %p
         | 
| 14 | 
            +
              %label{ :for => 'template_ttl' }
         | 
| 15 | 
            +
                Expires every (seconds)
         | 
| 16 | 
            +
              %input#template_ttl.text{ :name => 'template[ttl]', :value => @template.ttl || 600 }
         | 
| 17 | 
            +
            %p
         | 
| 18 | 
            +
              %label{ :for => 'template_content_type' }
         | 
| 19 | 
            +
                Content Type
         | 
| 20 | 
            +
              %input#template_content_type.short{ :name => 'template[content_type]', :value => @template.content_type || 'text/html' }
         | 
| 21 | 
            +
              %input#template_encoding.short{ :name => 'template[encoding]', :value => @template.encoding || 'utf-8' }
         | 
| 22 | 
            +
            %p
         | 
| 23 | 
            +
              %input.submit{ :value => 'Save', :type => 'submit' }
         |