rembrandt 0.0.3 → 0.1.0

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.
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