rembrandt 0.0.3 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: a112457eb1b4df68b42a90a4776fc11c5eee535a
4
- data.tar.gz: 106843ea850f71e800213a19cc52158df22b483b
3
+ metadata.gz: d4e5b88327738db6739926a9ac97b9b9d6fb2ac6
4
+ data.tar.gz: 80181d4b01d282d0323ba3cd54e0a861f47f6760
5
5
  SHA512:
6
- metadata.gz: 1ef0e17c8794f1d61522813f4e838ad9d1c43fe4a6eb43e8b04cbd647e423d4ffd904c350f334ca066333655b9ba240392f7287ccd4c66b673f632a5e95a4b85
7
- data.tar.gz: d90d7325af4d8a74478f69fba12e6c73c2c513a7cac4889fbdcd1cf973c8093e9dcbb8f555d074c1a0561576fd34c6174979f5e85298d03817fcde693437d599
6
+ metadata.gz: ad2e5d4336e996780f08aa5bd9eb0065add68477d71fad5a3de3227259ff4659fab4d11a0545f9848f623aae64935b50b3fe8ad7a323df54e138521dccc1732c
7
+ data.tar.gz: ca01834cba775497338a4e1b56b781f15aeefdfe2cd8c54f66139db81b639f6237e1c5f6fc0f4684dc0bfefa0429ff7a46ad176ab94984c1b5c1517de993f034
data/README.md CHANGED
@@ -18,7 +18,31 @@ Or install it yourself as:
18
18
 
19
19
  ## Usage
20
20
 
21
- TODO: Write usage instructions here
21
+ ### Basic Highlighting
22
+
23
+ ```irb
24
+ > require 'rembrandt'
25
+ > highlighter = Rembrandt::Highlighter.new
26
+ > highlighter.highlight("class Sample\nend", "ruby")
27
+ ```
28
+
29
+ ### Highlighting Source in a File
30
+
31
+ ```irb
32
+ > require 'rembrandt'
33
+ > highlighter = Rembrandt::Highlighter.new
34
+ > highlighter.highlight_file("./my_input_file.rb", "ruby")
35
+ ```
36
+
37
+ ### Using a Formatter
38
+
39
+ ```irb
40
+ > require 'rembrandt'
41
+ > highlighter = Rembrandt::Highlighter.new
42
+ > formatter = Rembrandt::Formatters::Table.new
43
+ > code = highlighter.highlight("class Sample\nend", "ruby")
44
+ > table = formatter.format(code, "ruby")
45
+ ```
22
46
 
23
47
  ## Contributing
24
48
 
@@ -27,3 +51,7 @@ TODO: Write usage instructions here
27
51
  3. Commit your changes (`git commit -am 'Add some feature'`)
28
52
  4. Push to the branch (`git push origin my-new-feature`)
29
53
  5. Create new Pull Request
54
+
55
+ ### When Developing
56
+
57
+ It's expected that when developing that you have both Redis and Python/Pygmentize available on your machine. If you don't have Pygments installed, Rembrant's tests will try to use the HTTP highlight engine which is blocked by VCR.
@@ -0,0 +1,39 @@
1
+ module Rembrandt
2
+ class Config
3
+ def self.default_language=(input)
4
+ @default_language = input
5
+ end
6
+
7
+ def self.default_language
8
+ @default_language ||= library_default_language
9
+ end
10
+
11
+ def self.library_default_language
12
+ "ruby"
13
+ end
14
+
15
+ def self.engine_priority=(engines)
16
+ @engine_priority = engines
17
+ end
18
+
19
+ def self.engine_priority
20
+ @engine_priority ||= library_default_engine_priority
21
+ end
22
+
23
+ def self.library_default_engine_priority
24
+ [Engines::Pygmentize, Engines::WebService]
25
+ end
26
+
27
+ def self.file_store_directory
28
+ @file_store_directory ||= library_default_file_store_directory
29
+ end
30
+
31
+ def self.library_default_file_store_directory
32
+ './tmp/.rembrandt_cache'
33
+ end
34
+
35
+ def self.file_store_directory=(input)
36
+ @file_store_directory = input
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,9 @@
1
+ module Rembrandt
2
+ module Engines
3
+ module PygmentsKnownLanguages
4
+ def known_languages
5
+ ['sourceslist', 'sources.list', 'delphi', 'pas', 'pascal', 'objectpascal', 'js+mako', 'javascript+mako', 'iex', 'psql', 'postgresql-console', 'postgres-console', 'brainfuck', 'bf', 'ceylon', 'js+django', 'javascript+django', 'js+jinja', 'javascript+jinja', 'html+evoque', 'numpy', 'modula2', 'm2', 'live-script', 'livescript', 'nimrod', 'nim', 'bash', 'sh', 'ksh', 'html+django', 'html+jinja', 'css+php', 'xml+lasso', 'vim', 'css+genshitext', 'css+genshi', 'fancy', 'fy', 'cfm', 'cfs', 'ssp', 'smarty', 'xml+evoque', 'hx', 'haXe', 'powershell', 'posh', 'ps1', 'tea', 'html+cheetah', 'html+spitfire', 'rbcon', 'irb', 'mason', 'django', 'jinja', 'jags', 'apacheconf', 'aconf', 'apache', 'dtd', 'dylan-console', 'dylan-repl', 'lighty', 'lighttpd', 'java', 'js+genshitext', 'js+genshi', 'javascript+genshitext', 'javascript+genshi', 'scheme', 'scm', 'nemerle', 'rhtml', 'html+erb', 'html+ruby', 'ragel-java', 'dpatch', 'puppet', 'octave', 'coffee-script', 'coffeescript', 'ragel-d', 'scilab', 'monkey', 'html+myghty', 'erl', 'css', 'js+smarty', 'javascript+smarty', 'io', 'cobolfree', 'asy', 'asymptote', 'vhdl', 'python3', 'py3', 'css+erb', 'css+ruby', 'fortran', 'd-objdump', 'mysql', 'rebol', 'cpp', 'c++', 'erb', 'cbmbas', 'befunge', 'julia', 'jl', 'moon', 'moonscript', 'rb', 'ruby', 'duby', 'xml+smarty', 'dylan', 'groovy', 'trac-wiki', 'moin', 'ahk', 'c', 'html', 'felix', 'flx', 'cmake', 'nsis', 'nsi', 'nsh', 'sp', 'mako', 'vgl', 'velocity', 'koka', 'cuda', 'cu', 'gnuplot', 'irc', 'prolog', 'python', 'py', 'sage', 'css+django', 'css+jinja', 'verilog', 'v', 'smalltalk', 'squeak', 'js+myghty', 'javascript+myghty', 'yaml', 'antlr-as', 'antlr-actionscript', 'xml+mako', 'xslt', 'urbiscript', 'scaml', 'SCAML', 'splus', 's', 'r', 'dylan-lid', 'lid', 'maql', 'sqlite3', 'boo', 'ocaml', 'ec', 'as', 'actionscript', 'vb.net', 'vbnet', 'squidconf', 'squid.conf', 'squid', 'xquery', 'xqy', 'xq', 'xql', 'xqm', 'd', 'fan', 'pot', 'po', 'logos', 'jlcon', 'lasso', 'lassoscript', 'scss', 'bbcode', 'haml', 'HAML', 'Clipper', 'XBase', 'py3tb', 'mupad', 'xml+erb', 'xml+ruby', 'dart', 'idl', 'dg', 'evoque', 'jade', 'JADE', 'c-objdump', 'kconfig', 'menuconfig', 'linux-config', 'kernel-config', 'jsp', 'registry', 'abap', 'xml+velocity', 'js+cheetah', 'javascript+cheetah', 'js+spitfire', 'javascript+spitfire', 'html+mako', 'ragel-ruby', 'ragel-rb', 'RobotFramework', 'robotframework', 'protobuf', 'cfengine3', 'cf3', 'ragel', 'glsl', 'cobol', 'ts', 'ada', 'ada95ada2005', 'postgresql', 'postgres', 'xtend', 'logtalk', 'objdump', 'css+mako', 'ca65', 'objective-c++', 'objectivec++', 'obj-c++', 'objc++', 'Cucumber', 'cucumber', 'Gherkin', 'gherkin', 'html+php', 'make', 'makefile', 'mf', 'bsdmake', 'postscript', 'haxeml', 'hxml', 'kotlin', 'plpgsql', 'vala', 'vapi', 'haskell', 'hs', 'bro', 'lua', 'pov', 'sass', 'SASS', 'antlr-java', 'tcl', 'antlr-objc', 'js+erb', 'javascript+erb', 'js+ruby', 'javascript+ruby', 'racket', 'rkt', 'aspectj', 'basemake', 'antlr-python', 'cpp-objdump', 'c++-objdumb', 'cxx-objdump', 'genshitext', 'ioke', 'ik', 'pypylog', 'pypy', 'croc', 'objective-j', 'objectivej', 'obj-j', 'objj', 'gas', 'bat', 'snobol', 'pycon', 'xml', 'antlr', 'opa', 'xml+cheetah', 'xml+spitfire', 'go', 'diff', 'udiff', 'minid', 'cython', 'pyx', 'ragel-c', 'erlang', 'control', 'aspx-vb', 'bugs', 'winbugs', 'openbugs', 'ragel-cpp', 'aspx-cs', 'matlabsession', 'properties', 'groff', 'nroff', 'man', 'clojure', 'clj', 'modelica', 'qml', 'Qt Meta Language', 'Qt modeling Language', 'js+lasso', 'javascript+lasso', 'antlr-perl', 'genshi', 'kid', 'xml+genshi', 'xml+kid', 'blitzmax', 'bmax', 'treetop', 'matlab', 'myghty', 'html+genshi', 'html+kid', 'duel', 'Duel Engine', 'Duel View', 'JBST', 'jbst', 'JsonML+BST', 'perl', 'pl', 'fsharp', 'rst', 'rest', 'restructuredtext', 'newlisp', 'scala', 'css+lasso', 'xml+php', 'stan', 'ini', 'cfg', 'moocode', 'shell-session', 'spec', 'newspeak', 'console', 'coq', 'raw', 'tcsh', 'csh', 'html+lasso', 'csharp', 'c#', 'gst', 'rconsole', 'rout', 'mxml', 'tex', 'latex', 'css+smarty', 'text', 'antlr-csharp', 'antlr-c#', 'openedge', 'abl', 'progress', 'cheetah', 'spitfire', 'smali', 'css+myghty', 'rd', 'llvm', 'sml', 'elixir', 'ex', 'exs', 'nginx', 'gooddata-cl', 'applescript', 'html+smarty', 'objective-c', 'objectivec', 'obj-c', 'objc', 'js', 'javascript', 'rust', 'common-lisp', 'cl', 'ragel-em', 'as3', 'actionscript3', 'systemverilog', 'sv', 'lhs', 'literate-haskell', 'pytb', 'php', 'php3', 'php4', 'php5', 'antlr-cpp', 'gosu', 'hybris', 'hy', 'js+php', 'javascript+php', 'factor', 'html+velocity', 'mscgen', 'msc', 'ooc', 'sql', 'http', 'ecl', 'redcode', 'ragel-objc', 'xml+django', 'xml+jinja', 'awk', 'gawk', 'mawk', 'nawk', 'json', 'nasm', 'antlr-ruby', 'antlr-rb', 'xml+myghty', 'autoit', 'Autoit']
6
+ end
7
+ end
8
+ end
9
+ end
@@ -1,3 +1,4 @@
1
+ require 'net/http'
1
2
  require 'uri'
2
3
 
3
4
  module Rembrandt
@@ -0,0 +1,21 @@
1
+ module Rembrandt
2
+ module Formatters
3
+ class FormattedCode
4
+ attr_reader :code, :language
5
+
6
+ def initialize(input_code, input_language)
7
+ @code = extract_code_from_html(input_code)
8
+ @language = input_language
9
+ end
10
+
11
+ def line_count
12
+ code.lines.count
13
+ end
14
+
15
+ def extract_code_from_html(input)
16
+ matches = input.match(/<pre>(.+)<\/pre>/m)
17
+ matches[1] if matches
18
+ end
19
+ end
20
+ end
21
+ end
@@ -1,7 +1,17 @@
1
+ require 'erb'
2
+ require 'tilt'
3
+ require_relative 'formatted_code'
4
+
1
5
  module Rembrandt
2
6
  module Formatters
3
7
  class Table
8
+ def format(input_code, input_language)
9
+ template.render FormattedCode.new(input_code, input_language)
10
+ end
4
11
 
12
+ def template
13
+ @template ||= Tilt.new('./lib/rembrandt/formatters/templates/table.erb', :trim => true)
14
+ end
5
15
  end
6
16
  end
7
17
  end
@@ -0,0 +1,24 @@
1
+ <div class="highlight">
2
+ <table>
3
+ <tr>
4
+ <td class="gutter">
5
+ <pre class="line-numbers">
6
+ <% line_count.times do |i| %>
7
+ <span class='line-number'><%= i + 1 %></span>
8
+ <% end %>
9
+ </pre>
10
+ </td>
11
+ <td class='code'>
12
+ <pre>
13
+ <code class='<%= language %>'>
14
+ <% code.lines.each do |line| %>
15
+ <span class='line'>
16
+ <%= line %>
17
+ </span>
18
+ <% end %>
19
+ </code>
20
+ </pre>
21
+ </td>
22
+ </tr>
23
+ </table>
24
+ </div>
@@ -1,23 +1,69 @@
1
1
  require_relative 'engines/pygmentize'
2
+ require_relative 'engines/web_service'
3
+ require_relative 'stores/file'
4
+ require_relative 'stores/redis'
5
+ require_relative 'config'
6
+ require_relative 'language_normalizer'
2
7
 
3
8
  module Rembrandt
4
9
  class Highlighter
5
- attr_reader :engine
10
+ attr_writer :store
6
11
 
7
12
  def initialize(input_engine = nil)
8
- @engine = (input_engine || autoselect_engine).new
13
+ @engine = input_engine.new if input_engine
14
+ end
15
+
16
+ def engine
17
+ @engine ||= autoselect_engine
18
+ end
19
+
20
+ def store
21
+ @store ||= autoselect_store
9
22
  end
10
23
 
11
24
  def default_language
12
- "ruby"
25
+ Config.default_language
26
+ end
27
+
28
+ def autoselect_store
29
+ redis = Stores::Redis.new
30
+ if redis.available?
31
+ redis
32
+ else
33
+ Stores::File.new
34
+ end
35
+ end
36
+
37
+ def engines
38
+ Config.engine_priority
13
39
  end
14
40
 
15
41
  def autoselect_engine
16
- [Engines::Pygmentize, Engines::WebService].detect(&:available?)
42
+ begin
43
+ engines.detect(&:available?).new
44
+ rescue
45
+ raise "Error: no highlight engine is available."
46
+ end
47
+ end
48
+
49
+ def highlight(input, input_language = default_language)
50
+ language = normalize_language(input_language)
51
+ store.fetch(input, language) do
52
+ engine.highlight(input, language)
53
+ end
54
+ end
55
+
56
+ def highlight_file(filename, language = default_language)
57
+ data = File.read(filename)
58
+ highlight(data, language)
59
+ end
60
+
61
+ def normalize_language(input)
62
+ language_normalizer.process(input)
17
63
  end
18
64
 
19
- def highlight(input, language = default_language)
20
- engine.highlight(input, language)
65
+ def language_normalizer
66
+ @language_normalizer ||= LanguageNormalizer.new
21
67
  end
22
68
  end
23
69
  end
@@ -0,0 +1,29 @@
1
+ require_relative 'engines/pygments_known_languages'
2
+
3
+ module Rembrandt
4
+ class LanguageNormalizer
5
+ include Engines::PygmentsKnownLanguages
6
+
7
+ def known_language?(input)
8
+ known_languages.detect{|lang| lang == input}
9
+ end
10
+
11
+ def known_variant?(input)
12
+ known_variants[input]
13
+ end
14
+
15
+ def known_variants
16
+ {'ru' => 'ruby',
17
+ 'm' => 'objc',
18
+ 'yml' => 'yaml'}
19
+ end
20
+
21
+ def process(input)
22
+ known_language?(input) || known_variant?(input) || raise_exception(input)
23
+ end
24
+
25
+ def raise_exception(input)
26
+ raise ArgumentError.new("Unknown language specifier: #{input}")
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,18 @@
1
+ module Rembrandt
2
+ module Stores
3
+ module Fetchable
4
+ def key_for(input, language)
5
+ Digest::MD5.hexdigest(input + language)
6
+ end
7
+
8
+ def fetch(input, language)
9
+ result = read key_for(input, language)
10
+ if result.nil? && block_given?
11
+ data_to_store = yield
12
+ write(key_for(input, language), data_to_store)
13
+ return data_to_store
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,51 @@
1
+ require 'fileutils'
2
+ require 'digest/md5'
3
+ require_relative 'fetchable'
4
+
5
+ module Rembrandt
6
+ module Stores
7
+ class File
8
+ include Fetchable
9
+ attr_reader :output_directory
10
+
11
+ def initialize(directory = nil)
12
+ self.output_directory = directory || Config.file_store_directory
13
+ create_directory
14
+ end
15
+
16
+ def output_directory=(name)
17
+ name += '/' unless name.end_with?('/')
18
+ @output_directory = name
19
+ end
20
+
21
+ def create_directory
22
+ FileUtils.mkdir_p output_directory
23
+ end
24
+
25
+ def write(key, data)
26
+ ::File.open( filename_for(key), "w" ) do |f|
27
+ f.write(data)
28
+ end
29
+ end
30
+
31
+ def read(key)
32
+ filename = filename_for(key)
33
+ if ::File.exist?(filename)
34
+ ::File.read(filename_for(key))
35
+ end
36
+ end
37
+
38
+ def filename_for(key)
39
+ output_directory + prefix + key
40
+ end
41
+
42
+ def prefix
43
+ 'rembrandt_'
44
+ end
45
+
46
+ def flush
47
+ `rm -rf #{output_directory}/*` if Dir.exist?(output_directory)
48
+ end
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,33 @@
1
+ require 'digest/md5'
2
+ require 'redis'
3
+ require_relative 'fetchable'
4
+
5
+ module Rembrandt
6
+ module Stores
7
+ class Redis
8
+ include Fetchable
9
+ attr_reader :database, :url
10
+
11
+ def initialize(url = nil)
12
+ @url = ENV['REMBRANDT_REDIS_URL']
13
+ @database = ::Redis.new(:url => url)
14
+ end
15
+
16
+ def available?
17
+ defined?(::Redis)
18
+ end
19
+
20
+ def write(key, data)
21
+ database.set(key, data)
22
+ end
23
+
24
+ def read(key)
25
+ database.get(key)
26
+ end
27
+
28
+ def flush
29
+ database.flushdb
30
+ end
31
+ end
32
+ end
33
+ end
@@ -1,3 +1,3 @@
1
1
  module Rembrandt
2
- VERSION = "0.0.3"
2
+ VERSION = "0.1.0"
3
3
  end
data/rembrandt.gemspec CHANGED
@@ -25,4 +25,7 @@ Gem::Specification.new do |spec|
25
25
  spec.add_development_dependency "vcr"
26
26
  spec.add_development_dependency "webmock"
27
27
  spec.add_development_dependency "mocha"
28
+ spec.add_development_dependency "redis"
29
+
30
+ spec.add_runtime_dependency 'tilt'
28
31
  end
@@ -0,0 +1,16 @@
1
+ require './test/test_helper'
2
+ require './lib/rembrandt/formatters/formatted_code'
3
+
4
+ class FormattedCodeTest < CodeHighlightTest
5
+ def test_it_counts_lines
6
+ input = File.read('./test/support/ruby_sample_1.rb.html')
7
+ code = Rembrandt::Formatters::FormattedCode.new(input, 'ruby')
8
+ assert_equal 5, code.line_count
9
+ end
10
+
11
+ def test_it_stores_the_language
12
+ input = File.read('./test/support/python_sample_1.py.html')
13
+ code = Rembrandt::Formatters::FormattedCode.new("", 'python')
14
+ assert_equal 'python', code.language
15
+ end
16
+ end
@@ -1,9 +1,33 @@
1
- require 'minitest/autorun'
2
- require 'minitest/pride'
1
+ require './test/test_helper'
3
2
  require './lib/rembrandt/formatters/table'
4
3
 
5
- class FormattersTableTest < Minitest::Test
4
+ class FormattersTableTest < CodeHighlightTest
5
+ attr_reader :formatter
6
+
7
+ def setup
8
+ @formatter = Rembrandt::Formatters::Table.new
9
+ end
10
+
6
11
  def test_it_exists
7
12
  assert Rembrandt::Formatters::Table.new
8
13
  end
14
+
15
+ def test_it_tableizes
16
+ input = File.read('./test/support/ruby_sample_2.rb.html')
17
+ expected = File.read('./test/support/ruby_sample_2.rb.tableized.html')
18
+ #expected_doc = Nokogiri::HTML(expected)
19
+ output = formatter.format(input, 'ruby')
20
+ #output_doc = Nokogiri::HTML(output)
21
+
22
+ #assert (expected_doc == output_doc), html_diff(expected_doc, output_doc)
23
+ assert_equal expected, output
24
+ end
25
+
26
+ def html_diff(doc_1, doc_2)
27
+ doc_1.diff(doc_2).collect do |change,node|
28
+ if ["+", "-"].include?(change)
29
+ "#{change} #{node.to_html}".ljust(30) + node.parent.path
30
+ end
31
+ end.reject!(&:nil?).join("\n")
32
+ end
9
33
  end
@@ -17,7 +17,8 @@ class HighlighterTest < CodeHighlightTest
17
17
  end
18
18
 
19
19
  def test_highlight_takes_an_input_and_a_language
20
- assert highlighter.highlight("Hello, World", 'ruby')
20
+ result = highlighter.highlight("Hello, World", 'ruby')
21
+ assert result, "Got: #{result}"
21
22
  end
22
23
 
23
24
  def test_highlight_properly_highlights_ruby
@@ -28,6 +29,16 @@ class HighlighterTest < CodeHighlightTest
28
29
  assert_highlight 'python_sample_1.py', 'python'
29
30
  end
30
31
 
32
+ def test_it_highlights_a_file_directly
33
+ input_filename = './test/support/ruby_sample_1.rb'
34
+ expected = File.read('./test/support/ruby_sample_1.rb.html')
35
+ assert_equal expected, highlighter.highlight_file(input_filename, 'ruby')
36
+ end
37
+
38
+ def test_it_normalizes_unusual_language_abbreviations
39
+ assert_highlight 'ruby_sample_1.rb', 'ru'
40
+ end
41
+
31
42
  class StubEngine
32
43
  def highlight(text, language)
33
44
  "stub highlight"
@@ -39,18 +50,40 @@ class HighlighterTest < CodeHighlightTest
39
50
  assert_equal "stub highlight", stubbed_highlighter.highlight("hello", "ruby")
40
51
  end
41
52
 
42
- def test_it_defaults_to_pygmentize_if_available
43
- expected_engine = Rembrandt::Engines::Pygmentize
44
- expected_engine.stubs(:available?).returns(true)
45
- lighter = Rembrandt::Highlighter.new
46
- assert_equal expected_engine, lighter.engine.class
53
+ class StubStore
54
+ def write(key, data)
55
+ true
56
+ end
57
+
58
+ def fetch(input, language)
59
+ true
60
+ end
61
+
62
+ def flush
63
+ true
64
+ end
65
+ end
66
+
67
+ def test_it_uses_a_datastore
68
+ lighter = Rembrandt::Highlighter.new(StubEngine)
69
+ store = StubStore.new
70
+ highlighter.store = store
71
+ store.expects(:fetch).once
72
+ highlighter.highlight("Hello, World")
73
+ end
74
+
75
+ def test_it_uses_the_default_language_from_config
76
+ Rembrandt::Config.default_language = "python"
77
+ assert_equal "python", highlighter.default_language
78
+ end
79
+
80
+ def test_it_uses_the_engine_prioritization_from_config
81
+ preferred = [Rembrandt::Engines::Pygmentize]
82
+ Rembrandt::Config.engine_priority = preferred
83
+ assert_equal preferred, highlighter.engines
47
84
  end
48
85
 
49
- def test_it_uses_the_web_engine_if_pygmentize_is_not_available
50
- Rembrandt::Engines::Pygmentize.stubs(:available?).returns(false)
51
- Rembrandt::Engines::WebService.stubs(:available?).returns(true)
52
- expected_engine = Rembrandt::Engines::WebService
53
- lighter = Rembrandt::Highlighter.new
54
- assert_equal expected_engine, lighter.engine.class
86
+ def teardown
87
+ highlighter.store.flush
55
88
  end
56
89
  end
@@ -0,0 +1,22 @@
1
+ require './test/test_helper'
2
+ require './lib/rembrandt/language_normalizer'
3
+
4
+ class LanguageNormalizerTest < CodeHighlightTest
5
+ attr_reader :normalizer
6
+
7
+ def setup
8
+ @normalizer = Rembrandt::LanguageNormalizer.new
9
+ end
10
+
11
+ def test_it_processes_a_known_variant
12
+ assert_equal 'ruby', normalizer.process('ru')
13
+ assert_equal 'objc', normalizer.process('m')
14
+ assert_equal 'yaml', normalizer.process('yml')
15
+ end
16
+
17
+ def test_it_cannot_process_an_unknown_language
18
+ assert_raises(ArgumentError){
19
+ normalizer.process('asdf')
20
+ }
21
+ end
22
+ end
@@ -0,0 +1,45 @@
1
+ require './test/test_helper'
2
+ require './lib/rembrandt/stores/file'
3
+ require './lib/rembrandt/config'
4
+
5
+ class StoresFileTest < CodeHighlightTest
6
+ attr_reader :store
7
+
8
+ def target
9
+ Rembrandt::Config.file_store_directory
10
+ end
11
+
12
+ def setup
13
+ @store = Rembrandt::Stores::File.new
14
+ end
15
+
16
+ def test_it_creates_the_storage_folder
17
+ `rm -rf #{target}` if Dir.exist?(target)
18
+ refute Dir.exist?(target), "Directory #{target} should not exist."
19
+ store = Rembrandt::Stores::File.new(target)
20
+ assert Dir.exist?(target), "Directory #{target} should exist."
21
+ end
22
+
23
+ def test_it_fetches_data_from_a_file
24
+ sample = "Hello, World!"
25
+ key = "001"
26
+ store.write(key, sample)
27
+ fetched = store.read(key)
28
+ assert_equal sample, fetched
29
+ end
30
+
31
+ def test_it_calculates_keys
32
+ sample = "Hello, World!"
33
+ assert store.key_for(sample, 'ruby')
34
+ end
35
+
36
+ def test_it_uses_the_configured_output_directory
37
+ Rembrandt::Config.file_store_directory = './tmp/'
38
+ store2 = Rembrandt::Stores::File.new
39
+ assert_equal './tmp/', store2.output_directory
40
+ end
41
+
42
+ def teardown
43
+ store.flush
44
+ end
45
+ end
@@ -0,0 +1,67 @@
1
+ require './test/test_helper'
2
+ require './lib/rembrandt/stores/redis'
3
+
4
+ class StoresRedisTest < CodeHighlightTest
5
+ attr_reader :store
6
+
7
+ def setup
8
+ @store = Rembrandt::Stores::Redis.new
9
+ end
10
+
11
+ def test_it_is_not_available_when_redis_is_not_loaded
12
+ Object.const_set('REAL_REDIS', Redis)
13
+ Object.send(:remove_const, :Redis)
14
+ refute store.available?
15
+ Object.const_set('Redis', REAL_REDIS)
16
+ end
17
+
18
+ def test_it_is_available_when_redis_is_loaded
19
+ assert store.available?, "Redis should be available when required"
20
+ end
21
+
22
+ def test_it_fetches_data
23
+ sample = "Hello, World!"
24
+ key = "001"
25
+ store.write(key, sample)
26
+ fetched = store.read(key)
27
+ assert_equal sample, fetched
28
+ end
29
+
30
+ def test_it_calculates_keys
31
+ sample = "Hello, World!"
32
+ assert store.key_for(sample, 'ruby')
33
+ end
34
+
35
+ def test_it_flushes_the_database
36
+ store.write("002", "Hello")
37
+ assert store.read("002")
38
+ store.flush
39
+ refute store.read("002"), "All keys should be gone"
40
+ end
41
+
42
+ def test_fetch_does_not_write_when_there_is_no_block
43
+ refute store.fetch("hello", "ruby"), "hello should not be found"
44
+ key = store.key_for("hello", "ruby")
45
+ refute store.read(key), "hello should not have been written"
46
+ end
47
+
48
+ def test_fetch_writes_the_result_of_a_block
49
+ refute store.fetch("hello", "ruby")
50
+ result = store.fetch("hello", "ruby"){ "Hello, World" }
51
+ assert_equal "Hello, World", result
52
+ key = store.key_for("hello", "ruby")
53
+ assert_equal result, store.read(key)
54
+ end
55
+
56
+ def test_it_uses_a_redis_url_in_an_environment_variable
57
+ url = "redis://redisuser:redispassword@provider.example.com:9352/"
58
+ ENV['REMBRANDT_REDIS_URL'] = url
59
+ store2 = Rembrandt::Stores::Redis.new
60
+ assert_equal url, store2.url
61
+ ENV['REMBRANDT_REDIS_URL'] = ''
62
+ end
63
+
64
+ def teardown
65
+ store.flush
66
+ end
67
+ end
@@ -0,0 +1,3 @@
1
+ Blogger::Application.routes.draw do
2
+ resources :articles
3
+ end
@@ -0,0 +1,4 @@
1
+ <div class="highlight"><pre><span class="ss">Blogger</span><span class="p">:</span><span class="ss">:Application</span><span class="o">.</span><span class="n">routes</span><span class="o">.</span><span class="n">draw</span> <span class="k">do</span>
2
+ <span class="n">resources</span> <span class="ss">:articles</span>
3
+ <span class="k">end</span>
4
+ </pre></div>
@@ -0,0 +1,28 @@
1
+ <div class="highlight">
2
+ <table>
3
+ <tr>
4
+ <td class="gutter">
5
+ <pre class="line-numbers">
6
+ <span class='line-number'>1</span>
7
+ <span class='line-number'>2</span>
8
+ <span class='line-number'>3</span>
9
+ </pre>
10
+ </td>
11
+ <td class='code'>
12
+ <pre>
13
+ <code class='ruby'>
14
+ <span class='line'>
15
+ <span class="ss">Blogger</span><span class="p">:</span><span class="ss">:Application</span><span class="o">.</span><span class="n">routes</span><span class="o">.</span><span class="n">draw</span> <span class="k">do</span>
16
+ </span>
17
+ <span class='line'>
18
+ <span class="n">resources</span> <span class="ss">:articles</span>
19
+ </span>
20
+ <span class='line'>
21
+ <span class="k">end</span>
22
+ </span>
23
+ </code>
24
+ </pre>
25
+ </td>
26
+ </tr>
27
+ </table>
28
+ </div>
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rembrandt
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.3
4
+ version: 0.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jeff Casimir
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2013-12-23 00:00:00.000000000 Z
11
+ date: 2014-01-02 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -108,6 +108,34 @@ dependencies:
108
108
  - - '>='
109
109
  - !ruby/object:Gem::Version
110
110
  version: '0'
111
+ - !ruby/object:Gem::Dependency
112
+ name: redis
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - '>='
116
+ - !ruby/object:Gem::Version
117
+ version: '0'
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - '>='
123
+ - !ruby/object:Gem::Version
124
+ version: '0'
125
+ - !ruby/object:Gem::Dependency
126
+ name: tilt
127
+ requirement: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - '>='
130
+ - !ruby/object:Gem::Version
131
+ version: '0'
132
+ type: :runtime
133
+ prerelease: false
134
+ version_requirements: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - '>='
137
+ - !ruby/object:Gem::Version
138
+ version: '0'
111
139
  description: A library for generating and storing syntax-highlighted code
112
140
  email:
113
141
  - jeff@casimircreative.com
@@ -122,20 +150,35 @@ files:
122
150
  - README.md
123
151
  - Rakefile
124
152
  - lib/rembrandt.rb
153
+ - lib/rembrandt/config.rb
125
154
  - lib/rembrandt/engines/pygmentize.rb
155
+ - lib/rembrandt/engines/pygments_known_languages.rb
126
156
  - lib/rembrandt/engines/web_service.rb
157
+ - lib/rembrandt/formatters/formatted_code.rb
127
158
  - lib/rembrandt/formatters/table.rb
159
+ - lib/rembrandt/formatters/templates/table.erb
128
160
  - lib/rembrandt/highlighter.rb
161
+ - lib/rembrandt/language_normalizer.rb
162
+ - lib/rembrandt/stores/fetchable.rb
163
+ - lib/rembrandt/stores/file.rb
164
+ - lib/rembrandt/stores/redis.rb
129
165
  - lib/rembrandt/version.rb
130
166
  - rembrandt.gemspec
131
167
  - test/rembrandt/engines/pygmentize_test.rb
132
168
  - test/rembrandt/engines/web_service_test.rb
169
+ - test/rembrandt/formatters/formatted_code_test.rb
133
170
  - test/rembrandt/formatters/table_test.rb
134
171
  - test/rembrandt/highlighter_test.rb
172
+ - test/rembrandt/language_normalizer_test.rb
173
+ - test/rembrandt/stores/file_test.rb
174
+ - test/rembrandt/stores/redis_test.rb
135
175
  - test/support/python_sample_1.py
136
176
  - test/support/python_sample_1.py.html
137
177
  - test/support/ruby_sample_1.rb
138
178
  - test/support/ruby_sample_1.rb.html
179
+ - test/support/ruby_sample_2.rb
180
+ - test/support/ruby_sample_2.rb.html
181
+ - test/support/ruby_sample_2.rb.tableized.html
139
182
  - test/support/vcr_cassettes/web_engine_highlights_ruby_sample_1.yml
140
183
  - test/support/vcr_cassettes/web_engine_is_accessible.yml
141
184
  - test/test_helper.rb
@@ -159,19 +202,26 @@ required_rubygems_version: !ruby/object:Gem::Requirement
159
202
  version: '0'
160
203
  requirements: []
161
204
  rubyforge_project:
162
- rubygems_version: 2.1.11
205
+ rubygems_version: 2.0.6
163
206
  signing_key:
164
207
  specification_version: 4
165
208
  summary: Powered by the amazing Pygments Python library.
166
209
  test_files:
167
210
  - test/rembrandt/engines/pygmentize_test.rb
168
211
  - test/rembrandt/engines/web_service_test.rb
212
+ - test/rembrandt/formatters/formatted_code_test.rb
169
213
  - test/rembrandt/formatters/table_test.rb
170
214
  - test/rembrandt/highlighter_test.rb
215
+ - test/rembrandt/language_normalizer_test.rb
216
+ - test/rembrandt/stores/file_test.rb
217
+ - test/rembrandt/stores/redis_test.rb
171
218
  - test/support/python_sample_1.py
172
219
  - test/support/python_sample_1.py.html
173
220
  - test/support/ruby_sample_1.rb
174
221
  - test/support/ruby_sample_1.rb.html
222
+ - test/support/ruby_sample_2.rb
223
+ - test/support/ruby_sample_2.rb.html
224
+ - test/support/ruby_sample_2.rb.tableized.html
175
225
  - test/support/vcr_cassettes/web_engine_highlights_ruby_sample_1.yml
176
226
  - test/support/vcr_cassettes/web_engine_is_accessible.yml
177
227
  - test/test_helper.rb