patch 8.0.0334: can't access b:changedtick from a dict reference

Problem:    Can't access b:changedtick from a dict reference.
Solution:   Make changedtick a member of the b: dict. (inspired by neovim
            #6112)
diff --git a/src/testdir/test91.in b/src/testdir/test91.in
index e1365cb..c184ac3 100644
--- a/src/testdir/test91.in
+++ b/src/testdir/test91.in
@@ -1,4 +1,4 @@
-Tests for getbufvar(), getwinvar(), gettabvar() and gettabwinvar().
+Tests for getwinvar(), gettabvar() and gettabwinvar().
 vim: set ft=vim :
 
 STARTTEST
@@ -10,34 +10,7 @@
 :let t:testvar='abcd'
 :$put =string(gettabvar(1,'testvar'))
 :$put =string(gettabvar(1,'testvar'))
-:" Test for getbufvar()
-:let b:var_num = '1234'
-:let def_num = '5678'
-:$put =string(getbufvar(1, 'var_num'))
-:$put =string(getbufvar(1, 'var_num', def_num))
-:$put =string(getbufvar(1, ''))
-:$put =string(getbufvar(1, '', def_num))
-:unlet b:var_num
-:$put =string(getbufvar(1, 'var_num', def_num))
-:$put =string(getbufvar(1, ''))
-:$put =string(getbufvar(1, '', def_num))
-:$put =string(getbufvar(9, ''))
-:$put =string(getbufvar(9, '', def_num))
-:unlet def_num
-:$put =string(getbufvar(1, '&autoindent'))
-:$put =string(getbufvar(1, '&autoindent', 1))
 :"
-:" Open new window with forced option values
-:set fileformats=unix,dos
-:new ++ff=dos ++bin ++enc=iso-8859-2
-:let otherff = getbufvar(bufnr('%'), '&fileformat')
-:let otherbin = getbufvar(bufnr('%'), '&bin')
-:let otherfenc = getbufvar(bufnr('%'), '&fenc')
-:close
-:$put =otherff
-:$put =string(otherbin)
-:$put =otherfenc
-:unlet otherff otherbin otherfenc
 :" test for getwinvar()
 :let w:var_str = "Dance"
 :let def_str = "Chance"
diff --git a/src/testdir/test91.ok b/src/testdir/test91.ok
index 62adec1..2cdf288 100644
--- a/src/testdir/test91.ok
+++ b/src/testdir/test91.ok
@@ -1,20 +1,6 @@
 start:
 'abcd'
 'abcd'
-'1234'
-'1234'
-{'var_num': '1234'}
-{'var_num': '1234'}
-'5678'
-{}
-{}
-''
-'5678'
-0
-0
-dos
-1
-iso-8859-2
 'Dance'
 'Dance'
 {'var_str': 'Dance'}
diff --git a/src/testdir/test_alot.vim b/src/testdir/test_alot.vim
index 38b9f7a..d43ae4f 100644
--- a/src/testdir/test_alot.vim
+++ b/src/testdir/test_alot.vim
@@ -3,10 +3,11 @@
 
 source test_assign.vim
 source test_autocmd.vim
+source test_changedtick.vim
 source test_cursor_func.vim
 source test_delete.vim
-source test_execute_func.vim
 source test_ex_undo.vim
+source test_execute_func.vim
 source test_expand.vim
 source test_expr.vim
 source test_expand_dllpath.vim
diff --git a/src/testdir/test_changedtick.vim b/src/testdir/test_changedtick.vim
new file mode 100644
index 0000000..f273f0f
--- /dev/null
+++ b/src/testdir/test_changedtick.vim
@@ -0,0 +1,45 @@
+" Tests for b:changedtick
+
+func Test_changedtick_increments()
+  new
+  " New buffer has an empty line, tick starts at 2.
+  let expected = 2
+  call assert_equal(expected, b:changedtick)
+  call assert_equal(expected, b:['changedtick'])
+  call setline(1, 'hello')
+  let expected += 1
+  call assert_equal(expected, b:changedtick)
+  call assert_equal(expected, b:['changedtick'])
+  undo
+  " Somehow undo counts as two changes.
+  let expected += 2
+  call assert_equal(expected, b:changedtick)
+  call assert_equal(expected, b:['changedtick'])
+  bwipe!
+endfunc
+
+func Test_changedtick_dict_entry()
+  let d = b:
+  call assert_equal(b:changedtick, d['changedtick'])
+endfunc
+
+func Test_changedtick_bdel()
+  new
+  let bnr = bufnr('%')
+  let v = b:changedtick
+  bdel
+  " Delete counts as a change too.
+  call assert_equal(v + 1, getbufvar(bnr, 'changedtick'))
+endfunc
+
+func Test_changedtick_fixed()
+  call assert_fails('let b:changedtick = 4', 'E46')
+  call assert_fails('let b:["changedtick"] = 4', 'E46')
+
+  call assert_fails('unlet b:changedtick', 'E795')
+  call assert_fails('unlet b:["changedtick"]', 'E46')
+
+  let d = b:
+  call assert_fails('unlet d["changedtick"]', 'E46')
+
+endfunc
diff --git a/src/testdir/test_functions.vim b/src/testdir/test_functions.vim
index bd4ff05..5e34c2f 100644
--- a/src/testdir/test_functions.vim
+++ b/src/testdir/test_functions.vim
@@ -424,3 +424,45 @@
   bwipe!
   iunmap <F2>
 endfunc
+
+func Test_getbufvar()
+  let bnr = bufnr('%')
+  let b:var_num = '1234'
+  let def_num = '5678'
+  call assert_equal('1234', getbufvar(bnr, 'var_num'))
+  call assert_equal('1234', getbufvar(bnr, 'var_num', def_num))
+
+  let bd = getbufvar(bnr, '')
+  call assert_equal('1234', bd['var_num'])
+  call assert_true(exists("bd['changedtick']"))
+  call assert_equal(2, len(bd))
+
+  let bd2 = getbufvar(bnr, '', def_num)
+  call assert_equal(bd, bd2)
+
+  unlet b:var_num
+  call assert_equal(def_num, getbufvar(bnr, 'var_num', def_num))
+  call assert_equal('', getbufvar(bnr, 'var_num'))
+
+  let bd = getbufvar(bnr, '')
+  call assert_equal(1, len(bd))
+  let bd = getbufvar(bnr, '',def_num)
+  call assert_equal(1, len(bd))
+
+  call assert_equal('', getbufvar(9, ''))
+  call assert_equal(def_num, getbufvar(9, '', def_num))
+  unlet def_num
+
+  call assert_equal(0, getbufvar(1, '&autoindent'))
+  call assert_equal(0, getbufvar(1, '&autoindent', 1))
+
+  " Open new window with forced option values
+  set fileformats=unix,dos
+  new ++ff=dos ++bin ++enc=iso-8859-2
+  call assert_equal('dos', getbufvar(bufnr('%'), '&fileformat'))
+  call assert_equal(1, getbufvar(bufnr('%'), '&bin'))
+  call assert_equal('iso-8859-2', getbufvar(bufnr('%'), '&fenc'))
+  close
+
+  set fileformats&
+endfunc