auser-poolparty 0.2.71 → 0.2.72

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.
Files changed (118) hide show
  1. data/History.txt +3 -0
  2. data/Manifest.txt +38 -81
  3. data/PostInstall.txt +1 -1
  4. data/README.txt +1 -0
  5. data/lib/erlang/messenger/Makefile +15 -0
  6. data/lib/erlang/messenger/lib/eunit/Makefile +28 -0
  7. data/lib/erlang/messenger/lib/eunit/ebin/autoload.beam +0 -0
  8. data/lib/erlang/messenger/lib/eunit/ebin/code_monitor.beam +0 -0
  9. data/lib/erlang/messenger/lib/eunit/ebin/eunit.beam +0 -0
  10. data/lib/erlang/messenger/lib/eunit/ebin/eunit_autoexport.beam +0 -0
  11. data/lib/erlang/messenger/lib/eunit/ebin/eunit_data.beam +0 -0
  12. data/lib/erlang/messenger/lib/eunit/ebin/eunit_lib.beam +0 -0
  13. data/lib/erlang/messenger/lib/eunit/ebin/eunit_proc.beam +0 -0
  14. data/lib/erlang/messenger/lib/eunit/ebin/eunit_serial.beam +0 -0
  15. data/lib/erlang/messenger/lib/eunit/ebin/eunit_server.beam +0 -0
  16. data/lib/erlang/messenger/lib/eunit/ebin/eunit_striptests.beam +0 -0
  17. data/lib/erlang/messenger/lib/eunit/ebin/eunit_test.beam +0 -0
  18. data/lib/erlang/messenger/lib/eunit/ebin/eunit_tests.beam +0 -0
  19. data/lib/erlang/messenger/lib/eunit/ebin/eunit_tty.beam +0 -0
  20. data/lib/erlang/messenger/lib/eunit/ebin/file_monitor.beam +0 -0
  21. data/lib/erlang/messenger/lib/eunit/src/Makefile +46 -0
  22. data/lib/poolparty/dependency_resolutions/puppet.rb +1 -0
  23. data/lib/poolparty/modules/resourcing_dsl.rb +5 -5
  24. data/lib/poolparty/plugins/deploydirectory.rb +1 -1
  25. data/lib/poolparty/pool/resource.rb +12 -3
  26. data/lib/poolparty/spec/core/string.rb +8 -2
  27. data/lib/poolparty/spec/matchers/a_spec_extensions_base.rb +3 -1
  28. data/lib/poolparty/spec/matchers/have_deploydirectory.rb +11 -11
  29. data/lib/poolparty/spec/matchers/have_gempackage.rb +1 -1
  30. data/lib/poolparty/version.rb +1 -1
  31. data/lib/poolpartyspec.rb +1 -3
  32. data/poolparty.gemspec +44 -87
  33. data/spec/poolparty/plugins/deploydirectory_spec.rb +1 -0
  34. data/spec/poolparty/pool/resource_spec.rb +13 -0
  35. data/spec/poolparty/spec/core/string_spec.rb +57 -0
  36. data/website/index.html +2 -2
  37. metadata +43 -86
  38. data/lib/erlang/messenger/lib/eunit/.svn/all-wcprops +0 -53
  39. data/lib/erlang/messenger/lib/eunit/.svn/entries +0 -140
  40. data/lib/erlang/messenger/lib/eunit/.svn/format +0 -1
  41. data/lib/erlang/messenger/lib/eunit/.svn/prop-base/NOTES.svn-base +0 -5
  42. data/lib/erlang/messenger/lib/eunit/.svn/text-base/AUTHORS.svn-base +0 -2
  43. data/lib/erlang/messenger/lib/eunit/.svn/text-base/CHANGELOG.svn-base +0 -14
  44. data/lib/erlang/messenger/lib/eunit/.svn/text-base/COPYING.svn-base +0 -504
  45. data/lib/erlang/messenger/lib/eunit/.svn/text-base/NOTES.svn-base +0 -276
  46. data/lib/erlang/messenger/lib/eunit/.svn/text-base/README.svn-base +0 -3
  47. data/lib/erlang/messenger/lib/eunit/.svn/text-base/sys.config.svn-base +0 -9
  48. data/lib/erlang/messenger/lib/eunit/.svn/text-base/vsn.mk.svn-base +0 -1
  49. data/lib/erlang/messenger/lib/eunit/doc/.svn/all-wcprops +0 -59
  50. data/lib/erlang/messenger/lib/eunit/doc/.svn/entries +0 -142
  51. data/lib/erlang/messenger/lib/eunit/doc/.svn/format +0 -1
  52. data/lib/erlang/messenger/lib/eunit/doc/.svn/prop-base/erlang.png.svn-base +0 -5
  53. data/lib/erlang/messenger/lib/eunit/doc/.svn/prop-base/eunit.html.svn-base +0 -5
  54. data/lib/erlang/messenger/lib/eunit/doc/.svn/prop-base/index.html.svn-base +0 -5
  55. data/lib/erlang/messenger/lib/eunit/doc/.svn/prop-base/modules-frame.html.svn-base +0 -5
  56. data/lib/erlang/messenger/lib/eunit/doc/.svn/prop-base/overview-summary.html.svn-base +0 -5
  57. data/lib/erlang/messenger/lib/eunit/doc/.svn/prop-base/packages-frame.html.svn-base +0 -5
  58. data/lib/erlang/messenger/lib/eunit/doc/.svn/text-base/edoc-info.svn-base +0 -3
  59. data/lib/erlang/messenger/lib/eunit/doc/.svn/text-base/erlang.png.svn-base +0 -0
  60. data/lib/erlang/messenger/lib/eunit/doc/.svn/text-base/eunit.html.svn-base +0 -172
  61. data/lib/erlang/messenger/lib/eunit/doc/.svn/text-base/index.html.svn-base +0 -17
  62. data/lib/erlang/messenger/lib/eunit/doc/.svn/text-base/modules-frame.html.svn-base +0 -12
  63. data/lib/erlang/messenger/lib/eunit/doc/.svn/text-base/overview-summary.html.svn-base +0 -984
  64. data/lib/erlang/messenger/lib/eunit/doc/.svn/text-base/overview.edoc.svn-base +0 -980
  65. data/lib/erlang/messenger/lib/eunit/doc/.svn/text-base/packages-frame.html.svn-base +0 -11
  66. data/lib/erlang/messenger/lib/eunit/doc/.svn/text-base/stylesheet.css.svn-base +0 -55
  67. data/lib/erlang/messenger/lib/eunit/ebin/.svn/all-wcprops +0 -5
  68. data/lib/erlang/messenger/lib/eunit/ebin/.svn/dir-prop-base +0 -8
  69. data/lib/erlang/messenger/lib/eunit/ebin/.svn/entries +0 -28
  70. data/lib/erlang/messenger/lib/eunit/ebin/.svn/format +0 -1
  71. data/lib/erlang/messenger/lib/eunit/examples/.svn/all-wcprops +0 -23
  72. data/lib/erlang/messenger/lib/eunit/examples/.svn/entries +0 -66
  73. data/lib/erlang/messenger/lib/eunit/examples/.svn/format +0 -1
  74. data/lib/erlang/messenger/lib/eunit/examples/.svn/prop-base/eunit_examples.erl.svn-base +0 -5
  75. data/lib/erlang/messenger/lib/eunit/examples/.svn/prop-base/fib.erl.svn-base +0 -5
  76. data/lib/erlang/messenger/lib/eunit/examples/.svn/text-base/eunit_examples.erl.svn-base +0 -339
  77. data/lib/erlang/messenger/lib/eunit/examples/.svn/text-base/fib.erl.svn-base +0 -19
  78. data/lib/erlang/messenger/lib/eunit/examples/.svn/text-base/tests.txt.svn-base +0 -1
  79. data/lib/erlang/messenger/lib/eunit/include/.svn/all-wcprops +0 -11
  80. data/lib/erlang/messenger/lib/eunit/include/.svn/entries +0 -41
  81. data/lib/erlang/messenger/lib/eunit/include/.svn/format +0 -1
  82. data/lib/erlang/messenger/lib/eunit/include/.svn/prop-base/eunit.hrl.svn-base +0 -5
  83. data/lib/erlang/messenger/lib/eunit/include/.svn/text-base/eunit.hrl.svn-base +0 -313
  84. data/lib/erlang/messenger/lib/eunit/src/.svn/all-wcprops +0 -113
  85. data/lib/erlang/messenger/lib/eunit/src/.svn/entries +0 -259
  86. data/lib/erlang/messenger/lib/eunit/src/.svn/format +0 -1
  87. data/lib/erlang/messenger/lib/eunit/src/.svn/prop-base/autoload.erl.svn-base +0 -5
  88. data/lib/erlang/messenger/lib/eunit/src/.svn/prop-base/code_monitor.erl.svn-base +0 -5
  89. data/lib/erlang/messenger/lib/eunit/src/.svn/prop-base/eunit.erl.svn-base +0 -5
  90. data/lib/erlang/messenger/lib/eunit/src/.svn/prop-base/eunit_autoexport.erl.svn-base +0 -5
  91. data/lib/erlang/messenger/lib/eunit/src/.svn/prop-base/eunit_data.erl.svn-base +0 -5
  92. data/lib/erlang/messenger/lib/eunit/src/.svn/prop-base/eunit_internal.hrl.svn-base +0 -5
  93. data/lib/erlang/messenger/lib/eunit/src/.svn/prop-base/eunit_lib.erl.svn-base +0 -5
  94. data/lib/erlang/messenger/lib/eunit/src/.svn/prop-base/eunit_proc.erl.svn-base +0 -5
  95. data/lib/erlang/messenger/lib/eunit/src/.svn/prop-base/eunit_serial.erl.svn-base +0 -5
  96. data/lib/erlang/messenger/lib/eunit/src/.svn/prop-base/eunit_server.erl.svn-base +0 -5
  97. data/lib/erlang/messenger/lib/eunit/src/.svn/prop-base/eunit_striptests.erl.svn-base +0 -5
  98. data/lib/erlang/messenger/lib/eunit/src/.svn/prop-base/eunit_test.erl.svn-base +0 -5
  99. data/lib/erlang/messenger/lib/eunit/src/.svn/prop-base/eunit_tests.erl.svn-base +0 -5
  100. data/lib/erlang/messenger/lib/eunit/src/.svn/prop-base/eunit_tty.erl.svn-base +0 -5
  101. data/lib/erlang/messenger/lib/eunit/src/.svn/prop-base/file_monitor.erl.svn-base +0 -5
  102. data/lib/erlang/messenger/lib/eunit/src/.svn/text-base/autoload.erl.svn-base +0 -388
  103. data/lib/erlang/messenger/lib/eunit/src/.svn/text-base/code_monitor.erl.svn-base +0 -243
  104. data/lib/erlang/messenger/lib/eunit/src/.svn/text-base/eunit.app.src.svn-base +0 -21
  105. data/lib/erlang/messenger/lib/eunit/src/.svn/text-base/eunit.appup.src.svn-base +0 -1
  106. data/lib/erlang/messenger/lib/eunit/src/.svn/text-base/eunit.erl.svn-base +0 -196
  107. data/lib/erlang/messenger/lib/eunit/src/.svn/text-base/eunit_autoexport.erl.svn-base +0 -102
  108. data/lib/erlang/messenger/lib/eunit/src/.svn/text-base/eunit_data.erl.svn-base +0 -798
  109. data/lib/erlang/messenger/lib/eunit/src/.svn/text-base/eunit_internal.hrl.svn-base +0 -48
  110. data/lib/erlang/messenger/lib/eunit/src/.svn/text-base/eunit_lib.erl.svn-base +0 -682
  111. data/lib/erlang/messenger/lib/eunit/src/.svn/text-base/eunit_proc.erl.svn-base +0 -552
  112. data/lib/erlang/messenger/lib/eunit/src/.svn/text-base/eunit_serial.erl.svn-base +0 -157
  113. data/lib/erlang/messenger/lib/eunit/src/.svn/text-base/eunit_server.erl.svn-base +0 -340
  114. data/lib/erlang/messenger/lib/eunit/src/.svn/text-base/eunit_striptests.erl.svn-base +0 -64
  115. data/lib/erlang/messenger/lib/eunit/src/.svn/text-base/eunit_test.erl.svn-base +0 -334
  116. data/lib/erlang/messenger/lib/eunit/src/.svn/text-base/eunit_tests.erl.svn-base +0 -45
  117. data/lib/erlang/messenger/lib/eunit/src/.svn/text-base/eunit_tty.erl.svn-base +0 -272
  118. data/lib/erlang/messenger/lib/eunit/src/.svn/text-base/file_monitor.erl.svn-base +0 -409
@@ -1,682 +0,0 @@
1
- %% This library is free software; you can redistribute it and/or modify
2
- %% it under the terms of the GNU Lesser General Public License as
3
- %% published by the Free Software Foundation; either version 2 of the
4
- %% License, or (at your option) any later version.
5
- %%
6
- %% This library is distributed in the hope that it will be useful, but
7
- %% WITHOUT ANY WARRANTY; without even the implied warranty of
8
- %% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
9
- %% Lesser General Public License for more details.
10
- %%
11
- %% You should have received a copy of the GNU Lesser General Public
12
- %% License along with this library; if not, write to the Free Software
13
- %% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
14
- %% USA
15
- %%
16
- %% $Id$
17
- %%
18
- %% @copyright 2004-2007 Micka�l R�mond, Richard Carlsson
19
- %% @author Micka�l R�mond <mickael.remond@process-one.net>
20
- %% [http://www.process-one.net/]
21
- %% @author Richard Carlsson <richardc@it.uu.se>
22
- %% [http://user.it.uu.se/~richardc/]
23
- %% @private
24
- %% @see eunit
25
- %% @doc Utility functions for eunit
26
-
27
- -module(eunit_lib).
28
-
29
- -include("eunit.hrl").
30
- -include("eunit_internal.hrl").
31
-
32
-
33
- -export([dlist_next/1, uniq/1, fun_parent/1, is_string/1, browse_fun/1,
34
- command/1, command/2, command/3, trie_new/0, trie_store/2,
35
- trie_match/2, split_node/1, consult_file/1, list_dir/1,
36
- format_exit_term/1, format_exception/1, format_error/1]).
37
-
38
-
39
- %% Type definitions for describing exceptions
40
- %%
41
- %% @type exception() = {exceptionClass(), Reason::term(), stackTrace()}
42
- %%
43
- %% @type exceptionClass() = error | exit | throw
44
- %%
45
- %% @type stackTrace() = [{moduleName(), functionName(),
46
- %% arity() | argList()}]
47
- %%
48
- %% @type moduleName() = atom()
49
- %% @type functionName() = atom()
50
- %% @type arity() = integer()
51
- %% @type mfa() = {moduleName(), functionName(), arity()}
52
- %% @type argList() = [term()]
53
- %% @type fileName() = string()
54
-
55
-
56
- %% ---------------------------------------------------------------------
57
- %% Formatting of error descriptors
58
-
59
- format_exception({Class,Term,Trace})
60
- when is_atom(Class), is_list(Trace) ->
61
- case is_stacktrace(Trace) of
62
- true ->
63
- io_lib:format("~w:~P\n~s",
64
- [Class, Term, 15, format_stacktrace(Trace)]);
65
- false ->
66
- format_term(Term)
67
- end;
68
- format_exception(Term) ->
69
- format_term(Term).
70
-
71
- format_term(Term) ->
72
- io_lib:format("~P\n", [Term, 15]).
73
-
74
- format_exit_term(Term) ->
75
- {Reason, Trace} = analyze_exit_term(Term),
76
- io_lib:format("~P~s", [Reason, 15, Trace]).
77
-
78
- analyze_exit_term({Reason, [_|_]=Trace}=Term) ->
79
- case is_stacktrace(Trace) of
80
- true ->
81
- {Reason, format_stacktrace(Trace)};
82
- false ->
83
- {Term, ""}
84
- end;
85
- analyze_exit_term(Term) ->
86
- {Term, ""}.
87
-
88
- is_stacktrace([]) ->
89
- true;
90
- is_stacktrace([{M,F,A}|Fs]) when is_atom(M), is_atom(F), is_integer(A) ->
91
- is_stacktrace(Fs);
92
- is_stacktrace([{M,F,As}|Fs]) when is_atom(M), is_atom(F), is_list(As) ->
93
- is_stacktrace(Fs);
94
- is_stacktrace(_) ->
95
- false.
96
-
97
- format_stacktrace(Trace) ->
98
- format_stacktrace(Trace, "in function", "in call from").
99
-
100
- format_stacktrace([{M,F,A}|Fs], Pre, Pre1) when is_integer(A) ->
101
- [io_lib:fwrite(" ~s ~w:~w/~w\n", [Pre, M, F, A])
102
- | format_stacktrace(Fs, Pre1, Pre1)];
103
- format_stacktrace([{M,F,As}|Fs], Pre, Pre1) when is_list(As) ->
104
- A = length(As),
105
- C = case is_op(M,F,A) of
106
- true when A == 1 ->
107
- [A1] = As,
108
- io_lib:fwrite("~s ~s", [F,format_arg(A1)]);
109
- true when A == 2 ->
110
- [A1, A2] = As,
111
- io_lib:fwrite("~s ~s ~s",
112
- [format_arg(A1),F,format_arg(A2)]);
113
- false ->
114
- io_lib:fwrite("~w(~s)", [F,format_arglist(As)])
115
- end,
116
- [io_lib:fwrite(" ~s ~w:~w/~w\n called as ~s\n",
117
- [Pre,M,F,A,C])
118
- | format_stacktrace(Fs,Pre1,Pre1)];
119
- format_stacktrace([],_Pre,_Pre1) ->
120
- "".
121
-
122
- format_arg(A) ->
123
- io_lib:format("~P",[A,15]).
124
-
125
- format_arglist([A]) ->
126
- format_arg(A);
127
- format_arglist([A|As]) ->
128
- [io_lib:format("~P,",[A,15]) | format_arglist(As)];
129
- format_arglist([]) ->
130
- "".
131
-
132
- is_op(erlang, F, A) ->
133
- erl_internal:arith_op(F, A)
134
- orelse erl_internal:bool_op(F, A)
135
- orelse erl_internal:comp_op(F, A)
136
- orelse erl_internal:list_op(F, A)
137
- orelse erl_internal:send_op(F, A);
138
- is_op(_M, _F, _A) ->
139
- false.
140
-
141
- format_error({bad_test, Term}) ->
142
- error_msg("bad test descriptor", "~P", [Term, 15]);
143
- format_error({generator_failed, Exception}) ->
144
- error_msg("test generator failed", "~s",
145
- [format_exception(Exception)]);
146
- format_error({no_such_function, {M,F,A}})
147
- when is_atom(M), is_atom(F), is_integer(A) ->
148
- error_msg(io_lib:format("no such function: ~w:~w/~w", [M,F,A]),
149
- "", []);
150
- format_error({module_not_found, M}) ->
151
- error_msg("test module not found", "~p", [M]);
152
- format_error({application_not_found, A}) when is_atom(A) ->
153
- error_msg("application not found", "~w", [A]);
154
- format_error({file_read_error, {_R, Msg, F}}) ->
155
- error_msg("error reading file", "~s: ~s", [Msg, F]);
156
- format_error({context_error, setup_failed, Exception}) ->
157
- error_msg("context setup failed", "~s",
158
- [format_exception(Exception)]);
159
- format_error({context_error, cleanup_failed, Exception}) ->
160
- error_msg("context cleanup failed", "~s",
161
- [format_exception(Exception)]);
162
- format_error({context_error, instantiation_failed, Exception}) ->
163
- error_msg("instantiation of subtests failed", "~s",
164
- [format_exception(Exception)]).
165
-
166
- error_msg(Title, Fmt, Args) ->
167
- Msg = io_lib:format("::"++Fmt, Args), % gets indentation right
168
- io_lib:fwrite("*** ~s ***\n~s\n\n", [Title, Msg]).
169
-
170
-
171
- %% ---------------------------------------------------------------------
172
- %% Deep list iterator; accepts improper lists/sublists, and also accepts
173
- %% non-lists on the top level. Nonempty strings (not deep strings) are
174
- %% recognized as separate elements, even on the top level. (It is not
175
- %% recommended to include integers in the deep list, since a list of
176
- %% integers is likely to be interpreted as a string.). The result is
177
- %% always presented as a list (which may be improper), which is either
178
- %% empty or otherwise has a non-list head element.
179
-
180
- dlist_next([X | Xs] = Xs0) when is_list(X) ->
181
- case is_nonempty_string(X) of
182
- true -> Xs0;
183
- false -> dlist_next(X, Xs)
184
- end;
185
- dlist_next([_|_] = Xs) ->
186
- case is_nonempty_string(Xs) of
187
- true -> [Xs];
188
- false -> Xs
189
- end;
190
- dlist_next([]) ->
191
- [];
192
- dlist_next(X) ->
193
- [X].
194
-
195
- %% the first two clauses avoid pushing empty lists on the stack
196
- dlist_next([X], Ys) when is_list(X) ->
197
- case is_nonempty_string(X) of
198
- true -> [X | Ys];
199
- false -> dlist_next(X, Ys)
200
- end;
201
- dlist_next([X], Ys) ->
202
- [X | Ys];
203
- dlist_next([X | Xs], Ys) when is_list(X) ->
204
- case is_nonempty_string(X) of
205
- true -> [X | [Xs | Ys]];
206
- false -> dlist_next(X, [Xs | Ys])
207
- end;
208
- dlist_next([X | Xs], Ys) ->
209
- [X | [Xs | Ys]];
210
- dlist_next([], Xs) ->
211
- dlist_next(Xs).
212
-
213
-
214
- -ifdef(TEST).
215
- dlist_test_() ->
216
- {"deep list traversal",
217
- [{"non-list term -> singleton list",
218
- ?_test([any] = dlist_next(any))},
219
- {"empty list -> empty list",
220
- ?_test([] = dlist_next([]))},
221
- {"singleton list -> singleton list",
222
- ?_test([any] = dlist_next([any]))},
223
- {"taking the head of a flat list",
224
- ?_test([a,b,c] = dlist_next([a,b,c]))},
225
- {"skipping an initial empty list",
226
- ?_test([a,b,c] = dlist_next([[],a,b,c]))},
227
- {"skipping nested initial empty lists",
228
- ?_test([a,b,c] = dlist_next([[[[]]],a,b,c]))},
229
- {"skipping a final empty list",
230
- ?_test([] = dlist_next([[]]))},
231
- {"skipping nested final empty lists",
232
- ?_test([] = dlist_next([[[[]]]]))},
233
- {"the first element is in a sublist",
234
- ?_test([a,b,c] = dlist_next([[a],b,c]))},
235
- {"recognizing a naked string",
236
- ?_test(["abc"] = dlist_next("abc"))},
237
- {"recognizing a wrapped string",
238
- ?_test(["abc"] = dlist_next(["abc"]))},
239
- {"recognizing a leading string",
240
- ?_test(["abc",a,b,c] = dlist_next(["abc",a,b,c]))},
241
- {"recognizing a nested string",
242
- ?_test(["abc"] = dlist_next([["abc"]]))},
243
- {"recognizing a leading string in a sublist",
244
- ?_test(["abc",a,b,c] = dlist_next([["abc"],a,b,c]))},
245
- {"traversing an empty list",
246
- ?_test([] = dlist_flatten([]))},
247
- {"traversing a flat list",
248
- ?_test([a,b,c] = dlist_flatten([a,b,c]))},
249
- {"traversing a deep list",
250
- ?_test([a,b,c] = dlist_flatten([[],[a,[b,[]],c],[]]))},
251
- {"traversing a deep but empty list",
252
- ?_test([] = dlist_flatten([[],[[[]]],[]]))}
253
- ]}.
254
-
255
- %% test support
256
- dlist_flatten(Xs) ->
257
- case dlist_next(Xs) of
258
- [X | Xs1] -> [X | dlist_flatten(Xs1)];
259
- [] -> []
260
- end.
261
- -endif.
262
-
263
-
264
- %% ---------------------------------------------------------------------
265
- %% Check for proper Unicode-stringness.
266
-
267
- is_string([C | Cs]) when is_integer(C), C >= 0, C =< 16#10ffff ->
268
- is_string(Cs);
269
- is_string([_ | _]) ->
270
- false;
271
- is_string([]) ->
272
- true;
273
- is_string(_) ->
274
- false.
275
-
276
- is_nonempty_string([]) -> false;
277
- is_nonempty_string(Cs) -> is_string(Cs).
278
-
279
- -ifdef(TEST).
280
- is_string_test_() ->
281
- {"is_string",
282
- [{"no non-lists", ?_assert(not is_string($A))},
283
- {"no non-integer lists", ?_assert(not is_string([true]))},
284
- {"empty string", ?_assert(is_string(""))},
285
- {"ascii string", ?_assert(is_string(lists:seq(0, 127)))},
286
- {"latin-1 string", ?_assert(is_string(lists:seq(0, 255)))},
287
- {"unicode string",
288
- ?_assert(is_string([0, $A, 16#10fffe, 16#10ffff]))},
289
- {"not above unicode range",
290
- ?_assert(not is_string([0, $A, 16#110000]))},
291
- {"no negative codepoints", ?_assert(not is_string([$A, -1, 0]))}
292
- ]}.
293
- -endif.
294
-
295
-
296
- %% ---------------------------------------------------------------------
297
- %% Splitting a full node name into basename and hostname,
298
- %% using 'localhost' as the default hostname
299
-
300
- split_node(N) when is_atom(N) -> split_node(atom_to_list(N));
301
- split_node(Cs) -> split_node_1(Cs, []).
302
-
303
- split_node_1([$@ | Cs], As) -> split_node_2(As, Cs);
304
- split_node_1([C | Cs], As) -> split_node_1(Cs, [C | As]);
305
- split_node_1([], As) -> split_node_2(As, "localhost").
306
-
307
- split_node_2(As, Cs) ->
308
- {list_to_atom(lists:reverse(As)), list_to_atom(Cs)}.
309
-
310
- %% ---------------------------------------------------------------------
311
- %% Get the name of the containing function for a fun. (This is encoded
312
- %% in the name of the generated function that implements the fun.)
313
-
314
- fun_parent(F) ->
315
- {name, N} = erlang:fun_info(F, name),
316
- case erlang:fun_info(F, type) of
317
- {type, external} ->
318
- N;
319
- {type, local} ->
320
- S = atom_to_list(N),
321
- list_to_atom(string:sub_string(S, 2, string:chr(S, $/) - 1))
322
- end.
323
-
324
- -ifdef(TEST).
325
- fun_parent_test() ->
326
- fun_parent_test = fun_parent(fun () -> ok end).
327
- -endif.
328
-
329
-
330
- %% ---------------------------------------------------------------------
331
- %% Ye olde uniq function
332
-
333
- uniq([X, X | Xs]) -> uniq([X | Xs]);
334
- uniq([X | Xs]) -> [X | uniq(Xs)];
335
- uniq([]) -> [].
336
-
337
- -ifdef(TEST).
338
- uniq_test_() ->
339
- {"uniq",
340
- [?_assertError(function_clause, uniq(ok)),
341
- ?_assertError(function_clause, uniq([1|2])),
342
- ?_test([] = uniq([])),
343
- ?_test([1,2,3] = uniq([1,2,3])),
344
- ?_test([1,2,3] = uniq([1,2,2,3])),
345
- ?_test([1,2,3,2,1] = uniq([1,2,2,3,2,2,1])),
346
- ?_test([1,2,3] = uniq([1,1,1,2,2,2,3,3,3])),
347
- ?_test(["1","2","3"] = uniq(["1","1","2","2","3","3"]))
348
- ]}.
349
- -endif.
350
-
351
-
352
- %% ---------------------------------------------------------------------
353
- %% Apply arbitrary unary function F with dummy arguments "until it
354
- %% works". (F must be side effect free! It will be called repeatedly.)
355
- %% No exceptions will be thrown unless the function actually crashes for
356
- %% some other reason than being unable to match the argument.
357
-
358
- %% @spec (F::(any()) -> any()) -> {Value::any(), Result::any()}
359
-
360
- browse_fun(F) ->
361
- browse_fun(F, arg_values()).
362
-
363
- browse_fun(F, Next) ->
364
- case Next() of
365
- [V | Next1] ->
366
- case try_apply(F, V) of
367
- {ok, Result} ->
368
- {V, Result};
369
- {error, function_clause} ->
370
- browse_fun(F, Next1);
371
- {error, badarity} ->
372
- erlang:error({badarity, {F, 1}});
373
- {error, {Class, Reason, Trace}} ->
374
- erlang:raise(Class, Reason, Trace)
375
- end;
376
- [] ->
377
- %% tried everything - this ought to provoke an error
378
- F(undefined)
379
- end.
380
-
381
- %% Apply argument to function and report whether it succeeded (and with
382
- %% what return value), or failed due to bad arity or a simple top-level
383
- %% function_clause error, or if it crashed in some other way.
384
-
385
- %% @spec (F::(any()) -> any(), V::any()) ->
386
- %% {ok, Result::any()}
387
- %% | {error, function_clause | badarity | eunit_test:exception()}
388
-
389
- try_apply(F, Arg) ->
390
- case erlang:fun_info(F, arity) of
391
- {arity, 1} ->
392
- {module, M} = erlang:fun_info(F, module),
393
- {name, N} = erlang:fun_info(F, name),
394
- try_apply(F, Arg, M, N);
395
- _ ->
396
- {error, badarity}
397
- end.
398
-
399
- try_apply(F, Arg, M, N) ->
400
- try F(Arg) of
401
- X -> {ok, X}
402
- catch
403
- error:function_clause ->
404
- case erlang:get_stacktrace() of
405
- [{M, N, _Args} | _] ->
406
- {error, function_clause};
407
- Trace ->
408
- {error, {error, function_clause, Trace}}
409
- end;
410
- Class:Reason ->
411
- {error, {Class, Reason, erlang:get_stacktrace()}}
412
- end.
413
-
414
- %% test value producers for function browsing
415
-
416
- arg_values() ->
417
- Vs = [undefined, ok, true, false, 0, 1],
418
- fun () -> arg_values(Vs) end.
419
-
420
- arg_values([V | Vs]) ->
421
- [V | fun () -> arg_values(Vs) end];
422
- arg_values(_) ->
423
- (arg_tuples())().
424
-
425
- arg_tuples() ->
426
- fun () -> arg_tuples(0) end.
427
-
428
- arg_tuples(N) when N >= 0, N =< 12 ->
429
- [erlang:make_tuple(N, undefined) | fun () -> arg_tuples(N + 1) end];
430
- arg_tuples(_) ->
431
- (arg_lists())().
432
-
433
- arg_lists() ->
434
- fun () -> arg_lists(0) end.
435
-
436
- arg_lists(N) when N >= 0, N =< 12 ->
437
- [lists:duplicate(N, undefined) | fun () -> arg_lists(N + 1) end];
438
- arg_lists(_) ->
439
- [].
440
-
441
- -ifdef(TEST).
442
- browse_fun_test_() ->
443
- {"browsing funs",
444
- [?_assertError({badarity, {_, 1}}, browse_fun(fun () -> ok end)),
445
- ?_assertError({badarity, {_, 1}}, browse_fun(fun (_,_) -> ok end)),
446
- ?_assertError(function_clause, browse_fun(fun (42) -> ok end)),
447
- ?_test({_, 17} = browse_fun(fun (_) -> 17 end)),
448
- ?_test({_, 17} = browse_fun(fun (undefined) -> 17 end)),
449
- ?_test({_, 17} = browse_fun(fun (ok) -> 17 end)),
450
- ?_test({_, 17} = browse_fun(fun (true) -> 17 end)),
451
- ?_test({_, 17} = browse_fun(fun ({}) -> 17 end)),
452
- ?_test({_, 17} = browse_fun(fun ({_}) -> 17 end)),
453
- ?_test({_, 17} = browse_fun(fun ({_,_}) -> 17 end)),
454
- ?_test({_, 17} = browse_fun(fun ({_,_,_}) -> 17 end)),
455
- ?_test({_, 17} = browse_fun(fun ([]) -> 17 end)),
456
- ?_test({_, 17} = browse_fun(fun ([_]) -> 17 end)),
457
- ?_test({_, 17} = browse_fun(fun ([_,_]) -> 17 end)),
458
- ?_test({_, 17} = browse_fun(fun ([_,_,_]) -> 17 end))
459
- ]}.
460
- -endif.
461
-
462
-
463
- %% ---------------------------------------------------------------------
464
- %% Replacement for os:cmd
465
-
466
- command(Cmd) ->
467
- command(Cmd, "").
468
-
469
- command(Cmd, Dir) ->
470
- command(Cmd, Dir, []).
471
-
472
- command(Cmd, Dir, Env) ->
473
- CD = if Dir == "" -> [];
474
- true -> [{cd, Dir}]
475
- end,
476
- SetEnv = if Env == [] -> [];
477
- true -> [{env, Env}]
478
- end,
479
- Opt = CD ++ SetEnv ++ [stream, exit_status, use_stdio,
480
- stderr_to_stdout, in, eof],
481
- P = open_port({spawn, Cmd}, Opt),
482
- get_data(P, []).
483
-
484
- get_data(P, D) ->
485
- receive
486
- {P, {data, D1}} ->
487
- get_data(P, [D1|D]);
488
- {P, eof} ->
489
- port_close(P),
490
- receive
491
- {P, {exit_status, N}} ->
492
- {N, normalize(lists:flatten(lists:reverse(D)))}
493
- end
494
- end.
495
-
496
- normalize([$\r, $\n | Cs]) ->
497
- [$\n | normalize(Cs)];
498
- normalize([$\r | Cs]) ->
499
- [$\n | normalize(Cs)];
500
- normalize([C | Cs]) ->
501
- [C | normalize(Cs)];
502
- normalize([]) ->
503
- [].
504
-
505
- -ifdef(TEST).
506
-
507
- cmd_test_() ->
508
- ([?_test({0, "hello\n"} = ?_cmd_("echo hello"))]
509
- ++ case os:type() of
510
- {unix, _} ->
511
- unix_cmd_tests();
512
- {win32, _} ->
513
- win32_cmd_tests();
514
- _ ->
515
- []
516
- end).
517
-
518
- unix_cmd_tests() ->
519
- [{"command execution, status, and output",
520
- [?_cmd("echo hello"),
521
- ?_assertCmdStatus(0, "true"),
522
- ?_assertCmdStatus(1, "false"),
523
- ?_assertCmd("true"),
524
- ?_assertCmdOutput("hello\n", "echo hello"),
525
- ?_assertCmdOutput("hello", "echo -n hello")
526
- ]},
527
- {"file setup and cleanup",
528
- setup,
529
- fun () -> ?cmd("mktemp tmp.XXXXXXXX") end,
530
- fun (File) -> ?cmd("rm " ++ File) end,
531
- fun (File) ->
532
- [?_assertCmd("echo xyzzy >" ++ File),
533
- ?_assertCmdOutput("xyzzy\n", "cat " ++ File)]
534
- end}
535
- ].
536
-
537
- win32_cmd_tests() ->
538
- [{"command execution, status, and output",
539
- [?_cmd("echo hello"),
540
- ?_assertCmdOutput("hello\n", "echo hello")
541
- ]}
542
- ].
543
-
544
- -endif. % TEST
545
-
546
-
547
- %% ---------------------------------------------------------------------
548
- %% Wrapper around file:path_consult
549
-
550
- %% @throws {file_read_error, {Reason::atom(), Message::string(),
551
- %% fileName()}}
552
-
553
- consult_file(File) ->
554
- case file:path_consult(["."]++code:get_path(), File) of
555
- {ok, Data, _Path} ->
556
- Data;
557
- {error, Reason} ->
558
- Msg = file:format_error(Reason),
559
- throw({file_read_error, {Reason, Msg, File}})
560
- end.
561
-
562
- %% ---------------------------------------------------------------------
563
- %% Wrapper around file:list_dir
564
-
565
- %% @throws {file_read_error, {Reason::atom(), Message::string(),
566
- %% fileName()}}
567
-
568
- list_dir(Dir) ->
569
- case file:list_dir(Dir) of
570
- {ok, Fs} ->
571
- Fs;
572
- {error, Reason} ->
573
- Msg = file:format_error(Reason),
574
- throw({file_read_error, {Reason, Msg, Dir}})
575
- end.
576
-
577
- %% ---------------------------------------------------------------------
578
- %% A trie for remembering and checking least specific cancelled events
579
- %% (an empty list `[]' simply represents a stored empty list, i.e., all
580
- %% events will match, while an empty tree means that no events match).
581
-
582
- trie_new() ->
583
- gb_trees:empty().
584
-
585
- trie_store([_ | _], []) ->
586
- [];
587
- trie_store([E | Es], T) ->
588
- case gb_trees:lookup(E, T) of
589
- none ->
590
- if Es == [] ->
591
- gb_trees:insert(E, [], T);
592
- true ->
593
- gb_trees:insert(E, trie_store(Es, gb_trees:empty()),
594
- T)
595
- end;
596
- {value, []} ->
597
- T; %% prefix already stored
598
- {value, T1} ->
599
- gb_trees:update(E, trie_store(Es, T1), T)
600
- end;
601
- trie_store([], _T) ->
602
- [].
603
-
604
- trie_match([_ | _], []) ->
605
- prefix;
606
- trie_match([E | Es], T) ->
607
- case gb_trees:lookup(E, T) of
608
- none ->
609
- no;
610
- {value, []} ->
611
- if Es == [] -> exact;
612
- true -> prefix
613
- end;
614
- {value, T1} ->
615
- trie_match(Es, T1)
616
- end;
617
- trie_match([], []) ->
618
- exact;
619
- trie_match([], _T) ->
620
- no.
621
-
622
- -ifdef(TEST).
623
-
624
- trie_test_() ->
625
- [{"basic representation",
626
- [?_assert(trie_new() == gb_trees:empty()),
627
- ?_assert(trie_store([1], trie_new())
628
- == gb_trees:insert(1, [], gb_trees:empty())),
629
- ?_assert(trie_store([1,2], trie_new())
630
- == gb_trees:insert(1,
631
- gb_trees:insert(2, [],
632
- gb_trees:empty()),
633
- gb_trees:empty())),
634
- ?_assert([] == trie_store([1], [])),
635
- ?_assert([] == trie_store([], gb_trees:empty()))
636
- ]},
637
- {"basic storing and matching",
638
- [?_test(no = trie_match([], trie_new())),
639
- ?_test(exact = trie_match([], trie_store([], trie_new()))),
640
- ?_test(no = trie_match([], trie_store([1], trie_new()))),
641
- ?_test(exact = trie_match([1], trie_store([1], trie_new()))),
642
- ?_test(prefix = trie_match([1,2], trie_store([1], trie_new()))),
643
- ?_test(no = trie_match([1], trie_store([1,2], trie_new()))),
644
- ?_test(no = trie_match([1,3], trie_store([1,2], trie_new()))),
645
- ?_test(exact = trie_match([1,2,3,4,5],
646
- trie_store([1,2,3,4,5], trie_new()))),
647
- ?_test(prefix = trie_match([1,2,3,4,5],
648
- trie_store([1,2,3], trie_new()))),
649
- ?_test(no = trie_match([1,2,2,4,5],
650
- trie_store([1,2,3], trie_new())))
651
- ]},
652
- {"matching with partially overlapping patterns",
653
- setup,
654
- fun () ->
655
- trie_store([1,3,2], trie_store([1,2,3], trie_new()))
656
- end,
657
- fun (T) ->
658
- [?_test(no = trie_match([], T)),
659
- ?_test(no = trie_match([1], T)),
660
- ?_test(no = trie_match([1,2], T)),
661
- ?_test(no = trie_match([1,3], T)),
662
- ?_test(exact = trie_match([1,2,3], T)),
663
- ?_test(exact = trie_match([1,3,2], T)),
664
- ?_test(no = trie_match([1,2,2], T)),
665
- ?_test(no = trie_match([1,3,3], T)),
666
- ?_test(prefix = trie_match([1,2,3,4], T)),
667
- ?_test(prefix = trie_match([1,3,2,1], T))]
668
- end},
669
- {"matching with more general pattern overriding less general",
670
- setup,
671
- fun () -> trie_store([1], trie_store([1,2,3], trie_new())) end,
672
- fun (_) -> ok end,
673
- fun (T) ->
674
- [?_test(no = trie_match([], T)),
675
- ?_test(exact = trie_match([1], T)),
676
- ?_test(prefix = trie_match([1,2], T)),
677
- ?_test(prefix = trie_match([1,2,3], T)),
678
- ?_test(prefix = trie_match([1,2,3,4], T))]
679
- end}
680
- ].
681
-
682
- -endif. % TEST