tickly 0.0.3 → 0.0.4
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/tickly/evaluator.rb +3 -2
- data/lib/tickly/node_extractor.rb +22 -0
- data/lib/tickly/parser.rb +59 -26
- data/lib/tickly.rb +10 -84
- data/test/test-data/nuke_group.txt +1 -1
- data/test/test_evaluator.rb +3 -3
- data/test/test_node_extractor.rb +30 -0
- data/test/test_parser.rb +49 -56
- data/tickly.gemspec +4 -3
- metadata +5 -4
- data/test/test_split_array.rb +0 -28
data/lib/tickly/evaluator.rb
CHANGED
@@ -18,7 +18,8 @@ module Tickly
|
|
18
18
|
handler_class = @node_handlers.find{|e| unconst_name(e) == expr[0]}
|
19
19
|
handler_arguments = expr[1]
|
20
20
|
hash_of_args = {}
|
21
|
-
|
21
|
+
# Use 1..-1 to skip the curly brace symbol
|
22
|
+
expr[1][1..-1].map do | e |
|
22
23
|
# The name of the command is the first element, always
|
23
24
|
hash_of_args[e[0]] = e[1]
|
24
25
|
end
|
@@ -41,7 +42,7 @@ module Tickly
|
|
41
42
|
end
|
42
43
|
|
43
44
|
def has_subcommand?(expr)
|
44
|
-
expr[1]
|
45
|
+
expr[1][0] == :c
|
45
46
|
end
|
46
47
|
end
|
47
48
|
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module Tickly
|
2
|
+
# A more refined version of the Parser class that can scope itself to the passed Nuke node
|
3
|
+
# classnames. It will toss all of the node data that is not relevant, keeping only nodes that are
|
4
|
+
# required.
|
5
|
+
class NodeExtractor < Parser
|
6
|
+
def initialize(*interesting_node_class_names)
|
7
|
+
@nodes = interesting_node_class_names
|
8
|
+
end
|
9
|
+
|
10
|
+
# Override this to remove any unneeded subexpressions
|
11
|
+
def expand_subexpr!(expr, at_depth)
|
12
|
+
if is_node_constructor?(expr, at_depth)
|
13
|
+
node_class_name = expr[0]
|
14
|
+
expr.replace([:discarded]) unless @nodes.include?(node_class_name)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def is_node_constructor?(expr, depth)
|
19
|
+
depth == 1 && expr[0].is_a?(String) && expr.length == 2 && expr[1][0] == :c
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
data/lib/tickly/parser.rb
CHANGED
@@ -3,14 +3,18 @@ require 'stringio'
|
|
3
3
|
module Tickly
|
4
4
|
|
5
5
|
class Parser
|
6
|
-
|
6
|
+
|
7
7
|
# Parses a piece of TCL and returns it converted into internal expression
|
8
|
-
# structures (nested StringExpr or
|
8
|
+
# structures (nested StringExpr or LiteralExpr objects).
|
9
9
|
def parse(io_or_str)
|
10
10
|
io = io_or_str.respond_to?(:read) ? io_or_str : StringIO.new(io_or_str)
|
11
11
|
sub_parse(io)
|
12
12
|
end
|
13
13
|
|
14
|
+
# Override this to remove any unneeded subexpressions
|
15
|
+
def expand_subexpr!(expr, at_depth)
|
16
|
+
end
|
17
|
+
|
14
18
|
private
|
15
19
|
|
16
20
|
LAST_CHAR = -1..-1 # If we were 1.9 only we could use -1
|
@@ -19,55 +23,98 @@ module Tickly
|
|
19
23
|
# or until the IO is exhausted. The last argument is the class used to
|
20
24
|
# compose the subexpression being parsed. The subparser is reentrant and not
|
21
25
|
# destructive for the object containing it.
|
22
|
-
def sub_parse(io, stop_char = nil,
|
26
|
+
def sub_parse(io, stop_char = nil, stack_depth = 0)
|
23
27
|
# A standard stack is an expression that does not evaluate to a string
|
24
|
-
stack =
|
28
|
+
stack = []
|
25
29
|
buf = ''
|
30
|
+
last_char_was_linebreak = false
|
26
31
|
until io.eof?
|
27
32
|
char = io.read(1)
|
28
33
|
|
29
34
|
if buf[LAST_CHAR] != ESC
|
30
35
|
if char == stop_char # Bail out of a subexpr
|
31
36
|
stack << buf if (buf.length > 0)
|
32
|
-
|
37
|
+
# Chip away the tailing linebreak if it's there
|
38
|
+
chomp!(stack)
|
39
|
+
return stack
|
33
40
|
elsif char == " " || char == "\n" # Space
|
34
41
|
if buf.length > 0
|
35
42
|
stack << buf
|
36
43
|
buf = ''
|
37
44
|
end
|
38
45
|
if char == "\n" # Introduce a stack separator! This is a new line
|
39
|
-
stack
|
46
|
+
if stack.any? && !last_char_was_linebreak
|
47
|
+
last_char_was_linebreak = true
|
48
|
+
stack = handle_expr_terminator(stack, stack_depth)
|
49
|
+
end
|
40
50
|
end
|
41
51
|
elsif char == '[' # Opens a new string expression
|
42
52
|
stack << buf if (buf.length > 0)
|
43
|
-
|
53
|
+
last_char_was_linebreak = false
|
54
|
+
stack << [:b] + sub_parse(io, ']', stack_depth + 1)
|
44
55
|
elsif char == '{' # Opens a new literal expression
|
45
56
|
stack << buf if (buf.length > 0)
|
46
|
-
|
57
|
+
last_char_was_linebreak = false
|
58
|
+
stack << [:c] + sub_parse(io, '}', stack_depth + 1)
|
47
59
|
elsif char == '"'
|
48
60
|
stack << buf if (buf.length > 0)
|
61
|
+
last_char_was_linebreak = false
|
49
62
|
stack << parse_str(io, '"')
|
50
63
|
elsif char == "'"
|
51
64
|
stack << buf if (buf.length > 0)
|
65
|
+
last_char_was_linebreak = false
|
52
66
|
stack << parse_str(io, "'")
|
53
67
|
else
|
68
|
+
last_char_was_linebreak = false
|
54
69
|
buf << char
|
55
70
|
end
|
56
71
|
else
|
72
|
+
last_char_was_linebreak = false
|
57
73
|
buf << char
|
58
74
|
end
|
59
75
|
end
|
60
76
|
|
61
77
|
# Ramass any remaining buffer contents
|
62
78
|
stack << buf if (buf.length > 0)
|
63
|
-
|
64
|
-
|
79
|
+
|
80
|
+
# Handle any remaining subexpressions
|
81
|
+
if stack.include?(nil)
|
82
|
+
stack = handle_expr_terminator(stack, stack_depth)
|
83
|
+
end
|
84
|
+
# Chip awiy the trailing null
|
85
|
+
chomp!(stack)
|
86
|
+
|
87
|
+
return stack
|
65
88
|
end
|
66
89
|
|
67
|
-
private
|
68
|
-
|
69
90
|
ESC = 92.chr # Backslash (\)
|
70
91
|
|
92
|
+
def chomp!(stack)
|
93
|
+
stack.delete_at(-1) if stack.any? && stack[-1].nil?
|
94
|
+
end
|
95
|
+
|
96
|
+
def handle_expr_terminator(stack, stack_depth)
|
97
|
+
# Figure out whether there was a previous expr terminator
|
98
|
+
previous_i = stack.index(nil)
|
99
|
+
# If there were none, just get this over with. Wrap the stack contents
|
100
|
+
# into a subexpression and carry on.
|
101
|
+
unless previous_i
|
102
|
+
subexpr = stack
|
103
|
+
expand_subexpr!(subexpr, stack_depth + 1)
|
104
|
+
return [subexpr] + [nil]
|
105
|
+
end
|
106
|
+
|
107
|
+
# Now, if there was one, we are the next subexpr in line that just terminated.
|
108
|
+
# What we need to do is pick out all the elements from that terminator onwards
|
109
|
+
# and wrap them.
|
110
|
+
subexpr = stack[previous_i+1..-1]
|
111
|
+
|
112
|
+
# Use expand_subexpr! to trim away any fat that we don't need
|
113
|
+
expand_subexpr!(subexpr, stack_depth + 1)
|
114
|
+
|
115
|
+
return stack[0...previous_i] + [subexpr] + [nil]
|
116
|
+
end
|
117
|
+
|
71
118
|
def parse_str(io, stop_char)
|
72
119
|
buf = ''
|
73
120
|
until io.eof?
|
@@ -85,19 +132,5 @@ module Tickly
|
|
85
132
|
return buf
|
86
133
|
end
|
87
134
|
|
88
|
-
# Tells whether a passed object is a StringExpr or LiteralExpr
|
89
|
-
def expr?(something)
|
90
|
-
[StringExpr, LiteralExpr].include?(something.class)
|
91
|
-
end
|
92
|
-
|
93
|
-
# Cleans up a subexpression stack. Currently it only removes nil objects
|
94
|
-
# in-between items (which act as line separators)
|
95
|
-
def cleanup(expr)
|
96
|
-
# Ensure multiple consecutive line breaks are ignored
|
97
|
-
no_multiple_breaks = Tickly.singularize_nils_in(expr)
|
98
|
-
# Convert line breaks into subexpressions
|
99
|
-
Tickly.split_array(no_multiple_breaks)
|
100
|
-
end
|
101
|
-
|
102
135
|
end
|
103
136
|
end
|
data/lib/tickly.rb
CHANGED
@@ -1,70 +1,30 @@
|
|
1
1
|
require File.dirname(__FILE__) + "/tickly/parser"
|
2
|
+
require File.dirname(__FILE__) + "/tickly/node_extractor"
|
2
3
|
require File.dirname(__FILE__) + "/tickly/evaluator"
|
3
4
|
require 'forwardable'
|
4
5
|
|
5
6
|
module Tickly
|
6
|
-
VERSION = '0.0.
|
7
|
-
|
8
|
-
# Represents a TCL expression with it's arguments (in curly or square braces)
|
9
|
-
class Expr
|
10
|
-
extend Forwardable
|
11
|
-
|
12
|
-
def_delegators :@e, :push, :<<, :any?, :reject!, :map!, :[], :delete_at, :include?, :each, :each_with_index, :empty?, :join, :length
|
13
|
-
|
14
|
-
def initialize(elements = [])
|
15
|
-
@e = elements
|
16
|
-
end
|
17
|
-
|
18
|
-
def map(&blk)
|
19
|
-
self.class.new(@e.map(&blk))
|
20
|
-
end
|
21
|
-
|
22
|
-
def to_a
|
23
|
-
@e
|
24
|
-
end
|
25
|
-
|
26
|
-
def ==(another)
|
27
|
-
another.to_a == to_a
|
28
|
-
end
|
29
|
-
|
30
|
-
def inspect
|
31
|
-
@e.map{|e| e.inspect }.join(', ')
|
32
|
-
end
|
33
|
-
|
34
|
-
end
|
35
|
-
|
36
|
-
# Represents an expression between curly braces (within which no text substitution will be done)
|
37
|
-
# like { 1 2 3 }
|
38
|
-
class LiteralExpr < Expr
|
39
|
-
def inspect
|
40
|
-
"le(%s)" % super
|
41
|
-
end
|
42
|
-
end
|
43
|
-
|
44
|
-
# Represents an expression between square brackets (where text substitution will be done)
|
45
|
-
# like [1 2 3]
|
46
|
-
class StringExpr < Expr
|
47
|
-
def inspect
|
48
|
-
"se(%s)" % super
|
49
|
-
end
|
50
|
-
end
|
7
|
+
VERSION = '0.0.4'
|
51
8
|
|
52
9
|
# Provides the methods for quickly emitting the LiteralExpr and StringExpr objects
|
53
10
|
module Emitter
|
54
11
|
def le(*elems)
|
55
|
-
|
12
|
+
[:c] + elems
|
13
|
+
end
|
14
|
+
|
15
|
+
def e(*elems)
|
16
|
+
elems
|
56
17
|
end
|
57
18
|
|
58
19
|
def se(*elems)
|
59
|
-
|
20
|
+
[:b] + elems
|
60
21
|
end
|
61
22
|
end
|
62
23
|
|
63
|
-
|
64
24
|
def self.to_tcl(e)
|
65
|
-
if e.is_a?(
|
25
|
+
if e.is_a?(Array) && e[0] == :c
|
66
26
|
'{%s}' % e.map{|e| to_tcl(e)}.join(' ')
|
67
|
-
elsif e.is_a?(
|
27
|
+
elsif e.is_a?(Array) && e[0] == :b
|
68
28
|
'[%s]' % e.map{|e| to_tcl(e)}.join(' ')
|
69
29
|
elsif e.is_a?(String) && (e.include?('"') || e.include?("'"))
|
70
30
|
e.inspect
|
@@ -73,39 +33,5 @@ module Tickly
|
|
73
33
|
end
|
74
34
|
end
|
75
35
|
|
76
|
-
# Splits the passed Array-like object into sub-arrays of the same class,
|
77
|
-
# delimited by the passed separator. Note that when the separators occur at the beginning or at the end of
|
78
|
-
# the passed object they will be discarded
|
79
|
-
def self.split_array(arr, separator = nil)
|
80
|
-
return arr unless arr.include?(separator)
|
81
|
-
|
82
|
-
subarrays = arr.class.new
|
83
|
-
subarrays.push(arr.class.new)
|
84
|
-
|
85
|
-
arr.each_with_index do | element, i |
|
86
|
-
if element == separator && subarrays.length > 0 && subarrays[-1].any? && (i < (arr.length - 1))
|
87
|
-
subarrays.push(arr.class.new)
|
88
|
-
elsif element == separator
|
89
|
-
# toss it
|
90
|
-
else
|
91
|
-
subarrays[-1].push(element)
|
92
|
-
end
|
93
|
-
end
|
94
|
-
return subarrays
|
95
|
-
end
|
96
|
-
|
97
|
-
# Removes consecutive nils from the passed Array-like object and returns a new one with all consecutive nils reduced
|
98
|
-
# to one nil
|
99
|
-
def self.singularize_nils_in(arr)
|
100
|
-
new_arr = arr.class.new
|
101
|
-
arr.each_with_index do | elem, i |
|
102
|
-
if elem.nil? && arr[i-1].nil? && i > 0
|
103
|
-
# pass
|
104
|
-
else
|
105
|
-
new_arr << elem
|
106
|
-
end
|
107
|
-
end
|
108
|
-
new_arr
|
109
|
-
end
|
110
36
|
|
111
37
|
end
|
data/test/test_evaluator.rb
CHANGED
@@ -16,7 +16,7 @@ class TestEvaluator < Test::Unit::TestCase
|
|
16
16
|
end
|
17
17
|
|
18
18
|
should "not send anything to the handler when the expr does not conform to the standard" do
|
19
|
-
stack =
|
19
|
+
stack = e("ShouldNotBeInstantiated")
|
20
20
|
e = Tickly::Evaluator.new
|
21
21
|
e.add_node_handler_class(ShouldNotBeInstantiated)
|
22
22
|
assert_nothing_raised { e.evaluate(stack) }
|
@@ -29,8 +29,8 @@ class TestEvaluator < Test::Unit::TestCase
|
|
29
29
|
end
|
30
30
|
end
|
31
31
|
|
32
|
-
|
33
|
-
stack =
|
32
|
+
def test_instantiates_handler_class
|
33
|
+
stack = e("SomeNode", le(e("foo", "bar"), e("baz", "bad")))
|
34
34
|
e = Tickly::Evaluator.new
|
35
35
|
e.add_node_handler_class(SomeNode)
|
36
36
|
node = e.evaluate(stack)
|
@@ -0,0 +1,30 @@
|
|
1
|
+
require 'helper'
|
2
|
+
|
3
|
+
class TestNodeExtractor < Test::Unit::TestCase
|
4
|
+
|
5
|
+
include Tickly::Emitter
|
6
|
+
|
7
|
+
def test_parsing_nuke_script_with_indentations
|
8
|
+
f = File.open(File.dirname(__FILE__) + "/test-data/nuke_group.txt")
|
9
|
+
x = Tickly::NodeExtractor.new("Group")
|
10
|
+
|
11
|
+
p = x.parse(f)
|
12
|
+
grp = e(
|
13
|
+
e("set", "cut_paste_input", se("stack", "0")),
|
14
|
+
e("version", "6.3", "v4"),
|
15
|
+
e("Group",
|
16
|
+
le(
|
17
|
+
e("inputs", "0"),
|
18
|
+
e("name", "Group1"),
|
19
|
+
e("selected", "true")
|
20
|
+
)
|
21
|
+
),
|
22
|
+
e(:discarded),
|
23
|
+
e(:discarded),
|
24
|
+
e(:discarded),
|
25
|
+
e("end_group")
|
26
|
+
)
|
27
|
+
assert_equal grp, p
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|
data/test/test_parser.rb
CHANGED
@@ -5,72 +5,65 @@ class TestParser < Test::Unit::TestCase
|
|
5
5
|
include Tickly::Emitter
|
6
6
|
|
7
7
|
should "parse a single int as a stack with a string" do
|
8
|
-
|
9
|
-
assert_equal le("2"), P.parse('2')
|
8
|
+
assert_equal e("2"), P.parse('2')
|
10
9
|
end
|
11
10
|
|
12
11
|
should "parse a single int and discard whitespace" do
|
13
12
|
p = P.parse(' 2 ')
|
14
|
-
|
15
|
-
assert_equal le("2"), p
|
16
|
-
assert_equal "{2}", Tickly.to_tcl(p)
|
13
|
+
assert_equal e("2"), p
|
17
14
|
end
|
18
15
|
|
19
16
|
should "parse multiple ints and strings as a stack of subexpressions" do
|
20
|
-
|
21
|
-
assert_equal le("2", "foo", "bar", "baz"), P.parse('2 foo bar baz')
|
17
|
+
assert_equal e("2", "foo", "bar", "baz"), P.parse('2 foo bar baz')
|
22
18
|
end
|
23
19
|
|
24
20
|
should "parse and expand a string in double quotes" do
|
25
21
|
p = P.parse('"This is a string literal with spaces"')
|
26
|
-
assert_equal
|
22
|
+
assert_equal e("This is a string literal with spaces"), p
|
27
23
|
|
28
24
|
p = P.parse('"This is a string literal \"escaped\" with spaces"')
|
29
|
-
assert_equal
|
25
|
+
assert_equal e("This is a string literal \"escaped\" with spaces"), p
|
30
26
|
end
|
31
27
|
|
32
28
|
should "parse a string expression" do
|
33
|
-
|
34
|
-
assert_kind_of Tickly::LiteralExpr, p
|
35
|
-
assert_equal 1, p.length
|
36
|
-
assert_kind_of Tickly::StringExpr, p[0]
|
29
|
+
assert_equal e(se("1", "2", "3")), P.parse("[1 2 3]")
|
37
30
|
end
|
38
31
|
|
39
32
|
should "parse multiple string expressions" do
|
40
33
|
p = P.parse("[1 2 3] [3 4 5 foo]")
|
41
|
-
assert_equal
|
34
|
+
assert_equal e(se("1", "2", "3"), se("3", "4", "5", "foo")), p
|
42
35
|
end
|
43
36
|
|
44
|
-
|
37
|
+
def test_parse_multiline_statements_as_literal_expressions
|
45
38
|
p = P.parse("2\n2")
|
46
|
-
assert_equal "
|
39
|
+
assert_equal e(e("2"), e("2")), p
|
47
40
|
end
|
48
41
|
|
49
|
-
|
42
|
+
def test_parse_expr
|
50
43
|
expr = '{4 + 5}'
|
51
44
|
p = P.parse(expr)
|
52
|
-
assert_equal
|
45
|
+
assert_equal e(le("4", "+", "5")), p
|
53
46
|
end
|
54
47
|
|
55
|
-
|
48
|
+
def test_parsing_a_nuke_node
|
56
49
|
f = File.open(File.dirname(__FILE__) + "/test-data/nukenode.txt")
|
57
50
|
p = P.parse(f)
|
58
|
-
script =
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
51
|
+
script = e(
|
52
|
+
e("set", "cut_paste_input", se("stack", "0")),
|
53
|
+
e("version", "6.3", "v4"),
|
54
|
+
e("push", "$cut_paste_input"),
|
55
|
+
e("Blur",
|
63
56
|
le(
|
64
|
-
|
57
|
+
e("size",
|
65
58
|
le(
|
66
59
|
le("curve", "x1", "0", "x20", "1.7", "x33", "3.9")
|
67
60
|
)
|
68
61
|
),
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
62
|
+
e("name", "Blur1"),
|
63
|
+
e("label", "With \"Escapes\""),
|
64
|
+
e("selected", "true"),
|
65
|
+
e("xpos", "-353"),
|
66
|
+
e("ypos", "-33")
|
74
67
|
)
|
75
68
|
)
|
76
69
|
)
|
@@ -81,54 +74,54 @@ class TestParser < Test::Unit::TestCase
|
|
81
74
|
f = File.open(File.dirname(__FILE__) + "/test-data/three_nodes_and_roto.txt")
|
82
75
|
p = P.parse(f)
|
83
76
|
# Should pass through the rotopaint node and get to the blur properly
|
84
|
-
blur =
|
77
|
+
blur = e("Blur",
|
85
78
|
le(
|
86
|
-
|
79
|
+
e("size",
|
87
80
|
le(
|
88
81
|
le("curve", "i", "x1", "0", "x20", "1.7", "x33", "3.9")
|
89
82
|
)
|
90
83
|
),
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
84
|
+
e("name", "Blur1"),
|
85
|
+
e("label", "With \"Escapes\""),
|
86
|
+
e("selected", "true"),
|
87
|
+
e("xpos", "-212"),
|
88
|
+
e("ypos", "-24")
|
96
89
|
)
|
97
90
|
)
|
98
91
|
assert_equal blur, p[4]
|
99
92
|
end
|
100
93
|
|
101
|
-
|
94
|
+
def test_parsing_nuke_script_with_indentations
|
102
95
|
f = File.open(File.dirname(__FILE__) + "/test-data/nuke_group.txt")
|
103
96
|
p = P.parse(f)
|
104
|
-
grp =
|
105
|
-
|
106
|
-
|
107
|
-
|
97
|
+
grp = e(
|
98
|
+
e("set", "cut_paste_input", se("stack", "0")),
|
99
|
+
e("version", "6.3", "v4"),
|
100
|
+
e("Group",
|
108
101
|
le(
|
109
|
-
|
110
|
-
|
111
|
-
|
102
|
+
e("inputs", "0"),
|
103
|
+
e("name", "Group1"),
|
104
|
+
e("selected", "true")
|
112
105
|
)
|
113
106
|
),
|
114
|
-
|
107
|
+
e("CheckerBoard2",
|
115
108
|
le(
|
116
|
-
|
117
|
-
|
109
|
+
e("inputs", "0"),
|
110
|
+
e("name", "CheckerBoard1")
|
118
111
|
)
|
119
112
|
),
|
120
|
-
|
113
|
+
e("Blur",
|
121
114
|
le(
|
122
|
-
|
123
|
-
|
115
|
+
e("size", "42.5"),
|
116
|
+
e("name", "Blur1")
|
124
117
|
)
|
125
118
|
),
|
126
|
-
|
119
|
+
e("Output",
|
127
120
|
le(
|
128
|
-
|
121
|
+
e("name", "Output1")
|
129
122
|
)
|
130
123
|
),
|
131
|
-
|
124
|
+
e("end_group")
|
132
125
|
)
|
133
126
|
assert_equal grp, p
|
134
127
|
end
|
@@ -136,9 +129,9 @@ class TestParser < Test::Unit::TestCase
|
|
136
129
|
def test_one_node_parsing
|
137
130
|
f = File.open(File.dirname(__FILE__) + "/test-data/one_node_with_one_param.txt")
|
138
131
|
p = P.parse(f)
|
139
|
-
ref =
|
132
|
+
ref = e("SomeNode",
|
140
133
|
le(
|
141
|
-
|
134
|
+
e("foo", "bar")
|
142
135
|
)
|
143
136
|
)
|
144
137
|
|
data/tickly.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = "tickly"
|
8
|
-
s.version = "0.0.
|
8
|
+
s.version = "0.0.4"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Julik Tarkhanov"]
|
12
|
-
s.date = "2013-03-
|
12
|
+
s.date = "2013-03-12"
|
13
13
|
s.description = "Parses the subset of the TCL grammar needed for Nuke scripts"
|
14
14
|
s.email = "me@julik.nl"
|
15
15
|
s.extra_rdoc_files = [
|
@@ -25,6 +25,7 @@ Gem::Specification.new do |s|
|
|
25
25
|
"Rakefile",
|
26
26
|
"lib/tickly.rb",
|
27
27
|
"lib/tickly/evaluator.rb",
|
28
|
+
"lib/tickly/node_extractor.rb",
|
28
29
|
"lib/tickly/parser.rb",
|
29
30
|
"test/helper.rb",
|
30
31
|
"test/test-data/nuke7_tracker_2tracks.nk",
|
@@ -37,8 +38,8 @@ Gem::Specification.new do |s|
|
|
37
38
|
"test/test-data/tracker_with_differing_gaps.nk",
|
38
39
|
"test/test-data/tracker_with_repeating_gaps.nk",
|
39
40
|
"test/test_evaluator.rb",
|
41
|
+
"test/test_node_extractor.rb",
|
40
42
|
"test/test_parser.rb",
|
41
|
-
"test/test_split_array.rb",
|
42
43
|
"tickly.gemspec"
|
43
44
|
]
|
44
45
|
s.homepage = "http://github.com/julik/tickly"
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: tickly
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.4
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2013-03-
|
12
|
+
date: 2013-03-12 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: shoulda
|
@@ -91,6 +91,7 @@ files:
|
|
91
91
|
- Rakefile
|
92
92
|
- lib/tickly.rb
|
93
93
|
- lib/tickly/evaluator.rb
|
94
|
+
- lib/tickly/node_extractor.rb
|
94
95
|
- lib/tickly/parser.rb
|
95
96
|
- test/helper.rb
|
96
97
|
- test/test-data/nuke7_tracker_2tracks.nk
|
@@ -103,8 +104,8 @@ files:
|
|
103
104
|
- test/test-data/tracker_with_differing_gaps.nk
|
104
105
|
- test/test-data/tracker_with_repeating_gaps.nk
|
105
106
|
- test/test_evaluator.rb
|
107
|
+
- test/test_node_extractor.rb
|
106
108
|
- test/test_parser.rb
|
107
|
-
- test/test_split_array.rb
|
108
109
|
- tickly.gemspec
|
109
110
|
homepage: http://github.com/julik/tickly
|
110
111
|
licenses:
|
@@ -121,7 +122,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
121
122
|
version: '0'
|
122
123
|
segments:
|
123
124
|
- 0
|
124
|
-
hash:
|
125
|
+
hash: -2196296843243875248
|
125
126
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
126
127
|
none: false
|
127
128
|
requirements:
|
data/test/test_split_array.rb
DELETED
@@ -1,28 +0,0 @@
|
|
1
|
-
require 'helper'
|
2
|
-
|
3
|
-
class TestSplitArray < Test::Unit::TestCase
|
4
|
-
should "return a standard array unscathed" do
|
5
|
-
assert_equal [1, 2, 3, 4], Tickly.split_array([1,2,3,4])
|
6
|
-
end
|
7
|
-
|
8
|
-
should "return a split array on nil" do
|
9
|
-
assert_equal [[1, 2], [3, 4]], Tickly.split_array([1, 2, nil, 3, 4])
|
10
|
-
end
|
11
|
-
|
12
|
-
should "only generate sub-elements where they make sense" do
|
13
|
-
assert_equal [[1, 2]], Tickly.split_array([nil, 1, 2, nil])
|
14
|
-
end
|
15
|
-
|
16
|
-
class Jock < Array; end
|
17
|
-
|
18
|
-
should "properly use subclasses" do
|
19
|
-
s = Tickly.split_array(Jock.new([1, 2, nil, 3, 4]))
|
20
|
-
assert_kind_of Jock, s
|
21
|
-
assert_kind_of Jock, s[0]
|
22
|
-
end
|
23
|
-
|
24
|
-
should 'squeeze nils out' do
|
25
|
-
s = Tickly.singularize_nils_in([nil, nil, 1,2,3,4, nil, nil, 456, nil, 9,nil,nil])
|
26
|
-
assert_equal [nil, 1,2,3,4, nil, 456, nil, 9, nil], s
|
27
|
-
end
|
28
|
-
end
|