sexp2ruby 0.0.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.
- checksums.yaml +7 -0
- data/.gitignore +2 -0
- data/.travis.yml +10 -0
- data/CHANGELOG.md +3 -0
- data/Gemfile +3 -0
- data/LICENSE.txt +24 -0
- data/README.md +32 -0
- data/Rakefile +92 -0
- data/lib/sexp2ruby/core_extensions/regexp.rb +26 -0
- data/lib/sexp2ruby/errors.rb +7 -0
- data/lib/sexp2ruby/processor.rb +1159 -0
- data/lib/sexp2ruby/version.rb +3 -0
- data/lib/sexp2ruby.rb +4 -0
- data/sexp2ruby.gemspec +32 -0
- data/spec/lib/processor_spec.rb +183 -0
- data/spec/spec_helper.rb +10 -0
- data/test/test_ruby2ruby.rb +496 -0
- metadata +137 -0
data/lib/sexp2ruby.rb
ADDED
data/sexp2ruby.gemspec
ADDED
@@ -0,0 +1,32 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require "sexp2ruby/version"
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "sexp2ruby"
|
8
|
+
spec.version = Sexp2Ruby::VERSION
|
9
|
+
spec.authors = ['Ryan Davis', 'Jared Beck']
|
10
|
+
spec.email = ['jared@jaredbeck.com']
|
11
|
+
spec.summary = 'Generates ruby from RubyParser S-expressions'
|
12
|
+
spec.description = <<-EOS
|
13
|
+
Generates ruby from RubyParser-compatible S-expressions.
|
14
|
+
It is a fork of ruby2ruby with slightly different goals.
|
15
|
+
EOS
|
16
|
+
spec.homepage = 'https://github.com/jaredbeck/sexp2ruby'
|
17
|
+
spec.license = 'MIT'
|
18
|
+
|
19
|
+
spec.files = `git ls-files -z`.split("\x0")
|
20
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
21
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
22
|
+
spec.require_paths = ['lib']
|
23
|
+
|
24
|
+
spec.required_ruby_version = ">= 1.9.3"
|
25
|
+
|
26
|
+
spec.add_runtime_dependency "sexp_processor", "~> 4.6"
|
27
|
+
|
28
|
+
spec.add_development_dependency "rspec-core", "~> 3.2"
|
29
|
+
spec.add_development_dependency "rspec-expectations", "~> 3.2"
|
30
|
+
spec.add_development_dependency "rspec-mocks", "~> 3.2"
|
31
|
+
spec.add_development_dependency "ruby_parser", "~> 3.7"
|
32
|
+
end
|
@@ -0,0 +1,183 @@
|
|
1
|
+
require 'ruby_parser'
|
2
|
+
|
3
|
+
module Sexp2Ruby
|
4
|
+
RSpec.describe Processor do
|
5
|
+
let(:processor) { described_class.new }
|
6
|
+
let(:processor_hash19) { described_class.new(hash_syntax: :ruby19) }
|
7
|
+
|
8
|
+
describe "#new" do
|
9
|
+
it "accepts hash_syntax option" do
|
10
|
+
expect(processor_hash19.hash_syntax).to eq(:ruby19)
|
11
|
+
end
|
12
|
+
|
13
|
+
context "unknown option" do
|
14
|
+
it "raises error" do
|
15
|
+
expect {
|
16
|
+
described_class.new(foo: "bar")
|
17
|
+
}.to raise_error(InvalidOption)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
context "bad option value" do
|
22
|
+
it "raises error" do
|
23
|
+
expect {
|
24
|
+
described_class.new(hash_syntax: "banana")
|
25
|
+
}.to raise_error(InvalidOption)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
describe "#extract_option" do
|
31
|
+
context "valid value" do
|
32
|
+
it "returns value" do
|
33
|
+
expect(
|
34
|
+
processor.extract_option([:a, :b], :b, :c)
|
35
|
+
).to eq(:b)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
context "nil value" do
|
40
|
+
it "returns default value" do
|
41
|
+
expect(
|
42
|
+
processor.extract_option([:a, :b], nil, :c)
|
43
|
+
).to eq(:c)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
context "invalid value" do
|
48
|
+
it "raises error" do
|
49
|
+
expect {
|
50
|
+
processor.extract_option([:a, :b], :d, :c)
|
51
|
+
}.to raise_error(InvalidOption)
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
describe "#process" do
|
57
|
+
context "hash" do
|
58
|
+
it "ruby19_one_pair" do
|
59
|
+
inp = s(:hash, s(:lit, :foo), s(:str, "bar"))
|
60
|
+
compare(inp, '{ foo: "bar" }', processor_hash19)
|
61
|
+
end
|
62
|
+
|
63
|
+
it "ruby19_when_key_has_special_chars" do
|
64
|
+
inp = s(:hash, s(:str, "hurr:durr"), s(:str, "bar"))
|
65
|
+
compare(inp, '{ "hurr:durr" => "bar" }', processor_hash19)
|
66
|
+
end
|
67
|
+
|
68
|
+
it "ruby19_when_key_is_not_a_literal" do
|
69
|
+
inp = s(:hash, s(:call, nil, :foo, s(:str, "bar")), s(:str, "baz"))
|
70
|
+
compare(inp, '{ foo("bar") => "baz" }', processor_hash19)
|
71
|
+
end
|
72
|
+
|
73
|
+
it "ruby19_mixed_pairs" do
|
74
|
+
inp = s(:hash, s(:lit, :foo), s(:str, "bar"), s(:lit, 0.7), s(:str, "baz"))
|
75
|
+
compare(inp, '{ foo: "bar", 0.7 => "baz" }', processor_hash19)
|
76
|
+
end
|
77
|
+
|
78
|
+
describe "parentheses" do
|
79
|
+
it "does not wrap string in parens" do
|
80
|
+
inp = s(:hash, s(:lit, :k), s(:str, "banana"))
|
81
|
+
out = '{ :k => "banana" }'
|
82
|
+
compare(inp, out, processor)
|
83
|
+
end
|
84
|
+
|
85
|
+
it "does not wrap number in parens" do
|
86
|
+
inp = s(:hash, s(:lit, :k), s(:lit, 0.07))
|
87
|
+
out = "{ :k => 0.07 }"
|
88
|
+
compare(inp, out, processor)
|
89
|
+
end
|
90
|
+
|
91
|
+
it "does not wrap boolean in parens" do
|
92
|
+
inp = s(:hash, s(:lit, :k), s(:true))
|
93
|
+
out = "{ :k => true }"
|
94
|
+
compare(inp, out, processor)
|
95
|
+
end
|
96
|
+
|
97
|
+
it "does not wrap nil in parens" do
|
98
|
+
inp = s(:hash, s(:lit, :k), s(:nil))
|
99
|
+
out = "{ :k => nil }"
|
100
|
+
compare(inp, out, processor)
|
101
|
+
end
|
102
|
+
|
103
|
+
it "does not wrap local variable (lvar) in parens" do
|
104
|
+
inp = s(:hash, s(:lit, :k), s(:lvar, :x))
|
105
|
+
out = "{ :k => x }"
|
106
|
+
compare(inp, out, processor, false)
|
107
|
+
end
|
108
|
+
|
109
|
+
it "does not wrap call in parens" do
|
110
|
+
inp = s(:hash, s(:lit, :k), s(:call, nil, :foo, s(:lit, :bar)))
|
111
|
+
out = "{ :k => foo(:bar) }"
|
112
|
+
compare(inp, out, processor)
|
113
|
+
end
|
114
|
+
|
115
|
+
it "wraps method call with block (iter) in parens" do
|
116
|
+
iter = s(:iter, s(:call, nil, :foo), s(:args), s(:str, "bar"))
|
117
|
+
inp = s(:hash, s(:lit, :k), iter)
|
118
|
+
out = '{ :k => (foo { "bar" }) }'
|
119
|
+
compare(inp, out, processor, false)
|
120
|
+
end
|
121
|
+
end
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
describe "#ruby19_hash_key?" do
|
126
|
+
context "symbol" do
|
127
|
+
it "returns true" do
|
128
|
+
expect(processor.ruby19_hash_key?(s(:lit, :foo))).to eq(true)
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
132
|
+
context "not a symbol" do
|
133
|
+
it "returns false" do
|
134
|
+
expect(processor.ruby19_hash_key?(s(:str, "foo"))).to eq(false)
|
135
|
+
expect(processor.ruby19_hash_key?(s(:lit, 7))).to eq(false)
|
136
|
+
expect(processor.ruby19_hash_key?(s(:true))).to eq(false)
|
137
|
+
end
|
138
|
+
end
|
139
|
+
end
|
140
|
+
|
141
|
+
describe "#util_dthing" do
|
142
|
+
let(:interpolation) {
|
143
|
+
s('a"b',
|
144
|
+
s(:evstr, s(:call, s(:lit, 1), :+, s(:lit, 1))),
|
145
|
+
s(:str, 'c"d/e')
|
146
|
+
)
|
147
|
+
}
|
148
|
+
|
149
|
+
context "dregx" do
|
150
|
+
it "generates regex with interpolation" do
|
151
|
+
out = '/a"b#{(1 + 1)}c"d\/e/'
|
152
|
+
expect(out).to eval_to(/a"b2c"d\/e/)
|
153
|
+
expect(processor.util_dthing(:dregx, interpolation)).to eq(out[1..-2])
|
154
|
+
end
|
155
|
+
|
156
|
+
it "generates regex with interpolation" do
|
157
|
+
interpolation = s('[\/\"]', s(:evstr, s(:lit, 42)))
|
158
|
+
out = '/[\/\"]#{42}/'
|
159
|
+
expect(out).to eval_to(/[\/\"]42/)
|
160
|
+
expect(processor.util_dthing(:dregx, interpolation)).to eq(out[1..-2])
|
161
|
+
end
|
162
|
+
end
|
163
|
+
|
164
|
+
context "dstr" do
|
165
|
+
it "generates string with interpolation" do
|
166
|
+
out = '"a\"b#{(1 + 1)}c\"d/e"'
|
167
|
+
expect(out).to eval_to('a"b2c"d/e')
|
168
|
+
expect(processor.util_dthing(:dstr, interpolation)).to eq(out[1..-2])
|
169
|
+
end
|
170
|
+
end
|
171
|
+
end
|
172
|
+
|
173
|
+
def compare(sexp, expected_ruby, processor, check_sexp = true, expected_eval = nil)
|
174
|
+
if check_sexp
|
175
|
+
expect(RubyParser.new.process(expected_ruby)).to eq(sexp)
|
176
|
+
end
|
177
|
+
expect(processor.process(sexp)).to eq(expected_ruby)
|
178
|
+
if expected_eval
|
179
|
+
expect(eval(expected_ruby)).to eq(expected_eval)
|
180
|
+
end
|
181
|
+
end
|
182
|
+
end
|
183
|
+
end
|