From f25797f86976cbccf697d6df953154c5e59656e6 Mon Sep 17 00:00:00 2001 From: Rui Abreu Ferreira Date: Sun, 25 Sep 2016 18:46:37 +0100 Subject: api: Nvim version, API level #5386 The API level is disconnected from the NVIM version. The API metadata holds the current API level, and the lowest backwards-compatible level supported by this instance. Release 0.1.6 will be the first release reporting the Nvim version and API level. metadata['version'] = { major: 0, minor: 1, patch: 6, prerelease: true, api_level: 1, api_compatible: 0, } The API level may remain unchanged across Neovim releases if the API has not changed. When changing the API the CMake variable NVIM_API_PRERELEASE is set to true, and NVIM_API_CURRENT/NVIM_API_COMPATIBILITY are incremented accordingly. The functional tests check the API table against fixtures of past versions of Neovim. It compares all the functions in the old table with the new one, it does ignore some metadata attributes that do not alter the function signature or were removed since 0.1.5. Currently the only fixture is 0.mpack, generated from Neovim 0.1.5 with nvim --api-info. --- test/functional/api/compatibility_spec.lua | 65 ++++++++++++++++++++++++++++++ 1 file changed, 65 insertions(+) create mode 100644 test/functional/api/compatibility_spec.lua (limited to 'test/functional/api') diff --git a/test/functional/api/compatibility_spec.lua b/test/functional/api/compatibility_spec.lua new file mode 100644 index 0000000000..e0fc625b46 --- /dev/null +++ b/test/functional/api/compatibility_spec.lua @@ -0,0 +1,65 @@ + +local helpers = require('test.functional.helpers')(after_each) +local lfs = require('lfs') +local mpack = require('mpack') +local clear, eq, neq = helpers.clear, helpers.eq, helpers.neq + +local read_mpack_file = function(fname) + local fd = io.open(fname, 'rb') + local data = fd:read('*a') + fd:close() + local unpack = mpack.Unpacker() + return unpack(data) +end + +-- ignore metadata in API function spec +local remove_function_metadata = function(fspec) + fspec['can_fail'] = nil + fspec['async'] = nil + fspec['method'] = nil + fspec['since'] = nil + fspec['deprecated_since'] = nil + fspec['receives_channel_id'] = nil + for idx,_ in ipairs(fspec['parameters']) do + fspec['parameters'][idx][2] = '' + end +end + +clear() +local api_level = helpers.call('api_info')['api_level'] + +describe('api compatibility', function() + before_each(clear) + + it("version metadata is sane", function() + local info = helpers.call('api_info') + local current = info['api_level']['current'] + local compatibility = info['api_level']['compatibility'] + neq(current, nil) + neq(compatibility, nil) + assert(current >= compatibility) + end) + + for ver = api_level['compatibility'], api_level['current'] do + local path = 'test/functional/fixtures/api-info/' .. tostring(ver) .. '.mpack' + it('are backwards compatible with api level '..ver, function() + if lfs.attributes(path,"mode") ~= "file" then + pending("No fixture found, skipping test") + return + end + + local old_api = read_mpack_file(path) + local api = helpers.call('api_info') + + for _, fspec in ipairs(old_api['functions']) do + remove_function_metadata(fspec) + for _, fspec_new in ipairs(api['functions']) do + if fspec['name'] == fspec_new['name'] then + remove_function_metadata(fspec_new) + eq(fspec, fspec_new) + end + end + end + end) + end +end) -- cgit From c5f5f427c6f8d1b4136bf41171f8f0980561080e Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Wed, 26 Oct 2016 15:20:00 +0200 Subject: api: api_info()['version'] API level is disconnected from NVIM version. The API metadata holds the current API level, and the lowest backwards-compatible level supported by this instance. Release 0.1.6 is the first release that reports the Nvim version and API level. metadata['version'] = { major: 0, minor: 1, patch: 6, api_level: 1, api_compatible: 0, api_prerelease: false, } The API level may remain unchanged across Nvim releases if the API has not changed. When changing the API, - set NVIM_API_PRERELEASE to true - increment NVIM_API_LEVEL (at most once per Nvim version) - adjust NVIM_API_LEVEL_COMPAT if backwards-compatibility was broken api_level_0.mpack was generated from Nvim 0.1.5 with: nvim --api-info --- test/functional/api/compatibility_spec.lua | 65 --------------------------- test/functional/api/version_spec.lua | 71 ++++++++++++++++++++++++++++++ 2 files changed, 71 insertions(+), 65 deletions(-) delete mode 100644 test/functional/api/compatibility_spec.lua create mode 100644 test/functional/api/version_spec.lua (limited to 'test/functional/api') diff --git a/test/functional/api/compatibility_spec.lua b/test/functional/api/compatibility_spec.lua deleted file mode 100644 index e0fc625b46..0000000000 --- a/test/functional/api/compatibility_spec.lua +++ /dev/null @@ -1,65 +0,0 @@ - -local helpers = require('test.functional.helpers')(after_each) -local lfs = require('lfs') -local mpack = require('mpack') -local clear, eq, neq = helpers.clear, helpers.eq, helpers.neq - -local read_mpack_file = function(fname) - local fd = io.open(fname, 'rb') - local data = fd:read('*a') - fd:close() - local unpack = mpack.Unpacker() - return unpack(data) -end - --- ignore metadata in API function spec -local remove_function_metadata = function(fspec) - fspec['can_fail'] = nil - fspec['async'] = nil - fspec['method'] = nil - fspec['since'] = nil - fspec['deprecated_since'] = nil - fspec['receives_channel_id'] = nil - for idx,_ in ipairs(fspec['parameters']) do - fspec['parameters'][idx][2] = '' - end -end - -clear() -local api_level = helpers.call('api_info')['api_level'] - -describe('api compatibility', function() - before_each(clear) - - it("version metadata is sane", function() - local info = helpers.call('api_info') - local current = info['api_level']['current'] - local compatibility = info['api_level']['compatibility'] - neq(current, nil) - neq(compatibility, nil) - assert(current >= compatibility) - end) - - for ver = api_level['compatibility'], api_level['current'] do - local path = 'test/functional/fixtures/api-info/' .. tostring(ver) .. '.mpack' - it('are backwards compatible with api level '..ver, function() - if lfs.attributes(path,"mode") ~= "file" then - pending("No fixture found, skipping test") - return - end - - local old_api = read_mpack_file(path) - local api = helpers.call('api_info') - - for _, fspec in ipairs(old_api['functions']) do - remove_function_metadata(fspec) - for _, fspec_new in ipairs(api['functions']) do - if fspec['name'] == fspec_new['name'] then - remove_function_metadata(fspec_new) - eq(fspec, fspec_new) - end - end - end - end) - end -end) diff --git a/test/functional/api/version_spec.lua b/test/functional/api/version_spec.lua new file mode 100644 index 0000000000..3efd00ddbe --- /dev/null +++ b/test/functional/api/version_spec.lua @@ -0,0 +1,71 @@ +local helpers = require('test.functional.helpers')(after_each) +local mpack = require('mpack') +local clear, funcs, eq = helpers.clear, helpers.funcs, helpers.eq + +local function read_mpack_file(fname) + local fd = io.open(fname, 'rb') + local data = fd:read('*a') + fd:close() + local unpack = mpack.Unpacker() + return unpack(data) +end + +-- Remove metadata that is not essential to backwards-compatibility. +local function remove_function_metadata(fspec) + fspec['can_fail'] = nil + fspec['async'] = nil + fspec['method'] = nil + fspec['since'] = nil + fspec['deprecated_since'] = nil + fspec['receives_channel_id'] = nil + for idx, _ in ipairs(fspec['parameters']) do + fspec['parameters'][idx][2] = '' -- Remove parameter name. + end + return fspec +end + +describe("api_info()['version']", function() + before_each(clear) + + it("returns API level", function() + local version = helpers.call('api_info')['version'] + local current = version['api_level'] + local compat = version['api_compatible'] + eq("number", type(current)) + eq("number", type(compat)) + assert(current >= compat) + end) + + it("returns Nvim version", function() + local version = helpers.call('api_info')['version'] + local major = version['major'] + local minor = version['minor'] + local patch = version['patch'] + eq("number", type(major)) + eq("number", type(minor)) + eq("number", type(patch)) + eq(1, funcs.has("nvim-"..major.."."..minor.."."..patch)) + eq(0, funcs.has("nvim-"..major.."."..minor.."."..(patch + 1))) + eq(0, funcs.has("nvim-"..major.."."..(minor + 1).."."..patch)) + eq(0, funcs.has("nvim-"..(major + 1).."."..minor.."."..patch)) + end) + + it("api_compatible level is valid", function() + local api = helpers.call('api_info') + local compat = api['version']['api_compatible'] + local path = 'test/functional/fixtures/api_level_' + ..tostring(compat)..'.mpack' + + -- Verify that the current API function signatures match those of the API + -- level for which we claim compatibility. + local old_api = read_mpack_file(path) + for _, fn_old in ipairs(old_api['functions']) do + for _, fn_new in ipairs(api['functions']) do + if fn_old['name'] == fn_new['name'] then + eq(remove_function_metadata(fn_old), + remove_function_metadata(fn_new)) + end + end + end + end) +end) -- cgit