ESBify 0.0.1 → 0.1.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.
data/.gitignore CHANGED
@@ -2,3 +2,5 @@
2
2
  .bundle
3
3
  Gemfile.lock
4
4
  pkg/*
5
+
6
+ .DS_Store
@@ -0,0 +1,24 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
3
+ <plist version="1.0">
4
+ <dict>
5
+ <key>beforeRunningCommand</key>
6
+ <string>saveActiveFile</string>
7
+ <key>command</key>
8
+ <string>#!/usr/bin/env bash
9
+ esbify "$TM_FILEPATH"
10
+ </string>
11
+ <key>input</key>
12
+ <string>document</string>
13
+ <key>keyEquivalent</key>
14
+ <string>@b</string>
15
+ <key>name</key>
16
+ <string>Compile</string>
17
+ <key>output</key>
18
+ <string>showAsTooltip</string>
19
+ <key>scope</key>
20
+ <string>source.esb</string>
21
+ <key>uuid</key>
22
+ <string>985AA142-639A-486B-B777-B358EFE2D2BB</string>
23
+ </dict>
24
+ </plist>
@@ -0,0 +1,24 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
3
+ <plist version="1.0">
4
+ <dict>
5
+ <key>name</key>
6
+ <string>Comments</string>
7
+ <key>scope</key>
8
+ <string>source.esb</string>
9
+ <key>settings</key>
10
+ <dict>
11
+ <key>shellVariables</key>
12
+ <array>
13
+ <dict>
14
+ <key>name</key>
15
+ <string>TM_COMMENT_START</string>
16
+ <key>value</key>
17
+ <string># </string>
18
+ </dict>
19
+ </array>
20
+ </dict>
21
+ <key>uuid</key>
22
+ <string>D248DB58-5512-4EB1-BCF1-B3FFC7B2C6AB</string>
23
+ </dict>
24
+ </plist>
@@ -0,0 +1,21 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
3
+ <plist version="1.0">
4
+ <dict>
5
+ <key>content</key>
6
+ <string>name: ${1:name_of_behavior}${2:
7
+ jason: ${3:jason_condition}}${4:
8
+ ctl: ${5:ctl_condition}}
9
+ action: $6
10
+
11
+ ----</string>
12
+ <key>name</key>
13
+ <string>Behavior</string>
14
+ <key>scope</key>
15
+ <string>source.esb</string>
16
+ <key>tabTrigger</key>
17
+ <string>beh</string>
18
+ <key>uuid</key>
19
+ <string>2585098C-57C4-4EA6-AE1A-FAE7CBCF7E94</string>
20
+ </dict>
21
+ </plist>
@@ -0,0 +1,27 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
3
+ <plist version="1.0">
4
+ <dict>
5
+ <key>content</key>
6
+ <string>name: ${1:expectation_name}${2:
7
+ agent: ${3:self}}
8
+ condition: ${4:some_condition}
9
+ phi: ${5:$1}
10
+ ${6:test_plus: $7
11
+ rho_plus:
12
+ ${8:+}}
13
+ ${9:test_minus: $0
14
+ rho_plus:
15
+ }
16
+
17
+ ------</string>
18
+ <key>name</key>
19
+ <string>Expectation</string>
20
+ <key>scope</key>
21
+ <string>source.esb</string>
22
+ <key>tabTrigger</key>
23
+ <string>exp</string>
24
+ <key>uuid</key>
25
+ <string>FEB78640-82A4-4257-AE82-F4A05C8981BE</string>
26
+ </dict>
27
+ </plist>
@@ -0,0 +1,18 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
3
+ <plist version="1.0">
4
+ <dict>
5
+ <key>content</key>
6
+ <string>!behaviors
7
+
8
+ ${1:beh}$0</string>
9
+ <key>name</key>
10
+ <string>Header: Behaviors</string>
11
+ <key>scope</key>
12
+ <string>source.esb</string>
13
+ <key>tabTrigger</key>
14
+ <string>!</string>
15
+ <key>uuid</key>
16
+ <string>76EAC2C8-2F4E-433F-9B30-11AE8CAB3C53</string>
17
+ </dict>
18
+ </plist>
@@ -0,0 +1,18 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
3
+ <plist version="1.0">
4
+ <dict>
5
+ <key>content</key>
6
+ <string>!expectations
7
+
8
+ ${1:exp}$0</string>
9
+ <key>name</key>
10
+ <string>Header: Expectation</string>
11
+ <key>scope</key>
12
+ <string>source.esb</string>
13
+ <key>tabTrigger</key>
14
+ <string>!</string>
15
+ <key>uuid</key>
16
+ <string>D6051F23-6604-4897-B36E-94719D45F86A</string>
17
+ </dict>
18
+ </plist>
@@ -0,0 +1,18 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
3
+ <plist version="1.0">
4
+ <dict>
5
+ <key>content</key>
6
+ <string>!strategies
7
+
8
+ </string>
9
+ <key>name</key>
10
+ <string>Header: Strategies</string>
11
+ <key>scope</key>
12
+ <string>source.esb</string>
13
+ <key>tabTrigger</key>
14
+ <string>!</string>
15
+ <key>uuid</key>
16
+ <string>0686E761-7C22-43A0-9A55-A1B2F8B83690</string>
17
+ </dict>
18
+ </plist>
@@ -0,0 +1,17 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
3
+ <plist version="1.0">
4
+ <dict>
5
+ <key>content</key>
6
+ <string>------------
7
+ </string>
8
+ <key>name</key>
9
+ <string>Separator</string>
10
+ <key>scope</key>
11
+ <string>source.esb</string>
12
+ <key>tabTrigger</key>
13
+ <string>-</string>
14
+ <key>uuid</key>
15
+ <string>78931B30-3E26-4FC6-AC18-3E5E9D64D62C</string>
16
+ </dict>
17
+ </plist>
@@ -0,0 +1,115 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
3
+ <plist version="1.0">
4
+ <dict>
5
+ <key>fileTypes</key>
6
+ <array>
7
+ <string>esb</string>
8
+ </array>
9
+ <key>foldingStartMarker</key>
10
+ <string>^[^#]\s*.*:(\s*\[?| &amp;.+)?$</string>
11
+ <key>foldingStopMarker</key>
12
+ <string>^\s*$|^\s*\}|^\s*\]|^\s*\)</string>
13
+ <key>keyEquivalent</key>
14
+ <string>^~@e</string>
15
+ <key>name</key>
16
+ <string>ESB</string>
17
+ <key>patterns</key>
18
+ <array>
19
+ <dict>
20
+ <key>include</key>
21
+ <string>#erb</string>
22
+ </dict>
23
+ <dict>
24
+ <key>match</key>
25
+ <string>!(expectation|behaviou?r|strateg(?:y|ie))s?</string>
26
+ <key>name</key>
27
+ <string>keyword.header.esb</string>
28
+ </dict>
29
+ <dict>
30
+ <key>match</key>
31
+ <string>^\s*([\w_]+\s*\:)</string>
32
+ <key>name</key>
33
+ <string>variable.key.esb</string>
34
+ </dict>
35
+ <dict>
36
+ <key>captures</key>
37
+ <dict>
38
+ <key>1</key>
39
+ <dict>
40
+ <key>name</key>
41
+ <string>keyword.operator.list.esb</string>
42
+ </dict>
43
+ </dict>
44
+ <key>match</key>
45
+ <string>^\s*([\+\-])\s*\w+</string>
46
+ <key>name</key>
47
+ <string>entity.list.esb</string>
48
+ </dict>
49
+ <dict>
50
+ <key>match</key>
51
+ <string>^---+$</string>
52
+ <key>name</key>
53
+ <string>keyword.operator.divider.esb</string>
54
+ </dict>
55
+ <dict>
56
+ <key>match</key>
57
+ <string>\#.*$</string>
58
+ <key>name</key>
59
+ <string>comment.source.esb</string>
60
+ </dict>
61
+ </array>
62
+ <key>repository</key>
63
+ <dict>
64
+ <key>erb</key>
65
+ <dict>
66
+ <key>begin</key>
67
+ <string>&lt;%+(?!&gt;)=?</string>
68
+ <key>captures</key>
69
+ <dict>
70
+ <key>0</key>
71
+ <dict>
72
+ <key>name</key>
73
+ <string>punctuation.section.embedded.ruby</string>
74
+ </dict>
75
+ </dict>
76
+ <key>end</key>
77
+ <string>%&gt;</string>
78
+ <key>name</key>
79
+ <string>source.ruby.rails.embedded.html</string>
80
+ <key>patterns</key>
81
+ <array>
82
+ <dict>
83
+ <key>captures</key>
84
+ <dict>
85
+ <key>1</key>
86
+ <dict>
87
+ <key>name</key>
88
+ <string>punctuation.definition.comment.ruby</string>
89
+ </dict>
90
+ </dict>
91
+ <key>match</key>
92
+ <string>(#).*?(?=%&gt;)</string>
93
+ <key>name</key>
94
+ <string>comment.line.number-sign.ruby</string>
95
+ </dict>
96
+ <dict>
97
+ <key>include</key>
98
+ <string>source.ruby.rails</string>
99
+ </dict>
100
+ </array>
101
+ </dict>
102
+ <key>escaped_char</key>
103
+ <dict>
104
+ <key>match</key>
105
+ <string>\\.</string>
106
+ <key>name</key>
107
+ <string>constant.character.escape.esb</string>
108
+ </dict>
109
+ </dict>
110
+ <key>scopeName</key>
111
+ <string>source.esb</string>
112
+ <key>uuid</key>
113
+ <string>B6D3CCA0-FDC8-442A-8D41-515DD8F93C50</string>
114
+ </dict>
115
+ </plist>
@@ -0,0 +1,37 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
3
+ <plist version="1.0">
4
+ <dict>
5
+ <key>mainMenu</key>
6
+ <dict>
7
+ <key>items</key>
8
+ <array>
9
+ <string>985AA142-639A-486B-B777-B358EFE2D2BB</string>
10
+ <string>------------------------------------</string>
11
+ <string>FEB78640-82A4-4257-AE82-F4A05C8981BE</string>
12
+ <string>2585098C-57C4-4EA6-AE1A-FAE7CBCF7E94</string>
13
+ <string>D6051F23-6604-4897-B36E-94719D45F86A</string>
14
+ <string>0686E761-7C22-43A0-9A55-A1B2F8B83690</string>
15
+ <string>76EAC2C8-2F4E-433F-9B30-11AE8CAB3C53</string>
16
+ </array>
17
+ <key>submenus</key>
18
+ <dict/>
19
+ </dict>
20
+ <key>name</key>
21
+ <string>ESB</string>
22
+ <key>ordering</key>
23
+ <array>
24
+ <string>B6D3CCA0-FDC8-442A-8D41-515DD8F93C50</string>
25
+ <string>D248DB58-5512-4EB1-BCF1-B3FFC7B2C6AB</string>
26
+ <string>985AA142-639A-486B-B777-B358EFE2D2BB</string>
27
+ <string>FEB78640-82A4-4257-AE82-F4A05C8981BE</string>
28
+ <string>2585098C-57C4-4EA6-AE1A-FAE7CBCF7E94</string>
29
+ <string>D6051F23-6604-4897-B36E-94719D45F86A</string>
30
+ <string>0686E761-7C22-43A0-9A55-A1B2F8B83690</string>
31
+ <string>76EAC2C8-2F4E-433F-9B30-11AE8CAB3C53</string>
32
+ <string>78931B30-3E26-4FC6-AC18-3E5E9D64D62C</string>
33
+ </array>
34
+ <key>uuid</key>
35
+ <string>6BD9FB9E-A820-4288-B9AF-D8588715D1D6</string>
36
+ </dict>
37
+ </plist>
@@ -22,4 +22,5 @@ Gem::Specification.new do |s|
22
22
  s.add_development_dependency "rake"
23
23
  s.add_runtime_dependency "builder"
24
24
  s.add_runtime_dependency "erubis"
25
+ s.add_runtime_dependency "fssm"
25
26
  end
data/README.md CHANGED
@@ -6,55 +6,61 @@ ESBify is a simple DSL for creating the necessary XML files for the ESB framewor
6
6
 
7
7
  $ gem install esbify
8
8
 
9
- should do the trick provided you have a recent enough installation of Ruby. Run
9
+ should do the trick provided you have a recent enough installation of Ruby. Run this to list basic usage:
10
10
 
11
11
  $ esbify -h
12
12
 
13
- to list basic usage.
14
-
15
13
  ## Syntax
16
14
 
17
- !expectations
18
-
15
+ # This is a comment
16
+
17
+ # This is a header. Anything after this header will go to the relevant file
18
+ !expectations
19
+
20
+ # And this is an element, in this case an expectation.
19
21
  name: may_not_have_bangs
22
+ # We haven't included an `agent:` label, it defaults to `self`.
20
23
  condition: played(P1, duel, P2) | responded(P1, bang, P2, duel) | played(P1, indians, P2)
21
24
  phi: requires_bang_response(P2)
22
25
  test_plus: lost_life(P2)
23
26
  test_minus: played(P2, bang, P3) | responded(P2, bang, P3, _)
24
27
  rho_plus:
25
- + has_no_bangs
28
+ + has_no_bangs # `+` means that this will be added to EXP_C
29
+ - may_not_have_bangs # `-` means this will be removed from EXP_C
26
30
  rho_minus:
27
31
  - has_no_bangs
28
-
32
+
33
+ # Lines separate elements
29
34
  ----------
30
35
 
31
- name: has_no_bangs
36
+ # As a shortcut if the first label in an element has no content it is automatically considered a name
37
+ has_no_bangs: # equivalent to `name: has_no_bangs`
32
38
  condition: requires_bang_response℗ | has_no_bangs(P)
33
39
  phi: has_no_bangs_phi(P)
40
+ # You can use embedded Ruby to process things compile time
41
+ <% if @drawing_supported %>
34
42
  test_minus: draw(P, X)
35
43
  rho_minus:
36
44
  - has_no_bangs
45
+ <% end %>
46
+ # Since test_plus (or minus) is closely related to rho_plus (or minus), the rho may be ommited
47
+ test_plus: see(Enemy)
48
+ - may_not_have_bangs
37
49
 
38
50
 
39
- # comment
40
-
51
+ # As you have guessed this goes to Behaviors.xml
41
52
  !behaviors
42
-
53
+
43
54
  name: JI plans
44
55
  jason: has_no_bangs(P)
45
56
  action: card_expectation(P, bang, 0)
46
57
 
47
58
 
59
+ ## TextMate Plugin ##
48
60
 
49
- ### Headers
50
-
51
- `!expectation`, `!behavior`, `!strategy`
52
-
53
- Are possible headers saying that the following code will be of that particular type.
54
-
55
- ### Expectations
61
+ The package contains a TextMate plugin that you may install. It provides syntax highlighting and some basic snippets.
56
62
 
57
- ### Behaviors
63
+ ### Notes on Behaviors
58
64
 
59
65
  `name` is an identifier and isn't particularly useful. When omitted, a random number will be used.
60
66
 
@@ -88,19 +94,18 @@ and p is true in s′.
88
94
  - AX p is true in a states iff or all states s′ wherethereisatransitionfromstos′,pistrue
89
95
  in s′.
90
96
  - EF p is true in a state s0 if there exists a series of transitions s0 → s1, s1 → s2, ...,
91
- sn−1 →sn suchthatpistrueinsn.
92
- - AF pistrueinastates0 ifforallseriesoftransitionss0 → s1,s1 → s2,...,sn−1 → sn
97
+ sn−1 →sn such that p is true in sn.
98
+ - AF p is true in a state s0 if for all series of transitions s0 → s1,s1 → s2,...,sn−1 → sn
93
99
  p is true in sn.
94
100
  - EG p is true in a state s0 if there exists an infinite series of transitions s0 → s1, s1 → s2,
95
101
  ... such that p is true in every si.
96
- - AG pistrueinastates0 ifforallinfiniteseriesoftransitionss0 →s1,s1 →s2,... p
102
+ - AG p is true in a state s0 if for all infinite series of transitions s0 →s1,s1 →s2,... p
97
103
  is true in every si.
98
104
  - E[p U q] is true in a state s0 if there exists a series of transitions s0 → s1, s1 → s2,
99
105
  ..., sn−1 → sn such that p is true in every state from s0 to sn−1 and q is true in state sn.
100
- - A[p U q]istrueinastates0 ifforallseriesoftransitionss0 → s1,s1 → s2,...,
106
+ - A[p U q] is true in a state s0 if for all series of transitions s0 → s1,s1 → s2,...,
101
107
  sn−1 → sn p is true in every state from s0 to sn−1 and q is true in state sn. A CTL formula is true if it is true in all initial states.
102
108
 
103
- ---
104
109
 
105
110
  `jason` is a logic inside the ASL agent.
106
111
 
data/bin/esbify CHANGED
@@ -1,12 +1,23 @@
1
1
  #!/usr/bin/env ruby
2
2
  require "optparse"
3
+ require "fssm"
3
4
  require File.dirname(__FILE__) + "/../lib/ESBify"
4
5
 
5
6
 
6
7
 
7
- options = {stdout: false, expectations: "./Expectations.xml", behaviors: "./Behaviours.xml", filter: /.*/, only: %w[expectations behaviors strategies], context: {}}
8
+ options = {stdout: false, expectations: "./Expectations.xml", behaviors: "./Behaviours.xml", strategies: "./Strategy.xml", filter: /.*/, only: %w[expectations behaviors strategies], context: {}, watch: false}
8
9
  OptionParser.new do |opts|
9
- opts.banner = "Usage: esbify [options] FILES..."
10
+ opts.banner = "Usage: esbify [options] FILES...
11
+ ESBify will parse FILES and transform them to the appropriate XML. By default it will save expectations to
12
+ Expectations.xml, behaviors to Behaviors.xml and strategies to Strategy.xml.
13
+
14
+ This can be customized with the following options:
15
+ "
16
+
17
+ opts.on("--only expectations,behaviors,strategies", Array, "Only parse these sections.") do |v|
18
+ raise ArgumentError unless v.all?{|o| %w[expectations behaviors strategies].include?(o)}
19
+ options[:only] = v
20
+ end
10
21
 
11
22
  opts.on("-e", "--expectations FILE", "Output Expectations to FILE") do |v|
12
23
  options[:expectations] = v
@@ -16,18 +27,21 @@ OptionParser.new do |opts|
16
27
  options[:behaviors] = v
17
28
  end
18
29
 
19
- opts.on("--[no-]stdout", "Print to STDOUT") do |v|
30
+ opts.on("-s", "--strategies FILE", "Output Strategies to FILE") do |v|
31
+ options[:strategies] = v
32
+ end
33
+
34
+ opts.on("--[no-]stdout", "Print all files to STDOUT insted of individual files.") do |v|
20
35
  options[:stdout] = v
21
36
  end
22
37
 
38
+ opts.separator("\nESBify will also print a list of expectation names to STDOUT.\n")
39
+
23
40
  opts.on("-f", "--filter REGEXP", "When printing out expectations, only print those matching this regexp.") do |v|
24
41
  options[:filter] = Regexp.new(v)
25
42
  end
26
43
 
27
- opts.on("--only expectations,behaviors,strategies", Array, "Only generate these files") do |v|
28
- raise ArgumentError unless v.all?{|o| %w[expectations behaviors strategies].include?(o)}
29
- options[:only] = v
30
- end
44
+ opts.separator("\nOther various options:\n")
31
45
 
32
46
  opts.on("--context HASH_OR_PATH", "A path to a ruby class or a hash of values that will be passed to ERB", "The ruby class should have a underscored filename and CamelCased classname. ") do |v|
33
47
  if v =~ /\:|=>/
@@ -40,6 +54,10 @@ OptionParser.new do |opts|
40
54
  end
41
55
  end
42
56
 
57
+ opts.on("-w", "--watch", "Watches files for changes and automatically recompiles on change.", "All files in `pwd` ending with .esb will be watched (FILES are ignored).") do |v|
58
+ options[:watch] = true
59
+ end
60
+
43
61
  opts.on_tail("-h", "--help [README]", "Call -h with README to view the readme file") do |t|
44
62
  if t == "README"
45
63
  puts File.read(File.dirname(__FILE__) + "/../README.md")
@@ -56,18 +74,38 @@ OptionParser.new do |opts|
56
74
 
57
75
  end.parse!
58
76
 
59
- parser = ESBify::Parser.new options[:context]
60
77
 
61
- ARGV.each do |f|
62
- parser.parse_file! f
63
- end
64
78
 
65
- if options[:stdout]
66
- puts parser.expectations if options[:only].include?("expectations")
67
- puts parser.behaviors if options[:only].include?("behaviors")
68
- else
69
- File.open(options[:expectations], "w") {|f| f << parser.expectations } if options[:only].include?("expectations")
70
- File.open(options[:behaviors], "w") {|f| f << parser.behaviors } if options[:only].include?("behaviors")
79
+ def run(files, options)
80
+ parser = ESBify::Parser.new options[:context]
81
+
82
+ files.each do |f|
83
+ parser.parse_file! f
84
+ end
85
+
86
+ if options[:stdout]
87
+ puts parser.expectations if options[:only].include?("expectations")
88
+ puts parser.behaviors if options[:only].include?("behaviors")
89
+ puts parser.strategies if options[:only].include?("strategies")
90
+ else
91
+ File.open(options[:expectations], "w") {|f| f << parser.expectations } if options[:only].include?("expectations")
92
+ File.open(options[:behaviors], "w") {|f| f << parser.behaviors } if options[:only].include?("behaviors")
93
+ File.open(options[:strategies], "w") {|f| f << parser.strategies } if options[:only].include?("strategies")
94
+ end
95
+ STDERR.puts "Compiled!"
96
+ puts parser.expectation.names.grep(options[:filter]).join(",")
71
97
  end
72
98
 
73
- puts parser.expectation.names.grep(options[:filter]).join(",")
99
+
100
+ if options[:watch]
101
+ run(Dir[Dir.pwd + '/*.esb'], options)
102
+
103
+ FSSM.monitor(Dir.pwd, '*.esb') do
104
+ update do |base, relative|
105
+ run(Dir[Dir.pwd + '/*.esb'], options)
106
+ end
107
+ end
108
+
109
+ else
110
+ run ARGV, options
111
+ end
@@ -3,4 +3,4 @@ require File.dirname(__FILE__) + "/ESBify/version"
3
3
  module ESBify
4
4
  # Your code goes here...
5
5
  end
6
- require File.dirname(__FILE__) + "/ESBify/parser"
6
+ require File.dirname(__FILE__) + "/ESBify/parser"
@@ -7,12 +7,22 @@ class ESBify::Base
7
7
  def defaults
8
8
 
9
9
  end
10
-
11
- def <<(sects)
12
- @data += sects.map do |sect|
13
- defaults.merge(sect)
14
- end
10
+
11
+ def keys
12
+ defaults.keys.join("|")
15
13
  end
14
+
15
+ def parse!(str)
16
+ segs = str.split(/\s*\n---+\s*\n\s*/m)
17
+ @data += segs.map do |seg|
18
+ ms = seg.scan /(?:^|\n)(#{keys})\s*\:\s*(.+?)(?=(?:\n(?:#{keys})\s*\:|\z))/m
19
+ if m1 = seg.strip.match(/(?:^)(?!#{keys})(\w+)\s*\:\s*\n/)
20
+ ms << ["name", m1[1]]
21
+ end
22
+ defaults.merge Hash[*ms.flatten.map(&:strip)]
23
+ end
24
+ end
25
+
16
26
 
17
27
  def to_xml_partial
18
28
  b = Builder::XmlMarkup.new indent: 2, margin: 1
@@ -22,15 +22,37 @@ module ESBify
22
22
  }
23
23
  end
24
24
 
25
- def <<(sects)
25
+ def parse!(str)
26
26
  @names ||= []
27
- @data += sects.map do |sect|
28
- sect["rho_plus"] = parse_mods(sect["rho_plus"]) if sect["rho_plus"]
29
- sect["rho_minus"] = parse_mods(sect["rho_minus"]) if sect["rho_minus"]
27
+ segs = str.split(/\s*\n---+\s*\n\s*/m)
28
+ @data += segs.map do |seg|
29
+ ms = seg.scan /(?:^|\n)(#{keys})\s*\:\s*(.+?)(?=(?:\n(?:#{keys})\s*\:|\z))/m
30
+ if m1 = seg.strip.match(/(?:^)(?!#{keys})(\w+)\s*\:\s*\n/)
31
+ ms << ["name", m1[1]]
32
+ end
33
+
34
+ sect = Hash[*ms.flatten.map(&:strip)]
35
+
36
+ if sect["rho_plus"]
37
+ sect["rho_plus"] = parse_mods(sect["rho_plus"])
38
+ elsif sect["test_plus"]
39
+ sect["rho_plus"] = parse_mods(sect["test_plus"])
40
+ sect["test_plus"] = sect["test_plus"].split(/^\s*(\+|\-)/).first.strip
41
+ end
42
+
43
+ if sect["rho_minus"]
44
+ sect["rho_minus"] = parse_mods(sect["rho_minus"])
45
+ elsif sect["test_minus"]
46
+ sect["rho_minus"] = parse_mods(sect["test_minus"])
47
+ sect["test_minus"] = sect["test_minus"].split(/^\s*(\+|\-)/).first.strip
48
+ end
49
+
30
50
  @names << sect["name"] if sect["name"]
31
- defaults.merge(sect)
51
+ defaults.merge sect
32
52
  end
53
+
33
54
  end
55
+
34
56
 
35
57
  def parse_mods(str)
36
58
  add_set = []
@@ -1,9 +1,17 @@
1
1
  require 'erubis'
2
2
  require File.dirname(__FILE__) + "/expectation"
3
3
  require File.dirname(__FILE__) + "/behavior"
4
- #require "./behavior"
5
- #require "./strategy"
4
+ require File.dirname(__FILE__) + "/strategy"
6
5
 
6
+
7
+ # The Parser is the top level class. It's responsibility it is to do most of the generic processing of
8
+ # the language and then delegate to the Strategy, Behavior and Expectation classes.
9
+ #
10
+ # Usage:
11
+ #
12
+ # parser = ESBify::Parser.new
13
+ # parser.parse_file! "path/to/file.esb"
14
+ # puts parser.expectations #=> "<?xml ..."
7
15
  class ESBify::Parser
8
16
 
9
17
  attr_reader :expectation
@@ -11,46 +19,52 @@ class ESBify::Parser
11
19
  def initialize(context = {})
12
20
  @expectation = ::ESBify::Expectation.new
13
21
  @behavior = ::ESBify::Behavior.new
14
- #@strategy = ::ESBify::Strategy.new
22
+ @strategy = ::ESBify::Strategy.new
15
23
 
16
24
  @context = context
17
25
  end
18
26
 
19
-
27
+ # After parsing contains the xml representation of all expectations.
20
28
  def expectations
21
29
  @expectation.to_xml
22
30
  end
23
31
 
32
+ # After parsing contains the xml representation of all behaviors.
24
33
  def behaviors
25
34
  @behavior.to_xml
26
35
  end
27
36
 
37
+ # After parsing contains the xml representation of the strategy.
28
38
  def strategies
29
39
  @strategy.to_xml
30
40
  end
41
+ alias_method :strategy, :strategies
31
42
 
43
+ # Pass a file path. File will be read and parsed.
32
44
  def parse_file!(path)
33
45
  parse! File.read(path)
34
46
  end
35
47
 
48
+ # Parse a string of esb code.
36
49
  def parse!(str)
37
50
  # Remove comments
38
51
  str = str.split("\n").map{|l| l.split('#').first }.join("\n")
52
+ # Evaluate ERB code
39
53
  str = Erubis::Eruby.new(str).evaluate(@context)
54
+ # Split by sections
40
55
  str.split(/\!(?=(?:expectation|behaviou?r|strateg(?:y|ie))s?\n)/).each do |section|
41
56
  next if section =~ /\A\s*\z/m
42
57
  m = section.match /\A(expectation|behaviou?r|strateg(?:y|ie))s?/
43
58
  txt = str.split("\n")
44
59
  txt.shift
45
60
  txt.join("\n")
46
- sect = parse_section(section)
47
61
  case m[1]
48
62
  when /expectations?/
49
- @expectation << sect
63
+ @expectation.parse! section
50
64
  when /behaviou?rs?/
51
- @behavior << sect
65
+ @behavior.parse! section
52
66
  when /strateg(?:y|ie)s?/
53
- @strategy << sect
67
+ @strategy.parse! section
54
68
  else
55
69
  raise ArgumentError
56
70
  end
@@ -58,12 +72,4 @@ class ESBify::Parser
58
72
 
59
73
  end
60
74
 
61
-
62
- def parse_section(str)
63
- segs = str.split(/\s*\n---+\s*\n\s*/m)
64
- segs.map do |seg|
65
- ms = seg.scan /(?:^|\n)([\w_]+)\s*\:\s*(.+?)(?=(?:\n[\w_]+\s*\:|\z))/m
66
- Hash[*ms.flatten.map(&:strip)]
67
- end
68
- end
69
75
  end
@@ -1,3 +1,3 @@
1
1
  module ESBify
2
- VERSION = "0.0.1"
2
+ VERSION = "0.1.1"
3
3
  end
data/test.esb CHANGED
@@ -6,4 +6,11 @@ name: test
6
6
  condition: played(1) & played(2)
7
7
  ----
8
8
  name: has_no_bangs
9
- condition: requires_bang_response(P) | has_no_bangs(P)
9
+ condition: requires_bang_response(P) | has_no_bangs(P)
10
+
11
+ ---
12
+
13
+ test_expectation:
14
+ condition: a
15
+ test_plus: a(b) & c(d)
16
+ + has_no_bangs
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ESBify
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.1.1
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,11 +9,11 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-04-02 00:00:00.000000000Z
12
+ date: 2012-04-07 00:00:00.000000000Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rake
16
- requirement: &70235824010600 !ruby/object:Gem::Requirement
16
+ requirement: &70218565146640 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ! '>='
@@ -21,10 +21,10 @@ dependencies:
21
21
  version: '0'
22
22
  type: :development
23
23
  prerelease: false
24
- version_requirements: *70235824010600
24
+ version_requirements: *70218565146640
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: builder
27
- requirement: &70235824010160 !ruby/object:Gem::Requirement
27
+ requirement: &70218565146140 !ruby/object:Gem::Requirement
28
28
  none: false
29
29
  requirements:
30
30
  - - ! '>='
@@ -32,10 +32,10 @@ dependencies:
32
32
  version: '0'
33
33
  type: :runtime
34
34
  prerelease: false
35
- version_requirements: *70235824010160
35
+ version_requirements: *70218565146140
36
36
  - !ruby/object:Gem::Dependency
37
37
  name: erubis
38
- requirement: &70235824009740 !ruby/object:Gem::Requirement
38
+ requirement: &70218565145640 !ruby/object:Gem::Requirement
39
39
  none: false
40
40
  requirements:
41
41
  - - ! '>='
@@ -43,7 +43,18 @@ dependencies:
43
43
  version: '0'
44
44
  type: :runtime
45
45
  prerelease: false
46
- version_requirements: *70235824009740
46
+ version_requirements: *70218565145640
47
+ - !ruby/object:Gem::Dependency
48
+ name: fssm
49
+ requirement: &70218565145060 !ruby/object:Gem::Requirement
50
+ none: false
51
+ requirements:
52
+ - - ! '>='
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ type: :runtime
56
+ prerelease: false
57
+ version_requirements: *70218565145060
47
58
  description: Generates proper XML files for the ESB framework from a DSL.
48
59
  email:
49
60
  - honitom@seznam.cz
@@ -53,6 +64,16 @@ extensions: []
53
64
  extra_rdoc_files: []
54
65
  files:
55
66
  - .gitignore
67
+ - ESB.tmbundle/Commands/Compile.tmCommand
68
+ - ESB.tmbundle/Preferences/Comments.tmPreferences
69
+ - ESB.tmbundle/Snippets/Behavior.tmSnippet
70
+ - ESB.tmbundle/Snippets/Expectation.tmSnippet
71
+ - ! 'ESB.tmbundle/Snippets/Header: Behaviors.tmSnippet'
72
+ - ! 'ESB.tmbundle/Snippets/Header: Expectation.tmSnippet'
73
+ - ! 'ESB.tmbundle/Snippets/Header: Strategies.tmSnippet'
74
+ - ESB.tmbundle/Snippets/Separator.tmSnippet
75
+ - ESB.tmbundle/Syntaxes/ESB.tmLanguage
76
+ - ESB.tmbundle/info.plist
56
77
  - ESBify.gemspec
57
78
  - Gemfile
58
79
  - README.md
@@ -80,7 +101,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
80
101
  version: '0'
81
102
  segments:
82
103
  - 0
83
- hash: -1658457591522309798
104
+ hash: 1348258640709416010
84
105
  required_rubygems_version: !ruby/object:Gem::Requirement
85
106
  none: false
86
107
  requirements:
@@ -89,7 +110,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
89
110
  version: '0'
90
111
  segments:
91
112
  - 0
92
- hash: -1658457591522309798
113
+ hash: 1348258640709416010
93
114
  requirements: []
94
115
  rubyforge_project: ESBify
95
116
  rubygems_version: 1.8.6