File: 05infobot.t

package info (click to toggle)
libbot-basicbot-pluggable-perl 1.30%2Bds1-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 516 kB
  • sloc: perl: 3,153; makefile: 17
file content (230 lines) | stat: -rw-r--r-- 8,302 bytes parent folder | download | duplicates (5)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
#!perl
use warnings;
use strict;
use Test::More tests => 89;
use Test::Bot::BasicBot::Pluggable;

use FindBin qw( $Bin );
use lib $Bin;

my $bot = Test::Bot::BasicBot::Pluggable->new();

ok( my $ib = $bot->load("Infobot"), "Loaded infobot module" );

ok( my $uur = $ib->get("user_unknown_responses"),
    "got list of unknown responses" )
  or die;
my $no_regex = qr/($uur)/;

# ok, the intent here is to test / document the infobot grammar, because
# every time I mess with it I get annoying regressions. In general, B::B::P
# wasn't built with Test-Driven techniques, and this is hurting me recently,
# it's way too hard to write tests retroactively..

ok( $ib->help, "module has help text" );

# by default, the infobot doesn't learn things that it merely overhears
ok( !$bot->tell_indirect("foo is red"), "passive learning off by default" );
ok( !$bot->tell_indirect("foo?"),       "no answer to passive learn" );
like( $bot->tell_direct("foo?"), $no_regex, "no info on foo" );

# ..but it will learn things it's told $bot->tell_directly.
like( $bot->tell_direct("foo?"), $no_regex, "no info on foo" );
is( $bot->tell_direct("foo is red"), "Okay.", "active learning works" );
is( $bot->tell_direct("foo?"), "foo is red", "correct answer to active learn" );

like( $bot->tell_direct("quux?"), $no_regex, "no info on quux" );
is( $bot->tell_direct("quux are blue"), "Okay.", "active learning works" );
is(
    $bot->tell_direct("quux?"),
    "quux are blue",
    "correct answer to active learn"
);

# you can tell someone about foo
is(
    $bot->tell_direct("tell testbot about foo"),
    "Told testbot about foo.",
    "tell someone about foo"
);

ok( !$bot->tell_indirect("foo?"), "passive questioning off by default" );

# you can turn on the ability to ask questions without addressing the bot
ok( $ib->set( "user_passive_answer", 1 ), "activate passive ask" );
is( $bot->tell_indirect("foo?"), "foo is red", "passive questioning now on" );

# and the ability to add factoids without addressing the bot
ok( $ib->set( "user_passive_learn", 1 ), "activate passive learn" );
is( $bot->tell_direct("bar is green"), "Okay.", "passive learning now works" );
is( $bot->tell_indirect("bar?"), "bar is green", "passive questioning works" );

# you can search factoids, but not in public
is(
    $bot->tell_direct("search for foo"),
    "privmsg only, please",
    "not searched in public"
);
$ib->set( "user_allow_searching", 0 );
is(
    $bot->tell_private("search for foo"),
    "searching disabled",
    "searched for 'foo' disabled"
);
$ib->set( "user_allow_searching", 1 );
is(
    $bot->tell_private("search for foo"),
    "I know about: 'foo'.",
    "searched for 'foo'"
);
is(
    $bot->tell_private("search for foobar"),
    "I don't know anything about foobar.",
    "searched for 'foobar' (which we know nothing about)"
);
is(
    $bot->tell_private("search for foo bar"),
    "I know about: 'foo', 'bar'.",
    "searched for 'foo' and 'bar'"
);
$ib->set( 'user_num_results' => 1 );
is(
    $bot->tell_private("search for foo bar"),
    "I know about: 'foo'.",
    "searched for 'foo' and 'bar' with user_num_results set to 1"
);

# you can append strings to factoids
is( $bot->tell_direct("foo is also blue"), "Okay.", "can append to faactoids" );
is( $bot->tell_direct("foo?"), "foo is red or blue", "works" );
is( $bot->tell_direct("foo is also pink"), "Okay.", "can append to faactoids" );
is( $bot->tell_direct("foo?"), "foo is red or blue or pink", "works" );

# factoids can be forgotten
is( $bot->tell_direct("forget foo"), "I forgot about foo.", "forgotten foo" );
like( $bot->tell_direct("foo?"), $no_regex, "no info on foo" );
is(
    $bot->tell_direct("forget foo"),
    "I don't know anything about foo.",
    "can't forget something i don't know"
);

# factoids can be replaced
my $but_reply =
  '... but bar is green ...';    # ok, why does this get interpreted as '1'
is( $bot->tell_direct("bar is yellow"),
    $but_reply, "Can't just redefine factoids" );
is( $bot->tell_indirect("bar is yellow"), '', "Can't just redefine factoids" );
is( $bot->tell_indirect("bar?"), "bar is green", "not changed" );
is( $bot->tell_direct("no, bar is yellow"),
    "Okay.", "Can explicitly redefine factoids" );
is( $bot->tell_indirect("bar?"), "bar is yellow", "changed" );

# factoids can contain RSS
SKIP: {
    eval "use XML::Feed";
    skip 'XML::Feed not installed', 4 if $@;

    is( $bot->tell_direct("rsstest is <rss=\"file:///$Bin/test.rss\">"),
        "Okay.", "set RSS" );
    is( $bot->tell_indirect("rsstest?"), "title", "can read rss" );
    $bot->tell_direct("rsstest2 is <rss=\"file:///$Bin/05infobot.t\">");
    like(
        $bot->tell_indirect("rsstest2?"),
qr{rsstest2 is << Error parsing RSS from file:///.*/05infobot.t: Cannot detect feed type >>},
        "can't read rss"
    );
    is(
        $bot->tell_direct("literal rsstest?"),
        "rsstest =is= <rss=\"file:///$Bin/test.rss\">",
        "literal of rsstest"
    );
}

my $old_stopwords = $ib->get("user_stopwords");

# certain things can't be factoid keys.
ok( $ib->set( "user_stopwords", "and" ), "set stopword 'and'" );
ok( !$bot->tell_direct("and is mumu"), "can't set 'and' as factoid" );
ok( !$bot->tell_direct("dkjsdlfkdsjfglkdsfjglfkdjgldksfjglkdfjglds is mumu"),
    "can't set very long factoid" );

$ib->set( "user_stopwords", $old_stopwords );

# literal syntax
ok( $bot->tell_direct("bar is also fum"), "bar also fum" );
is( $bot->tell_direct("literal bar?"), "bar =is= yellow =or= fum", "bar" );

# alternate factoids ('|')
is( $bot->tell_direct("foo is one"),         "Okay.", "foo is one" );
is( $bot->tell_direct("foo is also two"),    "Okay.", "foo is also two" );
is( $bot->tell_direct("foo is also |maybe"), "Okay.", "foo is also maybe" );

ok( my $reply = $bot->tell_direct("foo?"), "got one of the foos" );
ok( ( $reply eq 'foo is maybe' or $reply eq 'foo is one or two' ),
    "it's one of the two" );

# blech's torture test, all three in one
# notes on dipsy differences:
# * 'ok' is 'okay.' in a true infobot
# * literal doesn't highlight =or= like it does =is=
# * infobots attempt to parse english
# * there's a difference between 'is' and 'are'
# * doesn't respond to a passive attempt to reset an item

is( $bot->tell_direct("forget foo"), "I forgot about foo.", "forgotten foo" );

is( $bot->tell_direct("foo is foo"),   "Okay.",      "simple set" );
is( $bot->tell_direct("foo?"),         "foo is foo", "simple get" );
is( $bot->tell_direct("what is foo?"), "foo is foo", "English-language get" )
  ;    # fails
is( $bot->tell_direct("where is foo?"), "foo is foo", "Another English get" );
is( $bot->tell_direct("who is foo?"), "foo is foo", "Yet another English get" );

is( $bot->tell_direct("hoogas are things"), "Okay.", "simple 'are' set" )
  ;    # fails
is(
    $bot->tell_direct("what are hoogas?"),
    "hoogas are things",
    "English-language 'are' get"
);

is(
    $bot->tell_direct("foo is a silly thing"),
    "... but foo is foo ...",
    "warning about overwriting"
);
is( $bot->tell_indirect("foo is a silly thing"), "", "shouldn't get a reply" );

is( $bot->tell_direct("foo is also bar"), "Okay.", "simple append" );
is( $bot->tell_direct("foo?"), "foo is foo or bar", "appended ok" );
is( $bot->tell_direct("foo is also baz or quux"), "Okay.", "complex append" );
is( $bot->tell_direct("foo?"), "foo is foo or bar or baz or quux", "also ok" );
is( $bot->tell_direct("foo is also | a silly thing"),
    "Okay.", "alternate appended" );

is(
    $bot->tell_direct("literal foo?"),
    "foo =is= foo =or= bar =or= baz =or= quux =or= |a silly thing",
    "entire factoid looks right"
);
is( $bot->tell_direct("foo is also |<reply>this is a very silly thing"),
    "Okay.", "and a reply" );
is(
    $bot->tell_direct("literal foo?"),
"foo =is= foo =or= bar =or= baz =or= quux =or= |a silly thing =or= |<reply>this is a very silly thing",
    "entire entry looks fine to me"
);

# run through a few times, and see what we get out
foreach my $i ( 0 .. 9 ) {
    ok( $reply = $bot->tell_direct("foo?"), "got one of the foos" );
    ok(
        (
                 $reply eq 'foo is foo or bar or baz or quux'
              or $reply eq 'foo is a silly thing'
              or $reply eq 'this is a very silly thing'
        ),
        "it's '$reply'"
    );
}