summaryrefslogtreecommitdiff
path: root/doc/_extensions/autojsdoc/parser/tests/test_class.py
diff options
context:
space:
mode:
authorXavier Morel <xmo@odoo.com>2017-09-18 10:13:54 +0200
committerGéry Debongnie <ged@odoo.com>2017-09-18 11:54:36 +0200
commit313f69e9487e991e4db33c75682342b185da5c73 (patch)
treedfe8918e95a5f27888319e7a5c1a5187cd8c8751 /doc/_extensions/autojsdoc/parser/tests/test_class.py
parent8defed9536711a05f147f28916b7109854f9932c (diff)
[ADD] doc: JS document extraction system
* Fix a bunch of ill-documented/incomplete/incorrect method docs * add start of Sphinx extension to extract & integrate jsdoc into Sphinx documentation: - parse JS files (and don't blow up), uses a fork of pyjsparser as the project currently does not parse comments - extract cross-module dependency information - parse JsDoc comments using pyjsdoc and infer structure from code & jsdoc - ``ast`` CLI printing a simplified AST of the input files - ``dependencies`` creating a dependency graph of either all modules in the provided input files or the modules matching the specified filters (warning: will not work if missing dependencies), generates a .dot file - ``extractor`` generating a plain text module documentation (mix of rst and markdown styles, not anything formal) * sphinx extension with an "automodule" directive taking a module name and generating the documentation for it
Diffstat (limited to 'doc/_extensions/autojsdoc/parser/tests/test_class.py')
-rw-r--r--doc/_extensions/autojsdoc/parser/tests/test_class.py227
1 files changed, 227 insertions, 0 deletions
diff --git a/doc/_extensions/autojsdoc/parser/tests/test_class.py b/doc/_extensions/autojsdoc/parser/tests/test_class.py
new file mode 100644
index 00000000000..403ae9b48b7
--- /dev/null
+++ b/doc/_extensions/autojsdoc/parser/tests/test_class.py
@@ -0,0 +1,227 @@
+# -*- coding: utf-8 -*-
+import pytest
+
+from autojsdoc.parser import jsdoc
+from support import params, parse
+
+def test_classvar():
+ [mod] = parse("""
+ odoo.define('a.A', function(require) {
+ var Class = require('Class');
+ /**
+ * This is my class-kai
+ */
+ var A = Class.extend({});
+ return A;
+ });
+ """)
+ cls = mod.exports
+ assert type(cls) == jsdoc.ClassDoc
+
+ assert type(cls.superclass) == jsdoc.ClassDoc
+ assert cls.superclass.name == 'Class'
+
+ assert cls.name == 'A'
+ assert cls.constructor is None
+ assert cls.properties == []
+ assert cls['doc'] == 'This is my class-kai'
+
+def test_classret():
+ [mod] = parse("""
+ odoo.define('a.A', function(require) {
+ var Class = require('Class');
+ /**
+ * This is my class-kai
+ */
+ return Class.extend({});
+ });
+ """)
+ cls = mod.exports
+ assert type(cls) == jsdoc.ClassDoc
+
+ assert cls.name == ''
+ assert cls.constructor is None
+ assert cls.properties == []
+ assert cls['doc'] == 'This is my class-kai'
+
+def test_methods():
+ [mod] = parse("""
+ odoo.define('a.A', function(require) {
+ var Class = require('Class');
+ return Class.extend({
+ /**
+ * @param {Widget} parent
+ */
+ init: function (parent) {},
+ /**
+ * @returns {Widget}
+ */
+ itself: function () { return this; },
+ /**
+ * @param {MouseEvent} e
+ */
+ _onValidate: function (e) {},
+ });
+ });
+ """)
+ cls = mod.exports
+ assert len(cls.properties) == 3
+ assert cls.constructor
+ # assume methods are in source order
+ [_, init] = cls.properties[0]
+ assert init == cls.constructor
+ assert init.name == 'init'
+ assert not init.is_private
+ assert init.is_constructor
+ [param] = init.params
+ assert params(param) == ('parent', 'Widget', '')
+
+ [_, itself] = cls.properties[1]
+ assert itself.name == 'itself'
+ assert not itself.is_private
+ assert not itself.is_constructor
+ assert not itself.params
+ assert params(itself.return_val) == ('', 'Widget', '')
+
+ [_, _on] = cls.properties[2]
+ assert _on.name == '_onValidate'
+ assert _on.is_private
+ assert not _on.is_constructor
+ [param] = _on.params
+ assert params(param) == ('e', 'MouseEvent', '')
+
+def test_mixin_explicit():
+ [mod] = parse("""
+ odoo.define('a.A', function (require) {
+ var Class = require('Class');
+ var mixins = require('mixins');
+ /**
+ * This is my class-kai
+ * @mixes mixins.Bob
+ */
+ return Class.extend({});
+ });
+ """)
+ cls = mod.exports
+ # FIXME: ClassDoc may want to m2r(mixin, scope)?
+ assert cls.mixins == ['mixins.Bob']
+
+def test_mixin_implicit():
+ [mod] = parse("""
+ odoo.define('a.A', function(require) {
+ var Class = require('Class');
+ var Mixin = require('Mixin');
+ /**
+ * This is my class-kai
+ */
+ return Class.extend(Mixin, { foo: function() {} });
+ });
+ """)
+ cls = mod.exports
+ [mixin] = cls.mixins
+ assert type(mixin) == jsdoc.MixinDoc
+ assert params(mixin.properties[0][1]) == ('a', 'Function', '')
+ assert params(mixin.get_property('a')) == ('a', 'Function', '')
+
+ assert params(cls.get_property('foo')) == ('foo', 'Function', '')
+
+def test_instanciation():
+ [A, a] = parse("""
+ odoo.define('A', function (r) {
+ var Class = r('Class');
+ /**
+ * @class A
+ */
+ return Class.extend({
+ foo: function () {}
+ });
+ });
+ odoo.define('a', function (r) {
+ var A = r('A');
+ var a = new A;
+ return a;
+ });
+ """)
+ assert type(a.exports) == jsdoc.InstanceDoc
+ assert a.exports.cls.name == A.exports.name
+
+def test_non_function_properties():
+ [A] = parse("""
+ odoo.define('A', function (r) {
+ var Class = r('Class');
+ return Class.extend({
+ template: 'thing',
+ a_prop: [1, 2, 3],
+ 'other': {a: 7}
+ });
+ });
+ """)
+ t = A.exports.get_property('template')
+ assert type(t) == jsdoc.PropertyDoc
+ assert params(t) == ('template', 'String', '')
+ assert not t.is_private
+
+def test_non_extend_classes():
+ [mod] = parse("""
+ odoo.define('A', function () {
+ /**
+ * @class
+ */
+ var Class = function () {}
+ return Class;
+ });
+ """)
+ assert type(mod.exports) == jsdoc.ClassDoc
+
+def test_extend():
+ [a, _] = parse("""
+ odoo.define('A', function (require) {
+ var Class = require('Class');
+ return Class.extend({});
+ });
+ odoo.define('B', function (require) {
+ var A = require('A');
+ A.include({
+ /** A property */
+ a: 3,
+ /** A method */
+ b: function () {}
+ });
+ });
+ """)
+ cls = a.exports
+ assert type(cls) == jsdoc.ClassDoc
+ a = cls.get_property('a')
+ assert type(a) == jsdoc.PropertyDoc
+ assert params(a) == ('a', 'Number', 'A property')
+ b = cls.get_property('b')
+ assert type(b) == jsdoc.FunctionDoc
+ assert params(b) == ('b', 'Function', 'A method')
+
+# TODO: also support virtual members?
+# TODO: computed properties?
+@pytest.mark.skip(reason="Need to implement member/var-parsing?")
+def test_members():
+ [mod] = parse("""
+ odoo.define('A', function (r) {
+ var Class = r('Class');
+ return Class.extend({
+ init: function () {
+ /**
+ * This is bob
+ * @var {Foo}
+ */
+ this.foo = 3;
+ this.bar = 42;
+ /**
+ * @member {Baz}
+ */
+ this.baz = null;
+ }
+ });
+ });
+ """)
+ cls = mod.exports
+ assert params(cls.members[0]) == ('foo', 'Foo', 'This is bob')
+ assert params(cls.members[1]) == ('bar', '', '')
+ assert params(cls.members[2]) == ('baz', 'Baz', '')