ESBify 0.0.1 → 0.1.1
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +2 -0
- data/ESB.tmbundle/Commands/Compile.tmCommand +24 -0
- data/ESB.tmbundle/Preferences/Comments.tmPreferences +24 -0
- data/ESB.tmbundle/Snippets/Behavior.tmSnippet +21 -0
- data/ESB.tmbundle/Snippets/Expectation.tmSnippet +27 -0
- data/ESB.tmbundle/Snippets/Header: Behaviors.tmSnippet +18 -0
- data/ESB.tmbundle/Snippets/Header: Expectation.tmSnippet +18 -0
- data/ESB.tmbundle/Snippets/Header: Strategies.tmSnippet +18 -0
- data/ESB.tmbundle/Snippets/Separator.tmSnippet +17 -0
- data/ESB.tmbundle/Syntaxes/ESB.tmLanguage +115 -0
- data/ESB.tmbundle/info.plist +37 -0
- data/ESBify.gemspec +1 -0
- data/README.md +29 -24
- data/bin/esbify +56 -18
- data/lib/ESBify.rb +1 -1
- data/lib/ESBify/base.rb +15 -5
- data/lib/ESBify/expectation.rb +27 -5
- data/lib/ESBify/parser.rb +22 -16
- data/lib/ESBify/version.rb +1 -1
- data/test.esb +8 -1
- metadata +31 -10
@@ -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*\[?| &.+)?$</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><%+(?!>)=?</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>%></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>(#).*?(?=%>)</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>
|
data/ESBify.gemspec
CHANGED
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
|
-
|
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
|
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
|
-
#
|
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
|
-
|
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
|
92
|
-
- AF
|
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
|
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]
|
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("
|
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.
|
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
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
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
|
-
|
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
|
data/lib/ESBify.rb
CHANGED
data/lib/ESBify/base.rb
CHANGED
@@ -7,12 +7,22 @@ class ESBify::Base
|
|
7
7
|
def defaults
|
8
8
|
|
9
9
|
end
|
10
|
-
|
11
|
-
def
|
12
|
-
|
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
|
data/lib/ESBify/expectation.rb
CHANGED
@@ -22,15 +22,37 @@ module ESBify
|
|
22
22
|
}
|
23
23
|
end
|
24
24
|
|
25
|
-
def
|
25
|
+
def parse!(str)
|
26
26
|
@names ||= []
|
27
|
-
|
28
|
-
|
29
|
-
|
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
|
51
|
+
defaults.merge sect
|
32
52
|
end
|
53
|
+
|
33
54
|
end
|
55
|
+
|
34
56
|
|
35
57
|
def parse_mods(str)
|
36
58
|
add_set = []
|
data/lib/ESBify/parser.rb
CHANGED
@@ -1,9 +1,17 @@
|
|
1
1
|
require 'erubis'
|
2
2
|
require File.dirname(__FILE__) + "/expectation"
|
3
3
|
require File.dirname(__FILE__) + "/behavior"
|
4
|
-
|
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
|
-
|
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
|
63
|
+
@expectation.parse! section
|
50
64
|
when /behaviou?rs?/
|
51
|
-
@behavior
|
65
|
+
@behavior.parse! section
|
52
66
|
when /strateg(?:y|ie)s?/
|
53
|
-
@strategy
|
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
|
data/lib/ESBify/version.rb
CHANGED
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.
|
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-
|
12
|
+
date: 2012-04-07 00:00:00.000000000Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rake
|
16
|
-
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: *
|
24
|
+
version_requirements: *70218565146640
|
25
25
|
- !ruby/object:Gem::Dependency
|
26
26
|
name: builder
|
27
|
-
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: *
|
35
|
+
version_requirements: *70218565146140
|
36
36
|
- !ruby/object:Gem::Dependency
|
37
37
|
name: erubis
|
38
|
-
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: *
|
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:
|
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:
|
113
|
+
hash: 1348258640709416010
|
93
114
|
requirements: []
|
94
115
|
rubyforge_project: ESBify
|
95
116
|
rubygems_version: 1.8.6
|