code-ruby 0.7.4 → 0.7.6

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
  SHA256:
3
- metadata.gz: c1de692db935f0bf2da829334bd120b8fa972a686b700c529379f4ac4631d34b
4
- data.tar.gz: 1fc45c35736818f606f17ccb0876be91d6b40c71415dab4e5b66693f3ace40d5
3
+ metadata.gz: 64c95ed04939ffd5a6ef493a612ecd1e6b8d877d84be3d3f5bf3420a91642651
4
+ data.tar.gz: e8b9314d611e70a621f003ddf70d1e848a34dd479c907701c7bbddfdba7c136c
5
5
  SHA512:
6
- metadata.gz: e4f23cc4451bc13bed8b98068707c026bbf3e603849872e6c3593d0fd18d81b62afdc27105437138156bd7edc88716b2864a4653b2af49efe915ad0d097d3b1a
7
- data.tar.gz: 533109d631965b229c82a46ed04f5158a956f38eaa1154cdaed66f0a6f50943e2e7fb47ec8f81f229b14bb24b611fe1b32ffa3420ecf44eb5a61eb902cee78b7
6
+ metadata.gz: f4fd860c6788054132fab89667660dde0907f816cc9c07d251569a3599b1504a23b620145173243cc2d2e0f22cd35bedec8e695bd589b195de22adf6ee12ddbc
7
+ data.tar.gz: 627970ecc40ebc5831be9a099fab08d8372564fd036baa247ae1b953ffa693feda02da7c9d23dbbe217afd57ec807184ecb40f75a59cdd97aab97ff897ee44dd
data/bin/code CHANGED
@@ -1,13 +1,13 @@
1
1
  #!/usr/bin/env ruby
2
2
  # frozen_string_literal: true
3
3
 
4
- require 'optparse'
5
- require_relative '../lib/code-ruby'
4
+ require "optparse"
5
+ require_relative "../lib/code-ruby"
6
6
 
7
7
  options = {
8
8
  timeout: 0,
9
9
  profile: false,
10
- profiler: 'text',
10
+ profiler: "text",
11
11
  input: "",
12
12
  context: "",
13
13
  parse: false
@@ -15,17 +15,17 @@ options = {
15
15
 
16
16
  OptionParser
17
17
  .new do |opts|
18
- opts.banner = 'Usage: code [options]'
18
+ opts.banner = "Usage: code [options]"
19
19
 
20
- opts.on('-v', '--version', 'Version of template') do |_input|
20
+ opts.on("-v", "--version", "Version of template") do |_input|
21
21
  puts Code::Version
22
22
  exit
23
23
  end
24
24
 
25
25
  opts.on(
26
- '-i INPUT',
27
- '--input INPUT',
28
- 'Input in the code language (String or File)'
26
+ "-i INPUT",
27
+ "--input INPUT",
28
+ "Input in the code language (String or File)"
29
29
  ) do |input|
30
30
  input = File.read(input) if File.exist?(input)
31
31
 
@@ -33,35 +33,35 @@ OptionParser
33
33
  end
34
34
 
35
35
  opts.on(
36
- '-c CONTEXT',
37
- '--context CONTEXT',
38
- 'Context in the code language (String or File)'
36
+ "-c CONTEXT",
37
+ "--context CONTEXT",
38
+ "Context in the code language (String or File)"
39
39
  ) do |context|
40
40
  context = File.read(context) if File.exist?(context)
41
41
 
42
42
  options[:context] = context
43
43
  end
44
44
 
45
- opts.on('-p', '--parse', 'Get parser results for input') do |parse|
45
+ opts.on("-p", "--parse", "Get parser results for input") do |parse|
46
46
  options[:parse] = parse
47
47
  end
48
48
 
49
49
  opts.on(
50
- '-t TIMEOUT',
51
- '--timeout TIMEOUT',
52
- 'Set timeout in seconds'
50
+ "-t TIMEOUT",
51
+ "--timeout TIMEOUT",
52
+ "Set timeout in seconds"
53
53
  ) { |timeout| options[:timeout] = timeout.to_f }
54
54
 
55
- opts.on('--profile', 'Profile Ruby code') do |_timeout|
56
- require 'ruby-prof'
55
+ opts.on("--profile", "Profile Ruby code") do |_timeout|
56
+ require "ruby-prof"
57
57
  options[:profile] = true
58
58
  end
59
59
 
60
60
  opts.on(
61
- '--profiler TYPE',
62
- 'Profiler output type (text (default) or html)'
61
+ "--profiler TYPE",
62
+ "Profiler output type (text (default) or html)"
63
63
  ) do |profiler|
64
- require 'ruby-prof'
64
+ require "ruby-prof"
65
65
  options[:profile] = true
66
66
  options[:profiler] = profiler
67
67
  end
@@ -74,21 +74,21 @@ if options[:parse]
74
74
  pp Code::Parser.parse(options[:input]).to_raw
75
75
  else
76
76
  print Code.evaluate(
77
- options[:input],
78
- options[:context],
79
- output: $stdout,
80
- error: $stderr,
81
- timeout: options[:timeout]
82
- )
77
+ options[:input],
78
+ options[:context],
79
+ output: $stdout,
80
+ error: $stderr,
81
+ timeout: options[:timeout]
82
+ )
83
83
  end
84
84
 
85
85
  if options[:profile]
86
86
  result = RubyProf.stop
87
87
 
88
- if options[:profiler] == 'text'
88
+ if options[:profiler] == "text"
89
89
  printer = RubyProf::FlatPrinter.new(result)
90
90
  printer.print($stdout)
91
- elsif options[:profiler] == 'html'
91
+ elsif options[:profiler] == "html"
92
92
  printer = RubyProf::GraphHtmlPrinter.new(result)
93
93
  printer.print($stdout)
94
94
  else
@@ -6,7 +6,10 @@ class Code
6
6
  def initialize(parsed)
7
7
  @whole = parsed.delete(:whole)
8
8
 
9
- @exponent = Node::Statement.new(parsed.delete(:exponent)) if parsed.key?(:exponent)
9
+ @exponent =
10
+ Node::Statement.new(parsed.delete(:exponent)) if parsed.key?(
11
+ :exponent
12
+ )
10
13
 
11
14
  super(parsed)
12
15
  end
@@ -47,7 +47,7 @@ class Code
47
47
  else
48
48
  arguments << Object::Argument.new(
49
49
  Object::Dictionary.new(
50
- {argument.name => argument.evaluate(**args).value}
50
+ { argument.name => argument.evaluate(**args).value }
51
51
  )
52
52
  )
53
53
  end
@@ -6,7 +6,10 @@ class Code
6
6
  def initialize(parsed)
7
7
  @decimal = parsed.delete(:decimal)
8
8
 
9
- @exponent = Node::Statement.new(parsed.delete(:exponent)) if parsed.key?(:exponent)
9
+ @exponent =
10
+ Node::Statement.new(parsed.delete(:exponent)) if parsed.key?(
11
+ :exponent
12
+ )
10
13
 
11
14
  super(parsed)
12
15
  end
@@ -8,7 +8,7 @@ class Code
8
8
  if parsed.key?(:statement)
9
9
  @key = Node::Statement.new(parsed.delete(:statement))
10
10
  elsif parsed.key?(:name)
11
- @key = Node::String.new([{text: parsed.delete(:name)}])
11
+ @key = Node::String.new([{ text: parsed.delete(:name) }])
12
12
  end
13
13
 
14
14
  @value = Node::Code.new(parsed.delete(:value)) if parsed[:value]
data/lib/code/node/if.rb CHANGED
@@ -32,21 +32,21 @@ class Code
32
32
 
33
33
  def evaluate(**args)
34
34
  if @first_operator == IF_KEYWORD &&
35
- @first_statement.evaluate(**args).truthy?
35
+ @first_statement.evaluate(**args).truthy?
36
36
  @first_body.evaluate(**args)
37
37
  elsif @first_operator == UNLESS_KEYWORD &&
38
- @first_statement.evaluate(**args).falsy?
38
+ @first_statement.evaluate(**args).falsy?
39
39
  @first_body.evaluate(**args)
40
40
  else
41
41
  @elses.each do |elses|
42
42
  if elses.operator == ELSIF_KEYWORD &&
43
- elses.statement.evaluate(**args).truthy?
43
+ elses.statement.evaluate(**args).truthy?
44
44
  return elses.body.evaluate(**args)
45
45
  elsif elses.operator == IF_KEYWORD &&
46
- elses.statement.evaluate(**args).truthy?
46
+ elses.statement.evaluate(**args).truthy?
47
47
  return elses.body.evaluate(**args)
48
48
  elsif elses.operator == UNLESS_KEYWORD &&
49
- elses.statement.evaluate(**args).falsy?
49
+ elses.statement.evaluate(**args).falsy?
50
50
  return elses.body.evaluate(**args)
51
51
  elsif elses.operator == ELSE_KEYWORD
52
52
  return elses.body.evaluate(**args)
@@ -20,7 +20,16 @@ class Code
20
20
  end
21
21
 
22
22
  def evaluate(**_args)
23
- ::Code::Object::String.new(@text)
23
+ ::Code::Object::String.new(
24
+ @text
25
+ .gsub('\n', "\n")
26
+ .gsub('\r', "\r")
27
+ .gsub('\t', "\t")
28
+ .gsub('\b', "\b")
29
+ .gsub('\f', "\f")
30
+ .gsub('\a', "\a")
31
+ .gsub('\e', "\e")
32
+ )
24
33
  end
25
34
  end
26
35
 
@@ -9,7 +9,9 @@ class Code
9
9
  @raw = BigDecimal(decimal)
10
10
 
11
11
  return unless exponent
12
- raise ::Code::Error::TypeError, "exponent is not a number" unless exponent.is_a?(Number)
12
+ unless exponent.is_a?(Number)
13
+ raise ::Code::Error::TypeError, "exponent is not a number"
14
+ end
13
15
 
14
16
  @raw *= 10**exponent.raw
15
17
  end
@@ -215,7 +215,9 @@ class Code
215
215
  def code_delete(*arguments, index: Integer.new(0), **globals)
216
216
  default =
217
217
  (
218
- arguments.last if arguments.last.is_a?(Function) && arguments.size > 1
218
+ if arguments.last.is_a?(Function) && arguments.size > 1
219
+ arguments.last
220
+ end
219
221
  )
220
222
 
221
223
  arguments = arguments[..-2] if default
@@ -340,7 +342,9 @@ class Code
340
342
  def code_fetch(*arguments, index: Integer.new(0), **globals)
341
343
  default =
342
344
  (
343
- arguments.last if arguments.last.is_a?(Function) && arguments.size > 1
345
+ if arguments.last.is_a?(Function) && arguments.size > 1
346
+ arguments.last
347
+ end
344
348
  )
345
349
 
346
350
  arguments = arguments[..-2] if default
@@ -490,7 +494,9 @@ class Code
490
494
  def code_merge(*arguments, **globals)
491
495
  conflict =
492
496
  (
493
- arguments.last if arguments.last.is_a?(Function) && arguments.size > 1
497
+ if arguments.last.is_a?(Function) && arguments.size > 1
498
+ arguments.last
499
+ end
494
500
  )
495
501
 
496
502
  arguments = arguments[..-2] if conflict
@@ -76,7 +76,7 @@ class Code
76
76
  signature.last[parameter.name] = Object
77
77
  signature
78
78
  else
79
- signature + [{parameter.name => Object}]
79
+ signature + [{ parameter.name => Object }]
80
80
  end
81
81
  else
82
82
  signature + [Object]
@@ -12,7 +12,7 @@ class Code
12
12
  arguments = args.fetch(:arguments, [])
13
13
  output = args.fetch(:output)
14
14
  context = args.fetch(:context)
15
- multi_fetch(args, *GLOBALS)
15
+ globals = multi_fetch(args, *GLOBALS)
16
16
  value = arguments.first&.value
17
17
 
18
18
  case operator.to_s
@@ -28,6 +28,9 @@ class Code
28
28
  when "Dictionary"
29
29
  sig(args) { Object.maybe }
30
30
  value ? value.code_to_dictionnary : Class.new(Dictionary)
31
+ when "fetch"
32
+ sig(args) { [Object, Function.maybe] }
33
+ context.code_fetch(*arguments.map(&:value), **globals)
31
34
  when "Function"
32
35
  sig(args) { Object.maybe }
33
36
  value ? value.code_to_function : Class.new(Function)
@@ -10,7 +10,9 @@ class Code
10
10
 
11
11
  return unless exponent
12
12
 
13
- raise Code::Error::TypeError, "exponent is not a number" unless exponent.is_a?(Number)
13
+ unless exponent.is_a?(Number)
14
+ raise Code::Error::TypeError, "exponent is not a number"
15
+ end
14
16
 
15
17
  @raw *= 10**exponent.raw
16
18
  end
@@ -25,8 +25,8 @@ class Code
25
25
  args
26
26
  .select(&:keyword?)
27
27
  .map do |argument|
28
- [argument.name.to_sym, Ruby.from_code(argument.value)]
29
- end
28
+ [argument.name.to_sym, Ruby.from_code(argument.value)]
29
+ end
30
30
  .to_h
31
31
 
32
32
  Ruby.to_code(raw.call(*regular_arguments, **keyword_arguments))
@@ -68,7 +68,7 @@ class Code
68
68
  [
69
69
  {
70
70
  function: {
71
- parameters: [{name: "_"}],
71
+ parameters: [{ name: "_" }],
72
72
  body: [
73
73
  {
74
74
  left_operation: {
@@ -78,7 +78,7 @@ class Code
78
78
  }
79
79
  },
80
80
  others: [
81
- {operator: ".", statement: {call: {name: raw}}}
81
+ { operator: ".", statement: { call: { name: raw } } }
82
82
  ]
83
83
  }
84
84
  }
data/lib/code/object.rb CHANGED
@@ -149,7 +149,9 @@ class Code
149
149
  end
150
150
 
151
151
  def hash
152
- raise NotImplementedError, "#{self.class.name}#hash" unless respond_to?(:raw)
152
+ unless respond_to?(:raw)
153
+ raise NotImplementedError, "#{self.class.name}#hash"
154
+ end
153
155
 
154
156
  [self.class, raw].hash
155
157
  end
@@ -38,8 +38,7 @@ class Code
38
38
 
39
39
  def root
40
40
  (
41
- opening_square_bracket.ignore << whitespace? <<
42
- element.repeat <<
41
+ opening_square_bracket.ignore << whitespace? << element.repeat <<
43
42
  (whitespace? << closing_square_bracket.ignore).maybe
44
43
  ).aka(:list) | String
45
44
  end
data/lib/code/ruby.rb CHANGED
@@ -55,7 +55,7 @@ class Code
55
55
  def from_code
56
56
  if code?
57
57
  if code_nothing? || code_boolean? || code_decimal? || code_integer? ||
58
- code_range? || code_string?
58
+ code_range? || code_string?
59
59
  raw.raw
60
60
  elsif code_dictionnary?
61
61
  raw
@@ -15,7 +15,10 @@ class Code
15
15
  argument = argument.raw
16
16
  (argument.keys + hash.keys).uniq.all? do |key|
17
17
  if hash[key]
18
- valid_for?(expected: hash[key], actual: argument[key] || Object::Nothing.new)
18
+ valid_for?(
19
+ expected: hash[key],
20
+ actual: argument[key] || Object::Nothing.new
21
+ )
19
22
  else
20
23
  false
21
24
  end
@@ -10,8 +10,7 @@ class Code
10
10
  end
11
11
 
12
12
  def valid?(argument)
13
- !argument ||
14
- argument.is_a?(Object::Nothing) ||
13
+ !argument || argument.is_a?(Object::Nothing) ||
15
14
  valid_for?(expected: clazz, actual: argument)
16
15
  end
17
16
 
data/lib/code/version.rb CHANGED
@@ -2,4 +2,4 @@
2
2
 
3
3
  require_relative "../code"
4
4
 
5
- Code::Version = Gem::Version.new("0.7.4")
5
+ Code::Version = Gem::Version.new("0.7.6")
data/lib/code.rb CHANGED
@@ -37,7 +37,13 @@ class Code
37
37
  if context == EMPTY_STRING
38
38
  Object::Context.new
39
39
  else
40
- Code.evaluate(context, timeout:, output:, error:, ruby:).code_to_context
40
+ Code.evaluate(
41
+ context,
42
+ timeout:,
43
+ output:,
44
+ error:,
45
+ ruby:
46
+ ).code_to_context
41
47
  end
42
48
 
43
49
  context = ruby.merge(context)
@@ -0,0 +1,16 @@
1
+ require "spec_helper"
2
+
3
+ RSpec.describe Code::Object::String do
4
+ [
5
+ [":a", "a"],
6
+ [":a_b_c_0123", "a_b_c_0123"],
7
+ ['"Hello"', "Hello"],
8
+ ["'Hello'", "Hello"],
9
+ ['"Hello\nWorld"', "Hello\nWorld"],
10
+ ["'Hello\\nWorld'", "Hello\nWorld"],
11
+ ].each do |input, expected|
12
+ it "(#{input}).to_s == #{expected.inspect}" do
13
+ expect(Code.evaluate(input).to_s).to eq(expected)
14
+ end
15
+ end
16
+ end
data/spec/code_spec.rb CHANGED
@@ -4,7 +4,7 @@ require "spec_helper"
4
4
 
5
5
  RSpec.describe Code do
6
6
  [
7
- ["9975×14÷8", "17456.25"],
7
+ %w[9975×14÷8 17456.25],
8
8
  ["\r\n", "nothing"],
9
9
  ["1 + 1", "2"],
10
10
  ["a = 1", "1"],
@@ -148,7 +148,7 @@ RSpec.describe Code do
148
148
  end
149
149
 
150
150
  it "converts nil" do
151
- ruby = Code::Ruby.from_code(Code.evaluate("a", ruby: {a: nil}))
151
+ ruby = Code::Ruby.from_code(Code.evaluate("a", ruby: { a: nil }))
152
152
 
153
153
  expect(ruby).to eq(nil)
154
154
  end
@@ -159,9 +159,23 @@ RSpec.describe Code do
159
159
  )
160
160
  end
161
161
 
162
+ describe "#fetch" do
163
+ it "returns the value when present" do
164
+ expect(Code.evaluate("fetch(:downcase)", "{ downcase: 1 }")).to eq(
165
+ Code.evaluate("1")
166
+ )
167
+ end
168
+
169
+ it "returns the default value when not present" do
170
+ expect(Code.evaluate("fetch(:downcase) { 2 }")).to eq(
171
+ Code.evaluate("2")
172
+ )
173
+ end
174
+ end
175
+
162
176
  it "works with nested objects" do
163
177
  expect(
164
- Code.evaluate("items.first.title", ruby: {items: [{title: "Hello"}]})
178
+ Code.evaluate("items.first.title", ruby: { items: [{ title: "Hello" }] })
165
179
  ).to eq(Code.evaluate(":Hello"))
166
180
  end
167
181
 
@@ -170,7 +184,7 @@ RSpec.describe Code do
170
184
  Code.evaluate(
171
185
  "items.map { |item| item.title }",
172
186
  ruby: {
173
- items: [{title: "Hello"}]
187
+ items: [{ title: "Hello" }]
174
188
  }
175
189
  )
176
190
  ).to eq(Code.evaluate("[:Hello]"))
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: code-ruby
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.7.4
4
+ version: 0.7.6
5
5
  platform: ruby
6
6
  authors:
7
7
  - Dorian Marié
@@ -174,6 +174,7 @@ files:
174
174
  - spec/code/object/list_spec.rb
175
175
  - spec/code/object/nothing_spec.rb
176
176
  - spec/code/object/range_spec.rb
177
+ - spec/code/object/string_spec.rb
177
178
  - spec/code/parser/boolean_spec.rb
178
179
  - spec/code/parser/chained_call.rb
179
180
  - spec/code/parser/dictionary_spec.rb