mcollective-client 2.0.0 → 2.2.0

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of mcollective-client might be problematic. Click here for more details.

Files changed (140) hide show
  1. data/lib/mcollective.rb +32 -23
  2. data/lib/mcollective/agent.rb +5 -0
  3. data/lib/mcollective/agents.rb +5 -16
  4. data/lib/mcollective/aggregate.rb +61 -0
  5. data/lib/mcollective/aggregate/base.rb +40 -0
  6. data/lib/mcollective/aggregate/result.rb +9 -0
  7. data/lib/mcollective/aggregate/result/base.rb +25 -0
  8. data/lib/mcollective/aggregate/result/collection_result.rb +19 -0
  9. data/lib/mcollective/aggregate/result/numeric_result.rb +13 -0
  10. data/lib/mcollective/application.rb +7 -4
  11. data/lib/mcollective/applications.rb +3 -14
  12. data/lib/mcollective/cache.rb +145 -0
  13. data/lib/mcollective/client.rb +10 -87
  14. data/lib/mcollective/config.rb +22 -8
  15. data/lib/mcollective/data.rb +87 -0
  16. data/lib/mcollective/data/base.rb +67 -0
  17. data/lib/mcollective/data/result.rb +40 -0
  18. data/lib/mcollective/ddl.rb +113 -0
  19. data/lib/mcollective/ddl/agentddl.rb +185 -0
  20. data/lib/mcollective/ddl/base.rb +220 -0
  21. data/lib/mcollective/ddl/dataddl.rb +56 -0
  22. data/lib/mcollective/ddl/discoveryddl.rb +52 -0
  23. data/lib/mcollective/ddl/validatorddl.rb +6 -0
  24. data/lib/mcollective/discovery.rb +143 -0
  25. data/lib/mcollective/generators.rb +7 -0
  26. data/lib/mcollective/generators/agent_generator.rb +51 -0
  27. data/lib/mcollective/generators/base.rb +46 -0
  28. data/lib/mcollective/generators/data_generator.rb +51 -0
  29. data/lib/mcollective/generators/templates/action_snippet.erb +13 -0
  30. data/lib/mcollective/generators/templates/data_input_snippet.erb +7 -0
  31. data/lib/mcollective/generators/templates/ddl.erb +8 -0
  32. data/lib/mcollective/generators/templates/plugin.erb +7 -0
  33. data/lib/mcollective/logger/console_logger.rb +15 -15
  34. data/lib/mcollective/matcher.rb +167 -0
  35. data/lib/mcollective/matcher/parser.rb +60 -25
  36. data/lib/mcollective/matcher/scanner.rb +156 -78
  37. data/lib/mcollective/message.rb +47 -6
  38. data/lib/mcollective/monkey_patches.rb +17 -0
  39. data/lib/mcollective/optionparser.rb +18 -1
  40. data/lib/mcollective/pluginmanager.rb +3 -3
  41. data/lib/mcollective/pluginpackager.rb +10 -3
  42. data/lib/mcollective/pluginpackager/agent_definition.rb +28 -20
  43. data/lib/mcollective/pluginpackager/standard_definition.rb +11 -9
  44. data/lib/mcollective/registration/base.rb +3 -1
  45. data/lib/mcollective/rpc.rb +18 -24
  46. data/lib/mcollective/rpc/agent.rb +37 -113
  47. data/lib/mcollective/rpc/client.rb +186 -64
  48. data/lib/mcollective/rpc/helpers.rb +42 -80
  49. data/lib/mcollective/rpc/progress.rb +3 -3
  50. data/lib/mcollective/rpc/reply.rb +37 -13
  51. data/lib/mcollective/rpc/request.rb +17 -6
  52. data/lib/mcollective/rpc/result.rb +9 -5
  53. data/lib/mcollective/rpc/stats.rb +71 -24
  54. data/lib/mcollective/security/base.rb +41 -34
  55. data/lib/mcollective/shell.rb +1 -1
  56. data/lib/mcollective/ssl.rb +34 -0
  57. data/lib/mcollective/util.rb +194 -23
  58. data/lib/mcollective/validator.rb +80 -0
  59. data/spec/fixtures/util/1.in +10 -0
  60. data/spec/fixtures/util/1.out +10 -0
  61. data/spec/fixtures/util/2.in +1 -0
  62. data/spec/fixtures/util/2.out +1 -0
  63. data/spec/fixtures/util/3.in +1 -0
  64. data/spec/fixtures/util/3.out +2 -0
  65. data/spec/fixtures/util/4.in +5 -0
  66. data/spec/fixtures/util/4.out +9 -0
  67. data/spec/spec.opts +1 -1
  68. data/spec/spec_helper.rb +2 -0
  69. data/spec/unit/agents_spec.rb +34 -19
  70. data/spec/unit/aggregate/base_spec.rb +57 -0
  71. data/spec/unit/aggregate/result/base_spec.rb +28 -0
  72. data/spec/unit/aggregate/result/collection_result_spec.rb +18 -0
  73. data/spec/unit/aggregate/result/numeric_result_spec.rb +22 -0
  74. data/spec/unit/aggregate_spec.rb +110 -0
  75. data/spec/unit/application_spec.rb +8 -3
  76. data/spec/unit/applications_spec.rb +2 -2
  77. data/spec/unit/cache_spec.rb +115 -0
  78. data/spec/unit/client_spec.rb +78 -0
  79. data/spec/unit/config_spec.rb +32 -34
  80. data/spec/unit/data/base_spec.rb +90 -0
  81. data/spec/unit/data/result_spec.rb +64 -0
  82. data/spec/unit/data_spec.rb +158 -0
  83. data/spec/unit/ddl/agentddl_spec.rb +217 -0
  84. data/spec/unit/{rpc/ddl_spec.rb → ddl/base_spec.rb} +238 -224
  85. data/spec/unit/ddl/dataddl_spec.rb +65 -0
  86. data/spec/unit/ddl/discoveryddl_spec.rb +58 -0
  87. data/spec/unit/ddl_spec.rb +84 -0
  88. data/spec/unit/discovery_spec.rb +196 -0
  89. data/spec/unit/facts/base_spec.rb +1 -1
  90. data/spec/unit/generators/agent_generator_spec.rb +72 -0
  91. data/spec/unit/generators/base_spec.rb +83 -0
  92. data/spec/unit/generators/data_generator_spec.rb +37 -0
  93. data/spec/unit/generators/snippets/agent_ddl +19 -0
  94. data/spec/unit/generators/snippets/data_ddl +20 -0
  95. data/spec/unit/logger/console_logger_spec.rb +76 -0
  96. data/spec/unit/logger/syslog_logger_spec.rb +2 -2
  97. data/spec/unit/matcher/parser_spec.rb +27 -10
  98. data/spec/unit/matcher/scanner_spec.rb +108 -5
  99. data/spec/unit/matcher_spec.rb +260 -0
  100. data/spec/unit/message_spec.rb +35 -13
  101. data/spec/unit/optionparser_spec.rb +2 -2
  102. data/spec/unit/pluginpackager/agent_definition_spec.rb +59 -42
  103. data/spec/unit/pluginpackager/standard_definition_spec.rb +10 -8
  104. data/spec/unit/pluginpackager_spec.rb +131 -0
  105. data/spec/unit/plugins/mcollective/aggregate/average_spec.rb +45 -0
  106. data/spec/unit/plugins/mcollective/aggregate/sum_spec.rb +31 -0
  107. data/spec/unit/plugins/mcollective/aggregate/summary_spec.rb +45 -0
  108. data/spec/unit/plugins/mcollective/connector/activemq_spec.rb +1 -1
  109. data/spec/unit/plugins/mcollective/connector/rabbitmq_spec.rb +478 -0
  110. data/spec/unit/plugins/mcollective/connector/stomp_spec.rb +2 -0
  111. data/spec/unit/plugins/mcollective/data/agent_data_spec.rb +43 -0
  112. data/spec/unit/plugins/mcollective/data/fstat_data_spec.rb +135 -0
  113. data/spec/unit/plugins/mcollective/discovery/flatfile_spec.rb +48 -0
  114. data/spec/unit/plugins/mcollective/discovery/mc_spec.rb +40 -0
  115. data/spec/unit/plugins/mcollective/packagers/debpackage_packager_spec.rb +41 -15
  116. data/spec/unit/plugins/mcollective/packagers/ospackage_spec.rb +1 -1
  117. data/spec/unit/plugins/mcollective/packagers/rpmpackage_packager_spec.rb +22 -38
  118. data/spec/unit/plugins/mcollective/validator/array_validator_spec.rb +19 -0
  119. data/spec/unit/plugins/mcollective/validator/ipv4address_validator_spec.rb +19 -0
  120. data/spec/unit/plugins/mcollective/validator/ipv6address_validator_spec.rb +19 -0
  121. data/spec/unit/plugins/mcollective/validator/length_validator_spec.rb +19 -0
  122. data/spec/unit/plugins/mcollective/validator/regex_validator_spec.rb +19 -0
  123. data/spec/unit/plugins/mcollective/validator/shellsafe_validator_spec.rb +21 -0
  124. data/spec/unit/plugins/mcollective/validator/typecheck_validator_spec.rb +23 -0
  125. data/spec/unit/registration/base_spec.rb +1 -1
  126. data/spec/unit/rpc/actionrunner_spec.rb +2 -2
  127. data/spec/unit/rpc/agent_spec.rb +41 -65
  128. data/spec/unit/rpc/client_spec.rb +430 -134
  129. data/spec/unit/rpc/reply_spec.rb +31 -1
  130. data/spec/unit/rpc/request_spec.rb +33 -12
  131. data/spec/unit/rpc/result_spec.rb +7 -0
  132. data/spec/unit/rpc/stats_spec.rb +14 -14
  133. data/spec/unit/rpc_spec.rb +16 -0
  134. data/spec/unit/security/base_spec.rb +8 -8
  135. data/spec/unit/ssl_spec.rb +20 -2
  136. data/spec/unit/string_spec.rb +15 -0
  137. data/spec/unit/util_spec.rb +141 -21
  138. data/spec/unit/validator_spec.rb +67 -0
  139. metadata +145 -7
  140. data/lib/mcollective/rpc/ddl.rb +0 -258
@@ -0,0 +1,83 @@
1
+ #!/usr/bin/env rspec
2
+
3
+ require "spec_helper"
4
+
5
+ module MCollective
6
+ module Generators
7
+ describe Base do
8
+ before :each do
9
+ @erb = mock
10
+ @erb.stubs(:result)
11
+ File.stubs(:dirname).returns("/tmp")
12
+ @base = Base.new(nil, nil, nil, nil, nil, nil, nil)
13
+ end
14
+
15
+ describe "#initialize" do
16
+ it "should set the correct metaparameters" do
17
+ res = Base.new("name", "description", "author", "license", "version", "url", "timeout")
18
+ res.meta.should == {:name => "name",
19
+ :description => "description",
20
+ :author => "author",
21
+ :license => "license",
22
+ :version => "version",
23
+ :url => "url",
24
+ :timeout => "timeout"}
25
+ end
26
+ end
27
+
28
+ describe "#create_metadata_string" do
29
+ it "should load the ddl template if it is present" do
30
+ File.expects(:read).returns("ddl")
31
+ ERB.expects(:new).with("ddl", nil, "-").returns(@erb)
32
+ @base.create_metadata_string
33
+ end
34
+
35
+ it "should raise an error if the template is not present" do
36
+ File.expects(:read).raises(Errno::ENOENT)
37
+ expect{
38
+ @base.create_metadata_string
39
+ }.to raise_error(Errno::ENOENT)
40
+ end
41
+ end
42
+
43
+ describe "#create_plugin_string " do
44
+ it "should load the plugin template if it is present" do
45
+ File.expects(:read).returns("plugin")
46
+ ERB.expects(:new).with("plugin", nil, "-").returns(@erb)
47
+ @base.create_plugin_string
48
+ end
49
+
50
+ it "should raise an error if the template is not present" do
51
+ File.expects(:read).raises(Errno::ENOENT)
52
+ expect{
53
+ @base.create_plugin_string
54
+ }.to raise_error(Errno::ENOENT)
55
+ end
56
+ end
57
+
58
+ describe "#write_plugins" do
59
+ it "should fail if the directory already exists" do
60
+ Dir.expects(:mkdir).raises(Errno::EEXIST)
61
+ @base.plugin_name = "foo"
62
+ expect{
63
+ @base.write_plugins
64
+ }.to raise_error(RuntimeError)
65
+ end
66
+
67
+ it "should create the directory and the plugin files if it doesn't exist" do
68
+ Dir.stubs(:pwd).returns("/tmp")
69
+ @base.stubs(:puts)
70
+
71
+ Dir.expects(:mkdir).with("foo")
72
+ Dir.expects(:mkdir).with("foo/agent")
73
+ File.expects(:open).with("foo/agent/foo.ddl", "w")
74
+ File.expects(:open).with("foo/agent/foo.rb", "w")
75
+
76
+ @base.plugin_name = "foo"
77
+ @base.mod_name = "agent"
78
+ @base.write_plugins
79
+ end
80
+ end
81
+ end
82
+ end
83
+ end
@@ -0,0 +1,37 @@
1
+ #! /usr/bin/env rspec
2
+
3
+ require 'spec_helper'
4
+
5
+ module MCollective
6
+ module Generators
7
+ describe DataGenerator do
8
+
9
+ before :each do
10
+ DataGenerator.stubs(:create_metadata_string).returns("meta\n")
11
+ end
12
+
13
+ describe "#create_ddl" do
14
+ it "create the correct ddl string" do
15
+ DataGenerator.any_instance.stubs(:create_plugin_content)
16
+ DataGenerator.any_instance.stubs(:create_plugin_string)
17
+ DataGenerator.any_instance.stubs(:write_plugins)
18
+
19
+ ddl = DataGenerator.new("foo", ["output"]).ddl
20
+ expected = File.read(File.join(File.dirname(__FILE__), "snippets", "data_ddl")).chop
21
+ ddl.should == expected
22
+ end
23
+ end
24
+
25
+ describe "#create_plugin_content" do
26
+ it "should create the correct plugin content" do
27
+ DataGenerator.any_instance.stubs(:create_ddl)
28
+ DataGenerator.any_instance.stubs(:create_plugin_string)
29
+ DataGenerator.any_instance.stubs(:write_plugins)
30
+
31
+ ddl = DataGenerator.new("foo", ["output"]).content
32
+ ddl.should == " query do |what|\n result[:output] = nil\n end\n"
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,19 @@
1
+ metadata
2
+ action "action1", :description => "%ACTIONDESCRIPTION%" do
3
+ # Example Input
4
+ input :name,
5
+ :prompt => "%PROMPT%",
6
+ :description => "%DESCRIPTION%",
7
+ :type => %TYPE%,
8
+ :validation => '%VALIDATION%',
9
+ :optional => %OPTIONAL%,
10
+ :maxlength => %MAXLENGTH%
11
+
12
+ # Example output
13
+ output :name,
14
+ :description => "%DESCRIPTION%",
15
+ :display_as => "%DISPLAYAS%"
16
+ end
17
+
18
+ action "action2", :description => "%ACTIONDESCRIPTION%" do
19
+ end
@@ -0,0 +1,20 @@
1
+ metadata :name => "%FULLNANE%",
2
+ :description => "%DESCRIPTION%",
3
+ :author => "%AUTHOR%",
4
+ :license => "%LICENSE%",
5
+ :version => "%VERSION%",
6
+ :url => "%URL%",
7
+ :timeout => %TIMEOUT%
8
+
9
+ dataquery :description => "Query information" do
10
+ input :query,
11
+ :prompt => "%PROMP%",
12
+ :description => "%DESCRIPTION%",
13
+ :type => %TYPE%,
14
+ :validation => %VALIDATION%,
15
+ :maxlength => %MAXLENGTH%
16
+
17
+ output :output,
18
+ :description => "%DESCRIPTION%",
19
+ :display_as => "%DESCRIPTION%"
20
+ end
@@ -0,0 +1,76 @@
1
+ #!/usr/bin/env rspec
2
+
3
+ require 'spec_helper'
4
+
5
+ module MCollective
6
+ require 'mcollective/logger/console_logger'
7
+
8
+ module Logger
9
+ describe Console_logger do
10
+ describe "#start" do
11
+ it "should default to :info and allow the config to override" do
12
+ logger = Console_logger.new
13
+ logger.expects(:set_level).with(:info)
14
+ Config.instance.expects(:configured).returns(true)
15
+ Config.instance.expects(:loglevel).returns("error")
16
+ logger.expects(:set_level).with(:error)
17
+ logger.start
18
+ end
19
+ end
20
+
21
+ describe "#color" do
22
+ it "should not colorize if color was disabled" do
23
+ logger = Console_logger.new
24
+ Config.instance.stubs(:color).returns(false)
25
+ logger.color(:error).should == ""
26
+ logger.color(:reset).should == ""
27
+ end
28
+
29
+ it "should correctly colorize by level" do
30
+ logger = Console_logger.new
31
+ Config.instance.stubs(:color).returns(true)
32
+ logger.color(:error).should == Util.color(:red)
33
+ logger.color(:reset).should == Util.color(:reset)
34
+ end
35
+ end
36
+
37
+ describe "#log" do
38
+ it "should log higher than configured levels" do
39
+ io = StringIO.new
40
+ io.expects(:puts).with("error 2012/07/03 15:11:35: rspec message")
41
+
42
+ time = stub
43
+ time.expects(:strftime).returns("2012/07/03 15:11:35")
44
+
45
+ Time.expects(:new).returns(time)
46
+
47
+ Config.instance.stubs(:color).returns(false)
48
+ logger = Console_logger.new
49
+ logger.set_level(:warn)
50
+ logger.log(:error, "rspec", "message", io)
51
+ end
52
+
53
+ it "should not log lower than configured levels" do
54
+ io = StringIO.new
55
+ io.expects(:puts).never
56
+
57
+ logger = Console_logger.new
58
+ logger.set_level(:warn)
59
+ logger.log(:debug, "rspec", "message", io)
60
+ end
61
+
62
+ it "should resort to STDERR output if all else fails" do
63
+ io = StringIO.new
64
+ io.expects(:puts).raises
65
+
66
+ last_resort_io = StringIO.new
67
+ last_resort_io.expects(:puts).with("warn: message")
68
+
69
+ logger = Console_logger.new
70
+ logger.set_level(:debug)
71
+ logger.log(:warn, "rspec", "message", io, last_resort_io)
72
+ end
73
+ end
74
+ end
75
+ end
76
+ end
@@ -10,8 +10,8 @@ module MCollective
10
10
  describe Syslog_logger do
11
11
  describe "#start" do
12
12
  before do
13
- Config.any_instance.stubs(:logfacility).returns("user")
14
- Config.any_instance.stubs(:loglevel).returns("error")
13
+ Config.instance.stubs(:logfacility).returns("user")
14
+ Config.instance.stubs(:loglevel).returns("error")
15
15
  end
16
16
 
17
17
  it "should close the syslog if already opened" do
@@ -5,6 +5,10 @@ require 'spec_helper'
5
5
  module MCollective
6
6
  module Matcher
7
7
  describe Parser do
8
+ before :each do
9
+ Config.instance.stubs(:color).returns(false)
10
+ end
11
+
8
12
  describe '#parse' do
9
13
  it "should parse statements seperated by '='" do
10
14
  parser = Parser.new("foo=bar")
@@ -49,7 +53,7 @@ module MCollective
49
53
  it "should not parse an incorrect and token" do
50
54
  expect {
51
55
  parser = Parser.new("and foo=bar")
52
- }.to raise_error("Error at column 10. \n Expression cannot start with 'and'")
56
+ }.to raise_error(RuntimeError, "Parse errors found while parsing -S input and foo=bar")
53
57
  end
54
58
 
55
59
  it "should parse a correct 'or' token" do
@@ -57,10 +61,10 @@ module MCollective
57
61
  parser.execution_stack.should == [{"statement" => "foo=bar"}, {"or" => "or"}, {"statement" => "bar=foo"}]
58
62
  end
59
63
 
60
- it "should not parse an incorrect and token" do
61
- expect {
64
+ it "should not parse an incorrect or token" do
65
+ expect{
62
66
  parser = Parser.new("or foo=bar")
63
- }.to raise_error("Error at column 9. \n Expression cannot start with 'or'")
67
+ }.to raise_error(RuntimeError, "Parse errors found while parsing -S input or foo=bar")
64
68
  end
65
69
 
66
70
  it "should parse a correct 'not' token" do
@@ -71,9 +75,9 @@ module MCollective
71
75
  end
72
76
 
73
77
  it "should not parse an incorrect 'not' token" do
74
- expect {
78
+ expect{
75
79
  parser = Parser.new("foo=bar !")
76
- }.to raise_error("Error at column 8. \nExpected 'and', 'or', ')'. Found 'not'")
80
+ }.to raise_error(RuntimeError, "Parse errors found while parsing -S input foo=bar !")
77
81
  end
78
82
 
79
83
  it "should parse correct parentheses" do
@@ -82,15 +86,15 @@ module MCollective
82
86
  end
83
87
 
84
88
  it "should fail on incorrect parentheses" do
85
- expect {
89
+ expect{
86
90
  parser = Parser.new(")foo=bar(")
87
- }.to raise_error("Error. Missing parentheses '('.")
91
+ }.to raise_error(RuntimeError, "Malformed token(s) found while parsing -S input )foo=bar(")
88
92
  end
89
93
 
90
94
  it "should fail on missing parentheses" do
91
- expect {
95
+ expect{
92
96
  parser = Parser.new("(foo=bar")
93
- }.to raise_error("Error. Missing parentheses ')'.")
97
+ }.to raise_error(RuntimeError, "Missing parenthesis found while parsing -S input (foo=bar")
94
98
  end
95
99
 
96
100
  it "should parse correctly formatted compound statements" do
@@ -100,6 +104,19 @@ module MCollective
100
104
  {")"=>")"}]
101
105
  end
102
106
 
107
+ it "should parse complex fstatements and statements with operators seperated by whitespaces" do
108
+ parser = Parser.new("foo('bar').value = 1 and foo=bar or foo = bar")
109
+ parser.execution_stack.should == [{"fstatement"=>"foo('bar').value=1"}, {"and"=>"and"}, {"statement"=>"foo=bar"}, {"or"=>"or"}, {"statement"=>"foo=bar"}]
110
+ end
111
+
112
+ it "should parse statements where classes are mixed with fact comparisons and fstatements" do
113
+ parser = Parser.new("klass and function('param').value = 1 and fact=value")
114
+ parser.execution_stack.should == [{"statement" => "klass"},
115
+ {"and" => "and"},
116
+ {"fstatement" => "function('param').value=1"},
117
+ {"and" => "and"},
118
+ {"statement" => "fact=value"}]
119
+ end
103
120
  end
104
121
  end
105
122
  end
@@ -59,12 +59,115 @@ module MCollective
59
59
  token.should == ["statement", "/class/"]
60
60
  end
61
61
 
62
- it "should fail if expression terminates with 'and'" do
63
- scanner = Scanner.new("and")
62
+ it "should identify a function statement token with a dot value" do
63
+ scanner = Scanner.new("foo('bar').baz")
64
+ token = scanner.get_token
65
+ token.should == ["fstatement", "foo('bar').baz"]
66
+ end
67
+
68
+ it "should identify a function statement token without a dot value" do
69
+ scanner = Scanner.new("foo('bar')")
70
+ token = scanner.get_token
71
+ token.should == ["fstatement", "foo('bar')"]
72
+ end
73
+
74
+ it "should identify a function statement with multiple parameters" do
75
+ scanner = Scanner.new("foo('bar','baz')")
76
+ token = scanner.get_token
77
+ token.should == ["fstatement", "foo('bar','baz')"]
78
+ end
79
+
80
+ it "should identify a bad token when a function is missing its end bracket" do
81
+ scanner = Scanner.new("foo(")
82
+ token = scanner.get_token
83
+ token.should == ["bad_token", [0,3]]
84
+ end
85
+
86
+ it "should identify a bad token when there is a regex before a comparison operator" do
87
+ scanner = Scanner.new("/foo/=bar")
88
+ token = scanner.get_token
89
+ token.should == ["bad_token", [0,8]]
90
+ end
91
+
92
+ it "should identify a bad token where there is a forward slash before a comparison operator" do
93
+ scanner = Scanner.new("/foo=bar")
94
+ token = scanner.get_token
95
+ token.should == ["bad_token", [0,7]]
96
+ end
97
+
98
+ it "should identify a bad token where there is only one forward slash after a comparison operator" do
99
+ scanner = Scanner.new("foo=/bar")
100
+ token = scanner.get_token
101
+ token.should == ["bad_token", [0,7]]
102
+ end
103
+
104
+ it "should identify a bad token where function parameters are not in single quotes" do
105
+ scanner = Scanner.new("foo(bar)")
106
+ token = scanner.get_token
107
+ token.should == ["bad_token", [0,7]]
108
+ end
109
+
110
+ it "should identify a bad token where there are non alphanumerical or underscore chars in the dot value" do
111
+ scanner = Scanner.new("foo('bar').val-ue")
112
+ token = scanner.get_token
113
+ token.should == ["bad_token", [0,16]]
114
+ end
64
115
 
65
- expect {
66
- token = scanner.get_token
67
- }.to raise_error("Class name cannot be 'and', 'or', 'not'. Found 'and'")
116
+ it "should identify a bad token where there are chained dot values" do
117
+ scanner = Scanner.new("foo('bar').a.b")
118
+ token = scanner.get_token
119
+ token.should == ["bad_token", [0,13]]
120
+ end
121
+
122
+ it "should identify bad tokens where function parameters are not comma seperated" do
123
+ scanner = Scanner.new("foo('a' 'b')")
124
+ token = scanner.get_token
125
+ token.should == ["bad_token", [0,11]]
126
+
127
+ scanner = Scanner.new("foo(\"a\" \"b\")")
128
+ token = scanner.get_token
129
+ token.should == ["bad_token", [0,11]]
130
+
131
+ end
132
+
133
+ it "should identify fstatement tokens where the values and the comparison operator are seperated by whitespaces" do
134
+ scanner = Scanner.new("foo('a').bar = 1")
135
+ token = scanner.get_token
136
+ token.should == ["fstatement", "foo('a').bar=1"]
137
+ end
138
+
139
+ it "should identify statement tokens where the values and the comparison operator are seperated by whitespaces" do
140
+ scanner = Scanner.new("a = c")
141
+ token = scanner.get_token
142
+ token.should == ["statement", "a=c"]
143
+ end
144
+
145
+ it "should idenify a function statement where a parameter is an empty string" do
146
+ scanner = Scanner.new("foo('')")
147
+ token = scanner.get_token
148
+ token.should == ["fstatement", "foo('')"]
149
+ end
150
+
151
+ it "should correctly tokenize a statement with escaped qoutes in parameters" do
152
+ scanner = Scanner.new("foo('\"bar\"')")
153
+ token = scanner.get_token
154
+ token.should == ["fstatement", "foo('\"bar\"')"]
155
+
156
+ scanner = Scanner.new('foo("\'bar\'")')
157
+ token =scanner.get_token
158
+ token.should == ["fstatement", "foo(\"'bar'\")"]
159
+ end
160
+
161
+ it "should correctly tokenize a statement where a regular expression contains parentheses" do
162
+ scanner = Scanner.new("foo=/bar(1|2)/")
163
+ token = scanner.get_token
164
+ token.should == ["statement", "foo=/bar(1|2)/"]
165
+ end
166
+
167
+ it "should correctly tokenize a statement with a comparison operator in a parameter" do
168
+ scanner = Scanner.new("foo('bar=baz')")
169
+ token = scanner.get_token
170
+ token.should == ["fstatement", "foo('bar=baz')"]
68
171
  end
69
172
  end
70
173
  end