diff --git a/ChangeLog b/ChangeLog index 2851489..3cb160b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,4 +1,9 @@ +Mon Apr 8 08:40:10 2019 +0200 Emmanuel Garette + * version 3.0 rc6 + * import tiramisu-json in tiramisu repository + Fri Apr 5 20:57:05 2019 +0200 Emmanuel Garette + * version 3.0 rc4 and rc5 * change filename/directory name with Python Packaging Autority recommendations * do not change Config contexts properties when reload in MetaConfig diff --git a/tests/dict/__init__.py b/tests/dict/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/tests/dict/data/__init__.py b/tests/dict/data/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/tests/dict/data/boolean1.json b/tests/dict/data/boolean1.json new file mode 100644 index 0000000..b49b27d --- /dev/null +++ b/tests/dict/data/boolean1.json @@ -0,0 +1,26 @@ +{ + "schema": { + "options": { + "name": "options", + "properties": { + "options.boolean": { + "name": "options.boolean", + "type": "boolean", + "title": "Boolean 1" + } + }, + "type": "object", + "title": "Common configuration" + } + }, + "model": {}, + "form": { + "null": [ + { + "title": "Configurer", + "type": "submit" + } + ] + }, + "version": "1.0" +} \ No newline at end of file diff --git a/tests/dict/data/boolean1.py b/tests/dict/data/boolean1.py new file mode 100644 index 0000000..fddad23 --- /dev/null +++ b/tests/dict/data/boolean1.py @@ -0,0 +1,12 @@ +"""just an boolean option +""" +from tiramisu.option import BoolOption, OptionDescription + +def get_description(): + """generate description for this test + """ + option = BoolOption('boolean', "Boolean 1") + descr1 = OptionDescription("options", "Common configuration", [option]) + descr = OptionDescription("boolean1", "Simple boolean", [descr1]) + return descr + diff --git a/tests/dict/data/boolean1_frozen.json b/tests/dict/data/boolean1_frozen.json new file mode 100644 index 0000000..92b64f0 --- /dev/null +++ b/tests/dict/data/boolean1_frozen.json @@ -0,0 +1,30 @@ +{ + "schema": { + "options": { + "name": "options", + "properties": { + "options.boolean": { + "name": "options.boolean", + "type": "boolean", + "title": "Boolean 1 frozen" + } + }, + "type": "object", + "title": "Common configuration" + } + }, + "model": { + "options.boolean": { + "readOnly": true + } + }, + "form": { + "null": [ + { + "title": "Configurer", + "type": "submit" + } + ] + }, + "version": "1.0" +} \ No newline at end of file diff --git a/tests/dict/data/boolean1_frozen.py b/tests/dict/data/boolean1_frozen.py new file mode 100644 index 0000000..30f8318 --- /dev/null +++ b/tests/dict/data/boolean1_frozen.py @@ -0,0 +1,12 @@ +"""just an boolean option +""" +from tiramisu.option import BoolOption, OptionDescription + +def get_description(): + """generate description for this test + """ + option = BoolOption('boolean', "Boolean 1 frozen", properties=('frozen',)) + descr1 = OptionDescription("options", "Common configuration", [option]) + descr = OptionDescription("boolean1_frozen", "Simple boolean", [descr1]) + return descr + diff --git a/tests/dict/data/choice1.json b/tests/dict/data/choice1.json new file mode 100644 index 0000000..35fe924 --- /dev/null +++ b/tests/dict/data/choice1.json @@ -0,0 +1,34 @@ +{ + "schema": { + "options": { + "name": "options", + "properties": { + "options.choice": { + "name": "options.choice", + "type": "choice", + "enum": [ + "", + "choice 1", + "choice 2" + ], + "title": "Choice description" + } + }, + "type": "object", + "title": "Common configuration" + } + }, + "model": {}, + "form": { + "options.choice": { + "type": "choice" + }, + "null": [ + { + "title": "Configurer", + "type": "submit" + } + ] + }, + "version": "1.0" +} \ No newline at end of file diff --git a/tests/dict/data/choice1.py b/tests/dict/data/choice1.py new file mode 100644 index 0000000..171a184 --- /dev/null +++ b/tests/dict/data/choice1.py @@ -0,0 +1,10 @@ + +from tiramisu.option import ChoiceOption, OptionDescription + +def get_description(): + """generate description for this test + """ + option = ChoiceOption('choice', "Choice description", ("choice 1", "choice 2")) + descr1 = OptionDescription("options", "Common configuration", [option]) + descr = OptionDescription("choice1", "Simple choice", [descr1]) + return descr diff --git a/tests/dict/data/choice1_frozen.json b/tests/dict/data/choice1_frozen.json new file mode 100644 index 0000000..47b4762 --- /dev/null +++ b/tests/dict/data/choice1_frozen.json @@ -0,0 +1,38 @@ +{ + "schema": { + "options": { + "name": "options", + "properties": { + "options.choice": { + "name": "options.choice", + "type": "choice", + "enum": [ + "", + "choice 1", + "choice 2" + ], + "title": "Choice description frozen" + } + }, + "type": "object", + "title": "Common configuration" + } + }, + "model": { + "options.choice": { + "readOnly": true + } + }, + "form": { + "options.choice": { + "type": "choice" + }, + "null": [ + { + "title": "Configurer", + "type": "submit" + } + ] + }, + "version": "1.0" +} \ No newline at end of file diff --git a/tests/dict/data/choice1_frozen.py b/tests/dict/data/choice1_frozen.py new file mode 100644 index 0000000..c222e54 --- /dev/null +++ b/tests/dict/data/choice1_frozen.py @@ -0,0 +1,10 @@ + +from tiramisu.option import ChoiceOption, OptionDescription + +def get_description(): + """generate description for this test + """ + option = ChoiceOption('choice', "Choice description frozen", ("choice 1", "choice 2"), properties=('frozen',)) + descr1 = OptionDescription("options", "Common configuration", [option]) + descr = OptionDescription("choice1_frozen", "Simple choice", [descr1]) + return descr diff --git a/tests/dict/data/choice1_leadership.json b/tests/dict/data/choice1_leadership.json new file mode 100644 index 0000000..e2ea39f --- /dev/null +++ b/tests/dict/data/choice1_leadership.json @@ -0,0 +1,87 @@ +{ + "schema": { + "options": { + "name": "options", + "properties": { + "options.choice1": { + "name": "options.choice1", + "properties": { + "options.choice1.choice1": { + "name": "options.choice1.choice1", + "type": "choice", + "isMulti": true, + "enum": [ + "choice 1", + "choice 2" + ], + "title": "Choice description leader" + }, + "options.choice1.choice2": { + "name": "options.choice1.choice2", + "type": "choice", + "isMulti": true, + "enum": [ + "", + "choice 3", + "choice 4" + ], + "title": "Choice description follower 1" + }, + "options.choice1.choice3": { + "name": "options.choice1.choice3", + "type": "choice", + "isMulti": true, + "enum": [ + "", + "choice 5", + "choice 6" + ], + "title": "Choice description follower 2" + }, + "options.choice1.choice4": { + "name": "options.choice1.choice4", + "type": "choice", + "isMulti": true, + "enum": [ + "", + "choice 7", + "choice 8" + ], + "title": "Choice description follower 3" + } + }, + "type": "array", + "title": "Common configuration 1" + } + }, + "type": "object", + "title": "Common configuration 2" + } + }, + "model": { + "options.choice1.choice1": { + "required": true + } + }, + "form": { + "options.choice1.choice1": { + "type": "choice" + }, + "options.choice1.choice2": { + "type": "choice" + }, + "options.choice1.choice3": { + "type": "choice" + }, + "options.choice1.choice4": { + "type": "choice" + }, + "null": [ + { + "title": "Configurer", + "type": "submit" + } + ] + }, + "version": "1.0" +} \ No newline at end of file diff --git a/tests/dict/data/choice1_leadership.py b/tests/dict/data/choice1_leadership.py new file mode 100644 index 0000000..572f323 --- /dev/null +++ b/tests/dict/data/choice1_leadership.py @@ -0,0 +1,16 @@ +from tiramisu.option import ChoiceOption, OptionDescription +from tiramisu import Leadership + + +def get_description(): + """generate description for this test + """ + option = ChoiceOption('choice1', "Choice description leader", ("choice 1", "choice 2"), multi=True) + option1 = ChoiceOption('choice2', "Choice description follower 1", ("choice 3", "choice 4"), multi=True) + option2 = ChoiceOption('choice3', "Choice description follower 2", ("choice 5", "choice 6"), multi=True) + option3 = ChoiceOption('choice4', "Choice description follower 3", ("choice 7", "choice 8"), multi=True) + descr1 = Leadership("choice1", "Common configuration 1", + [option, option1, option2, option3]) + descr = OptionDescription("options", "Common configuration 2", [descr1]) + descr = OptionDescription("choice1_leadership", "Leader followers with choice", [descr]) + return descr diff --git a/tests/dict/data/choice1_leadership_hidden.json b/tests/dict/data/choice1_leadership_hidden.json new file mode 100644 index 0000000..3c89705 --- /dev/null +++ b/tests/dict/data/choice1_leadership_hidden.json @@ -0,0 +1,93 @@ +{ + "schema": { + "options": { + "name": "options", + "properties": { + "options.choice1": { + "name": "options.choice1", + "properties": { + "options.choice1.choice1": { + "name": "options.choice1.choice1", + "type": "choice", + "isMulti": true, + "enum": [ + "choice 1", + "choice 2" + ], + "title": "Choice description leader" + }, + "options.choice1.choice2": { + "name": "options.choice1.choice2", + "type": "choice", + "isMulti": true, + "enum": [ + "", + "choice 3", + "choice 4" + ], + "title": "Choice description follower 1" + }, + "options.choice1.choice3": { + "name": "options.choice1.choice3", + "type": "choice", + "isMulti": true, + "enum": [ + "", + "choice 5", + "choice 6" + ], + "title": "Choice description follower 2 hidden" + }, + "options.choice1.choice4": { + "name": "options.choice1.choice4", + "type": "choice", + "isMulti": true, + "enum": [ + "", + "choice 7", + "choice 8" + ], + "title": "Choice description follower 3" + } + }, + "type": "array", + "title": "Slave 2 is hidden" + } + }, + "type": "object", + "title": "Common configuration 2" + } + }, + "model": { + "options.choice1.choice1": { + "required": true + }, + "options.choice1.choice3": { + "null": { + "display": false, + "hidden": true + } + } + }, + "form": { + "options.choice1.choice1": { + "type": "choice" + }, + "options.choice1.choice2": { + "type": "choice" + }, + "options.choice1.choice3": { + "type": "choice" + }, + "options.choice1.choice4": { + "type": "choice" + }, + "null": [ + { + "title": "Configurer", + "type": "submit" + } + ] + }, + "version": "1.0" +} \ No newline at end of file diff --git a/tests/dict/data/choice1_leadership_hidden.py b/tests/dict/data/choice1_leadership_hidden.py new file mode 100644 index 0000000..66c34bc --- /dev/null +++ b/tests/dict/data/choice1_leadership_hidden.py @@ -0,0 +1,16 @@ +from tiramisu.option import ChoiceOption, OptionDescription +from tiramisu import Leadership +from tiramisu.setting import groups + +def get_description(): + """generate description for this test + """ + option = ChoiceOption('choice1', "Choice description leader", ("choice 1", "choice 2"), multi=True) + option1 = ChoiceOption('choice2', "Choice description follower 1", ("choice 3", "choice 4"), multi=True) + option2 = ChoiceOption('choice3', "Choice description follower 2 hidden", ("choice 5", "choice 6"), multi=True, properties=('hidden',)) + option3 = ChoiceOption('choice4', "Choice description follower 3", ("choice 7", "choice 8"), multi=True) + descr1 = Leadership("choice1", "Slave 2 is hidden", + [option, option1, option2, option3]) + descr = OptionDescription("options", "Common configuration 2", [descr1]) + descr = OptionDescription("choice1_leadership_hidden", "Leader follower with choice, one is hidden", [descr]) + return descr diff --git a/tests/dict/data/choice1_leadership_value.json b/tests/dict/data/choice1_leadership_value.json new file mode 100644 index 0000000..b8e1d51 --- /dev/null +++ b/tests/dict/data/choice1_leadership_value.json @@ -0,0 +1,97 @@ +{ + "schema": { + "options": { + "name": "options", + "properties": { + "options.choice1": { + "name": "options.choice1", + "properties": { + "options.choice1.choice1": { + "name": "options.choice1.choice1", + "type": "choice", + "isMulti": true, + "enum": [ + "choice 1", + "choice 2" + ], + "title": "Choice leader" + }, + "options.choice1.choice2": { + "name": "options.choice1.choice2", + "type": "choice", + "isMulti": true, + "enum": [ + "", + "choice 3", + "choice 4" + ], + "title": "Choice follower 1" + }, + "options.choice1.choice3": { + "name": "options.choice1.choice3", + "type": "choice", + "isMulti": true, + "enum": [ + "", + "choice 5", + "choice 6" + ], + "title": "Choice follower 2" + }, + "options.choice1.choice4": { + "name": "options.choice1.choice4", + "type": "choice", + "isMulti": true, + "enum": [ + "", + "choice 7", + "choice 8" + ], + "title": "Choice follower 3" + } + }, + "type": "array", + "title": "Common configuration 1" + } + }, + "type": "object", + "title": "Common configuration 2" + } + }, + "model": { + "options.choice1.choice1": { + "required": true, + "value": [ + "choice 2" + ], + "owner": "user" + }, + "options.choice1.choice2": { + "0": { + "value": "choice 4", + "owner": "user" + } + } + }, + "form": { + "options.choice1.choice1": { + "type": "choice" + }, + "options.choice1.choice2": { + "type": "choice" + }, + "options.choice1.choice3": { + "type": "choice" + }, + "options.choice1.choice4": { + "type": "choice" + }, + "null": [ + { + "title": "Configurer", + "type": "submit" + } + ] + }, + "version": "1.0" +} \ No newline at end of file diff --git a/tests/dict/data/choice1_leadership_value.py b/tests/dict/data/choice1_leadership_value.py new file mode 100644 index 0000000..d6b8520 --- /dev/null +++ b/tests/dict/data/choice1_leadership_value.py @@ -0,0 +1,25 @@ +from tiramisu.option import ChoiceOption, OptionDescription +from tiramisu import Leadership + + +def get_description(): + """generate description for this test + """ + option = ChoiceOption('choice1', "Choice leader", ("choice 1", "choice 2"), multi=True) + option1 = ChoiceOption('choice2', "Choice follower 1", ("choice 3", "choice 4"), multi=True) + option2 = ChoiceOption('choice3', "Choice follower 2", ("choice 5", "choice 6"), multi=True) + option3 = ChoiceOption('choice4', "Choice follower 3", ("choice 7", "choice 8"), multi=True) + descr1 = Leadership("choice1", "Common configuration 1", + [option, option1, option2, option3]) + descr = OptionDescription("options", "Common configuration 2", [descr1]) + descr = OptionDescription("choice1_leadership_value", "Leader followers with choices, leader is 'choice 2' and follower 1 is 'choice 4'", [descr]) + return descr + + +def get_values(api, allpath=False): + if allpath: + root = 'choice1_leadership_value.' + else: + root = '' + api.option(root + 'options.choice1.choice1').value.set(['choice 2']) + api.option(root + 'options.choice1.choice2', 0).value.set('choice 4') diff --git a/tests/dict/data/choice1_multi.json b/tests/dict/data/choice1_multi.json new file mode 100644 index 0000000..58f7f1b --- /dev/null +++ b/tests/dict/data/choice1_multi.json @@ -0,0 +1,38 @@ +{ + "schema": { + "options": { + "name": "options", + "properties": { + "options.choice": { + "name": "options.choice", + "type": "choice", + "isMulti": true, + "enum": [ + "choice 1", + "choice 2" + ], + "title": "Choice description" + } + }, + "type": "object", + "title": "Common configuration" + } + }, + "model": { + "options.choice": { + "required": true + } + }, + "form": { + "options.choice": { + "type": "choice" + }, + "null": [ + { + "title": "Configurer", + "type": "submit" + } + ] + }, + "version": "1.0" +} \ No newline at end of file diff --git a/tests/dict/data/choice1_multi.py b/tests/dict/data/choice1_multi.py new file mode 100644 index 0000000..d68fae6 --- /dev/null +++ b/tests/dict/data/choice1_multi.py @@ -0,0 +1,10 @@ + +from tiramisu.option import ChoiceOption, OptionDescription + +def get_description(): + """generate description for this test + """ + option = ChoiceOption('choice', "Choice description", ("choice 1", "choice 2"), multi=True) + descr1 = OptionDescription("options", "Common configuration", [option]) + descr = OptionDescription("choice1_multi", "Multi choice", [descr1]) + return descr diff --git a/tests/dict/data/choice1_rename.json b/tests/dict/data/choice1_rename.json new file mode 100644 index 0000000..f81397d --- /dev/null +++ b/tests/dict/data/choice1_rename.json @@ -0,0 +1,38 @@ +{ + "schema": { + "options": { + "name": "options", + "properties": { + "options.choice": { + "name": "options.choice", + "type": "choice", + "enum": [ + "", + "choice 1", + "choice 2" + ], + "title": "Choice description" + } + }, + "type": "object", + "title": "Common configuration" + } + }, + "model": {}, + "form": { + "options.choice": { + "type": "choice", + "displayed": { + "choice 1": "renamed 1", + "choice 2": "renamed 2" + } + }, + "null": [ + { + "title": "Configurer", + "type": "submit" + } + ] + }, + "version": "1.0" +} \ No newline at end of file diff --git a/tests/dict/data/choice1_rename.py b/tests/dict/data/choice1_rename.py new file mode 100644 index 0000000..b7bded3 --- /dev/null +++ b/tests/dict/data/choice1_rename.py @@ -0,0 +1,20 @@ + +from tiramisu.option import ChoiceOption, OptionDescription + +def get_description(): + """generate description for this test + """ + option = ChoiceOption('choice', "Choice description", ("choice 1", "choice 2")) + descr1 = OptionDescription("options", "Common configuration", [option]) + descr = OptionDescription("choice1_rename", "Rename displayed value", [descr1]) + return descr + + +def get_form(allpath=False): + key = 'options.choice' + if allpath: + key = 'choice1_rename.' + key + return [{'key': key, + 'displayed': {'choice 1': 'renamed 1', + 'choice 2': 'renamed 2'} + }] diff --git a/tests/dict/data/choice1_requires.json b/tests/dict/data/choice1_requires.json new file mode 100644 index 0000000..73a5cc3 --- /dev/null +++ b/tests/dict/data/choice1_requires.json @@ -0,0 +1,71 @@ +{ + "schema": { + "options": { + "name": "options", + "properties": { + "options.choice": { + "name": "options.choice", + "type": "choice", + "value": "hide", + "enum": [ + "hide", + "show" + ], + "title": "Choice description" + }, + "options.unicode2": { + "name": "options.unicode2", + "type": "string", + "title": "Unicode 2" + } + }, + "type": "object", + "title": "Common configuration" + } + }, + "model": { + "options.choice": { + "required": true, + "value": "hide", + "owner": "default" + }, + "options.unicode2": { + "hidden": true + } + }, + "form": { + "options.choice": { + "clearable": true, + "type": "choice", + "dependencies": { + "default": { + "show": [ + "options.unicode2" + ] + }, + "expected": { + "hide": { + "hide": [ + "options.unicode2" + ] + }, + "show": { + "show": [ + "options.unicode2" + ] + } + } + } + }, + "options.unicode2": { + "type": "input" + }, + "null": [ + { + "title": "Configurer", + "type": "submit" + } + ] + }, + "version": "1.0" +} \ No newline at end of file diff --git a/tests/dict/data/choice1_requires.py b/tests/dict/data/choice1_requires.py new file mode 100644 index 0000000..101a1ba --- /dev/null +++ b/tests/dict/data/choice1_requires.py @@ -0,0 +1,12 @@ +from tiramisu.option import ChoiceOption, StrOption, OptionDescription + +def get_description(): + """generate description for this test + """ + option1 = ChoiceOption('choice', "Choice description", ("hide", "show"), default='hide', properties=('mandatory',)) + option2 = StrOption('unicode2', "Unicode 2", requires=[{'option': option1, + 'expected': 'hide', + 'action': 'hidden'}]) + descr1 = OptionDescription("options", "Common configuration", [option1, option2]) + descr = OptionDescription("choice1_requires", "Choice with requirement", [descr1]) + return descr diff --git a/tests/dict/data/date1.json b/tests/dict/data/date1.json new file mode 100644 index 0000000..387c5f5 --- /dev/null +++ b/tests/dict/data/date1.json @@ -0,0 +1,26 @@ +{ + "schema": { + "options": { + "name": "options", + "properties": { + "options.date": { + "name": "options.date", + "type": "date", + "title": "Date description" + } + }, + "type": "object", + "title": "Common configuration" + } + }, + "model": {}, + "form": { + "null": [ + { + "title": "Configurer", + "type": "submit" + } + ] + }, + "version": "1.0" +} \ No newline at end of file diff --git a/tests/dict/data/date1.py b/tests/dict/data/date1.py new file mode 100644 index 0000000..8f4a8f5 --- /dev/null +++ b/tests/dict/data/date1.py @@ -0,0 +1,9 @@ +from tiramisu.option import DateOption, OptionDescription + +def get_description(): + """generate description for this test + """ + option = DateOption('date', "Date description") + descr1 = OptionDescription("options", "Common configuration", [option]) + descr = OptionDescription("date1", "Simple date", [descr1]) + return descr diff --git a/tests/dict/data/date1_frozen.json b/tests/dict/data/date1_frozen.json new file mode 100644 index 0000000..d18a175 --- /dev/null +++ b/tests/dict/data/date1_frozen.json @@ -0,0 +1,30 @@ +{ + "schema": { + "options": { + "name": "options", + "properties": { + "options.date": { + "name": "options.date", + "type": "date", + "title": "Date description frozen" + } + }, + "type": "object", + "title": "Common configuration" + } + }, + "model": { + "options.date": { + "readOnly": true + } + }, + "form": { + "null": [ + { + "title": "Configurer", + "type": "submit" + } + ] + }, + "version": "1.0" +} \ No newline at end of file diff --git a/tests/dict/data/date1_frozen.py b/tests/dict/data/date1_frozen.py new file mode 100644 index 0000000..635e965 --- /dev/null +++ b/tests/dict/data/date1_frozen.py @@ -0,0 +1,9 @@ +from tiramisu.option import DateOption, OptionDescription + +def get_description(): + """generate description for this test + """ + option = DateOption('date', "Date description frozen", properties=('frozen',)) + descr1 = OptionDescription("options", "Common configuration", [option]) + descr = OptionDescription("date1_frozen", "Simple date", [descr1]) + return descr diff --git a/tests/dict/data/filename1.json b/tests/dict/data/filename1.json new file mode 100644 index 0000000..48bf2ad --- /dev/null +++ b/tests/dict/data/filename1.json @@ -0,0 +1,27 @@ +{ + "schema": { + "usbpath": { + "name": "usbpath", + "type": "filename", + "title": "Chemin d'acc\u00e8s" + } + }, + "model": { + "usbpath": { + "required": true + } + }, + "form": { + "usbpath": { + "pattern": "^[a-zA-Z0-9\\-\\._~/+]+$", + "type": "input" + }, + "null": [ + { + "title": "Configurer", + "type": "submit" + } + ] + }, + "version": "1.0" +} \ No newline at end of file diff --git a/tests/dict/data/filename1.py b/tests/dict/data/filename1.py new file mode 100644 index 0000000..f9cb7e6 --- /dev/null +++ b/tests/dict/data/filename1.py @@ -0,0 +1,6 @@ +# -*- coding: utf-8 -*- +from tiramisu.option import FilenameOption, OptionDescription +def get_description(): + usbpath = FilenameOption('usbpath', "Chemin d'accès", properties=('mandatory',)) + descr = OptionDescription("filename1", "Simple filename", [usbpath]) + return descr diff --git a/tests/dict/data/hostname1.json b/tests/dict/data/hostname1.json new file mode 100644 index 0000000..fddf8f9 --- /dev/null +++ b/tests/dict/data/hostname1.json @@ -0,0 +1,57 @@ +{ + "schema": { + "options": { + "name": "options", + "properties": { + "options.hostname1": { + "name": "options.hostname1", + "type": "domainname", + "title": "Domainname Description" + }, + "options.hostname2": { + "name": "options.hostname2", + "type": "domainname", + "title": "Domainname without dot Description" + }, + "options.hostname3": { + "name": "options.hostname3", + "type": "domainname", + "title": "Hostname or IP Description" + }, + "options.hostname4": { + "name": "options.hostname4", + "type": "domainname", + "title": "Netbios Description" + } + }, + "type": "object", + "title": "Common configuration" + } + }, + "model": {}, + "form": { + "options.hostname1": { + "pattern": "^((?!-)[a-z0-9-]{1,63}\\.){1,}[a-z0-9-]{1,63}$", + "type": "input" + }, + "options.hostname2": { + "pattern": "^((?!-)[a-z0-9-]{0,63}\\.){0,}[a-z0-9-]{1,63}$", + "type": "input" + }, + "options.hostname3": { + "pattern": "^(?:((?!-)[a-z0-9-]{1,63})|(?:(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)))$", + "type": "input" + }, + "options.hostname4": { + "pattern": "^((?!-)[a-z0-9-]{1,15})$", + "type": "input" + }, + "null": [ + { + "title": "Configurer", + "type": "submit" + } + ] + }, + "version": "1.0" +} \ No newline at end of file diff --git a/tests/dict/data/hostname1.py b/tests/dict/data/hostname1.py new file mode 100644 index 0000000..44fa7f6 --- /dev/null +++ b/tests/dict/data/hostname1.py @@ -0,0 +1,12 @@ +from tiramisu.option import DomainnameOption, OptionDescription + +def get_description(): + """generate description for this test + """ + option1 = DomainnameOption('hostname1', "Domainname Description") + option2 = DomainnameOption('hostname2', "Domainname without dot Description", allow_without_dot=True) + option3 = DomainnameOption('hostname3', "Hostname or IP Description", type_='hostname', allow_ip=True) + option4 = DomainnameOption('hostname4', "Netbios Description", type_='netbios') + descr1 = OptionDescription("options", "Common configuration", [option1, option2, option3, option4]) + descr = OptionDescription("hostname1", "Simple hostnames", [descr1]) + return descr diff --git a/tests/dict/data/ip1.json b/tests/dict/data/ip1.json new file mode 100644 index 0000000..821d3d7 --- /dev/null +++ b/tests/dict/data/ip1.json @@ -0,0 +1,30 @@ +{ + "schema": { + "options": { + "name": "options", + "properties": { + "options.ip": { + "name": "options.ip", + "type": "ip", + "title": "IP Description" + } + }, + "type": "object", + "title": "Common configuration" + } + }, + "model": {}, + "form": { + "options.ip": { + "pattern": "^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$", + "type": "input" + }, + "null": [ + { + "title": "Configurer", + "type": "submit" + } + ] + }, + "version": "1.0" +} \ No newline at end of file diff --git a/tests/dict/data/ip1.py b/tests/dict/data/ip1.py new file mode 100644 index 0000000..f9e5241 --- /dev/null +++ b/tests/dict/data/ip1.py @@ -0,0 +1,9 @@ +from tiramisu.option import IPOption, OptionDescription + +def get_description(): + """generate description for this test + """ + option1 = IPOption('ip', "IP Description") + descr1 = OptionDescription("options", "Common configuration", [option1]) + descr = OptionDescription("ip1", "Simple IP", [descr1]) + return descr diff --git a/tests/dict/data/ip1_frozen.json b/tests/dict/data/ip1_frozen.json new file mode 100644 index 0000000..0990e14 --- /dev/null +++ b/tests/dict/data/ip1_frozen.json @@ -0,0 +1,34 @@ +{ + "schema": { + "options": { + "name": "options", + "properties": { + "options.ip": { + "name": "options.ip", + "type": "ip", + "title": "IP Description frozen" + } + }, + "type": "object", + "title": "Common configuration" + } + }, + "model": { + "options.ip": { + "readOnly": true + } + }, + "form": { + "options.ip": { + "pattern": "^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$", + "type": "input" + }, + "null": [ + { + "title": "Configurer", + "type": "submit" + } + ] + }, + "version": "1.0" +} \ No newline at end of file diff --git a/tests/dict/data/ip1_frozen.py b/tests/dict/data/ip1_frozen.py new file mode 100644 index 0000000..90499d0 --- /dev/null +++ b/tests/dict/data/ip1_frozen.py @@ -0,0 +1,9 @@ +from tiramisu.option import IPOption, OptionDescription + +def get_description(): + """generate description for this test + """ + option1 = IPOption('ip', "IP Description frozen", properties=('frozen',)) + descr1 = OptionDescription("options", "Common configuration", [option1]) + descr = OptionDescription("ip1_frozen", "Simple IP", [descr1]) + return descr diff --git a/tests/dict/data/mail1.json b/tests/dict/data/mail1.json new file mode 100644 index 0000000..aa82efd --- /dev/null +++ b/tests/dict/data/mail1.json @@ -0,0 +1,30 @@ +{ + "schema": { + "options": { + "name": "options", + "properties": { + "options.mail": { + "name": "options.mail", + "type": "email", + "title": "Mail Description" + } + }, + "type": "object", + "title": "Common configuration" + } + }, + "model": {}, + "form": { + "options.mail": { + "pattern": "^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9-]+(?:\\.[a-zA-Z0-9-]+)*$", + "type": "input" + }, + "null": [ + { + "title": "Configurer", + "type": "submit" + } + ] + }, + "version": "1.0" +} \ No newline at end of file diff --git a/tests/dict/data/mail1.py b/tests/dict/data/mail1.py new file mode 100644 index 0000000..2177d90 --- /dev/null +++ b/tests/dict/data/mail1.py @@ -0,0 +1,10 @@ + +from tiramisu.option import EmailOption, OptionDescription + +def get_description(): + """generate description for this test + """ + option = EmailOption('mail', "Mail Description") + descr1 = OptionDescription("options", "Common configuration", [option]) + descr = OptionDescription("mail1", "Simple mail", [descr1]) + return descr diff --git a/tests/dict/data/number1.json b/tests/dict/data/number1.json new file mode 100644 index 0000000..d38be1b --- /dev/null +++ b/tests/dict/data/number1.json @@ -0,0 +1,30 @@ +{ + "schema": { + "options": { + "name": "options", + "properties": { + "options.integer": { + "name": "options.integer", + "type": "integer", + "title": "integer 1" + } + }, + "type": "object", + "title": "Common configuration" + } + }, + "model": {}, + "form": { + "options.integer": { + "allowedpattern": "[0-9]", + "type": "input" + }, + "null": [ + { + "title": "Configurer", + "type": "submit" + } + ] + }, + "version": "1.0" +} \ No newline at end of file diff --git a/tests/dict/data/number1.py b/tests/dict/data/number1.py new file mode 100644 index 0000000..2783b60 --- /dev/null +++ b/tests/dict/data/number1.py @@ -0,0 +1,10 @@ + +from tiramisu.option import IntOption, OptionDescription + +def get_description(): + """generate description for this test + """ + option = IntOption('integer', "integer 1") + descr1 = OptionDescription("options", "Common configuration", [option]) + descr = OptionDescription("number1", "Simple number", [descr1]) + return descr diff --git a/tests/dict/data/number1_frozen.json b/tests/dict/data/number1_frozen.json new file mode 100644 index 0000000..cc1131f --- /dev/null +++ b/tests/dict/data/number1_frozen.json @@ -0,0 +1,34 @@ +{ + "schema": { + "options": { + "name": "options", + "properties": { + "options.integer": { + "name": "options.integer", + "type": "integer", + "title": "integer 1 frozen" + } + }, + "type": "object", + "title": "Common configuration" + } + }, + "model": { + "options.integer": { + "readOnly": true + } + }, + "form": { + "options.integer": { + "allowedpattern": "[0-9]", + "type": "input" + }, + "null": [ + { + "title": "Configurer", + "type": "submit" + } + ] + }, + "version": "1.0" +} \ No newline at end of file diff --git a/tests/dict/data/number1_frozen.py b/tests/dict/data/number1_frozen.py new file mode 100644 index 0000000..1de3bc3 --- /dev/null +++ b/tests/dict/data/number1_frozen.py @@ -0,0 +1,10 @@ + +from tiramisu.option import IntOption, OptionDescription + +def get_description(): + """generate description for this test + """ + option = IntOption('integer', "integer 1 frozen", properties=('frozen',)) + descr1 = OptionDescription("options", "Common configuration", [option]) + descr = OptionDescription("number1_frozen", "Simple number", [descr1]) + return descr diff --git a/tests/dict/data/number1_mod_value.json b/tests/dict/data/number1_mod_value.json new file mode 100644 index 0000000..45ea367 --- /dev/null +++ b/tests/dict/data/number1_mod_value.json @@ -0,0 +1,37 @@ +{ + "schema": { + "options": { + "name": "options", + "properties": { + "options.integer": { + "name": "options.integer", + "type": "integer", + "value": 0, + "title": "integer 1" + } + }, + "type": "object", + "title": "Common configuration" + } + }, + "model": { + "options.integer": { + "value": 3, + "owner": "user" + } + }, + "form": { + "options.integer": { + "clearable": true, + "allowedpattern": "[0-9]", + "type": "input" + }, + "null": [ + { + "title": "Configurer", + "type": "submit" + } + ] + }, + "version": "1.0" +} \ No newline at end of file diff --git a/tests/dict/data/number1_mod_value.py b/tests/dict/data/number1_mod_value.py new file mode 100644 index 0000000..158b5d9 --- /dev/null +++ b/tests/dict/data/number1_mod_value.py @@ -0,0 +1,18 @@ + +from tiramisu.option import IntOption, OptionDescription + +def get_description(): + """generate description for this test + """ + option = IntOption('integer', "integer 1", 0) + descr1 = OptionDescription("options", "Common configuration", [option]) + descr = OptionDescription("number1_mod_value", "Number with modified value 3 and default value 0", [descr1]) + return descr + + +def get_values(api, allpath=False): + if allpath: + root = 'number1_mod_value.' + else: + root = '' + api.option(root + 'options.integer').value.set(3) diff --git a/tests/dict/data/number1_value.json b/tests/dict/data/number1_value.json new file mode 100644 index 0000000..3f8538b --- /dev/null +++ b/tests/dict/data/number1_value.json @@ -0,0 +1,37 @@ +{ + "schema": { + "options": { + "name": "options", + "properties": { + "options.integer": { + "name": "options.integer", + "type": "integer", + "value": 0, + "title": "integer 1" + } + }, + "type": "object", + "title": "Common configuration" + } + }, + "model": { + "options.integer": { + "value": 0, + "owner": "default" + } + }, + "form": { + "options.integer": { + "clearable": true, + "allowedpattern": "[0-9]", + "type": "input" + }, + "null": [ + { + "title": "Configurer", + "type": "submit" + } + ] + }, + "version": "1.0" +} \ No newline at end of file diff --git a/tests/dict/data/number1_value.py b/tests/dict/data/number1_value.py new file mode 100644 index 0000000..f0b972b --- /dev/null +++ b/tests/dict/data/number1_value.py @@ -0,0 +1,11 @@ + +from tiramisu.option import IntOption, OptionDescription + +def get_description(): + """generate description for this test + """ + option = IntOption('integer', "integer 1", 0) + descr1 = OptionDescription("options", "Common configuration", [option]) + descr = OptionDescription("number1_value", "Number with value 0", [descr1]) + return descr + diff --git a/tests/dict/data/unicode1.dict b/tests/dict/data/unicode1.dict new file mode 100644 index 0000000..ba0b015 --- /dev/null +++ b/tests/dict/data/unicode1.dict @@ -0,0 +1 @@ +{"options.unicode": null} diff --git a/tests/dict/data/unicode1.dict1 b/tests/dict/data/unicode1.dict1 new file mode 100644 index 0000000..674e06e --- /dev/null +++ b/tests/dict/data/unicode1.dict1 @@ -0,0 +1 @@ +{"options.unicode": "val"} diff --git a/tests/dict/data/unicode1.json b/tests/dict/data/unicode1.json new file mode 100644 index 0000000..1f13193 --- /dev/null +++ b/tests/dict/data/unicode1.json @@ -0,0 +1,29 @@ +{ + "schema": { + "options": { + "name": "options", + "properties": { + "options.unicode": { + "name": "options.unicode", + "type": "string", + "title": "Unicode 1" + } + }, + "type": "object", + "title": "Common configuration" + } + }, + "model": {}, + "form": { + "options.unicode": { + "type": "input" + }, + "null": [ + { + "title": "Configurer", + "type": "submit" + } + ] + }, + "version": "1.0" +} \ No newline at end of file diff --git a/tests/dict/data/unicode1.mod1 b/tests/dict/data/unicode1.mod1 new file mode 100644 index 0000000..f58f1b8 --- /dev/null +++ b/tests/dict/data/unicode1.mod1 @@ -0,0 +1,5 @@ +{"cmd": "config.option('options.unicode').value.set('val')", + "body": {"updates": [{"action": "modify", + "name": "options.unicode", + "value": "val"}]} +} diff --git a/tests/dict/data/unicode1.py b/tests/dict/data/unicode1.py new file mode 100644 index 0000000..147fe8a --- /dev/null +++ b/tests/dict/data/unicode1.py @@ -0,0 +1,11 @@ +"""just an unicode option +""" +from tiramisu.option import StrOption, OptionDescription + +def get_description(): + """generate description for this test + """ + option = StrOption('unicode', "Unicode 1") + descr1 = OptionDescription("options", "Common configuration", [option]) + descr = OptionDescription("unicode1", "Simple unicode", [descr1]) + return descr diff --git a/tests/dict/data/unicode1.updates1 b/tests/dict/data/unicode1.updates1 new file mode 100644 index 0000000..c622016 --- /dev/null +++ b/tests/dict/data/unicode1.updates1 @@ -0,0 +1,3 @@ +{"updates": ["options.unicode"], + "model": {"options.unicode": {"owner": "user", + "value": "val"}}} diff --git a/tests/dict/data/unicode1_frozen.json b/tests/dict/data/unicode1_frozen.json new file mode 100644 index 0000000..f86b351 --- /dev/null +++ b/tests/dict/data/unicode1_frozen.json @@ -0,0 +1,33 @@ +{ + "schema": { + "options": { + "name": "options", + "properties": { + "options.unicode": { + "name": "options.unicode", + "type": "string", + "title": "Unicode 1 frozen" + } + }, + "type": "object", + "title": "Common configuration" + } + }, + "model": { + "options.unicode": { + "readOnly": true + } + }, + "form": { + "options.unicode": { + "type": "input" + }, + "null": [ + { + "title": "Configurer", + "type": "submit" + } + ] + }, + "version": "1.0" +} \ No newline at end of file diff --git a/tests/dict/data/unicode1_frozen.py b/tests/dict/data/unicode1_frozen.py new file mode 100644 index 0000000..6fcbd32 --- /dev/null +++ b/tests/dict/data/unicode1_frozen.py @@ -0,0 +1,11 @@ +"""just an unicode option +""" +from tiramisu.option import StrOption, OptionDescription + +def get_description(): + """generate description for this test + """ + option = StrOption('unicode', "Unicode 1 frozen", properties=('frozen',)) + descr1 = OptionDescription("options", "Common configuration", [option]) + descr = OptionDescription("unicode1_frozen", "Simple unicode", [descr1]) + return descr diff --git a/tests/dict/data/unicode1_leader_hidden_followers.json b/tests/dict/data/unicode1_leader_hidden_followers.json new file mode 100644 index 0000000..2330c7b --- /dev/null +++ b/tests/dict/data/unicode1_leader_hidden_followers.json @@ -0,0 +1,70 @@ +{ + "schema": { + "options": { + "name": "options", + "properties": { + "options.unicode": { + "name": "options.unicode", + "properties": { + "options.unicode.unicode": { + "name": "options.unicode.unicode", + "type": "string", + "isMulti": true, + "title": "Unicode leader" + }, + "options.unicode.unicode1": { + "name": "options.unicode.unicode1", + "type": "string", + "isMulti": true, + "title": "Unicode follower 1" + }, + "options.unicode.unicode2": { + "name": "options.unicode.unicode2", + "type": "string", + "isMulti": true, + "title": "Unicode follower 2" + }, + "options.unicode.unicode3": { + "name": "options.unicode.unicode3", + "type": "string", + "isMulti": true, + "title": "Unicode follower 3" + } + }, + "type": "array", + "title": "Common configuration" + } + }, + "type": "object", + "title": "Common configuration" + } + }, + "model": { + "options.unicode.unicode": { + "display": false, + "required": true, + "hidden": true + } + }, + "form": { + "options.unicode.unicode": { + "type": "input" + }, + "options.unicode.unicode1": { + "type": "input" + }, + "options.unicode.unicode2": { + "type": "input" + }, + "options.unicode.unicode3": { + "type": "input" + }, + "null": [ + { + "title": "Configurer", + "type": "submit" + } + ] + }, + "version": "1.0" +} \ No newline at end of file diff --git a/tests/dict/data/unicode1_leader_hidden_followers.py b/tests/dict/data/unicode1_leader_hidden_followers.py new file mode 100644 index 0000000..59430d4 --- /dev/null +++ b/tests/dict/data/unicode1_leader_hidden_followers.py @@ -0,0 +1,15 @@ +from tiramisu.option import UnicodeOption, OptionDescription +from tiramisu import Leadership + +def get_description(): + """generate description for this test + """ + option = UnicodeOption('unicode', "Unicode leader", multi=True, properties=('hidden',)) + option1 = UnicodeOption('unicode1', "Unicode follower 1", multi=True) + option2 = UnicodeOption('unicode2', "Unicode follower 2", multi=True) + option3 = UnicodeOption('unicode3', "Unicode follower 3", multi=True) + descr1 = Leadership("unicode", "Common configuration", + [option, option1, option2, option3]) + descr = OptionDescription("options", "Common configuration", [descr1]) + descr = OptionDescription("unicode1_leader_hidden_followers", "Leader follower with unicode and hidden leader", [descr]) + return descr diff --git a/tests/dict/data/unicode1_leadership.json b/tests/dict/data/unicode1_leadership.json new file mode 100644 index 0000000..291bc40 --- /dev/null +++ b/tests/dict/data/unicode1_leadership.json @@ -0,0 +1,68 @@ +{ + "schema": { + "options": { + "name": "options", + "properties": { + "options.unicode": { + "name": "options.unicode", + "properties": { + "options.unicode.unicode": { + "name": "options.unicode.unicode", + "type": "string", + "isMulti": true, + "title": "Unicode leader" + }, + "options.unicode.unicode1": { + "name": "options.unicode.unicode1", + "type": "string", + "isMulti": true, + "title": "Unicode follower 1" + }, + "options.unicode.unicode2": { + "name": "options.unicode.unicode2", + "type": "string", + "isMulti": true, + "title": "Unicode follower 2" + }, + "options.unicode.unicode3": { + "name": "options.unicode.unicode3", + "type": "string", + "isMulti": true, + "title": "Unicode follower 3" + } + }, + "type": "array", + "title": "Common configuration 1" + } + }, + "type": "object", + "title": "Common configuration 2" + } + }, + "model": { + "options.unicode.unicode": { + "required": true + } + }, + "form": { + "options.unicode.unicode": { + "type": "input" + }, + "options.unicode.unicode1": { + "type": "input" + }, + "options.unicode.unicode2": { + "type": "input" + }, + "options.unicode.unicode3": { + "type": "input" + }, + "null": [ + { + "title": "Configurer", + "type": "submit" + } + ] + }, + "version": "1.0" +} \ No newline at end of file diff --git a/tests/dict/data/unicode1_leadership.py b/tests/dict/data/unicode1_leadership.py new file mode 100644 index 0000000..5c95632 --- /dev/null +++ b/tests/dict/data/unicode1_leadership.py @@ -0,0 +1,15 @@ +from tiramisu.option import UnicodeOption, OptionDescription, Leadership + + +def get_description(): + """generate description for this test + """ + option = UnicodeOption('unicode', "Unicode leader", multi=True) + option1 = UnicodeOption('unicode1', "Unicode follower 1", multi=True) + option2 = UnicodeOption('unicode2', "Unicode follower 2", multi=True) + option3 = UnicodeOption('unicode3', "Unicode follower 3", multi=True) + descr1 = Leadership("unicode", "Common configuration 1", + [option, option1, option2, option3]) + descr = OptionDescription("options", "Common configuration 2", [descr1]) + descr = OptionDescription("unicode1_leadership", "Leader followers with Unicode", [descr]) + return descr diff --git a/tests/dict/data/unicode1_leadership_default_value.json b/tests/dict/data/unicode1_leadership_default_value.json new file mode 100644 index 0000000..180db3d --- /dev/null +++ b/tests/dict/data/unicode1_leadership_default_value.json @@ -0,0 +1,90 @@ +{ + "schema": { + "options": { + "name": "options", + "properties": { + "options.unicode": { + "name": "options.unicode", + "properties": { + "options.unicode.unicode": { + "name": "options.unicode.unicode", + "type": "string", + "value": [ + "val1", + "val2" + ], + "isMulti": true, + "title": "Unicode leader" + }, + "options.unicode.unicode1": { + "name": "options.unicode.unicode1", + "type": "string", + "isMulti": true, + "title": "Unicode follower 1" + }, + "options.unicode.unicode2": { + "name": "options.unicode.unicode2", + "type": "string", + "default": "follower2", + "isMulti": true, + "title": "Unicode follower 2 with default multi" + }, + "options.unicode.unicode3": { + "name": "options.unicode.unicode3", + "type": "string", + "isMulti": true, + "title": "Unicode follower 3" + } + }, + "type": "array", + "title": "Common configuration 1" + } + }, + "type": "object", + "title": "Common configuration 2" + } + }, + "model": { + "options.unicode.unicode": { + "required": true, + "value": [ + "val1", + "val2" + ], + "owner": "default" + }, + "options.unicode.unicode2": { + "0": { + "value": "follower2", + "owner": "default" + }, + "1": { + "value": "follower2", + "owner": "default" + } + } + }, + "form": { + "options.unicode.unicode": { + "clearable": true, + "type": "input" + }, + "options.unicode.unicode1": { + "type": "input" + }, + "options.unicode.unicode2": { + "clearable": true, + "type": "input" + }, + "options.unicode.unicode3": { + "type": "input" + }, + "null": [ + { + "title": "Configurer", + "type": "submit" + } + ] + }, + "version": "1.0" +} \ No newline at end of file diff --git a/tests/dict/data/unicode1_leadership_default_value.py b/tests/dict/data/unicode1_leadership_default_value.py new file mode 100644 index 0000000..1eb4268 --- /dev/null +++ b/tests/dict/data/unicode1_leadership_default_value.py @@ -0,0 +1,16 @@ +from tiramisu.option import UnicodeOption, OptionDescription +from tiramisu import Leadership +from tiramisu.setting import groups + +def get_description(): + """generate description for this test + """ + option = UnicodeOption('unicode', "Unicode leader", ['val1', 'val2'], multi=True) + option1 = UnicodeOption('unicode1', "Unicode follower 1", multi=True) + option2 = UnicodeOption('unicode2', "Unicode follower 2 with default multi", default_multi="follower2", multi=True) + option3 = UnicodeOption('unicode3', "Unicode follower 3", multi=True) + descr1 = Leadership("unicode", "Common configuration 1", + [option, option1, option2, option3]) + descr = OptionDescription("options", "Common configuration 2", [descr1]) + descr = OptionDescription("unicode1_leadership_default_value", "Leader followers with unicode with default value", [descr]) + return descr diff --git a/tests/dict/data/unicode1_leadership_hidden.json b/tests/dict/data/unicode1_leadership_hidden.json new file mode 100644 index 0000000..727b834 --- /dev/null +++ b/tests/dict/data/unicode1_leadership_hidden.json @@ -0,0 +1,89 @@ +{ + "schema": { + "options": { + "name": "options", + "properties": { + "options.unicode": { + "name": "options.unicode", + "properties": { + "options.unicode.unicode": { + "name": "options.unicode.unicode", + "type": "string", + "isMulti": true, + "title": "Unicode leader" + }, + "options.unicode.unicode1": { + "name": "options.unicode.unicode1", + "type": "string", + "isMulti": true, + "title": "Unicode follower 1" + }, + "options.unicode.unicode2": { + "name": "options.unicode.unicode2", + "type": "string", + "isMulti": true, + "title": "Unicode follower 2 hidden" + }, + "options.unicode.unicode3": { + "name": "options.unicode.unicode3", + "type": "string", + "isMulti": true, + "title": "Unicode follower 3" + } + }, + "type": "array", + "title": "Common configuration" + } + }, + "type": "object", + "title": "Common configuration" + } + }, + "model": { + "options.unicode.unicode": { + "required": true, + "value": [ + "val1", + "val2" + ], + "owner": "user" + }, + "options.unicode.unicode2": { + "0": { + "display": false, + "hidden": true, + "value": "super", + "owner": "user" + }, + "1": { + "display": false, + "hidden": true + }, + "null": { + "display": false, + "hidden": true + } + } + }, + "form": { + "options.unicode.unicode": { + "type": "input" + }, + "options.unicode.unicode1": { + "type": "input" + }, + "options.unicode.unicode2": { + "type": "input" + }, + "options.unicode.unicode3": { + "type": "input" + }, + "null": [ + { + "title": "Configurer", + "type": "submit" + } + ] + }, + "version": "1.0" +} \ No newline at end of file diff --git a/tests/dict/data/unicode1_leadership_hidden.py b/tests/dict/data/unicode1_leadership_hidden.py new file mode 100644 index 0000000..8e67ff4 --- /dev/null +++ b/tests/dict/data/unicode1_leadership_hidden.py @@ -0,0 +1,25 @@ +from tiramisu.option import UnicodeOption, OptionDescription +from tiramisu import Leadership + + +def get_description(): + """generate description for this test + """ + option = UnicodeOption('unicode', "Unicode leader", multi=True) + option1 = UnicodeOption('unicode1', "Unicode follower 1", multi=True) + option2 = UnicodeOption('unicode2', "Unicode follower 2 hidden", multi=True, properties=('hidden',)) + option3 = UnicodeOption('unicode3', "Unicode follower 3", multi=True) + descr1 = Leadership("unicode", "Common configuration", + [option, option1, option2, option3]) + descr = OptionDescription("options", "Common configuration", [descr1]) + descr = OptionDescription("unicode1_leadership_hidden", "Leader followers with second follower hidden", [descr]) + return descr + + +def get_values(api, allpath=False): + if allpath: + root = 'unicode1_leadership_hidden.' + else: + root = '' + api.option(root + 'options.unicode.unicode').value.set([u'val1', u'val2']) + api.option(root + 'options.unicode.unicode2', 0).value.set(u'super') diff --git a/tests/dict/data/unicode1_leadership_hidden_all_default.json b/tests/dict/data/unicode1_leadership_hidden_all_default.json new file mode 100644 index 0000000..f0252b5 --- /dev/null +++ b/tests/dict/data/unicode1_leadership_hidden_all_default.json @@ -0,0 +1,67 @@ +{ + "schema": { + "options": { + "name": "options", + "properties": { + "options.unicode": { + "name": "options.unicode", + "type": "string", + "title": "Unicode leader" + }, + "options.unicode1": { + "name": "options.unicode1", + "properties": { + "options.unicode1.unicode1": { + "name": "options.unicode1.unicode1", + "type": "string", + "isMulti": true, + "title": "Unicode follower 1" + }, + "options.unicode1.unicode2": { + "name": "options.unicode1.unicode2", + "type": "string", + "isMulti": true, + "title": "Unicode follower 2" + }, + "options.unicode1.unicode3": { + "name": "options.unicode1.unicode3", + "type": "string", + "isMulti": true, + "title": "Unicode follower 3" + } + }, + "type": "array", + "title": "Common configuration" + } + }, + "type": "object", + "title": "Common configuration" + } + }, + "model": { + "options.unicode1.unicode1": { + "required": true + } + }, + "form": { + "options.unicode": { + "type": "input" + }, + "options.unicode1.unicode1": { + "type": "input" + }, + "options.unicode1.unicode2": { + "type": "input" + }, + "options.unicode1.unicode3": { + "type": "input" + }, + "null": [ + { + "title": "Configurer", + "type": "submit" + } + ] + }, + "version": "1.0" +} \ No newline at end of file diff --git a/tests/dict/data/unicode1_leadership_hidden_all_default.py b/tests/dict/data/unicode1_leadership_hidden_all_default.py new file mode 100644 index 0000000..0eaf0d6 --- /dev/null +++ b/tests/dict/data/unicode1_leadership_hidden_all_default.py @@ -0,0 +1,16 @@ +from tiramisu.option import UnicodeOption, OptionDescription +from tiramisu import Leadership + + +def get_description(): + """generate description for this test + """ + option = UnicodeOption('unicode', "Unicode leader") + option1 = UnicodeOption('unicode1', "Unicode follower 1", multi=True) + option2 = UnicodeOption('unicode2', "Unicode follower 2", multi=True) + option3 = UnicodeOption('unicode3', "Unicode follower 3", multi=True) + descr1 = Leadership("unicode1", "Common configuration", + [option1, option2, option3]) + descr = OptionDescription("options", "Common configuration", [option, descr1]) + descr = OptionDescription("unicode1_leadership_hidden_all_default", "FIXME...", [descr]) + return descr diff --git a/tests/dict/data/unicode1_leadership_not_equal.json b/tests/dict/data/unicode1_leadership_not_equal.json new file mode 100644 index 0000000..cc827a1 --- /dev/null +++ b/tests/dict/data/unicode1_leadership_not_equal.json @@ -0,0 +1,78 @@ +{ + "schema": { + "options": { + "name": "options", + "properties": { + "options.unicode": { + "name": "options.unicode", + "properties": { + "options.unicode.unicode": { + "name": "options.unicode.unicode", + "type": "string", + "isMulti": true, + "title": "Unicode leader" + }, + "options.unicode.unicode1": { + "name": "options.unicode.unicode1", + "type": "string", + "isMulti": true, + "title": "Unicode follower 1" + }, + "options.unicode.unicode2": { + "name": "options.unicode.unicode2", + "type": "string", + "isMulti": true, + "title": "Unicode follower 2 not equal" + }, + "options.unicode.unicode3": { + "name": "options.unicode.unicode3", + "type": "string", + "isMulti": true, + "title": "Unicode follower 3 not equal" + } + }, + "type": "array", + "title": "Common configuration 1" + } + }, + "type": "object", + "title": "Common configuration 2" + } + }, + "model": { + "options.unicode.unicode": { + "required": true + } + }, + "form": { + "options.unicode.unicode": { + "type": "input" + }, + "options.unicode.unicode1": { + "type": "input" + }, + "options.unicode.unicode2": { + "type": "input", + "not_equal": { + "options": [ + "options.unicode.unicode3" + ] + } + }, + "options.unicode.unicode3": { + "type": "input", + "not_equal": { + "options": [ + "options.unicode.unicode2" + ] + } + }, + "null": [ + { + "title": "Configurer", + "type": "submit" + } + ] + }, + "version": "1.0" +} \ No newline at end of file diff --git a/tests/dict/data/unicode1_leadership_not_equal.py b/tests/dict/data/unicode1_leadership_not_equal.py new file mode 100644 index 0000000..02ba6b5 --- /dev/null +++ b/tests/dict/data/unicode1_leadership_not_equal.py @@ -0,0 +1,17 @@ +from tiramisu.option import UnicodeOption, OptionDescription +from tiramisu import Leadership + + +def get_description(): + """generate description for this test + """ + option = UnicodeOption('unicode', "Unicode leader", multi=True) + option1 = UnicodeOption('unicode1', "Unicode follower 1", multi=True) + option2 = UnicodeOption('unicode2', "Unicode follower 2 not equal", multi=True) + option3 = UnicodeOption('unicode3', "Unicode follower 3 not equal", multi=True) + option2.impl_add_consistency('not_equal', option3) + descr1 = Leadership("unicode", "Common configuration 1", + [option, option1, option2, option3]) + descr = OptionDescription("options", "Common configuration 2", [descr1]) + descr = OptionDescription("unicode1_leadership_not_equal", "Leader followers with follower not equal", [descr]) + return descr diff --git a/tests/dict/data/unicode1_leadership_requires.json b/tests/dict/data/unicode1_leadership_requires.json new file mode 100644 index 0000000..55bf1a0 --- /dev/null +++ b/tests/dict/data/unicode1_leadership_requires.json @@ -0,0 +1,82 @@ +{ + "schema": { + "options": { + "name": "options", + "properties": { + "options.unicode": { + "name": "options.unicode", + "properties": { + "options.unicode.unicode": { + "name": "options.unicode.unicode", + "type": "string", + "isMulti": true, + "title": "Unicode leader" + }, + "options.unicode.unicode1": { + "name": "options.unicode.unicode1", + "type": "string", + "isMulti": true, + "title": "Unicode follower 1" + }, + "options.unicode.unicode2": { + "name": "options.unicode.unicode2", + "type": "string", + "isMulti": true, + "title": "Values 'test' must show 'Unicode follower 3'" + }, + "options.unicode.unicode3": { + "name": "options.unicode.unicode3", + "type": "string", + "isMulti": true, + "title": "Unicode follower 3" + } + }, + "type": "array", + "title": "Common configuration 1" + } + }, + "type": "object", + "title": "Common configuration 2" + } + }, + "model": { + "options.unicode.unicode": { + "required": true + } + }, + "form": { + "options.unicode.unicode": { + "type": "input" + }, + "options.unicode.unicode1": { + "type": "input" + }, + "options.unicode.unicode2": { + "type": "input", + "dependencies": { + "default": { + "hide": [ + "options.unicode.unicode3" + ] + }, + "expected": { + "test": { + "show": [ + "options.unicode.unicode3" + ] + } + } + } + }, + "options.unicode.unicode3": { + "type": "input" + }, + "null": [ + { + "title": "Configurer", + "type": "submit" + } + ] + }, + "version": "1.0" +} \ No newline at end of file diff --git a/tests/dict/data/unicode1_leadership_requires.py b/tests/dict/data/unicode1_leadership_requires.py new file mode 100644 index 0000000..60fc7e9 --- /dev/null +++ b/tests/dict/data/unicode1_leadership_requires.py @@ -0,0 +1,20 @@ +from tiramisu.option import UnicodeOption, OptionDescription +from tiramisu import Leadership + + +def get_description(): + """generate description for this test + """ + option = UnicodeOption('unicode', "Unicode leader", multi=True) + option1 = UnicodeOption('unicode1', "Unicode follower 1", multi=True) + option2 = UnicodeOption('unicode2', "Values 'test' must show 'Unicode follower 3'", multi=True) + option3 = UnicodeOption('unicode3', "Unicode follower 3", requires=[{'option': option2, + 'expected': u'test', + 'action': 'hidden', + 'inverse': True}], + multi=True) + descr1 = Leadership("unicode", "Common configuration 1", + [option, option1, option2, option3]) + descr = OptionDescription("options", "Common configuration 2", [descr1]) + descr = OptionDescription("unicode1_leadership_requires", "Leader followers with Unicode follower 3 hidden when Unicode follower 2 is test", [descr]) + return descr diff --git a/tests/dict/data/unicode1_leadership_requires_all.json b/tests/dict/data/unicode1_leadership_requires_all.json new file mode 100644 index 0000000..2179a85 --- /dev/null +++ b/tests/dict/data/unicode1_leadership_requires_all.json @@ -0,0 +1,87 @@ +{ + "schema": { + "options": { + "name": "options", + "properties": { + "options.unicode": { + "name": "options.unicode", + "type": "string", + "title": "Value 'test' must show Leadership" + }, + "options.unicode1": { + "name": "options.unicode1", + "properties": { + "options.unicode1.unicode1": { + "name": "options.unicode1.unicode1", + "type": "string", + "isMulti": true, + "title": "Unicode leader" + }, + "options.unicode1.unicode2": { + "name": "options.unicode1.unicode2", + "type": "string", + "isMulti": true, + "title": "Unicode follower 1" + }, + "options.unicode1.unicode3": { + "name": "options.unicode1.unicode3", + "type": "string", + "isMulti": true, + "title": "Unicode follower 2" + } + }, + "type": "array", + "title": "Common configuration" + } + }, + "type": "object", + "title": "Common configuration" + } + }, + "model": { + "options.unicode1": { + "properties": [ + "hidden" + ], + "hidden": true + }, + "options.unicode1.unicode1": { + "required": true + } + }, + "form": { + "options.unicode": { + "type": "input", + "dependencies": { + "default": { + "hide": [ + "options.unicode1" + ] + }, + "expected": { + "test": { + "show": [ + "options.unicode1" + ] + } + } + } + }, + "options.unicode1.unicode1": { + "type": "input" + }, + "options.unicode1.unicode2": { + "type": "input" + }, + "options.unicode1.unicode3": { + "type": "input" + }, + "null": [ + { + "title": "Configurer", + "type": "submit" + } + ] + }, + "version": "1.0" +} \ No newline at end of file diff --git a/tests/dict/data/unicode1_leadership_requires_all.py b/tests/dict/data/unicode1_leadership_requires_all.py new file mode 100644 index 0000000..46f442c --- /dev/null +++ b/tests/dict/data/unicode1_leadership_requires_all.py @@ -0,0 +1,19 @@ +from tiramisu.option import UnicodeOption, OptionDescription +from tiramisu import Leadership + + +def get_description(): + """generate description for this test + """ + option = UnicodeOption('unicode', "Value 'test' must show Leadership") + option1 = UnicodeOption('unicode1', "Unicode leader", multi=True) + option2 = UnicodeOption('unicode2', "Unicode follower 1", multi=True) + option3 = UnicodeOption('unicode3', "Unicode follower 2", multi=True) + descr1 = Leadership("unicode1", "Common configuration", + [option1, option2, option3], requires=[{'option': option, + 'expected': u'test', + 'action': 'hidden', + 'inverse': True}]) + descr = OptionDescription("options", "Common configuration", [option, descr1]) + descr = OptionDescription("unicode1_leadership_requires_all", "Leader follower with requirement", [descr]) + return descr diff --git a/tests/dict/data/unicode1_leadership_requires_follower.json b/tests/dict/data/unicode1_leadership_requires_follower.json new file mode 100644 index 0000000..e0cdd16 --- /dev/null +++ b/tests/dict/data/unicode1_leadership_requires_follower.json @@ -0,0 +1,73 @@ +{ + "schema": { + "options": { + "name": "options", + "properties": { + "options.unicode1": { + "name": "options.unicode1", + "properties": { + "options.unicode1.unicode1": { + "name": "options.unicode1.unicode1", + "type": "string", + "isMulti": true, + "title": "Values 'test' must show 'Unicode follower 2'" + }, + "options.unicode1.unicode2": { + "name": "options.unicode1.unicode2", + "type": "string", + "isMulti": true, + "title": "Unicode follower 1" + }, + "options.unicode1.unicode3": { + "name": "options.unicode1.unicode3", + "type": "string", + "isMulti": true, + "title": "Unicode follower 2" + } + }, + "type": "array", + "title": "Common configuration" + } + }, + "type": "object", + "title": "Common configuration" + } + }, + "model": { + "options.unicode1.unicode1": { + "required": true + } + }, + "form": { + "options.unicode1.unicode1": { + "type": "input", + "dependencies": { + "default": { + "hide": [ + "options.unicode1.unicode3" + ] + }, + "expected": { + "test": { + "show": [ + "options.unicode1.unicode3" + ] + } + } + } + }, + "options.unicode1.unicode2": { + "type": "input" + }, + "options.unicode1.unicode3": { + "type": "input" + }, + "null": [ + { + "title": "Configurer", + "type": "submit" + } + ] + }, + "version": "1.0" +} \ No newline at end of file diff --git a/tests/dict/data/unicode1_leadership_requires_follower.py b/tests/dict/data/unicode1_leadership_requires_follower.py new file mode 100644 index 0000000..48b7273 --- /dev/null +++ b/tests/dict/data/unicode1_leadership_requires_follower.py @@ -0,0 +1,19 @@ +from tiramisu.option import UnicodeOption, OptionDescription +from tiramisu import Leadership + + +def get_description(): + """generate description for this test + """ + option1 = UnicodeOption('unicode1', "Values 'test' must show 'Unicode follower 2'", multi=True) + option2 = UnicodeOption('unicode2', "Unicode follower 1", multi=True) + option3 = UnicodeOption('unicode3', "Unicode follower 2", multi=True, + requires=[{'option': option1, + 'expected': u'test', + 'action': 'hidden', + 'inverse': True}]) + descr1 = Leadership("unicode1", "Common configuration", + [option1, option2, option3]) + descr = OptionDescription("options", "Common configuration", [descr1]) + descr = OptionDescription("unicode1_leadership_requires_follower", "Leader follower requires follower with leader", [descr]) + return descr diff --git a/tests/dict/data/unicode1_leadership_requires_follower_value.json b/tests/dict/data/unicode1_leadership_requires_follower_value.json new file mode 100644 index 0000000..a1d7a6f --- /dev/null +++ b/tests/dict/data/unicode1_leadership_requires_follower_value.json @@ -0,0 +1,93 @@ +{ + "schema": { + "options": { + "name": "options", + "properties": { + "options.unicode1": { + "name": "options.unicode1", + "properties": { + "options.unicode1.unicode1": { + "name": "options.unicode1.unicode1", + "type": "string", + "isMulti": true, + "title": "Values 'test' must show 'Unicode follower 2'" + }, + "options.unicode1.unicode2": { + "name": "options.unicode1.unicode2", + "type": "string", + "isMulti": true, + "title": "Unicode follower 1" + }, + "options.unicode1.unicode3": { + "name": "options.unicode1.unicode3", + "type": "string", + "isMulti": true, + "title": "Unicode follower 2" + } + }, + "type": "array", + "title": "Common configuration" + } + }, + "type": "object", + "title": "Common configuration" + } + }, + "model": { + "options.unicode1.unicode1": { + "required": true, + "value": [ + "test", + "pas test" + ], + "owner": "user" + }, + "options.unicode1.unicode2": { + "0": { + "value": "super1", + "owner": "user" + } + }, + "options.unicode1.unicode3": { + "0": { + "value": "super1", + "owner": "user" + }, + "1": { + "hidden": true + } + } + }, + "form": { + "options.unicode1.unicode1": { + "type": "input", + "dependencies": { + "default": { + "hide": [ + "options.unicode1.unicode3" + ] + }, + "expected": { + "test": { + "show": [ + "options.unicode1.unicode3" + ] + } + } + } + }, + "options.unicode1.unicode2": { + "type": "input" + }, + "options.unicode1.unicode3": { + "type": "input" + }, + "null": [ + { + "title": "Configurer", + "type": "submit" + } + ] + }, + "version": "1.0" +} \ No newline at end of file diff --git a/tests/dict/data/unicode1_leadership_requires_follower_value.py b/tests/dict/data/unicode1_leadership_requires_follower_value.py new file mode 100644 index 0000000..9e33997 --- /dev/null +++ b/tests/dict/data/unicode1_leadership_requires_follower_value.py @@ -0,0 +1,29 @@ +from tiramisu.option import UnicodeOption, OptionDescription +from tiramisu import Leadership + + +def get_description(): + """generate description for this test + """ + option1 = UnicodeOption('unicode1', "Values 'test' must show 'Unicode follower 2'", multi=True) + option2 = UnicodeOption('unicode2', "Unicode follower 1", multi=True) + option3 = UnicodeOption('unicode3', "Unicode follower 2", multi=True, + requires=[{'option': option1, + 'expected': u'test', + 'action': 'hidden', + 'inverse': True}]) + descr1 = Leadership("unicode1", "Common configuration", + [option1, option2, option3]) + descr = OptionDescription("options", "Common configuration", [descr1]) + descr = OptionDescription("unicode1_leadership_requires_follower_value", "Leader follower requires follower with leader value", [descr]) + return descr + + +def get_values(api, allpath=False): + if allpath: + root = 'unicode1_leadership_requires_follower_value.' + else: + root = '' + api.option(root + 'options.unicode1.unicode1').value.set([u'test', u'pas test']) + api.option(root + 'options.unicode1.unicode2', 0).value.set(u'super1') + api.option(root + 'options.unicode1.unicode3', 0).value.set(u'super1') diff --git a/tests/dict/data/unicode1_leadership_requires_followers.json b/tests/dict/data/unicode1_leadership_requires_followers.json new file mode 100644 index 0000000..5a987de --- /dev/null +++ b/tests/dict/data/unicode1_leadership_requires_followers.json @@ -0,0 +1,73 @@ +{ + "schema": { + "options": { + "name": "options", + "properties": { + "options.unicode1": { + "name": "options.unicode1", + "properties": { + "options.unicode1.unicode1": { + "name": "options.unicode1.unicode1", + "type": "string", + "isMulti": true, + "title": "Unicode leader" + }, + "options.unicode1.unicode2": { + "name": "options.unicode1.unicode2", + "type": "string", + "isMulti": true, + "title": "Values 'test' must show 'Unicode follower 2'" + }, + "options.unicode1.unicode3": { + "name": "options.unicode1.unicode3", + "type": "string", + "isMulti": true, + "title": "Unicode follower 2" + } + }, + "type": "array", + "title": "Common configuration" + } + }, + "type": "object", + "title": "Common configuration" + } + }, + "model": { + "options.unicode1.unicode1": { + "required": true + } + }, + "form": { + "options.unicode1.unicode1": { + "type": "input" + }, + "options.unicode1.unicode2": { + "type": "input", + "dependencies": { + "default": { + "hide": [ + "options.unicode1.unicode3" + ] + }, + "expected": { + "test": { + "show": [ + "options.unicode1.unicode3" + ] + } + } + } + }, + "options.unicode1.unicode3": { + "type": "input" + }, + "null": [ + { + "title": "Configurer", + "type": "submit" + } + ] + }, + "version": "1.0" +} \ No newline at end of file diff --git a/tests/dict/data/unicode1_leadership_requires_followers.py b/tests/dict/data/unicode1_leadership_requires_followers.py new file mode 100644 index 0000000..726a893 --- /dev/null +++ b/tests/dict/data/unicode1_leadership_requires_followers.py @@ -0,0 +1,19 @@ +from tiramisu.option import UnicodeOption, OptionDescription +from tiramisu import Leadership + + +def get_description(): + """generate description for this test + """ + option1 = UnicodeOption('unicode1', "Unicode leader", multi=True) + option2 = UnicodeOption('unicode2', "Values 'test' must show 'Unicode follower 2'", multi=True) + option3 = UnicodeOption('unicode3', "Unicode follower 2", multi=True, + requires=[{'option': option2, + 'expected': u'test', + 'action': 'hidden', + 'inverse': True}]) + descr1 = Leadership("unicode1", "Common configuration", + [option1, option2, option3]) + descr = OptionDescription("options", "Common configuration", [descr1]) + descr = OptionDescription("unicode1_leadership_requires_followers", "Leader follower requires follower with a follower", [descr]) + return descr diff --git a/tests/dict/data/unicode1_leadership_requires_leader.json b/tests/dict/data/unicode1_leadership_requires_leader.json new file mode 100644 index 0000000..39a5656 --- /dev/null +++ b/tests/dict/data/unicode1_leadership_requires_leader.json @@ -0,0 +1,87 @@ +{ + "schema": { + "options": { + "name": "options", + "properties": { + "options.unicode": { + "name": "options.unicode", + "type": "string", + "title": "Value 'test' must show leader" + }, + "options.unicode1": { + "name": "options.unicode1", + "properties": { + "options.unicode1.unicode1": { + "name": "options.unicode1.unicode1", + "type": "string", + "isMulti": true, + "title": "Unicode leader" + }, + "options.unicode1.unicode2": { + "name": "options.unicode1.unicode2", + "type": "string", + "isMulti": true, + "title": "Unicode follower 1" + }, + "options.unicode1.unicode3": { + "name": "options.unicode1.unicode3", + "type": "string", + "isMulti": true, + "title": "Unicode follower 2" + } + }, + "type": "array", + "title": "Common configuration" + } + }, + "type": "object", + "title": "Common configuration" + } + }, + "model": { + "options.unicode1": { + "properties": [ + "hidden" + ], + "hidden": true + }, + "options.unicode1.unicode1": { + "required": true + } + }, + "form": { + "options.unicode": { + "type": "input", + "dependencies": { + "default": { + "hide": [ + "options.unicode1" + ] + }, + "expected": { + "test": { + "show": [ + "options.unicode1" + ] + } + } + } + }, + "options.unicode1.unicode1": { + "type": "input" + }, + "options.unicode1.unicode2": { + "type": "input" + }, + "options.unicode1.unicode3": { + "type": "input" + }, + "null": [ + { + "title": "Configurer", + "type": "submit" + } + ] + }, + "version": "1.0" +} \ No newline at end of file diff --git a/tests/dict/data/unicode1_leadership_requires_leader.py b/tests/dict/data/unicode1_leadership_requires_leader.py new file mode 100644 index 0000000..f65593d --- /dev/null +++ b/tests/dict/data/unicode1_leadership_requires_leader.py @@ -0,0 +1,19 @@ +from tiramisu.option import UnicodeOption, OptionDescription +from tiramisu import Leadership + + +def get_description(): + """generate description for this test + """ + option = UnicodeOption('unicode', "Value 'test' must show leader") + option1 = UnicodeOption('unicode1', "Unicode leader", multi=True, requires=[{'option': option, + 'expected': u'test', + 'action': 'hidden', + 'inverse': True}]) + option2 = UnicodeOption('unicode2', "Unicode follower 1", multi=True) + option3 = UnicodeOption('unicode3', "Unicode follower 2", multi=True) + descr1 = Leadership("unicode1", "Common configuration", + [option1, option2, option3]) + descr = OptionDescription("options", "Common configuration", [option, descr1]) + descr = OptionDescription("unicode1_leadership_requires_leader", "Leader follower with requirement on leader", [descr]) + return descr diff --git a/tests/dict/data/unicode1_leadership_requires_value.json b/tests/dict/data/unicode1_leadership_requires_value.json new file mode 100644 index 0000000..0028926 --- /dev/null +++ b/tests/dict/data/unicode1_leadership_requires_value.json @@ -0,0 +1,114 @@ +{ + "schema": { + "options": { + "name": "options", + "properties": { + "options.unicode": { + "name": "options.unicode", + "properties": { + "options.unicode.unicode": { + "name": "options.unicode.unicode", + "type": "string", + "isMulti": true, + "title": "Values 'test' must show 'Unicode follower 3'" + }, + "options.unicode.unicode1": { + "name": "options.unicode.unicode1", + "type": "string", + "isMulti": true, + "title": "Unicode follower 1" + }, + "options.unicode.unicode2": { + "name": "options.unicode.unicode2", + "type": "string", + "isMulti": true, + "title": "Unicode follower 2" + }, + "options.unicode.unicode3": { + "name": "options.unicode.unicode3", + "type": "string", + "isMulti": true, + "title": "Unicode follower 3" + } + }, + "type": "array", + "title": "Common configuration 1" + } + }, + "type": "object", + "title": "Common configuration 2" + } + }, + "model": { + "options.unicode.unicode": { + "required": true, + "value": [ + "test", + "val2" + ], + "owner": "user" + }, + "options.unicode.unicode1": { + "0": { + "value": "super1", + "owner": "user" + }, + "1": { + "value": "super2", + "owner": "user" + } + }, + "options.unicode.unicode2": { + "0": { + "value": "pas test", + "owner": "user" + }, + "1": { + "value": "test", + "owner": "user" + } + }, + "options.unicode.unicode3": { + "1": { + "hidden": true, + "value": "super", + "owner": "user" + } + } + }, + "form": { + "options.unicode.unicode": { + "type": "input", + "dependencies": { + "default": { + "hide": [ + "options.unicode.unicode3" + ] + }, + "expected": { + "test": { + "show": [ + "options.unicode.unicode3" + ] + } + } + } + }, + "options.unicode.unicode1": { + "type": "input" + }, + "options.unicode.unicode2": { + "type": "input" + }, + "options.unicode.unicode3": { + "type": "input" + }, + "null": [ + { + "title": "Configurer", + "type": "submit" + } + ] + }, + "version": "1.0" +} \ No newline at end of file diff --git a/tests/dict/data/unicode1_leadership_requires_value.py b/tests/dict/data/unicode1_leadership_requires_value.py new file mode 100644 index 0000000..c52aedf --- /dev/null +++ b/tests/dict/data/unicode1_leadership_requires_value.py @@ -0,0 +1,33 @@ +from tiramisu.option import UnicodeOption, OptionDescription +from tiramisu import Leadership + + +def get_description(): + """generate description for this test + """ + option = UnicodeOption('unicode', "Values 'test' must show 'Unicode follower 3'", multi=True) + option1 = UnicodeOption('unicode1', "Unicode follower 1", multi=True) + option2 = UnicodeOption('unicode2', "Unicode follower 2", multi=True) + option3 = UnicodeOption('unicode3', "Unicode follower 3", requires=[{'option': option, + 'expected': u'test', + 'action': 'hidden', + 'inverse': True}], + multi=True) + descr1 = Leadership("unicode", "Common configuration 1", + [option, option1, option2, option3]) + descr = OptionDescription("options", "Common configuration 2", [descr1]) + descr = OptionDescription("unicode1_leadership_requires_value", "Leader followers with Unicode follower 3 hidden when Unicode follower 2 is test and modified value", [descr]) + return descr + + +def get_values(api, allpath=False): + if allpath: + root = 'unicode1_leadership_requires_value.' + else: + root = '' + api.option(root + 'options.unicode.unicode').value.set([u'test', u'val2']) + api.option(root + 'options.unicode.unicode1', 0).value.set(u'super1') + api.option(root + 'options.unicode.unicode1', 1).value.set(u'super2') + api.option(root + 'options.unicode.unicode2', 0).value.set(u'pas test') + api.option(root + 'options.unicode.unicode2', 1).value.set(u'test') + api.option(root + 'options.unicode.unicode3', 1).value.set(u'super') diff --git a/tests/dict/data/unicode1_leadership_submulti.json b/tests/dict/data/unicode1_leadership_submulti.json new file mode 100644 index 0000000..fad6e7d --- /dev/null +++ b/tests/dict/data/unicode1_leadership_submulti.json @@ -0,0 +1,69 @@ +{ + "schema": { + "options": { + "name": "options", + "properties": { + "options.unicode": { + "name": "options.unicode", + "properties": { + "options.unicode.unicode": { + "name": "options.unicode.unicode", + "type": "string", + "isMulti": true, + "title": "Unicode leader" + }, + "options.unicode.unicode1": { + "name": "options.unicode.unicode1", + "type": "string", + "isMulti": true, + "title": "Unicode follower 1" + }, + "options.unicode.unicode2": { + "name": "options.unicode.unicode2", + "type": "string", + "isMulti": true, + "isSubMulti": true, + "title": "Unicode follower 2 submulti" + }, + "options.unicode.unicode3": { + "name": "options.unicode.unicode3", + "type": "string", + "isMulti": true, + "title": "Unicode follower 3" + } + }, + "type": "array", + "title": "Common configuration 1" + } + }, + "type": "object", + "title": "Common configuration 2" + } + }, + "model": { + "options.unicode.unicode": { + "required": true + } + }, + "form": { + "options.unicode.unicode": { + "type": "input" + }, + "options.unicode.unicode1": { + "type": "input" + }, + "options.unicode.unicode2": { + "type": "input" + }, + "options.unicode.unicode3": { + "type": "input" + }, + "null": [ + { + "title": "Configurer", + "type": "submit" + } + ] + }, + "version": "1.0" +} \ No newline at end of file diff --git a/tests/dict/data/unicode1_leadership_submulti.py b/tests/dict/data/unicode1_leadership_submulti.py new file mode 100644 index 0000000..68518f4 --- /dev/null +++ b/tests/dict/data/unicode1_leadership_submulti.py @@ -0,0 +1,17 @@ +from tiramisu.option import UnicodeOption, OptionDescription, submulti +from tiramisu import Leadership + + +def get_description(): + """generate description for this test + """ + option = UnicodeOption('unicode', "Unicode leader", multi=True) + option1 = UnicodeOption('unicode1', "Unicode follower 1", multi=True) + option2 = UnicodeOption('unicode2', "Unicode follower 2 submulti", multi=submulti) + option3 = UnicodeOption('unicode3', "Unicode follower 3", multi=True) + descr1 = Leadership("unicode", "Common configuration 1", + [option, option1, option2, option3]) + descr = OptionDescription("options", "Common configuration 2", [descr1]) + descr = OptionDescription("unicode1_leadership_submulti", "Leader followers with submulti Unicode", [descr]) + return descr + diff --git a/tests/dict/data/unicode1_leadership_value.dict b/tests/dict/data/unicode1_leadership_value.dict new file mode 100644 index 0000000..4bb56b9 --- /dev/null +++ b/tests/dict/data/unicode1_leadership_value.dict @@ -0,0 +1,4 @@ +{"options.unicode.unicode": ["val3", "val4"], + "options.unicode.unicode1": ["super1", "super2"], + "options.unicode.unicode2": ["pas test", "test"], + "options.unicode.unicode3": [null, "super"]} diff --git a/tests/dict/data/unicode1_leadership_value.dict1 b/tests/dict/data/unicode1_leadership_value.dict1 new file mode 100644 index 0000000..f89aef6 --- /dev/null +++ b/tests/dict/data/unicode1_leadership_value.dict1 @@ -0,0 +1,4 @@ +{"options.unicode.unicode": ["val1", "val2"], + "options.unicode.unicode1": [null, null], + "options.unicode.unicode2": ["follower2", "follower2"], + "options.unicode.unicode3": [null, null]} diff --git a/tests/dict/data/unicode1_leadership_value.dict2 b/tests/dict/data/unicode1_leadership_value.dict2 new file mode 100644 index 0000000..8fbff8b --- /dev/null +++ b/tests/dict/data/unicode1_leadership_value.dict2 @@ -0,0 +1,4 @@ +{"options.unicode.unicode": ["val3"], + "options.unicode.unicode1": ["super1"], + "options.unicode.unicode2": ["pas test"], + "options.unicode.unicode3": [null]} diff --git a/tests/dict/data/unicode1_leadership_value.dict3 b/tests/dict/data/unicode1_leadership_value.dict3 new file mode 100644 index 0000000..9f0ea36 --- /dev/null +++ b/tests/dict/data/unicode1_leadership_value.dict3 @@ -0,0 +1,4 @@ +{"options.unicode.unicode": ["val3", "val4", "val5"], + "options.unicode.unicode1": ["super1", "super2", null], + "options.unicode.unicode2": ["pas test", "test", "follower2"], + "options.unicode.unicode3": [null, "super", null]} diff --git a/tests/dict/data/unicode1_leadership_value.dict4 b/tests/dict/data/unicode1_leadership_value.dict4 new file mode 100644 index 0000000..9f0ea36 --- /dev/null +++ b/tests/dict/data/unicode1_leadership_value.dict4 @@ -0,0 +1,4 @@ +{"options.unicode.unicode": ["val3", "val4", "val5"], + "options.unicode.unicode1": ["super1", "super2", null], + "options.unicode.unicode2": ["pas test", "test", "follower2"], + "options.unicode.unicode3": [null, "super", null]} diff --git a/tests/dict/data/unicode1_leadership_value.dict5 b/tests/dict/data/unicode1_leadership_value.dict5 new file mode 100644 index 0000000..0c611c8 --- /dev/null +++ b/tests/dict/data/unicode1_leadership_value.dict5 @@ -0,0 +1,4 @@ +{"options.unicode.unicode": ["val3", "val4"], + "options.unicode.unicode1": ["super1", "super2"], + "options.unicode.unicode2": ["pas test", "follower2"], + "options.unicode.unicode3": [null, "super"]} diff --git a/tests/dict/data/unicode1_leadership_value.dict6 b/tests/dict/data/unicode1_leadership_value.dict6 new file mode 100644 index 0000000..752ff14 --- /dev/null +++ b/tests/dict/data/unicode1_leadership_value.dict6 @@ -0,0 +1,4 @@ +{"options.unicode.unicode": ["val3", "val4"], + "options.unicode.unicode1": ["super1", "super2"], + "options.unicode.unicode2": ["pas test", "test2"], + "options.unicode.unicode3": [null, "super"]} diff --git a/tests/dict/data/unicode1_leadership_value.json b/tests/dict/data/unicode1_leadership_value.json new file mode 100644 index 0000000..9f41169 --- /dev/null +++ b/tests/dict/data/unicode1_leadership_value.json @@ -0,0 +1,106 @@ +{ + "schema": { + "options": { + "name": "options", + "properties": { + "options.unicode": { + "name": "options.unicode", + "properties": { + "options.unicode.unicode": { + "name": "options.unicode.unicode", + "type": "string", + "value": [ + "val1", + "val2" + ], + "isMulti": true, + "title": "Unicode leader" + }, + "options.unicode.unicode1": { + "name": "options.unicode.unicode1", + "type": "string", + "isMulti": true, + "title": "Unicode follower 1" + }, + "options.unicode.unicode2": { + "name": "options.unicode.unicode2", + "type": "string", + "default": "follower2", + "isMulti": true, + "title": "Unicode follower 2 with default multi" + }, + "options.unicode.unicode3": { + "name": "options.unicode.unicode3", + "type": "string", + "isMulti": true, + "title": "Unicode follower 3" + } + }, + "type": "array", + "title": "Common configuration 1" + } + }, + "type": "object", + "title": "Common configuration 2" + } + }, + "model": { + "options.unicode.unicode": { + "required": true, + "value": [ + "val3", + "val4" + ], + "owner": "user" + }, + "options.unicode.unicode1": { + "0": { + "value": "super1", + "owner": "user" + }, + "1": { + "value": "super2", + "owner": "user" + } + }, + "options.unicode.unicode2": { + "0": { + "value": "pas test", + "owner": "user" + }, + "1": { + "value": "test", + "owner": "user" + } + }, + "options.unicode.unicode3": { + "1": { + "value": "super", + "owner": "user" + } + } + }, + "form": { + "options.unicode.unicode": { + "clearable": true, + "type": "input" + }, + "options.unicode.unicode1": { + "type": "input" + }, + "options.unicode.unicode2": { + "clearable": true, + "type": "input" + }, + "options.unicode.unicode3": { + "type": "input" + }, + "null": [ + { + "title": "Configurer", + "type": "submit" + } + ] + }, + "version": "1.0" +} \ No newline at end of file diff --git a/tests/dict/data/unicode1_leadership_value.mod1 b/tests/dict/data/unicode1_leadership_value.mod1 new file mode 100644 index 0000000..c566d0e --- /dev/null +++ b/tests/dict/data/unicode1_leadership_value.mod1 @@ -0,0 +1,3 @@ +{"cmd": "config.option('options.unicode.unicode').value.reset()", + "body": {"updates": [{"action": "delete", + "name": "options.unicode.unicode"}]}} diff --git a/tests/dict/data/unicode1_leadership_value.mod2 b/tests/dict/data/unicode1_leadership_value.mod2 new file mode 100644 index 0000000..d9c6f97 --- /dev/null +++ b/tests/dict/data/unicode1_leadership_value.mod2 @@ -0,0 +1,4 @@ +{"cmd": "config.option('options.unicode.unicode', 1).value.reset()", + "body": {"updates": [{"action": "delete", + "index": 1, + "name": "options.unicode.unicode"}]}} diff --git a/tests/dict/data/unicode1_leadership_value.mod3 b/tests/dict/data/unicode1_leadership_value.mod3 new file mode 100644 index 0000000..e70eed0 --- /dev/null +++ b/tests/dict/data/unicode1_leadership_value.mod3 @@ -0,0 +1,4 @@ +{"cmd": "config.option('options.unicode.unicode').value.set(['val3', 'val4', 'val5'])", + "body": {"updates": [{"action": "modify", + "name": "options.unicode.unicode", + "value": ["val3", "val4", "val5"]}]}} diff --git a/tests/dict/data/unicode1_leadership_value.mod4 b/tests/dict/data/unicode1_leadership_value.mod4 new file mode 100644 index 0000000..e70eed0 --- /dev/null +++ b/tests/dict/data/unicode1_leadership_value.mod4 @@ -0,0 +1,4 @@ +{"cmd": "config.option('options.unicode.unicode').value.set(['val3', 'val4', 'val5'])", + "body": {"updates": [{"action": "modify", + "name": "options.unicode.unicode", + "value": ["val3", "val4", "val5"]}]}} diff --git a/tests/dict/data/unicode1_leadership_value.mod5 b/tests/dict/data/unicode1_leadership_value.mod5 new file mode 100644 index 0000000..0052ba3 --- /dev/null +++ b/tests/dict/data/unicode1_leadership_value.mod5 @@ -0,0 +1,4 @@ +{"cmd": "config.option('options.unicode.unicode2', 1).value.reset()", + "body": {"updates": [{"action": "delete", + "name": "options.unicode.unicode2", + "index": 1}]}} diff --git a/tests/dict/data/unicode1_leadership_value.mod6 b/tests/dict/data/unicode1_leadership_value.mod6 new file mode 100644 index 0000000..02c4f2a --- /dev/null +++ b/tests/dict/data/unicode1_leadership_value.mod6 @@ -0,0 +1,5 @@ +{"cmd": "config.option('options.unicode.unicode2', 1).value.set('test2')", + "body": {"updates": [{"action": "modify", + "name": "options.unicode.unicode2", + "index": 1, + "value": "test2"}]}} diff --git a/tests/dict/data/unicode1_leadership_value.py b/tests/dict/data/unicode1_leadership_value.py new file mode 100644 index 0000000..ec846c8 --- /dev/null +++ b/tests/dict/data/unicode1_leadership_value.py @@ -0,0 +1,29 @@ +from tiramisu.option import UnicodeOption, OptionDescription +from tiramisu import Leadership + + +def get_description(): + """generate description for this test + """ + option = UnicodeOption('unicode', "Unicode leader", ['val1', 'val2'], multi=True) + option1 = UnicodeOption('unicode1', "Unicode follower 1", multi=True) + option2 = UnicodeOption('unicode2', "Unicode follower 2 with default multi", default_multi="follower2", multi=True) + option3 = UnicodeOption('unicode3', "Unicode follower 3", multi=True) + descr1 = Leadership("unicode", "Common configuration 1", + [option, option1, option2, option3]) + descr = OptionDescription("options", "Common configuration 2", [descr1]) + descr = OptionDescription("unicode1_leadership_value", "Leader followers with unicode with default value", [descr]) + return descr + + +def get_values(api, allpath=False): + if allpath: + root = 'unicode1_leadership_value.' + else: + root = '' + api.option(root + 'options.unicode.unicode').value.set([u'val3', u'val4']) + api.option(root + 'options.unicode.unicode1', 0).value.set(u'super1') + api.option(root + 'options.unicode.unicode1', 1).value.set(u'super2') + api.option(root + 'options.unicode.unicode2', 0).value.set(u'pas test') + api.option(root + 'options.unicode.unicode2', 1).value.set(u'test') + api.option(root + 'options.unicode.unicode3', 1).value.set(u'super') diff --git a/tests/dict/data/unicode1_leadership_value.updates1 b/tests/dict/data/unicode1_leadership_value.updates1 new file mode 100644 index 0000000..029a459 --- /dev/null +++ b/tests/dict/data/unicode1_leadership_value.updates1 @@ -0,0 +1,11 @@ +{"updates": ["options.unicode.unicode", + "options.unicode.unicode1", + "options.unicode.unicode2", + "options.unicode.unicode3"], + "model": {"options.unicode.unicode": {"owner": "default", + "required": true, + "value": ["val1", "val2"]}, + "options.unicode.unicode2": {"0": {"owner": "default", + "value": "follower2"}, + "1": {"owner": "default", + "value": "follower2"}}}} diff --git a/tests/dict/data/unicode1_leadership_value.updates2 b/tests/dict/data/unicode1_leadership_value.updates2 new file mode 100644 index 0000000..c1f76a6 --- /dev/null +++ b/tests/dict/data/unicode1_leadership_value.updates2 @@ -0,0 +1,11 @@ +{"updates": ["options.unicode.unicode", + "options.unicode.unicode1", + "options.unicode.unicode2", + "options.unicode.unicode3"], + "model": {"options.unicode.unicode": {"required": true, + "value": ["val3"], + "owner": "user"}, + "options.unicode.unicode1": {"0": {"value": "super1", + "owner": "user"}}, + "options.unicode.unicode2": {"0": {"value": "pas test", + "owner": "user"}}}} diff --git a/tests/dict/data/unicode1_leadership_value.updates3 b/tests/dict/data/unicode1_leadership_value.updates3 new file mode 100644 index 0000000..143fd34 --- /dev/null +++ b/tests/dict/data/unicode1_leadership_value.updates3 @@ -0,0 +1,17 @@ +{"updates": ["options.unicode.unicode", + "options.unicode.unicode2"], + "model": {"options.unicode.unicode": {"required": true, + "value": ["val3", "val4", "val5"], + "owner": "user"}, + "options.unicode.unicode1": {"0": {"value": "super1", + "owner": "user"}, + "1": {"value": "super2", + "owner": "user"}}, + "options.unicode.unicode2": {"0": {"value": "pas test", + "owner": "user"}, + "1": {"value": "test", + "owner": "user"}, + "2": {"value": "follower2", + "owner": "default"}}, + "options.unicode.unicode3": {"1": {"value": "super", + "owner": "user"}}}} diff --git a/tests/dict/data/unicode1_leadership_value.updates4 b/tests/dict/data/unicode1_leadership_value.updates4 new file mode 100644 index 0000000..bc286b8 --- /dev/null +++ b/tests/dict/data/unicode1_leadership_value.updates4 @@ -0,0 +1,16 @@ +{"model": {"options.unicode.unicode": {"owner": "user", + "required": true, + "value": ["val3", "val4", "val5"]}, + "options.unicode.unicode1": {"0": {"owner": "user", + "value": "super1"}, + "1": {"owner": "user", + "value": "super2"}}, + "options.unicode.unicode2": {"0": {"owner": "user", + "value": "pas test"}, + "1": {"owner": "user", + "value": "test"}, + "2": {"owner": "default", + "value": "follower2"}}, + "options.unicode.unicode3": {"1": {"owner": "user", + "value": "super"}}}, + "updates": ["options.unicode.unicode", "options.unicode.unicode2"]} diff --git a/tests/dict/data/unicode1_leadership_value.updates5 b/tests/dict/data/unicode1_leadership_value.updates5 new file mode 100644 index 0000000..127e7f6 --- /dev/null +++ b/tests/dict/data/unicode1_leadership_value.updates5 @@ -0,0 +1,14 @@ +{"updates": ["options.unicode.unicode2"], + "model": {"options.unicode.unicode": {"required": true, + "value": ["val3", "val4"], + "owner": "user"}, + "options.unicode.unicode1": {"0": {"value": "super1", + "owner": "user"}, + "1": {"value": "super2", + "owner": "user"}}, + "options.unicode.unicode2": {"0": {"value": "pas test", + "owner": "user"}, + "1": {"value": "follower2", + "owner": "default"}}, + "options.unicode.unicode3": {"1": {"value": "super", + "owner": "user"}}}} diff --git a/tests/dict/data/unicode1_leadership_value.updates6 b/tests/dict/data/unicode1_leadership_value.updates6 new file mode 100644 index 0000000..307d6ef --- /dev/null +++ b/tests/dict/data/unicode1_leadership_value.updates6 @@ -0,0 +1,14 @@ +{"updates": ["options.unicode.unicode2"], + "model": {"options.unicode.unicode": {"required": true, + "value": ["val3", "val4"], + "owner": "user"}, + "options.unicode.unicode1": {"0": {"value": "super1", + "owner": "user"}, + "1": {"value": "super2", + "owner": "user"}}, + "options.unicode.unicode2": {"0": {"value": "pas test", + "owner": "user"}, + "1": {"value": "test2", + "owner": "user"}}, + "options.unicode.unicode3": {"1": {"value": "super", + "owner": "user"}}}} diff --git a/tests/dict/data/unicode1_mandatory.json b/tests/dict/data/unicode1_mandatory.json new file mode 100644 index 0000000..f5449e0 --- /dev/null +++ b/tests/dict/data/unicode1_mandatory.json @@ -0,0 +1,33 @@ +{ + "schema": { + "options": { + "name": "options", + "properties": { + "options.unicode": { + "name": "options.unicode", + "type": "string", + "title": "Unicode 1" + } + }, + "type": "object", + "title": "Common configuration" + } + }, + "model": { + "options.unicode": { + "required": true + } + }, + "form": { + "options.unicode": { + "type": "input" + }, + "null": [ + { + "title": "Configurer", + "type": "submit" + } + ] + }, + "version": "1.0" +} \ No newline at end of file diff --git a/tests/dict/data/unicode1_mandatory.py b/tests/dict/data/unicode1_mandatory.py new file mode 100644 index 0000000..77ca67a --- /dev/null +++ b/tests/dict/data/unicode1_mandatory.py @@ -0,0 +1,11 @@ +"""just a multi unicode option +""" +from tiramisu.option import UnicodeOption, OptionDescription + +def get_description(): + """generate description for this test + """ + option = UnicodeOption('unicode', "Unicode 1", properties=('mandatory',)) + descr1 = OptionDescription("options", "Common configuration", [option]) + descr = OptionDescription("unicode1_mandatory", "Mandatory unicode", [descr1]) + return descr diff --git a/tests/dict/data/unicode1_mod_value.dict b/tests/dict/data/unicode1_mod_value.dict new file mode 100644 index 0000000..f28f4dc --- /dev/null +++ b/tests/dict/data/unicode1_mod_value.dict @@ -0,0 +1 @@ +{"options.unicode": "a"} diff --git a/tests/dict/data/unicode1_mod_value.dict1 b/tests/dict/data/unicode1_mod_value.dict1 new file mode 100644 index 0000000..674e06e --- /dev/null +++ b/tests/dict/data/unicode1_mod_value.dict1 @@ -0,0 +1 @@ +{"options.unicode": "val"} diff --git a/tests/dict/data/unicode1_mod_value.dict2 b/tests/dict/data/unicode1_mod_value.dict2 new file mode 100644 index 0000000..ba0b015 --- /dev/null +++ b/tests/dict/data/unicode1_mod_value.dict2 @@ -0,0 +1 @@ +{"options.unicode": null} diff --git a/tests/dict/data/unicode1_mod_value.json b/tests/dict/data/unicode1_mod_value.json new file mode 100644 index 0000000..5d8949b --- /dev/null +++ b/tests/dict/data/unicode1_mod_value.json @@ -0,0 +1,34 @@ +{ + "schema": { + "options": { + "name": "options", + "properties": { + "options.unicode": { + "name": "options.unicode", + "type": "string", + "title": "Unicode 1" + } + }, + "type": "object", + "title": "Common configuration" + } + }, + "model": { + "options.unicode": { + "value": "a", + "owner": "user" + } + }, + "form": { + "options.unicode": { + "type": "input" + }, + "null": [ + { + "title": "Configurer", + "type": "submit" + } + ] + }, + "version": "1.0" +} \ No newline at end of file diff --git a/tests/dict/data/unicode1_mod_value.mod b/tests/dict/data/unicode1_mod_value.mod new file mode 100644 index 0000000..f031ad6 --- /dev/null +++ b/tests/dict/data/unicode1_mod_value.mod @@ -0,0 +1 @@ +config.option(root_path + 'options.unicode').value.set('a') diff --git a/tests/dict/data/unicode1_mod_value.mod1 b/tests/dict/data/unicode1_mod_value.mod1 new file mode 100644 index 0000000..14f84c3 --- /dev/null +++ b/tests/dict/data/unicode1_mod_value.mod1 @@ -0,0 +1,4 @@ +{"cmd": "config.option('options.unicode').value.set('val')", + "body": {"updates": [{"action": "modify", + "name": "options.unicode", + "value": "val"}]}} diff --git a/tests/dict/data/unicode1_mod_value.mod2 b/tests/dict/data/unicode1_mod_value.mod2 new file mode 100644 index 0000000..ebabe53 --- /dev/null +++ b/tests/dict/data/unicode1_mod_value.mod2 @@ -0,0 +1,4 @@ +{"cmd": "config.option('options.unicode').value.reset()", + "body": {"updates": [{"action": "delete", + "name": "options.unicode"}]}} + diff --git a/tests/dict/data/unicode1_mod_value.py b/tests/dict/data/unicode1_mod_value.py new file mode 100644 index 0000000..5cd113b --- /dev/null +++ b/tests/dict/data/unicode1_mod_value.py @@ -0,0 +1,19 @@ +"""just an unicode option +""" +from tiramisu.option import StrOption, OptionDescription + +def get_description(): + """generate description for this test + """ + option = StrOption('unicode', "Unicode 1") + descr1 = OptionDescription("options", "Common configuration", [option]) + descr = OptionDescription("unicode1_mod_value", "Simple unicode with modified value", [descr1]) + return descr + + +def get_values(api, allpath=False): + if allpath: + root = 'unicode1_mod_value.' + else: + root = '' + api.option(root + 'options.unicode').value.set('a') diff --git a/tests/dict/data/unicode1_mod_value.updates1 b/tests/dict/data/unicode1_mod_value.updates1 new file mode 100644 index 0000000..c622016 --- /dev/null +++ b/tests/dict/data/unicode1_mod_value.updates1 @@ -0,0 +1,3 @@ +{"updates": ["options.unicode"], + "model": {"options.unicode": {"owner": "user", + "value": "val"}}} diff --git a/tests/dict/data/unicode1_mod_value.updates2 b/tests/dict/data/unicode1_mod_value.updates2 new file mode 100644 index 0000000..b512f06 --- /dev/null +++ b/tests/dict/data/unicode1_mod_value.updates2 @@ -0,0 +1,3 @@ +{"updates": ["options.unicode"], + "model": {}} + diff --git a/tests/dict/data/unicode1_multi.dict b/tests/dict/data/unicode1_multi.dict new file mode 100644 index 0000000..66a217b --- /dev/null +++ b/tests/dict/data/unicode1_multi.dict @@ -0,0 +1 @@ +{"options.unicode": []} diff --git a/tests/dict/data/unicode1_multi.dict1 b/tests/dict/data/unicode1_multi.dict1 new file mode 100644 index 0000000..9d6b074 --- /dev/null +++ b/tests/dict/data/unicode1_multi.dict1 @@ -0,0 +1 @@ +{"options.unicode": ["val"]} diff --git a/tests/dict/data/unicode1_multi.json b/tests/dict/data/unicode1_multi.json new file mode 100644 index 0000000..b1afd72 --- /dev/null +++ b/tests/dict/data/unicode1_multi.json @@ -0,0 +1,34 @@ +{ + "schema": { + "options": { + "name": "options", + "properties": { + "options.unicode": { + "name": "options.unicode", + "type": "string", + "isMulti": true, + "title": "Multi string 1" + } + }, + "type": "object", + "title": "Common configuration" + } + }, + "model": { + "options.unicode": { + "required": true + } + }, + "form": { + "options.unicode": { + "type": "input" + }, + "null": [ + { + "title": "Configurer", + "type": "submit" + } + ] + }, + "version": "1.0" +} \ No newline at end of file diff --git a/tests/dict/data/unicode1_multi.mod1 b/tests/dict/data/unicode1_multi.mod1 new file mode 100644 index 0000000..bfaae52 --- /dev/null +++ b/tests/dict/data/unicode1_multi.mod1 @@ -0,0 +1,4 @@ +{"cmd": ["config.option('options.unicode').value.set([undefined])", "config.option('options.unicode').value.set(['val'])"], + "body": {"updates": [{"action": "modify", + "name": "options.unicode", + "value": ["val"]}]}} diff --git a/tests/dict/data/unicode1_multi.py b/tests/dict/data/unicode1_multi.py new file mode 100644 index 0000000..d429e18 --- /dev/null +++ b/tests/dict/data/unicode1_multi.py @@ -0,0 +1,11 @@ +"""just a multi unicode option +""" +from tiramisu.option import UnicodeOption, OptionDescription + +def get_description(): + """generate description for this test + """ + option = UnicodeOption('unicode', "Multi string 1", multi=True) + descr1 = OptionDescription("options", "Common configuration", [option]) + descr = OptionDescription("unicode1_multi", "Multi unicode", [descr1]) + return descr diff --git a/tests/dict/data/unicode1_multi.updates1 b/tests/dict/data/unicode1_multi.updates1 new file mode 100644 index 0000000..dd21440 --- /dev/null +++ b/tests/dict/data/unicode1_multi.updates1 @@ -0,0 +1,4 @@ +{"updates": ["options.unicode"], + "model": {"options.unicode": {"owner": "user", + "required": true, + "value": ["val"]}}} diff --git a/tests/dict/data/unicode1_multi_hidden.json b/tests/dict/data/unicode1_multi_hidden.json new file mode 100644 index 0000000..4ba005c --- /dev/null +++ b/tests/dict/data/unicode1_multi_hidden.json @@ -0,0 +1,36 @@ +{ + "schema": { + "options": { + "name": "options", + "properties": { + "options.unicode": { + "name": "options.unicode", + "type": "string", + "isMulti": true, + "title": "Unicode 1" + } + }, + "type": "object", + "title": "Common configuration" + } + }, + "model": { + "options.unicode": { + "display": false, + "required": true, + "hidden": true + } + }, + "form": { + "options.unicode": { + "type": "input" + }, + "null": [ + { + "title": "Configurer", + "type": "submit" + } + ] + }, + "version": "1.0" +} \ No newline at end of file diff --git a/tests/dict/data/unicode1_multi_hidden.py b/tests/dict/data/unicode1_multi_hidden.py new file mode 100644 index 0000000..137e2d8 --- /dev/null +++ b/tests/dict/data/unicode1_multi_hidden.py @@ -0,0 +1,11 @@ +"""just a multi unicode option +""" +from tiramisu.option import UnicodeOption, OptionDescription + +def get_description(): + """generate description for this test + """ + option = UnicodeOption('unicode', "Unicode 1", properties=('hidden',), multi=True) + descr1 = OptionDescription("options", "Common configuration", [option]) + descr = OptionDescription("unicode1_multi_hidden", "Hidden multi unicode", [descr1]) + return descr diff --git a/tests/dict/data/unicode1_multi_mandatory.json b/tests/dict/data/unicode1_multi_mandatory.json new file mode 100644 index 0000000..2fa6b66 --- /dev/null +++ b/tests/dict/data/unicode1_multi_mandatory.json @@ -0,0 +1,35 @@ +{ + "schema": { + "options": { + "name": "options", + "properties": { + "options.unicode": { + "name": "options.unicode", + "type": "string", + "isMulti": true, + "title": "Unicode 1" + } + }, + "type": "object", + "title": "Common configuration" + } + }, + "model": { + "options.unicode": { + "required": true, + "needs_len": true + } + }, + "form": { + "options.unicode": { + "type": "input" + }, + "null": [ + { + "title": "Configurer", + "type": "submit" + } + ] + }, + "version": "1.0" +} \ No newline at end of file diff --git a/tests/dict/data/unicode1_multi_mandatory.py b/tests/dict/data/unicode1_multi_mandatory.py new file mode 100644 index 0000000..de3648b --- /dev/null +++ b/tests/dict/data/unicode1_multi_mandatory.py @@ -0,0 +1,11 @@ +"""just a multi unicode option +""" +from tiramisu.option import UnicodeOption, OptionDescription + +def get_description(): + """generate description for this test + """ + option = UnicodeOption('unicode', "Unicode 1", multi=True, properties=('mandatory',)) + descr1 = OptionDescription("options", "Common configuration", [option]) + descr = OptionDescription("unicode1_multi_mandatory", "Mandatory multi Unicode", [descr1]) + return descr diff --git a/tests/dict/data/unicode1_multi_mod_value.dict b/tests/dict/data/unicode1_multi_mod_value.dict new file mode 100644 index 0000000..3aa1ece --- /dev/null +++ b/tests/dict/data/unicode1_multi_mod_value.dict @@ -0,0 +1 @@ +{"options.unicode": ["c", "d", "e"]} diff --git a/tests/dict/data/unicode1_multi_mod_value.dict1 b/tests/dict/data/unicode1_multi_mod_value.dict1 new file mode 100644 index 0000000..f572a0b --- /dev/null +++ b/tests/dict/data/unicode1_multi_mod_value.dict1 @@ -0,0 +1 @@ +{"options.unicode": ["a", "b"]} diff --git a/tests/dict/data/unicode1_multi_mod_value.dict2 b/tests/dict/data/unicode1_multi_mod_value.dict2 new file mode 100644 index 0000000..2b794c6 --- /dev/null +++ b/tests/dict/data/unicode1_multi_mod_value.dict2 @@ -0,0 +1 @@ +{"options.unicode": ["c", "f", "e"]} diff --git a/tests/dict/data/unicode1_multi_mod_value.json b/tests/dict/data/unicode1_multi_mod_value.json new file mode 100644 index 0000000..05916b7 --- /dev/null +++ b/tests/dict/data/unicode1_multi_mod_value.json @@ -0,0 +1,45 @@ +{ + "schema": { + "options": { + "name": "options", + "properties": { + "options.unicode": { + "name": "options.unicode", + "type": "string", + "value": [ + "a", + "b" + ], + "isMulti": true, + "title": "String 1" + } + }, + "type": "object", + "title": "Common configuration" + } + }, + "model": { + "options.unicode": { + "required": true, + "value": [ + "c", + "d", + "e" + ], + "owner": "user" + } + }, + "form": { + "options.unicode": { + "clearable": true, + "type": "input" + }, + "null": [ + { + "title": "Configurer", + "type": "submit" + } + ] + }, + "version": "1.0" +} \ No newline at end of file diff --git a/tests/dict/data/unicode1_multi_mod_value.mod b/tests/dict/data/unicode1_multi_mod_value.mod new file mode 100644 index 0000000..b50499b --- /dev/null +++ b/tests/dict/data/unicode1_multi_mod_value.mod @@ -0,0 +1 @@ +config.option(root_path + 'options.unicode').value.set(['c', 'd', 'e']) diff --git a/tests/dict/data/unicode1_multi_mod_value.mod1 b/tests/dict/data/unicode1_multi_mod_value.mod1 new file mode 100644 index 0000000..6f5d6fe --- /dev/null +++ b/tests/dict/data/unicode1_multi_mod_value.mod1 @@ -0,0 +1,3 @@ +{"cmd": "config.option('options.unicode').value.reset()", + "body": {"updates": [{"action": "delete", + "name": "options.unicode"}]}} diff --git a/tests/dict/data/unicode1_multi_mod_value.mod2 b/tests/dict/data/unicode1_multi_mod_value.mod2 new file mode 100644 index 0000000..dc48c5f --- /dev/null +++ b/tests/dict/data/unicode1_multi_mod_value.mod2 @@ -0,0 +1,5 @@ +{"cmd": "config.option('options.unicode').value.set(['c', 'f', 'e'])", + "body": {"updates": [{"action": "modify", + "name": "options.unicode", + "value": ["c", "f", "e"]}]}} + diff --git a/tests/dict/data/unicode1_multi_mod_value.py b/tests/dict/data/unicode1_multi_mod_value.py new file mode 100644 index 0000000..5a0d5bf --- /dev/null +++ b/tests/dict/data/unicode1_multi_mod_value.py @@ -0,0 +1,19 @@ +"""just a multi unicode option +""" +from tiramisu.option import StrOption, OptionDescription + +def get_description(): + """generate description for this test + """ + option = StrOption('unicode', "String 1", ['a', 'b'], multi=True) + descr1 = OptionDescription("options", "Common configuration", [option]) + descr = OptionDescription("unicode1_multi_mod_value", "Multi unicode with default value 'a' and 'b' and modified value 'c', 'd' and 'e'", [descr1]) + return descr + + +def get_values(api, allpath=False): + if allpath: + root = 'unicode1_multi_mod_value.' + else: + root = '' + api.option(root + 'options.unicode').value.set(['c', 'd', 'e']) diff --git a/tests/dict/data/unicode1_multi_mod_value.updates1 b/tests/dict/data/unicode1_multi_mod_value.updates1 new file mode 100644 index 0000000..ef1fbb2 --- /dev/null +++ b/tests/dict/data/unicode1_multi_mod_value.updates1 @@ -0,0 +1,4 @@ +{"updates": ["options.unicode"], + "model": {"options.unicode": {"owner": "default", + "required": true, + "value": ["a", "b"]}}} diff --git a/tests/dict/data/unicode1_multi_mod_value.updates2 b/tests/dict/data/unicode1_multi_mod_value.updates2 new file mode 100644 index 0000000..d63b3a5 --- /dev/null +++ b/tests/dict/data/unicode1_multi_mod_value.updates2 @@ -0,0 +1,4 @@ +{"updates": ["options.unicode"], + "model": {"options.unicode": {"owner": "user", + "required": true, + "value": ["c", "f", "e"]}}} diff --git a/tests/dict/data/unicode1_multi_not_equal_collapse.json b/tests/dict/data/unicode1_multi_not_equal_collapse.json new file mode 100644 index 0000000..bd237c7 --- /dev/null +++ b/tests/dict/data/unicode1_multi_not_equal_collapse.json @@ -0,0 +1,157 @@ +{ + "schema": { + "descr1": { + "name": "descr1", + "properties": { + "descr1.unicode1": { + "name": "descr1.unicode1", + "type": "string", + "title": "Unicode 1, not equal to 'a'" + }, + "descr1.unicode1_multi": { + "name": "descr1.unicode1_multi", + "type": "string", + "isMulti": true, + "title": "Multi unicode 1, not equal to 'a' or 'b'" + } + }, + "type": "object", + "title": "Common configuration 1" + }, + "descr2": { + "name": "descr2", + "properties": { + "descr2.unicode2": { + "name": "descr2.unicode2", + "type": "string", + "value": "a", + "title": "Unicode 2" + }, + "descr2.unicode2_multi": { + "name": "descr2.unicode2_multi", + "type": "string", + "value": [ + "a", + "b" + ], + "isMulti": true, + "title": "Multi unicode 2" + } + }, + "type": "object", + "title": "Common configuration 2" + }, + "descr3": { + "name": "descr3", + "properties": { + "descr3.unicode3": { + "name": "descr3.unicode3", + "type": "string", + "title": "Unicode 3" + }, + "descr3.unicode3_multi": { + "name": "descr3.unicode3_multi", + "type": "string", + "isMulti": true, + "title": "Multi unicode 3" + } + }, + "type": "object", + "title": "Common configuration 3" + } + }, + "model": { + "descr1.unicode1_multi": { + "required": true + }, + "descr2.unicode2": { + "value": "a", + "owner": "default" + }, + "descr2.unicode2_multi": { + "required": true, + "value": [ + "a", + "b" + ], + "owner": "default" + }, + "descr3.unicode3_multi": { + "required": true + } + }, + "form": { + "descr1.unicode1": { + "type": "input", + "not_equal": { + "options": [ + "descr2.unicode2", + "descr3.unicode3" + ] + } + }, + "descr1.unicode1_multi": { + "type": "input", + "not_equal": { + "options": [ + "descr2.unicode2_multi", + "descr3.unicode3_multi" + ] + } + }, + "descr2.unicode2": { + "clearable": true, + "type": "input", + "not_equal": { + "options": [ + "descr1.unicode1", + "descr3.unicode3" + ] + } + }, + "descr2.unicode2_multi": { + "clearable": true, + "type": "input", + "not_equal": { + "options": [ + "descr1.unicode1_multi", + "descr3.unicode3_multi" + ] + } + }, + "descr3.unicode3": { + "type": "input", + "not_equal": { + "options": [ + "descr1.unicode1", + "descr2.unicode2" + ] + } + }, + "descr3.unicode3_multi": { + "type": "input", + "not_equal": { + "options": [ + "descr1.unicode1_multi", + "descr2.unicode2_multi" + ] + } + }, + "null": [ + { + "title": "Configurer", + "type": "submit" + } + ], + "descr1": { + "collapse": true + }, + "descr2": { + "collapse": true + }, + "descr3": { + "collapse": true + } + }, + "version": "1.0" +} \ No newline at end of file diff --git a/tests/dict/data/unicode1_multi_not_equal_collapse.py b/tests/dict/data/unicode1_multi_not_equal_collapse.py new file mode 100644 index 0000000..92d6de5 --- /dev/null +++ b/tests/dict/data/unicode1_multi_not_equal_collapse.py @@ -0,0 +1,45 @@ +from tiramisu.option import UnicodeOption, OptionDescription + +def get_description(): + """generate description for this test + """ + option1 = UnicodeOption('unicode1', "Unicode 1, not equal to 'a'") + option2 = UnicodeOption('unicode1_multi', "Multi unicode 1, not equal to 'a' or 'b'", multi=True) + option3 = UnicodeOption('unicode2', "Unicode 2", default='a') + option4 = UnicodeOption('unicode2_multi', "Multi unicode 2", multi=True, default=['a', 'b']) + option5 = UnicodeOption('unicode3', "Unicode 3") + option6 = UnicodeOption('unicode3_multi', "Multi unicode 3", multi=True) + #option1.impl_add_consistency('not_equal', option3, option5) + #option2.impl_add_consistency('not_equal', option4, option6) + option3.impl_add_consistency('not_equal', option1) + option4.impl_add_consistency('not_equal', option2) + option5.impl_add_consistency('not_equal', option1) + option6.impl_add_consistency('not_equal', option2) + option5.impl_add_consistency('not_equal', option3) + option6.impl_add_consistency('not_equal', option4) + descr1 = OptionDescription("descr1", "Common configuration 1", [option1, option2]) + descr2 = OptionDescription("descr2", "Common configuration 2", [option3, option4]) + descr3 = OptionDescription("descr3", "Common configuration 3", [option5, option6]) + descr = OptionDescription("unicode1_multi_not_equal_collapse", + "Multi Unicode 1 and unicode 2 not equal with collapse", + [descr1, descr2, descr3]) + return descr + + +def get_form(allpath=False): + key1 = 'descr1' + if allpath: + key1 = 'unicode1_multi_not_equal_collapse.' + key1 + key2 = 'descr2' + if allpath: + key2 = 'unicode1_multi_not_equal_collapse.' + key2 + key3 = 'descr3' + if allpath: + key3 = 'unicode1_multi_not_equal_collapse.' + key3 + return [{'key': key1, + 'collapse': True}, + {'key': key2, + 'collapse': True}, + {'key': key3, + 'collapse': True} + ] diff --git a/tests/dict/data/unicode1_multi_requires.json b/tests/dict/data/unicode1_multi_requires.json new file mode 100644 index 0000000..987057b --- /dev/null +++ b/tests/dict/data/unicode1_multi_requires.json @@ -0,0 +1,57 @@ +{ + "schema": { + "options": { + "name": "options", + "properties": { + "options.unicode1": { + "name": "options.unicode1", + "type": "string", + "title": "Value 'test' must show Unicode 2" + }, + "options.unicode2": { + "name": "options.unicode2", + "type": "string", + "isMulti": true, + "title": "Unicode 2" + } + }, + "type": "object", + "title": "Common configuration" + } + }, + "model": { + "options.unicode2": { + "required": true, + "hidden": true + } + }, + "form": { + "options.unicode1": { + "type": "input", + "dependencies": { + "default": { + "hide": [ + "options.unicode2" + ] + }, + "expected": { + "test": { + "show": [ + "options.unicode2" + ] + } + } + } + }, + "options.unicode2": { + "type": "input" + }, + "null": [ + { + "title": "Configurer", + "type": "submit" + } + ] + }, + "version": "1.0" +} \ No newline at end of file diff --git a/tests/dict/data/unicode1_multi_requires.py b/tests/dict/data/unicode1_multi_requires.py new file mode 100644 index 0000000..893274d --- /dev/null +++ b/tests/dict/data/unicode1_multi_requires.py @@ -0,0 +1,15 @@ +from tiramisu.option import StrOption, OptionDescription + + +def get_description(): + """generate description for this test + """ + option1 = StrOption('unicode1', "Value 'test' must show Unicode 2") + option2 = StrOption('unicode2', "Unicode 2", requires=[{'option': option1, + 'expected': u'test', + 'action': 'hidden', + 'inverse': True}], + multi=True) + descr1 = OptionDescription("options", "Common configuration", [option1, option2]) + descr = OptionDescription("unicode1_multi_requires", "Unicode multi with requirement", [descr1]) + return descr diff --git a/tests/dict/data/unicode1_multi_value.json b/tests/dict/data/unicode1_multi_value.json new file mode 100644 index 0000000..ec717b4 --- /dev/null +++ b/tests/dict/data/unicode1_multi_value.json @@ -0,0 +1,44 @@ +{ + "schema": { + "options": { + "name": "options", + "properties": { + "options.unicode": { + "name": "options.unicode", + "type": "string", + "value": [ + "a", + "b" + ], + "isMulti": true, + "title": "String 1" + } + }, + "type": "object", + "title": "Common configuration" + } + }, + "model": { + "options.unicode": { + "required": true, + "value": [ + "a", + "b" + ], + "owner": "default" + } + }, + "form": { + "options.unicode": { + "clearable": true, + "type": "input" + }, + "null": [ + { + "title": "Configurer", + "type": "submit" + } + ] + }, + "version": "1.0" +} \ No newline at end of file diff --git a/tests/dict/data/unicode1_multi_value.py b/tests/dict/data/unicode1_multi_value.py new file mode 100644 index 0000000..140fffa --- /dev/null +++ b/tests/dict/data/unicode1_multi_value.py @@ -0,0 +1,12 @@ +"""just a multi unicode option +""" +from tiramisu.option import UnicodeOption, OptionDescription + +def get_description(): + """generate description for this test + """ + option = UnicodeOption('unicode', "String 1", ['a', 'b'], multi=True) + descr1 = OptionDescription("options", "Common configuration", [option]) + descr = OptionDescription("unicode1_multi_value", "Multi unicode with default value 'a' and 'b'", [descr1]) + return descr + diff --git a/tests/dict/data/unicode1_not_equal.json b/tests/dict/data/unicode1_not_equal.json new file mode 100644 index 0000000..f2c34ac --- /dev/null +++ b/tests/dict/data/unicode1_not_equal.json @@ -0,0 +1,47 @@ +{ + "schema": { + "options": { + "name": "options", + "properties": { + "options.unicode1": { + "name": "options.unicode1", + "type": "string", + "title": "Unicode 1" + }, + "options.unicode2": { + "name": "options.unicode2", + "type": "string", + "title": "Unicode 2" + } + }, + "type": "object", + "title": "Common configuration" + } + }, + "model": {}, + "form": { + "options.unicode1": { + "type": "input", + "not_equal": { + "options": [ + "options.unicode2" + ] + } + }, + "options.unicode2": { + "type": "input", + "not_equal": { + "options": [ + "options.unicode1" + ] + } + }, + "null": [ + { + "title": "Configurer", + "type": "submit" + } + ] + }, + "version": "1.0" +} \ No newline at end of file diff --git a/tests/dict/data/unicode1_not_equal.py b/tests/dict/data/unicode1_not_equal.py new file mode 100644 index 0000000..be290df --- /dev/null +++ b/tests/dict/data/unicode1_not_equal.py @@ -0,0 +1,11 @@ +from tiramisu.option import UnicodeOption, OptionDescription + +def get_description(): + """generate description for this test + """ + option1 = UnicodeOption('unicode1', "Unicode 1") + option2 = UnicodeOption('unicode2', "Unicode 2") + option2.impl_add_consistency('not_equal', option1) + descr1 = OptionDescription("options", "Common configuration", [option1, option2]) + descr = OptionDescription("unicode1_not_equal", "Unicode 1 and unicode 2 not equal", [descr1]) + return descr diff --git a/tests/dict/data/unicode1_optiondescription_requires.json b/tests/dict/data/unicode1_optiondescription_requires.json new file mode 100644 index 0000000..10ae37a --- /dev/null +++ b/tests/dict/data/unicode1_optiondescription_requires.json @@ -0,0 +1,73 @@ +{ + "schema": { + "options": { + "name": "options", + "properties": { + "options.unicode1": { + "name": "options.unicode1", + "type": "string", + "title": "Value 'test' must show OptionDescription" + } + }, + "type": "object", + "title": "Common configuration" + }, + "unicode1": { + "name": "unicode1", + "properties": { + "unicode1.unicode2": { + "name": "unicode1.unicode2", + "type": "string", + "title": "Unicode 2" + }, + "unicode1.unicode3": { + "name": "unicode1.unicode3", + "type": "string", + "title": "Unicode 3" + } + }, + "type": "object", + "title": "OptionDescription with 2 options" + } + }, + "model": { + "unicode1": { + "properties": [ + "hidden" + ], + "hidden": true + } + }, + "form": { + "options.unicode1": { + "type": "input", + "dependencies": { + "default": { + "hide": [ + "unicode1" + ] + }, + "expected": { + "test": { + "show": [ + "unicode1" + ] + } + } + } + }, + "unicode1.unicode2": { + "type": "input" + }, + "unicode1.unicode3": { + "type": "input" + }, + "null": [ + { + "title": "Configurer", + "type": "submit" + } + ] + }, + "version": "1.0" +} \ No newline at end of file diff --git a/tests/dict/data/unicode1_optiondescription_requires.py b/tests/dict/data/unicode1_optiondescription_requires.py new file mode 100644 index 0000000..d22c9a0 --- /dev/null +++ b/tests/dict/data/unicode1_optiondescription_requires.py @@ -0,0 +1,17 @@ +from tiramisu.option import UnicodeOption, OptionDescription + + +def get_description(): + """generate description for this test + """ + option1 = UnicodeOption('unicode1', "Value 'test' must show OptionDescription") + descr1 = OptionDescription("options", "Common configuration", [option1]) + option2 = UnicodeOption('unicode2', "Unicode 2") + option3 = UnicodeOption('unicode3', "Unicode 3") + descr2 = OptionDescription("unicode1", "OptionDescription with 2 options", + [option2, option3], requires=[{'option': option1, + 'expected': u'test', + 'action': 'hidden', + 'inverse': True}]) + descr = OptionDescription("unicode1_optiondescription_requires", "OptionDesciption with requirement", [descr1, descr2]) + return descr diff --git a/tests/dict/data/unicode1_requires.json b/tests/dict/data/unicode1_requires.json new file mode 100644 index 0000000..756256a --- /dev/null +++ b/tests/dict/data/unicode1_requires.json @@ -0,0 +1,55 @@ +{ + "schema": { + "options": { + "name": "options", + "properties": { + "options.unicode1": { + "name": "options.unicode1", + "type": "string", + "title": "Value 'test' must show Unicode 2" + }, + "options.unicode2": { + "name": "options.unicode2", + "type": "string", + "title": "Unicode 2" + } + }, + "type": "object", + "title": "Common configuration" + } + }, + "model": { + "options.unicode2": { + "hidden": true + } + }, + "form": { + "options.unicode1": { + "type": "input", + "dependencies": { + "default": { + "hide": [ + "options.unicode2" + ] + }, + "expected": { + "test": { + "show": [ + "options.unicode2" + ] + } + } + } + }, + "options.unicode2": { + "type": "input" + }, + "null": [ + { + "title": "Configurer", + "type": "submit" + } + ] + }, + "version": "1.0" +} \ No newline at end of file diff --git a/tests/dict/data/unicode1_requires.py b/tests/dict/data/unicode1_requires.py new file mode 100644 index 0000000..07d1fd5 --- /dev/null +++ b/tests/dict/data/unicode1_requires.py @@ -0,0 +1,14 @@ +from tiramisu.option import StrOption, OptionDescription + + +def get_description(): + """generate description for this test + """ + option1 = StrOption('unicode1', "Value 'test' must show Unicode 2") + option2 = StrOption('unicode2', "Unicode 2", requires=[{'option': option1, + 'expected': u'test', + 'action': 'hidden', + 'inverse': True}]) + descr1 = OptionDescription("options", "Common configuration", [option1, option2]) + descr = OptionDescription("unicode1_requires", "Unicode with requirement", [descr1]) + return descr diff --git a/tests/dict/data/unicode1_simple_callback.json b/tests/dict/data/unicode1_simple_callback.json new file mode 100644 index 0000000..37d73a1 --- /dev/null +++ b/tests/dict/data/unicode1_simple_callback.json @@ -0,0 +1,36 @@ +{ + "schema": { + "options": { + "name": "options", + "properties": { + "options.unicode1": { + "name": "options.unicode1", + "type": "string", + "title": "Unicode 1", + "value": "word" + } + }, + "type": "object", + "title": "Common configuration" + } + }, + "model": { + "options.unicode1": { + "value": "word", + "owner": "default" + } + }, + "form": { + "options.unicode1": { + "type": "input", + "clearable": true + }, + "null": [ + { + "title": "Configurer", + "type": "submit" + } + ] + }, + "version": "1.0" +} \ No newline at end of file diff --git a/tests/dict/data/unicode1_simple_callback.py b/tests/dict/data/unicode1_simple_callback.py new file mode 100644 index 0000000..f224c16 --- /dev/null +++ b/tests/dict/data/unicode1_simple_callback.py @@ -0,0 +1,18 @@ +"""two unicode options +""" +from tiramisu.option import StrOption, OptionDescription +from tiramisu import Params, ParamOption + + +def return_word(): + return "word" + + +def get_description(): + """generate description for this test + """ + option = StrOption('unicode1', "Unicode 1", callback=return_word) + descr1 = OptionDescription("options", "Common configuration", [option]) + descr = OptionDescription("unicode1_simple_callback", "Calculate 'word' even if not remotable", [descr1]) + return descr + diff --git a/tests/dict/data/unicode2.json b/tests/dict/data/unicode2.json new file mode 100644 index 0000000..c8905bd --- /dev/null +++ b/tests/dict/data/unicode2.json @@ -0,0 +1,37 @@ +{ + "schema": { + "options": { + "name": "options", + "properties": { + "options.unicode1": { + "name": "options.unicode1", + "type": "string", + "title": "Unicode 1" + }, + "options.unicode2": { + "name": "options.unicode2", + "type": "string", + "title": "Unicode 2" + } + }, + "type": "object", + "title": "Common configuration" + } + }, + "model": {}, + "form": { + "options.unicode1": { + "type": "input" + }, + "options.unicode2": { + "type": "input" + }, + "null": [ + { + "title": "Configurer", + "type": "submit" + } + ] + }, + "version": "1.0" +} \ No newline at end of file diff --git a/tests/dict/data/unicode2.py b/tests/dict/data/unicode2.py new file mode 100644 index 0000000..cdd2de2 --- /dev/null +++ b/tests/dict/data/unicode2.py @@ -0,0 +1,13 @@ +"""two unicode options +""" +from tiramisu.option import StrOption, OptionDescription + +def get_description(): + """generate description for this test + """ + option1 = StrOption('unicode1', "Unicode 1") + option2 = StrOption('unicode2', "Unicode 2") + descr1 = OptionDescription("options", "Common configuration", [option1, option2]) + descr = OptionDescription("unicode2", "Two unicodes", [descr1]) + return descr + diff --git a/tests/dict/data/unicode2_copy.json b/tests/dict/data/unicode2_copy.json new file mode 100644 index 0000000..a050efa --- /dev/null +++ b/tests/dict/data/unicode2_copy.json @@ -0,0 +1,41 @@ +{ + "schema": { + "options": { + "name": "options", + "properties": { + "options.unicode1": { + "name": "options.unicode1", + "type": "string", + "title": "Unicode 1" + }, + "options.unicode2": { + "name": "options.unicode2", + "type": "string", + "title": "Unicode 2 (copy)" + } + }, + "type": "object", + "title": "Common configuration" + } + }, + "model": {}, + "form": { + "options.unicode1": { + "type": "input", + "copy": [ + "options.unicode2" + ] + }, + "options.unicode2": { + "type": "input", + "clearable": true + }, + "null": [ + { + "title": "Configurer", + "type": "submit" + } + ] + }, + "version": "1.0" +} \ No newline at end of file diff --git a/tests/dict/data/unicode2_copy.py b/tests/dict/data/unicode2_copy.py new file mode 100644 index 0000000..3931e91 --- /dev/null +++ b/tests/dict/data/unicode2_copy.py @@ -0,0 +1,15 @@ +"""two unicode options +""" +from tiramisu.option import StrOption, OptionDescription +from tiramisu import Params, ParamOption +from tiramisu import tiramisu_copy + +def get_description(): + """generate description for this test + """ + option1 = StrOption('unicode1', "Unicode 1") + option2 = StrOption('unicode2', "Unicode 2 (copy)", callback=tiramisu_copy, callback_params=Params(ParamOption(option1))) + descr1 = OptionDescription("options", "Common configuration", [option1, option2]) + descr = OptionDescription("unicode2_copy", "First unicode copy in second unicode", [descr1]) + return descr + diff --git a/tests/dict/data/unicode2_multi_copy.json b/tests/dict/data/unicode2_multi_copy.json new file mode 100644 index 0000000..dbcd907 --- /dev/null +++ b/tests/dict/data/unicode2_multi_copy.json @@ -0,0 +1,50 @@ +{ + "schema": { + "options": { + "name": "options", + "properties": { + "options.unicode1": { + "name": "options.unicode1", + "type": "string", + "isMulti": true, + "title": "Unicode 1" + }, + "options.unicode2": { + "name": "options.unicode2", + "type": "string", + "isMulti": true, + "title": "Unicode 2" + } + }, + "type": "object", + "title": "Common configuration" + } + }, + "model": { + "options.unicode1": { + "required": true + }, + "options.unicode2": { + "required": true + } + }, + "form": { + "options.unicode1": { + "type": "input", + "copy": [ + "options.unicode2" + ] + }, + "options.unicode2": { + "type": "input", + "clearable": true + }, + "null": [ + { + "title": "Configurer", + "type": "submit" + } + ] + }, + "version": "1.0" +} \ No newline at end of file diff --git a/tests/dict/data/unicode2_multi_copy.py b/tests/dict/data/unicode2_multi_copy.py new file mode 100644 index 0000000..b1c9795 --- /dev/null +++ b/tests/dict/data/unicode2_multi_copy.py @@ -0,0 +1,15 @@ +"""two unicode options +""" +from tiramisu.option import StrOption, OptionDescription +from tiramisu import Params, ParamOption +from tiramisu import tiramisu_copy + +def get_description(): + """generate description for this test + """ + option1 = StrOption('unicode1', "Unicode 1", multi=True) + option2 = StrOption('unicode2', "Unicode 2", callback=tiramisu_copy, callback_params=Params(ParamOption(option1)), multi=True) + descr1 = OptionDescription("options", "Common configuration", [option1, option2]) + descr = OptionDescription("unicode2_multi_copy", "First multi unicode copy in second multi unicode", [descr1]) + return descr + diff --git a/tests/dict/data/unicode_hidden.json b/tests/dict/data/unicode_hidden.json new file mode 100644 index 0000000..5995b6f --- /dev/null +++ b/tests/dict/data/unicode_hidden.json @@ -0,0 +1,34 @@ +{ + "schema": { + "options": { + "name": "options", + "properties": { + "options.unicode": { + "name": "options.unicode", + "type": "string", + "title": "Unicode 1" + } + }, + "type": "object", + "title": "Common configuration" + } + }, + "model": { + "options.unicode": { + "display": false, + "hidden": true + } + }, + "form": { + "options.unicode": { + "type": "input" + }, + "null": [ + { + "title": "Configurer", + "type": "submit" + } + ] + }, + "version": "1.0" +} \ No newline at end of file diff --git a/tests/dict/data/unicode_hidden.py b/tests/dict/data/unicode_hidden.py new file mode 100644 index 0000000..7e5d515 --- /dev/null +++ b/tests/dict/data/unicode_hidden.py @@ -0,0 +1,11 @@ +"""just an unicode option +""" +from tiramisu.option import UnicodeOption, OptionDescription + +def get_description(): + """generate description for this test + """ + option = UnicodeOption('unicode', "Unicode 1", properties=('hidden',)) + descr1 = OptionDescription("options", "Common configuration", [option]) + descr = OptionDescription("unicode_hidden", "Hidden unicode", [descr1]) + return descr diff --git a/tests/dict/data/unicode_property.json b/tests/dict/data/unicode_property.json new file mode 100644 index 0000000..bfcb46c --- /dev/null +++ b/tests/dict/data/unicode_property.json @@ -0,0 +1,35 @@ +{ + "schema": { + "options": { + "name": "options", + "properties": { + "options.unicode": { + "name": "options.unicode", + "type": "string", + "title": "Expert unicode" + } + }, + "type": "object", + "title": "Common configuration" + } + }, + "model": { + "options.unicode": { + "properties": [ + "expert" + ] + } + }, + "form": { + "options.unicode": { + "type": "input" + }, + "null": [ + { + "title": "Configurer", + "type": "submit" + } + ] + }, + "version": "1.0" +} \ No newline at end of file diff --git a/tests/dict/data/unicode_property.py b/tests/dict/data/unicode_property.py new file mode 100644 index 0000000..82c5a72 --- /dev/null +++ b/tests/dict/data/unicode_property.py @@ -0,0 +1,19 @@ +"""just an unicode option +""" +from tiramisu.option import UnicodeOption, OptionDescription + +def get_description(): + """generate description for this test + """ + option = UnicodeOption('unicode', "Expert unicode", properties=('expert',)) + descr1 = OptionDescription("options", "Common configuration", [option]) + descr = OptionDescription("unicode_property", "Hidden because expert", [descr1]) + return descr + + +def get_permissives(): + return frozenset(['expert']) + + +def get_properties(): + return frozenset(['expert']) diff --git a/tests/dict/data/unicode_property_optiondescription.json b/tests/dict/data/unicode_property_optiondescription.json new file mode 100644 index 0000000..61b2103 --- /dev/null +++ b/tests/dict/data/unicode_property_optiondescription.json @@ -0,0 +1,35 @@ +{ + "schema": { + "options": { + "name": "options", + "properties": { + "options.unicode": { + "name": "options.unicode", + "type": "string", + "title": "Expert unicode" + } + }, + "type": "object", + "title": "Common configuration" + } + }, + "model": { + "options": { + "properties": [ + "expert" + ] + } + }, + "form": { + "options.unicode": { + "type": "input" + }, + "null": [ + { + "title": "Configurer", + "type": "submit" + } + ] + }, + "version": "1.0" +} \ No newline at end of file diff --git a/tests/dict/data/unicode_property_optiondescription.py b/tests/dict/data/unicode_property_optiondescription.py new file mode 100644 index 0000000..e56063f --- /dev/null +++ b/tests/dict/data/unicode_property_optiondescription.py @@ -0,0 +1,19 @@ +"""just an unicode option +""" +from tiramisu.option import UnicodeOption, OptionDescription + +def get_description(): + """generate description for this test + """ + option = UnicodeOption('unicode', "Expert unicode") + descr1 = OptionDescription("options", "Common configuration", [option], properties=('expert',)) + descr = OptionDescription("unicode_property_optiondescription", "OptionDescription hidden because expert", [descr1]) + return descr + + +def get_permissives(): + return frozenset(['expert']) + + +def get_properties(): + return frozenset(['expert']) diff --git a/tests/dict/data/username1.json b/tests/dict/data/username1.json new file mode 100644 index 0000000..0d5ed95 --- /dev/null +++ b/tests/dict/data/username1.json @@ -0,0 +1,30 @@ +{ + "schema": { + "options": { + "name": "options", + "properties": { + "options.username": { + "name": "options.username", + "type": "username", + "title": "Username description" + } + }, + "type": "object", + "title": "Common configuration" + } + }, + "model": {}, + "form": { + "options.username": { + "pattern": "^[a-z_][a-z0-9_-]{0,30}[$a-z0-9_-]{0,1}$", + "type": "input" + }, + "null": [ + { + "title": "Configurer", + "type": "submit" + } + ] + }, + "version": "1.0" +} \ No newline at end of file diff --git a/tests/dict/data/username1.py b/tests/dict/data/username1.py new file mode 100644 index 0000000..942b48c --- /dev/null +++ b/tests/dict/data/username1.py @@ -0,0 +1,9 @@ +from tiramisu.option import UsernameOption, OptionDescription + +def get_description(): + """generate description for this test + """ + option = UsernameOption('username', "Username description") + descr1 = OptionDescription("options", "Common configuration", [option]) + descr = OptionDescription("username1", "Simple username", [descr1]) + return descr diff --git a/tests/dict/data/username1_frozen.json b/tests/dict/data/username1_frozen.json new file mode 100644 index 0000000..b1828e2 --- /dev/null +++ b/tests/dict/data/username1_frozen.json @@ -0,0 +1,34 @@ +{ + "schema": { + "options": { + "name": "options", + "properties": { + "options.username": { + "name": "options.username", + "type": "username", + "title": "Username description frozen" + } + }, + "type": "object", + "title": "Common configuration" + } + }, + "model": { + "options.username": { + "readOnly": true + } + }, + "form": { + "options.username": { + "pattern": "^[a-z_][a-z0-9_-]{0,30}[$a-z0-9_-]{0,1}$", + "type": "input" + }, + "null": [ + { + "title": "Configurer", + "type": "submit" + } + ] + }, + "version": "1.0" +} \ No newline at end of file diff --git a/tests/dict/data/username1_frozen.py b/tests/dict/data/username1_frozen.py new file mode 100644 index 0000000..2b7a7c9 --- /dev/null +++ b/tests/dict/data/username1_frozen.py @@ -0,0 +1,9 @@ +from tiramisu.option import UsernameOption, OptionDescription + +def get_description(): + """generate description for this test + """ + option = UsernameOption('username', "Username description frozen", properties=('frozen',)) + descr1 = OptionDescription("options", "Common configuration", [option]) + descr = OptionDescription("username1_frozen", "Simple username", [descr1]) + return descr diff --git a/tests/dict/test_json.py b/tests/dict/test_json.py new file mode 100644 index 0000000..566340c --- /dev/null +++ b/tests/dict/test_json.py @@ -0,0 +1,347 @@ +# -*- coding: utf-8 -*- +from json import loads, dumps, dump +from os import listdir +from os.path import dirname, abspath, join, normpath, splitext, isfile +import sys +import warnings + +from tiramisu import OptionDescription, Config +from tiramisu.error import ValueWarning +from tests.dict.data.unicode1_leadership_value import get_description as get_description_unicode1_leadership_value, \ + get_values as get_values_unicode1_leadership_value + + +warnings.simplefilter("always", ValueWarning) + + +def datapath(): + path_ = join(normpath(dirname(abspath(__file__))), 'data') + if path_ not in sys.path: + sys.path.insert(1, path_) + return path_ + + +def list_data(ext='.py'): + # return ['unicode1_leader_hidden_followers.py'] + datadir = datapath() + filenames = listdir(datadir) + filenames.sort() + ret = [] + for filename in filenames: + if filename.endswith(ext) and not filename.startswith('__'): + ret.append(filename) + return ret + + +def load_config(filename, + add_extra_od=False, + remote='minimum', + clearable='minimum', + root=None): + modulepath = splitext(filename)[0] + mod = __import__(modulepath) + descr = mod.get_description() + if add_extra_od: + descr = OptionDescription('root', '', [descr]) + config = Config(descr) + config.property.add('demoting_error_warning') + if 'get_values' in dir(mod): + mod.get_values(config, add_extra_od) + + form = [{'title': 'Configurer', + 'type': 'submit'}] + if 'get_form' in dir(mod): + form.extend(mod.get_form(add_extra_od)) + config.property.read_write() + if root is None: + values = loads(dumps(config.option.dict(remotable=remote, clearable=clearable, form=form))) + else: + values = loads(dumps(config.option(root).dict(remotable=remote, clearable=clearable, form=form))) + return values + + +def parse_expected(schema, all_options): + for key, value in schema['properties'].items(): + if 'properties' in value: + parse_expected(value, all_options) + else: + all_options.append(key) + + +def del_property(expected, prop): + new_form = {} + for key, form in expected['form'].items(): + if prop in form: + del form[prop] + if form: + new_form[key] = form + return new_form + + +def add_property(expected, prop, prop_value): + all_options = [] + all_descroptions = [] + for key, root in expected['schema'].items(): + if 'properties' in root: + parse_expected(root, all_options) + all_descroptions.append(key) + else: + all_options.append(key) + + all_options.extend(all_descroptions) + ordered_options = all_options.copy() + new_form = {} + buttons = [] + for key, form in expected['form'].items(): + if key == 'null': + # for button + buttons = form + else: + if 'collapse' not in form.keys(): + form[prop] = prop_value + all_options.remove(key) + new_form[key] = form + for option in all_options: + if option not in all_descroptions: + new_form[option] = {prop: prop_value} + ordered_form = {} + for key in ordered_options: + if key in new_form: + ordered_form[key] = new_form[key] + ordered_form['null'] = buttons + return ordered_form + + +def test_jsons(): + debug = False + # debug = True + datadir = datapath() + if debug: + print() + # for clearable in ['minimum']: + for clearable in ['minimum', 'none', 'all']: + if debug: + print('==> clearable', clearable) + # for remote in ['all']: + for remote in ['minimum', 'none', 'all']: + if debug: + print(' ==> remotable', remote) + filenames = list_data() + for filename in filenames: + modulepath = splitext(filename)[0] + if debug: + print(" {} (remote: {}, clearable: {})".format(filename, remote, clearable)) + values = load_config(filename, + remote=remote, + clearable=clearable) + # + if not isfile(join(datadir, modulepath + '.json')) and \ + clearable == 'minimum' and \ + remote == 'minimum': + with open(join(datadir, modulepath + '.json'), 'w') as fh: + dump(values, fh, indent=2) + with open(join(datadir, modulepath + '.json'), 'r') as fh: + expected = loads(fh.read()) + if clearable == 'none': + expected['form'] = del_property(expected, 'clearable') + if remote == 'none' and 'tiramisu' in expected: + del expected['tiramisu'] + if clearable == 'all': + expected['form'] = add_property(expected, 'clearable', True) + if remote == 'all': + expected['form'] = add_property(expected, 'remote', True) + new_expected = {} + for key, form in expected['form'].items(): + if key != 'null' and form.get('remote', False): + if 'dependencies' in form: + del form['dependencies'] + if 'copy' in form: + del form['copy'] + if 'not_equal' in form: + del form['not_equal'] + new_expected[key] = form + expected['form'] = new_expected + + # properties are unordered + for model in expected['model']: + if 'properties' in model: + model['properties'] = set(model['properties']) + for model in values['model']: + if 'properties' in model: + model['properties'] = set(model['properties']) + if debug: + from pprint import pprint + pprint(values) + print('----------------') + pprint(expected) + assert values == expected, "error in file {}".format(filename) + + +def test_jsons_subconfig(): + debug = False + # debug = True + datadir = datapath() + if debug: + print() + filenames = list_data() + for filename in filenames: + modulepath = splitext(filename)[0] + if debug: + print(" ", filename) + values = load_config(filename, add_extra_od=True, root=modulepath) + # + with open(join(datadir, modulepath + '.json'), 'r') as fh: + expected = loads(fh.read()) + # properties are unordered + for model in expected['model'].values(): + if 'properties' in model: + model['properties'] = set(model['properties']) + for model in values['model'].values(): + if 'properties' in model: + model['properties'] = set(model['properties']) + # add root + + def change_key(schema): + new_schema = {} + for key_schema, val_schema in schema.items(): + key = modulepath + '.' + key_schema + val_schema['name'] = key + if 'properties' in val_schema: + val_schema['properties'] = change_key(val_schema['properties']) + new_schema[key] = val_schema + return new_schema + + expected['schema'] = change_key(expected['schema']) + new_form_all = {} + for key, form in expected['form'].items(): + if key != 'null': + key = modulepath + '.' + key + new_form_all[key] = form + if 'copy' in form: + for idx, noteq in enumerate(form['copy']): + form['copy'][idx] = modulepath + '.' + noteq + if 'not_equal' in form: + new_form = [] + for noteq in form['not_equal']['options']: + new_form.append(modulepath + '.' + noteq) + form['not_equal']['options'] = new_form + if 'dependencies' in form: + for dependency in form['dependencies'].values(): + for val1 in dependency.values(): + if isinstance(val1, list): + for idx, lst in enumerate(val1): + val1[idx] = modulepath + '.' + lst + else: + for val2 in val1.values(): + if isinstance(val2, list): + for idx, lst in enumerate(val2): + val2[idx] = modulepath + '.' + lst + + expected['form'] = new_form_all + new_model = {} + for key, model in expected['model'].items(): + new_model[modulepath + '.' + key] = model + expected['model'] = new_model + if debug: + from pprint import pprint + pprint(values) + print('----------------') + pprint(expected) + assert values == expected, "error in file {}".format(filename) + + +def test_updates(): + debug = False + # debug = True + datadir = datapath() + idx = 0 + while True: + idx += 1 + list_files = list_data('.mod{}'.format(idx)) + if not list_files: + break + for filename in list_files: + if debug: + print("test/data/" + filename) + for issub in [False, True]: + modulepath = splitext(filename)[0] + mod = __import__(modulepath) + descr = mod.get_description() + if issub: + descr = OptionDescription('root', '', [descr]) + root = modulepath + else: + root = None + # dict before modification + with open(join(datadir, modulepath + '.dict'), 'r') as fh: + dico_ori = loads(fh.read()) + if issub: + new_dico_ori = {} + for key, value in dico_ori.items(): + key = modulepath + '.' + key + new_dico_ori[key] = value + dico_ori = new_dico_ori + # modify config + with open(join(datadir, modulepath + '.mod{}'.format(idx)), 'r') as fh: + body = loads(fh.read())['body'] + if issub: + for value in body['updates']: + value['name'] = modulepath + '.' + value['name'] + # returns of set_updates + with open(join(datadir, modulepath + '.updates{}'.format(idx)), 'r') as fh: + values = loads(fh.read()) + if issub: + for lidx, key in enumerate(values['updates']): + values['updates'][lidx] = modulepath + '.' + key + if 'model' in values: + new_model = {} + for key, value in values['model'].items(): + new_model[modulepath + '.' + key] = value + values['model'] = new_model + # dict after modification + with open(join(datadir, modulepath + '.dict{}'.format(idx)), 'r') as fh: + dico_mod = loads(fh.read()) + if issub: + new_dico = {} + for key, value in dico_mod.items(): + key = modulepath + '.' + key + new_dico[key] = value + dico_mod = new_dico + if root is None: + root_path = '' + else: + root_path = '{}.'.format(root) + for clearable in ['none', 'minimum', 'all']: + for remote in ['none', 'minimum', 'all']: + if debug: + print(" (remote: {}, clearable: {}, issub {}, root {}, root_path {})".format(remote, clearable, issub, root, root_path)) + for with_model in [False, True]: + config = Config(descr) + config.property.add('demoting_error_warning') + if 'get_values' in dir(mod): + mod.get_values(config, issub) + if isfile(join(datadir, modulepath + '.mod')): + with open(join(datadir, modulepath + '.mod'), 'r') as fh: + eval(fh.read()) + assert config.value.dict() == dico_ori, "clearable {}, remote: {}, filename: {}".format(clearable, remote, filename) + if root is None: + suboption = config.option + else: + suboption = config.option(root) + if with_model: + bodym = body.copy() + bodym['model'] = loads(dumps(suboption.dict(remotable=remote, clearable=clearable)))['model'] + else: + suboption.dict(remotable=remote, clearable=clearable) + bodym = body + if with_model: + cal_values = suboption.updates(bodym) + if debug: + from pprint import pprint + pprint(cal_values) + print('------------') + pprint(values) + assert cal_values == values + else: + assert suboption.updates(bodym) is None + assert config.value.dict() == dico_mod diff --git a/tests/test_config.py b/tests/test_config.py index cacb7d6..76658a2 100644 --- a/tests/test_config.py +++ b/tests/test_config.py @@ -273,12 +273,12 @@ def test_prefix_error(): try: config.option('test1').value.set('yes') except Exception as err: - assert str(err) == '"yes" is an invalid integer for "test1"' + assert str(err) == _('"{0}" is an invalid {1} for "{2}"').format('yes', _('integer'), 'test1') try: config.option('test1').value.set('yes') except Exception as err: err.prefix = '' - assert str(err) == 'invalid value' + assert str(err) == _('invalid value') def test_no_validation(): diff --git a/tests/test_option.py b/tests/test_option.py index 585f304..d069f54 100644 --- a/tests/test_option.py +++ b/tests/test_option.py @@ -10,6 +10,7 @@ from tiramisu.error import APIError, ConfigError from tiramisu import IntOption, SymLinkOption, OptionDescription, Config from tiramisu.setting import groups from tiramisu.storage import list_sessions +from tiramisu.i18n import _ def teardown_function(function): @@ -236,7 +237,7 @@ def test_intoption(): def test_get_display_type(): i1 = IntOption('test1', 'description', min_number=3) - assert i1.get_display_type() == 'integer' + assert i1.get_display_type() == _('integer') def test_option_not_in_config(): diff --git a/tests/test_option_callback.py b/tests/test_option_callback.py index 967f10c..7686c3d 100644 --- a/tests/test_option_callback.py +++ b/tests/test_option_callback.py @@ -696,7 +696,7 @@ def test_consistency_leader_and_followers_leader_mandatory_transitive(): try: api.option('val1.val1').value.get() except PropertiesOptionError as error: - assert str(error) == str(_('cannot access to {0} "{1}" because "{2}" has {3} {4}').format('option', 'val1', 'val2', 'property', '"disabled"')) + assert str(error) == str(_('cannot access to {0} "{1}" because "{2}" has {3} {4}').format('option', 'val1', 'val2', _('property'), '"disabled"')) else: raise Exception('must raises') raises(PropertiesOptionError, "api.option('val3.val3').value.get()") diff --git a/tests/test_option_consistency.py b/tests/test_option_consistency.py index 9097997..f79ffa7 100644 --- a/tests/test_option_consistency.py +++ b/tests/test_option_consistency.py @@ -11,6 +11,7 @@ from tiramisu.error import ConfigError, ValueWarning, PropertiesOptionError from tiramisu.api import TIRAMISU_VERSION import warnings from tiramisu.storage import list_sessions +from tiramisu.i18n import _ def teardown_function(function): @@ -98,12 +99,12 @@ def test_consistency_error_prefix(): try: api.option('b').value.set(1) except Exception as err: - assert str(err) == '"1" is an invalid integer for "b", must be different from the value of "a"' + assert str(err) == _('"{0}" is an invalid {1} for "{2}"').format('1', _('integer'), 'b') + ', ' + _('must be different from the value of "{}"').format('a') try: api.option('b').value.set(1) except Exception as err: err.prefix = '' - assert str(err) == 'must be different from the value of "a"' + assert str(err) == _('must be different from the value of "{}"').format('a') def test_consistency_warnings_only_option(): diff --git a/tests/test_option_setting.py b/tests/test_option_setting.py index 209f829..c8355aa 100644 --- a/tests/test_option_setting.py +++ b/tests/test_option_setting.py @@ -591,7 +591,7 @@ def test_set_modified_value(): def test_pprint(): msg_error = _("cannot access to {0} \"{1}\" because has {2} {3}") msg_is_not = _('the value of "{0}" is not {1}') - msg_is = _('the value of "{0}" is "{1}"') + msg_is = _('the value of "{0}" is {1}') properties = _('properties') prop = _('property') @@ -621,7 +621,7 @@ def test_pprint(): except PropertiesOptionError as error: err = error - list_disabled = '"disabled" (' + display_list([msg_is.format('Test int option', '1'), msg_is.format('string2', 'string')]) + ')' + list_disabled = '"disabled" (' + display_list([msg_is.format('Test int option', '"1"'), msg_is.format('string2', '"string"')]) + ')' list_hidden = '"hidden" (' + msg_is_not.format('Test int option', display_list([2, 3, 4], 'or', add_quote=True)) + ')' assert str(err) == _(msg_error.format('option', 'Test string option', properties, display_list([list_disabled, list_hidden]))) del err @@ -632,7 +632,7 @@ def test_pprint(): except PropertiesOptionError as error: err = error - assert str(err) == msg_error.format('optiondescription', 'options', prop, '"hidden" (' + msg_is.format('Test int option', 1) + ')') + assert str(err) == msg_error.format('optiondescription', 'options', prop, '"hidden" (' + msg_is.format('Test int option', '"1"') + ')') #err = None #try: diff --git a/tests/test_option_validator.py b/tests/test_option_validator.py index 6d5e47c..cd5e078 100644 --- a/tests/test_option_validator.py +++ b/tests/test_option_validator.py @@ -15,7 +15,7 @@ def teardown_function(function): assert list_sessions() == [], 'session list is not empty when leaving "{}"'.format(function.__name__) -msg_err = _('attention, "{0}" could be an invalid {1} for "{2}", {3}') +msg_err = _('attention, "{0}" could be an invalid {1} for "{2}"') def return_true(value, param=None): @@ -112,7 +112,7 @@ def test_validator(): try: api.option('opt2').value.set('val') except ValueError as err: - msg = _('"{0}" is an invalid {1} for "{2}", {3}').format('val', _('string'), 'opt2', 'test error return_false') + msg = _('"{0}" is an invalid {1} for "{2}"').format('val', _('string'), 'opt2') + ', ' + _('test error return_false') assert str(err) == msg api.property.add('demoting_error_warning') warnings.simplefilter("always", ValueWarning) @@ -366,7 +366,7 @@ def test_validator_warning(): api.option('opt2').value.set('val') assert len(w) == 1 assert w[0].message.opt() == opt2 - assert str(w[0].message) == msg_err.format('val', opt2._display_name, 'opt2', 'test error return_false') + assert str(w[0].message) == msg_err.format('val', opt2._display_name, 'opt2') + ', ' + 'test error return_false' # with warnings.catch_warnings(record=True) as w: api.option('opt3').value.set(['val']) @@ -376,7 +376,7 @@ def test_validator_warning(): api.option('opt3').value.set(['val', 'val1']) assert len(w) == 1 assert w[0].message.opt() == opt3 - assert str(w[0].message) == msg_err.format('val1', opt3._display_name, 'opt3', 'test error') + assert str(w[0].message) == msg_err.format('val1', opt3._display_name, 'opt3') + ', ' + 'test error' # with warnings.catch_warnings(record=True) as w: raises(ValueError, "api.option('opt2').value.set(1)") @@ -387,9 +387,9 @@ def test_validator_warning(): api.option('opt3').value.set(['val', 'val1', 'val']) assert len(w) == 2 assert w[0].message.opt() == opt2 - assert str(w[0].message) == msg_err.format('val', opt2._display_name, 'opt2', 'test error return_false') + assert str(w[0].message) == msg_err.format('val', opt2._display_name, 'opt2') + ', ' + 'test error return_false' assert w[1].message.opt() == opt3 - assert str(w[1].message) == msg_err.format('val1', opt3._display_name, 'opt3', 'test error') + assert str(w[1].message) == msg_err.format('val1', opt3._display_name, 'opt3') + ', ' + 'test error' def test_validator_warning_disabled(): @@ -448,27 +448,27 @@ def test_validator_warning_leadership(): api.option('ip_admin_eth0.netmask_admin_eth0', 0).value.set('val1') assert len(w) == 1 assert w[0].message.opt() == netmask_admin_eth0 - assert str(w[0].message) == msg_err.format('val1', netmask_admin_eth0._display_name, display_name_netmask, 'test error') + assert str(w[0].message) == msg_err.format('val1', netmask_admin_eth0._display_name, display_name_netmask) + ', test error' # with warnings.catch_warnings(record=True) as w: api.option('ip_admin_eth0.ip_admin_eth0').value.set(['val']) assert len(w) == 1 assert w[0].message.opt() == ip_admin_eth0 - assert str(w[0].message) == msg_err.format('val', ip_admin_eth0._display_name, display_name_ip, 'test error return_false') + assert str(w[0].message) == msg_err.format('val', ip_admin_eth0._display_name, display_name_ip) + ', test error return_false' # with warnings.catch_warnings(record=True) as w: api.option('ip_admin_eth0.ip_admin_eth0').value.set(['val', 'val1', 'val1']) #FIXME #assert len(w) == 1 assert w[0].message.opt() == ip_admin_eth0 - assert str(w[0].message) == msg_err.format('val', ip_admin_eth0._display_name, display_name_ip, 'test error return_false') + assert str(w[0].message) == msg_err.format('val', ip_admin_eth0._display_name, display_name_ip) + ', test error return_false' # with warnings.catch_warnings(record=True) as w: api.option('ip_admin_eth0.ip_admin_eth0').value.set(['val1', 'val', 'val1']) #FIXME #assert len(w) == 1 assert w[0].message.opt() == ip_admin_eth0 - assert str(w[0].message) == msg_err.format('val', ip_admin_eth0._display_name, display_name_ip, 'test error return_false') + assert str(w[0].message) == msg_err.format('val', ip_admin_eth0._display_name, display_name_ip) + ', test error return_false' # warnings.resetwarnings() with warnings.catch_warnings(record=True) as w: @@ -476,7 +476,7 @@ def test_validator_warning_leadership(): #FIXME #assert len(w) == 1 assert w[0].message.opt() == ip_admin_eth0 - assert str(w[0].message) == msg_err.format('val', ip_admin_eth0._display_name, display_name_ip, 'test error return_false') + assert str(w[0].message) == msg_err.format('val', ip_admin_eth0._display_name, display_name_ip) + ', test error return_false' def test_validator_follower_param(): diff --git a/tests/test_requires.py b/tests/test_requires.py index 45f9350..18fbfae 100644 --- a/tests/test_requires.py +++ b/tests/test_requires.py @@ -194,9 +194,9 @@ def test_requires_same_action(): except PropertiesOptionError as err: props = err.proptype submsg = '"disabled" (' + _('the value of "{0}" is {1}').format('activate_service', '"False"') + ')' - assert str(err) == str(_('cannot access to {0} "{1}" because has {2} {3}').format('option', 'ip_address_service_web', 'property', submsg)) + assert str(err) == str(_('cannot access to {0} "{1}" because has {2} {3}').format('option', 'ip_address_service_web', _('property'), submsg)) #access to cache - assert str(err) == str(_('cannot access to {0} "{1}" because has {2} {3}').format('option', 'ip_address_service_web', 'property', submsg)) + assert str(err) == str(_('cannot access to {0} "{1}" because has {2} {3}').format('option', 'ip_address_service_web', _('property'), submsg)) assert frozenset(props) == frozenset(['disabled']) @@ -232,9 +232,9 @@ def test_requires_same_action_callback(): except PropertiesOptionError as err: props = err.proptype submsg = '"disabled" (' + _('the calculated value is {0}').format('"False"') + ')' - assert str(err) == str(_('cannot access to {0} "{1}" because has {2} {3}').format('option', 'ip_address_service_web', 'property', submsg)) + assert str(err) == str(_('cannot access to {0} "{1}" because has {2} {3}').format('option', 'ip_address_service_web', _('property'), submsg)) #access to cache - assert str(err) == str(_('cannot access to {0} "{1}" because has {2} {3}').format('option', 'ip_address_service_web', 'property', submsg)) + assert str(err) == str(_('cannot access to {0} "{1}" because has {2} {3}').format('option', 'ip_address_service_web', _('property'), submsg)) assert frozenset(props) == frozenset(['disabled']) @@ -558,7 +558,7 @@ def test_requires_transitive_hidden_disabled_multiple(): except RequirementError as err: req = err assert req, "ip_address_service_web should raise RequirementError" - assert str(req) == str(_('cannot access to option "{}" because required option "{}" has {} {}').format('ip_address_service_web', 'activate_service_web', 'property', '"disabled"')) + assert str(req) == str(_('cannot access to option "{0}" because required option "{1}" has {2} {3}').format('ip_address_service_web', 'activate_service_web', _('property'), '"disabled"')) del req # api.permissive.set(frozenset()) @@ -567,7 +567,7 @@ def test_requires_transitive_hidden_disabled_multiple(): except RequirementError as err: req = err assert req, "ip_address_service_web should raise RequirementError" - assert str(req) == str(_('cannot access to option "{}" because required option "{}" has {} {}').format('ip_address_service_web', 'activate_service_web', 'properties', '"disabled" and "hidden"')) + assert str(req) == str(_('cannot access to option "{0}" because required option "{1}" has {2} {3}').format('ip_address_service_web', 'activate_service_web', _('properties'), '"disabled" {} "hidden"'.format(_('and')))) del req diff --git a/tiramisu/api.py b/tiramisu/api.py index 1399f1d..fd66d2e 100644 --- a/tiramisu/api.py +++ b/tiramisu/api.py @@ -25,6 +25,7 @@ from .setting import ConfigBag, OptionBag, owners, groups, Undefined, undefined, FORBIDDEN_SET_PROPERTIES, SPECIAL_PROPERTIES, EXPIRATION_TIME from .config import KernelConfig, SubConfig, KernelGroupConfig, KernelMetaConfig, KernelMixConfig from .option import ChoiceOption, OptionDescription +from .todict import TiramisuDict TIRAMISU_VERSION = 3 @@ -626,6 +627,7 @@ class _TiramisuOption(CommonTiramisu): self._option_bag.path = self._path self._option_bag.index = self._index self._option_bag.config_bag = self._config_bag + self._tiramisu_dict = None if not self._registers: _registers(self._registers, 'TiramisuOption') @@ -728,6 +730,29 @@ class _TiramisuOptionDescription(_TiramisuOption): subconfig, self._config_bag) + def dict(self, + clearable: str="all", + remotable: str="minimum", + form: List=[]) -> Dict: + """convert config and option to tiramisu format""" + if self._tiramisu_dict is None: + option = self._get_option() + name = option.impl_getname() + root = self._subconfig._get_subpath(name) + config = self._config_bag.context + self._tiramisu_dict = TiramisuDict(Config(self._config_bag.context), + root=root, + clearable=clearable, + remotable=remotable) + return self._tiramisu_dict.todict(form) + + def updates(self, + body: List) -> Dict: + """updates value with tiramisu format""" + if self._tiramisu_dict is None: + raise APIError(_('please use .dict() before .updates()')) + return self._tiramisu_dict.set_updates(body) + class TiramisuOption(CommonTiramisuOption): """Manage selected option""" @@ -1060,6 +1085,11 @@ class TiramisuContextPermissive(TiramisuContext): class TiramisuContextOption(TiramisuContext): + def __init__(self, + *args, + **kwargs) -> None: + self._tiramisu_dict = None + super().__init__(*args, **kwargs) def _find(self, name, @@ -1159,6 +1189,25 @@ class TiramisuContextOption(TiramisuContext): config_bag.context): yield toption + def dict(self, + clearable="all", + remotable="minimum", + form=[]): + """convert config and option to tiramisu format""" + if self._tiramisu_dict is None: + self._tiramisu_dict = TiramisuDict(Config(self._config_bag.context), + root=None, + clearable=clearable, + remotable=remotable) + return self._tiramisu_dict.todict(form) + + def updates(self, + body: List) -> Dict: + """updates value with tiramisu format""" + if self._tiramisu_dict is None: + raise APIError(_('please use .dict() before .updates()')) + return self._tiramisu_dict.set_updates(body) + class _TiramisuContextConfigReset(): def reset(self): diff --git a/tiramisu/locale/fr/LC_MESSAGES/tiramisu.po b/tiramisu/locale/fr/LC_MESSAGES/tiramisu.po index 4f2a07c..f4d3684 100644 --- a/tiramisu/locale/fr/LC_MESSAGES/tiramisu.po +++ b/tiramisu/locale/fr/LC_MESSAGES/tiramisu.po @@ -2,7 +2,7 @@ msgid "" msgstr "" "Project-Id-Version: Tiramisu\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2019-03-05 08:46+CET\n" +"POT-Creation-Date: 2019-04-08 08:41+CEST\n" "PO-Revision-Date: \n" "Last-Translator: Emmanuel Garette \n" "Language-Team: Tiramisu's team \n" @@ -14,74 +14,78 @@ msgstr "" "Plural-Forms: nplurals=2; plural=(n > 1);\n" "X-Poedit-SourceCharset: UTF-8\n" -#: tiramisu/api.py:58 +#: tiramisu/api.py:59 msgid "Settings:" msgstr "Paramètres :" -#: tiramisu/api.py:59 +#: tiramisu/api.py:60 msgid "Access to option without verifying permissive properties" msgstr "Accès à une option sans vérifié les propriétés permises" -#: tiramisu/api.py:60 +#: tiramisu/api.py:61 msgid "Access to option without property restriction" msgstr "Accès à une option sans restriction de propriété" -#: tiramisu/api.py:64 +#: tiramisu/api.py:65 msgid "Call: {}" msgstr "Appel : {}" -#: tiramisu/api.py:66 +#: tiramisu/api.py:67 msgid "Commands:" msgstr "Commandes :" -#: tiramisu/api.py:103 +#: tiramisu/api.py:104 msgid "" "index \"{}\" is higher than the leadership length \"{}\" for option \"{}\"" msgstr "" "l'index \"{}\" est supérieur à la longueur de l'option leadership \"{}\" " "pour l'option \"{}\"" -#: tiramisu/api.py:108 +#: tiramisu/api.py:109 msgid "option must not be an optiondescription" msgstr "option ne doit pas être une optiondescription" -#: tiramisu/api.py:135 +#: tiramisu/api.py:136 msgid "index must be set with the follower option \"{}\"" msgstr "l'index est obligatoire pour l'option suiveuse \"{}\"" -#: tiramisu/api.py:138 +#: tiramisu/api.py:139 msgid "unknown method {}" msgstr "méthode {} inconnue" -#: tiramisu/api.py:360 +#: tiramisu/api.py:361 msgid "cannot add this property: \"{0}\"" msgstr "ne peut pas ajouter cette propriété : \"{0}\"" -#: tiramisu/api.py:503 tiramisu/config.py:252 +#: tiramisu/api.py:505 tiramisu/config.py:252 msgid "can't delete a SymLinkOption" msgstr "ne peut supprimer une valeur à une SymLinkOption" -#: tiramisu/api.py:636 tiramisu/api.py:1322 +#: tiramisu/api.py:639 tiramisu/api.py:1375 msgid "please specify a valid sub function ({})" msgstr "veuillez spécifier une sous fonction valide ({})" -#: tiramisu/api.py:699 tiramisu/api.py:1145 +#: tiramisu/api.py:702 tiramisu/api.py:1176 msgid "unknown list type {}" msgstr "type de liste inconnue {}" -#: tiramisu/api.py:701 tiramisu/api.py:1147 +#: tiramisu/api.py:704 tiramisu/api.py:1178 msgid "unknown group_type: {0}" msgstr "group_type inconnu: {0}" -#: tiramisu/api.py:974 +#: tiramisu/api.py:753 tiramisu/api.py:1208 +msgid "please use .dict() before .updates()" +msgstr "faire .dico() avant .updates()" + +#: tiramisu/api.py:1000 msgid "properties must be a set" msgstr "une propriété doit être de type set" -#: tiramisu/api.py:980 tiramisu/api.py:1002 +#: tiramisu/api.py:1006 tiramisu/api.py:1028 msgid "unknown when {} (must be in append or remove)" msgstr "value {} inconsistent (doit être append ou remove)" -#: tiramisu/api.py:992 tiramisu/api.py:1014 tiramisu/config.py:1227 +#: tiramisu/api.py:1018 tiramisu/api.py:1040 tiramisu/config.py:1249 msgid "unknown type {}" msgstr "type inconnu {}" @@ -191,9 +195,9 @@ msgstr "le nom d'un config doit être unique dans un groupconfig pour \"{0}\"" msgid "unknown config \"{}\"" msgstr "config \"{}\" inconnue" -#: tiramisu/config.py:987 tiramisu/config.py:1202 +#: tiramisu/config.py:987 tiramisu/config.py:1224 msgid "{}config's children should be config, not {}" -msgstr "enfants d'un {}config doit être une config, pas {0}" +msgstr "enfants d'un {}config doit être une config, pas {}" #: tiramisu/config.py:992 msgid "child must be a Config, MixConfig or MetaConfig" @@ -216,27 +220,38 @@ msgid "force_default and force_dont_change_value cannot be set together" msgstr "" "force_default et force_dont_change_value ne peuvent pas être mis ensemble" -#: tiramisu/config.py:1189 +#: tiramisu/config.py:1176 +msgid "config is already in a metaconfig" +msgstr "la config est déjà dans une metaconfig" + +#: tiramisu/config.py:1178 tiramisu/config.py:1247 +msgid "config name must be uniq in groupconfig for {0}" +msgstr "le nom de la config doit être unique dans un groupconfig pour {0}" + +#: tiramisu/config.py:1192 +msgid "cannot find the config {}" +msgstr "ne peut pas trouver la config {0}" + +#: tiramisu/config.py:1211 msgid "MetaConfig with optiondescription must have string has child, not {}" msgstr "" "MetaConfig avec une optiondescription doit avoir un nom comme enfant, pas {}" -#: tiramisu/config.py:1208 +#: tiramisu/config.py:1230 msgid "child must be a Config or MetaConfig" msgstr "enfant doit être une une Config ou une MetaConfig" -#: tiramisu/config.py:1212 +#: tiramisu/config.py:1234 msgid "all config in metaconfig must have the same optiondescription" msgstr "" "toutes les configs d'une metaconfig doivent avoir la même optiondescription" -#: tiramisu/config.py:1225 -msgid "config name must be uniq in groupconfig for {0}" -msgstr "le nom de la config doit être unique dans un groupconfig pour {0}" - -#: tiramisu/config.py:1250 -msgid "cannot find the config {}" -msgstr "ne peut pas trouver la config {0}" +#: tiramisu/config.py:1272 +#, fuzzy +#| msgid "all config in metaconfig must have the same optiondescription" +msgid "metaconfig must have the same optiondescription" +msgstr "" +"toutes les configs d'une metaconfig doivent avoir la même optiondescription" #: tiramisu/error.py:24 msgid "and" @@ -250,11 +265,11 @@ msgstr "ou" msgid " {} " msgstr " {} " -#: tiramisu/error.py:103 tiramisu/setting.py:563 +#: tiramisu/error.py:103 tiramisu/setting.py:579 msgid "property" msgstr "de la propriété" -#: tiramisu/error.py:105 tiramisu/setting.py:565 +#: tiramisu/error.py:105 tiramisu/setting.py:581 msgid "properties" msgstr "des propriétés" @@ -266,38 +281,42 @@ msgstr "ne peut accéder à {0} \"{1}\" parce que \"{2}\" a {3} {4}" msgid "cannot access to {0} \"{1}\" because has {2} {3}" msgstr "ne peut accéder à l'{0} \"{1}\" a cause {2} {3}" -#: tiramisu/error.py:185 +#: tiramisu/error.py:189 msgid "invalid value" msgstr "valeur invalide" -#: tiramisu/error.py:190 +#: tiramisu/error.py:194 msgid "attention, \"{0}\" could be an invalid {1} for \"{2}\"" msgstr "attention, \"{0}\" peut être un {1} invalide pour \"{2}\"" -#: tiramisu/error.py:194 tiramisu/error.py:198 +#: tiramisu/error.py:198 tiramisu/error.py:202 msgid "\"{0}\" is an invalid {1} for \"{2}\"" msgstr "\"{0}\" est une valeur invalide pour l'option \"{2}\" de type {1}" -#: tiramisu/function.py:31 +#: tiramisu/function.py:34 msgid "args in params must be a tuple" msgstr "args dans params doit être un tuple" -#: tiramisu/function.py:34 tiramisu/function.py:39 +#: tiramisu/function.py:37 tiramisu/function.py:42 msgid "arg in params must be a Param" msgstr "arg dans params doit être un Param" -#: tiramisu/function.py:36 +#: tiramisu/function.py:39 msgid "kwargs in params must be a dict" msgstr "kwargs dans params doit être un dict" -#: tiramisu/function.py:52 +#: tiramisu/function.py:58 msgid "paramoption needs an option not {}" msgstr "paramoption doit être une option pas {0}" -#: tiramisu/function.py:58 +#: tiramisu/function.py:64 msgid "param must have a boolean not a {} for notraisepropertyerror" msgstr "param doit avoir un booléan pas un {} pour notraisepropertyerror" +#: tiramisu/function.py:271 +msgid "unexpected {} condition_operator in calc_value" +msgstr "condition_operator {} inattendue dans la fonction calc_value" + #: tiramisu/option/baseoption.py:75 tiramisu/option/symlinkoption.py:33 msgid "\"{0}\" is an invalid name for an option" msgstr "\"{0}\" est un nom invalide pour une option" @@ -328,7 +347,7 @@ msgstr "" msgid "missing those arguments \"{}\" in function \"{}\" for \"{}\"" msgstr "les arguments \"{}\" sont manquant dans la fonction \"{}\" pour \"{}\"" -#: tiramisu/option/baseoption.py:257 +#: tiramisu/option/baseoption.py:258 msgid "" "params defined for a callback function but no callback defined yet for " "option \"{0}\"" @@ -336,28 +355,28 @@ msgstr "" "paramètres définis pour la fonction de callback mais aucun callback défini " "pour l'option \"{0}\"" -#: tiramisu/option/baseoption.py:349 tiramisu/storage/dictionary/value.py:275 +#: tiramisu/option/baseoption.py:350 tiramisu/storage/dictionary/value.py:275 #: tiramisu/storage/sqlite3/value.py:201 msgid "information's item not found: {0}" msgstr "item '{0}' dans les informations non trouvée" -#: tiramisu/option/baseoption.py:362 +#: tiramisu/option/baseoption.py:363 msgid "'{0}' ({1}) object attribute '{2}' is read-only" msgstr "l'attribut {2} de l'objet '{0}' ({1}) est en lecture seule" -#: tiramisu/option/baseoption.py:393 +#: tiramisu/option/baseoption.py:394 msgid "\"{}\" ({}) object attribute \"{}\" is read-only" msgstr "\"{}\" ({}) l'attribut de l'objet \"{}\" est en lecture seule" -#: tiramisu/option/baseoption.py:403 +#: tiramisu/option/baseoption.py:404 msgid "\"{}\" not part of any Config" msgstr "\"{}\" ne fait pas parti d'une Config" -#: tiramisu/option/baseoption.py:450 +#: tiramisu/option/baseoption.py:453 msgid "malformed requirements must be an option in option {0}" msgstr "requirements mal formés doit être une option dans l'option {0}" -#: tiramisu/option/baseoption.py:453 +#: tiramisu/option/baseoption.py:456 msgid "" "malformed requirements multi option must not set as requires of non multi " "option {0}" @@ -365,59 +384,59 @@ msgstr "" "requirements mal formés une option multiple ne doit pas être spécifié comme " "pré-requis à l'option non multiple {0}" -#: tiramisu/option/baseoption.py:486 +#: tiramisu/option/baseoption.py:495 msgid "" "malformed requirements expected must have option and value for option {0}" msgstr "" "expected mal formés pour le requirements, doit avoir une option et une " "valeur pour l'option {0}" -#: tiramisu/option/baseoption.py:493 tiramisu/option/baseoption.py:509 +#: tiramisu/option/baseoption.py:502 tiramisu/option/baseoption.py:518 msgid "malformed requirements expected value must be valid for option {0}: {1}" msgstr "" "valeur de \"expected\" malformé, doit être valide pour l'option {0} : {1}" -#: tiramisu/option/baseoption.py:523 +#: tiramisu/option/baseoption.py:532 msgid "" "malformed requirements for option: {0} action cannot be force_store_value" msgstr "" "requirements mal formés pour l'option : {0} action ne peut pas être " "force_store_value" -#: tiramisu/option/baseoption.py:531 +#: tiramisu/option/baseoption.py:540 msgid "malformed requirements for option: {0} inverse must be boolean" msgstr "" "requirements mal formés pour l'option : {0} inverse doit être un booléen" -#: tiramisu/option/baseoption.py:538 +#: tiramisu/option/baseoption.py:547 msgid "malformed requirements for option: {0} transitive must be boolean" msgstr "" "requirements mal formés pour l'option : {0} transitive doit être booléen" -#: tiramisu/option/baseoption.py:545 +#: tiramisu/option/baseoption.py:554 msgid "malformed requirements for option: {0} same_action must be boolean" msgstr "" "requirements mal formés pour l'option : {0} same_action doit être un booléen" -#: tiramisu/option/baseoption.py:552 +#: tiramisu/option/baseoption.py:561 msgid "" "malformed requirements for option: \"{0}\" operator must be \"or\" or \"and\"" msgstr "" "requirements mal formés pour l'option : \"{0}\" l'opérateur doit être \"or\" " "ou \"and\"" -#: tiramisu/option/baseoption.py:564 +#: tiramisu/option/baseoption.py:574 msgid "malformed requirements type for option: {0}, must be a dict" msgstr "" "type requirements malformé pour l'option : {0}, doit être un dictionnaire" -#: tiramisu/option/baseoption.py:570 +#: tiramisu/option/baseoption.py:580 msgid "malformed requirements for option: {0} unknown keys {1}, must only {2}" msgstr "" "requirements mal formés pour l'option : {0} clefs inconnues {1}, doit " "seulement avoir {2}" -#: tiramisu/option/baseoption.py:579 +#: tiramisu/option/baseoption.py:592 msgid "" "malformed requirements for option: {0} require must have option, expected " "and action keys" @@ -425,56 +444,56 @@ msgstr "" "requirements malformé pour l'option : {0} l'exigence doit avoir les clefs " "option, expected et action" -#: tiramisu/option/booloption.py:30 +#: tiramisu/option/booloption.py:31 msgid "boolean" msgstr "booléen" -#: tiramisu/option/broadcastoption.py:31 +#: tiramisu/option/broadcastoption.py:32 msgid "broadcast address" msgstr "adresse broadcast" -#: tiramisu/option/broadcastoption.py:38 tiramisu/option/dateoption.py:37 -#: tiramisu/option/domainnameoption.py:113 tiramisu/option/ipoption.py:77 -#: tiramisu/option/netmaskoption.py:41 tiramisu/option/networkoption.py:67 -#: tiramisu/option/passwordoption.py:38 tiramisu/option/portoption.py:106 -#: tiramisu/option/urloption.py:40 +#: tiramisu/option/broadcastoption.py:39 tiramisu/option/dateoption.py:38 +#: tiramisu/option/domainnameoption.py:118 tiramisu/option/ipoption.py:83 +#: tiramisu/option/netmaskoption.py:42 tiramisu/option/networkoption.py:68 +#: tiramisu/option/passwordoption.py:39 tiramisu/option/portoption.py:107 +#: tiramisu/option/urloption.py:41 msgid "invalid string" msgstr "invalide caractère" -#: tiramisu/option/broadcastoption.py:56 +#: tiramisu/option/broadcastoption.py:57 msgid "invalid len for vals" msgstr "longueur invalide pour vals" -#: tiramisu/option/broadcastoption.py:61 +#: tiramisu/option/broadcastoption.py:62 msgid "broadcast \"{4}\" invalid with network {0}/{1} (\"{2}\"/\"{3}\")" msgstr "" "le broadcast \"{4}\" est invalide pour le réseau {0}/{1} (\"{2}\"/\"{3}\")" -#: tiramisu/option/choiceoption.py:36 +#: tiramisu/option/choiceoption.py:37 msgid "choice" msgstr "choix" -#: tiramisu/option/choiceoption.py:65 +#: tiramisu/option/choiceoption.py:66 msgid "values is not a function, so values_params must be None" msgstr "values n'est pas une fonction, donc values_params doit être None" -#: tiramisu/option/choiceoption.py:67 +#: tiramisu/option/choiceoption.py:68 msgid "values must be a tuple or a function for {0}" msgstr "values doit être un tuple ou une fonction pour {0}" -#: tiramisu/option/choiceoption.py:100 +#: tiramisu/option/choiceoption.py:101 msgid "calculated values for {0} is not a list" msgstr "valeurs calculées for {0} n'est pas une liste" -#: tiramisu/option/choiceoption.py:113 +#: tiramisu/option/choiceoption.py:114 msgid "only \"{0}\" is allowed" msgstr "seul \"{0}\" est autorisé" -#: tiramisu/option/choiceoption.py:116 +#: tiramisu/option/choiceoption.py:117 msgid "only \"{0}\" are allowed" msgstr "seul \"{0}\" sont autorisés" -#: tiramisu/option/dateoption.py:30 +#: tiramisu/option/dateoption.py:31 msgid "date" msgstr "date" @@ -482,43 +501,43 @@ msgstr "date" msgid "domain name" msgstr "nom de domaine" -#: tiramisu/option/domainnameoption.py:58 +#: tiramisu/option/domainnameoption.py:59 msgid "unknown type_ {0} for hostname" msgstr "type_ inconnu {0} pour le nom d'hôte" -#: tiramisu/option/domainnameoption.py:61 +#: tiramisu/option/domainnameoption.py:62 msgid "allow_ip must be a boolean" msgstr "allow_ip doit être un booléen" -#: tiramisu/option/domainnameoption.py:63 +#: tiramisu/option/domainnameoption.py:64 msgid "allow_without_dot must be a boolean" msgstr "allow_without_dot doit être un booléen" -#: tiramisu/option/domainnameoption.py:107 +#: tiramisu/option/domainnameoption.py:112 msgid "invalid length (min 1)" msgstr "longueur invalide (min 1)" -#: tiramisu/option/domainnameoption.py:109 +#: tiramisu/option/domainnameoption.py:114 msgid "invalid length (max {0})" msgstr "longueur invalide (max {0})" -#: tiramisu/option/domainnameoption.py:121 +#: tiramisu/option/domainnameoption.py:125 msgid "must not be an IP" msgstr "ne doit pas être une IP" -#: tiramisu/option/domainnameoption.py:125 +#: tiramisu/option/domainnameoption.py:131 msgid "must have dot" msgstr "doit avec un point" -#: tiramisu/option/domainnameoption.py:127 +#: tiramisu/option/domainnameoption.py:133 msgid "invalid length (max 255)" msgstr "longueur invalide (max 255)" -#: tiramisu/option/domainnameoption.py:135 +#: tiramisu/option/domainnameoption.py:141 msgid "some characters are uppercase" msgstr "des caractères sont en majuscule" -#: tiramisu/option/domainnameoption.py:138 +#: tiramisu/option/domainnameoption.py:144 msgid "some characters may cause problems" msgstr "des caractères peuvent poser problèmes" @@ -550,63 +569,63 @@ msgstr "" "le callback de DynOptionDescription retourne une list avec plusieurs valeurs " "\"{}\"" -#: tiramisu/option/emailoption.py:31 +#: tiramisu/option/emailoption.py:32 msgid "email address" msgstr "adresse mail" -#: tiramisu/option/filenameoption.py:30 +#: tiramisu/option/filenameoption.py:31 msgid "file name" msgstr "nom de fichier" -#: tiramisu/option/floatoption.py:30 +#: tiramisu/option/floatoption.py:31 msgid "float" msgstr "nombre flottant" -#: tiramisu/option/intoption.py:30 +#: tiramisu/option/intoption.py:31 msgid "integer" msgstr "nombre" -#: tiramisu/option/intoption.py:54 +#: tiramisu/option/intoption.py:55 msgid "value must be greater than \"{0}\"" msgstr "valeur doit être supérieur à {0}" -#: tiramisu/option/intoption.py:57 +#: tiramisu/option/intoption.py:58 msgid "value must be less than \"{0}\"" msgstr "valeur doit être inférieur à \"{0}\"" -#: tiramisu/option/ipoption.py:35 +#: tiramisu/option/ipoption.py:36 msgid "IP" msgstr "IP" -#: tiramisu/option/ipoption.py:83 tiramisu/option/networkoption.py:73 +#: tiramisu/option/ipoption.py:89 tiramisu/option/networkoption.py:74 msgid "must use CIDR notation" msgstr "doit utiliser la notation CIDR" -#: tiramisu/option/ipoption.py:105 +#: tiramisu/option/ipoption.py:111 msgid "shouldn't be reserved IP" msgstr "ne devrait pas être une IP réservée" -#: tiramisu/option/ipoption.py:107 +#: tiramisu/option/ipoption.py:113 msgid "mustn't be reserved IP" msgstr "ne doit pas être une IP réservée" -#: tiramisu/option/ipoption.py:111 +#: tiramisu/option/ipoption.py:117 msgid "should be private IP" msgstr "devrait être une IP privée" -#: tiramisu/option/ipoption.py:113 +#: tiramisu/option/ipoption.py:119 msgid "must be private IP" msgstr "doit être une IP privée" -#: tiramisu/option/ipoption.py:141 +#: tiramisu/option/ipoption.py:147 msgid "\"{0}\" is not in network \"{1}\" (\"{2}\")" msgstr "\"{0}\" n'est pas dans le réseau \"{1}\" (\"{2}\")" -#: tiramisu/option/ipoption.py:157 +#: tiramisu/option/ipoption.py:163 msgid "ip_network needs an IP, a network and a netmask" msgstr "ip_network nécessite une IP, un réseau et un masque de réseau" -#: tiramisu/option/ipoption.py:163 +#: tiramisu/option/ipoption.py:169 msgid "\"{4}\" is not in network \"{0}\"/\"{1}\" (\"{2}\"/\"{3}\")" msgstr "\"{4}\" n'est pas dans le réseau \"{0}\"/\"{1}\" (\"{2}\"/\"{3}\")" @@ -657,51 +676,51 @@ msgstr "" "requirement mal formé pour l'option \"{0}\" ne doit pas être dans une " "suiveuse pour \"{1}\"" -#: tiramisu/option/netmaskoption.py:34 +#: tiramisu/option/netmaskoption.py:35 msgid "netmask address" msgstr "adresse netmask" -#: tiramisu/option/netmaskoption.py:59 +#: tiramisu/option/netmaskoption.py:60 msgid "network_netmask needs a network and a netmask" msgstr "network_netmask nécessite un réseau et un masque de réseau" -#: tiramisu/option/netmaskoption.py:68 +#: tiramisu/option/netmaskoption.py:69 msgid "with netmask \"{0}\" (\"{1}\")" msgstr "avec le masque \"{0}\" (\"{1}\")" -#: tiramisu/option/netmaskoption.py:71 +#: tiramisu/option/netmaskoption.py:72 msgid "with network \"{0}\" (\"{1}\")" msgstr "avec le réseau \"{0}\" (\"{1}\")" -#: tiramisu/option/netmaskoption.py:82 +#: tiramisu/option/netmaskoption.py:83 msgid "ip_netmask needs an IP and a netmask" msgstr "ip_netmask nécessite une IP et un masque de réseau" -#: tiramisu/option/netmaskoption.py:90 +#: tiramisu/option/netmaskoption.py:91 msgid "this is a network with netmask \"{0}\" (\"{1}\")" msgstr "c'est une adresse réseau avec le masque \"{0}\" (\"{1}\")" -#: tiramisu/option/netmaskoption.py:94 +#: tiramisu/option/netmaskoption.py:95 msgid "this is a broadcast with netmask \"{0}\" (\"{1}\")" msgstr "c'est une adresse broadcast avec le masque \"{0}\" (\"{1}\")" -#: tiramisu/option/netmaskoption.py:99 +#: tiramisu/option/netmaskoption.py:100 msgid "IP \"{0}\" (\"{1}\") is the network" msgstr "IP \"{0}\" (\"{1}\") est le réseau" -#: tiramisu/option/netmaskoption.py:103 +#: tiramisu/option/netmaskoption.py:104 msgid "IP \"{0}\" (\"{1}\") is the broadcast" msgstr "IP \"{0}\" (\"{1}\") est l'adresse de broadcast" -#: tiramisu/option/networkoption.py:31 +#: tiramisu/option/networkoption.py:32 msgid "network address" msgstr "adresse réseau" -#: tiramisu/option/networkoption.py:90 +#: tiramisu/option/networkoption.py:91 msgid "shouldn't be reserved network" msgstr "ne devrait pas être une IP réservée" -#: tiramisu/option/networkoption.py:92 +#: tiramisu/option/networkoption.py:93 msgid "mustn't be reserved network" msgstr "ne doit pas être une IP réservée" @@ -734,89 +753,89 @@ msgstr "" "la valeur de la default_multi \"{0}\" est invalide pour l'option \"{1}\", " "doit être une liste pour une submulti" -#: tiramisu/option/option.py:255 +#: tiramisu/option/option.py:259 msgid "invalid value \"{}\", this value is already in \"{}\"" msgstr "valeur invalide \"{}\", cette valeur est déjà dans \"{}\"" -#: tiramisu/option/option.py:285 +#: tiramisu/option/option.py:289 msgid "which must not be a list" msgstr "qui ne doit pas être une liste" -#: tiramisu/option/option.py:319 tiramisu/option/option.py:328 +#: tiramisu/option/option.py:323 tiramisu/option/option.py:332 msgid "which must be a list" msgstr "qui doit être une liste" -#: tiramisu/option/option.py:333 +#: tiramisu/option/option.py:337 msgid "which \"{}\" must be a list of list" msgstr "lequel \"{}\" doit être une liste de liste" -#: tiramisu/option/option.py:375 +#: tiramisu/option/option.py:379 msgid "default value not allowed if option \"{0}\" is calculated" msgstr "" "la valeur par défaut n'est pas possible si l'option \"{0}\" est calculée" -#: tiramisu/option/option.py:423 +#: tiramisu/option/option.py:427 msgid "'{0}' ({1}) cannot add consistency, option is read-only" msgstr "" "'{0}' ({1}) ne peut ajouter de consistency, l'option est en lecture seul" -#: tiramisu/option/option.py:431 +#: tiramisu/option/option.py:435 msgid "consistency {0} not available for this option" msgstr "consistency {0} non valable pour cette option" -#: tiramisu/option/option.py:438 +#: tiramisu/option/option.py:442 msgid "unknown parameter {0} in consistency" msgstr "paramètre inconnu {0} dans un test de consistance" -#: tiramisu/option/option.py:550 tiramisu/option/option.py:555 +#: tiramisu/option/option.py:554 tiramisu/option/option.py:559 msgid "cannot add consistency with submulti option" msgstr "ne peut ajouter de test de consistence a une option submulti" -#: tiramisu/option/option.py:556 +#: tiramisu/option/option.py:560 msgid "consistency must be set with an option, not {}" msgstr "" "test de consistence doit être renseigné avec une option, et non avec {}" -#: tiramisu/option/option.py:559 tiramisu/option/option.py:567 +#: tiramisu/option/option.py:563 tiramisu/option/option.py:571 msgid "" "almost one option in consistency is in a dynoptiondescription but not all" msgstr "" "au moins une option dans le test de consistance est dans une " "dynoptiondescription mais pas toutes" -#: tiramisu/option/option.py:563 +#: tiramisu/option/option.py:567 msgid "option in consistency must be in same dynoptiondescription" msgstr "" "option dans une consistency doit être dans le même dynoptiondescription" -#: tiramisu/option/option.py:570 +#: tiramisu/option/option.py:574 msgid "cannot add consistency with itself" msgstr "ne peut ajouter une consistency avec lui même" -#: tiramisu/option/option.py:572 +#: tiramisu/option/option.py:576 msgid "every options in consistency must be multi or none" msgstr "" "toutes les options d'une consistency doivent être multi ou ne pas l'être" -#: tiramisu/option/option.py:612 +#: tiramisu/option/option.py:616 msgid "unexpected length of \"{}\" in constency \"{}\", should be \"{}\"" msgstr "" "longueur inconsistante pour \"{}\" dans le test de consistence \"{}\", " "devrait être \"{}\"" -#: tiramisu/option/option.py:712 +#: tiramisu/option/option.py:716 msgid "should be different from the value of \"{}\"" msgstr "devrait être différent de la valeur de \"{}\"" -#: tiramisu/option/option.py:714 +#: tiramisu/option/option.py:718 msgid "must be different from the value of \"{}\"" msgstr "doit être différent de la valeur de \"{}\"" -#: tiramisu/option/option.py:717 +#: tiramisu/option/option.py:721 msgid "value for {} should be different" msgstr "valeur pour {} devrait être différent" -#: tiramisu/option/option.py:719 +#: tiramisu/option/option.py:723 msgid "value for {} must be different" msgstr "valeur pour {} doit être différent" @@ -835,7 +854,7 @@ msgstr "" msgid "the dynoption \"{0}\" cannot have \"force_store_value\" property" msgstr "la dynoption \"{0}\" ne peut avoir la propriété \"force_store_value\"" -#: tiramisu/option/optiondescription.py:97 tiramisu/setting.py:643 +#: tiramisu/option/optiondescription.py:97 tiramisu/setting.py:665 msgid "" "a leader ({0}) cannot have \"force_default_on_freeze\" or " "\"force_metaconfig_on_freeze\" property without \"frozen\"" @@ -910,35 +929,35 @@ msgstr "ne peut changer group_type si déjà spécifié (ancien {0}, nouveau {1} msgid "group_type: {0} not allowed" msgstr "group_type : {0} non autorisé" -#: tiramisu/option/passwordoption.py:31 +#: tiramisu/option/passwordoption.py:32 msgid "password" msgstr "mot de passe" -#: tiramisu/option/portoption.py:43 +#: tiramisu/option/portoption.py:44 msgid "port" msgstr "port" -#: tiramisu/option/portoption.py:80 +#: tiramisu/option/portoption.py:81 msgid "inconsistency in allowed range" msgstr "inconsistence dans la plage autorisée" -#: tiramisu/option/portoption.py:85 +#: tiramisu/option/portoption.py:86 msgid "max value is empty" msgstr "la valeur maximum est vide" -#: tiramisu/option/portoption.py:110 +#: tiramisu/option/portoption.py:111 msgid "range must have two values only" msgstr "un rang doit avoir deux valeurs seulement" -#: tiramisu/option/portoption.py:112 +#: tiramisu/option/portoption.py:113 msgid "first port in range must be smaller than the second one" msgstr "le premier port d'un rang doit être plus petit que le second" -#: tiramisu/option/portoption.py:122 +#: tiramisu/option/portoption.py:123 msgid "must be an integer between {0} and {1}" msgstr "doit être une nombre entre {0} et {1}" -#: tiramisu/option/stroption.py:32 +#: tiramisu/option/stroption.py:33 msgid "string" msgstr "texte" @@ -950,23 +969,23 @@ msgstr "symlinkoption mal formé, doit être une option pour symlink {0}" msgid "unknown option \"{0}\" in syndynoptiondescription \"{1}\"" msgstr "l'option \"{0}\" inconnue dans la syndynoptiondescription \"{1}\"" -#: tiramisu/option/urloption.py:33 +#: tiramisu/option/urloption.py:34 msgid "URL" msgstr "URL" -#: tiramisu/option/urloption.py:43 +#: tiramisu/option/urloption.py:44 msgid "must start with http:// or https://" msgstr "doit débuter par http:// ou https://" -#: tiramisu/option/urloption.py:61 +#: tiramisu/option/urloption.py:62 msgid "port must be an between 0 and 65536" msgstr "port doit être entre 0 et 65536" -#: tiramisu/option/urloption.py:70 +#: tiramisu/option/urloption.py:71 msgid "must ends with a valid resource name" msgstr "doit finir par un nom de ressource valide" -#: tiramisu/option/usernameoption.py:31 +#: tiramisu/option/usernameoption.py:32 msgid "username" msgstr "nom d'utilisateur" @@ -978,7 +997,7 @@ msgstr "ne peut redéfinir ({0})" msgid "can't unbind {0}" msgstr "ne peut supprimer ({0})" -#: tiramisu/setting.py:518 +#: tiramisu/setting.py:519 msgid "" "malformed requirements imbrication detected for option: '{0}' with " "requirement on: '{1}'" @@ -986,48 +1005,56 @@ msgstr "" "imbrication de requirements mal formés detectée pour l'option : '{0}' avec " "requirement sur : '{1}'" -#: tiramisu/setting.py:566 +#: tiramisu/setting.py:582 msgid "" "cannot access to option \"{0}\" because required option \"{1}\" has {2} {3}" msgstr "" "ne peut accéder à l'option \"{0}\" parce que l'option requise \"{1}\" a {2} " "{3}" -#: tiramisu/setting.py:590 +#: tiramisu/setting.py:608 +msgid "the calculated value is {0}" +msgstr "valeurs calculées est {0}" + +#: tiramisu/setting.py:610 +msgid "the calculated value is not {0}" +msgstr "valeurs calculées n'est pas {0}" + +#: tiramisu/setting.py:614 msgid "the value of \"{0}\" is {1}" msgstr "la valeur de \"{0}\" est {1}" -#: tiramisu/setting.py:592 +#: tiramisu/setting.py:616 msgid "the value of \"{0}\" is not {1}" msgstr "la valeur de \"{0}\" n'est pas {1}" -#: tiramisu/setting.py:633 +#: tiramisu/setting.py:655 msgid "cannot set property {} for option \"{}\" this property is calculated" msgstr "" "ne peut ajouter la propriété {} pour l'option \"{}\" cette propriété est " "calculée" -#: tiramisu/setting.py:638 +#: tiramisu/setting.py:660 msgid "can't assign property to the symlinkoption \"{}\"" msgstr "ne peut assigner une propriété à une symlinkoption \"{}\"" -#: tiramisu/setting.py:670 +#: tiramisu/setting.py:692 msgid "permissive must be a frozenset" msgstr "une permissive doit être de type frozenset" -#: tiramisu/setting.py:674 +#: tiramisu/setting.py:696 msgid "can't assign permissive to the symlinkoption \"{}\"" msgstr "ne peut assigner une permissive à la symlinkoption \"{}\"" -#: tiramisu/setting.py:681 +#: tiramisu/setting.py:703 msgid "cannot add those permissives: {0}" msgstr "ne peut ajouter ces permissives : {0}" -#: tiramisu/setting.py:698 +#: tiramisu/setting.py:720 msgid "can't reset properties to the symlinkoption \"{}\"" msgstr "ne peut réinitialiser les propriétés de la symlinkoption \"{}\"" -#: tiramisu/setting.py:713 +#: tiramisu/setting.py:735 msgid "can't reset permissives to the symlinkoption \"{}\"" msgstr "ne peut réinitialiser les permissive de la symlinkoption \"{}\"" @@ -1061,19 +1088,45 @@ msgstr "ne peut supprimer une session non persistante" msgid "cannot change setting when connexion is already opened" msgstr "ne peut changer les paramètres quand une connexion est déjà ouverte" -#: tiramisu/value.py:424 +#: tiramisu/todict.py:66 +msgid "context is not supported from now for {}" +msgstr "context n'est pas supporté maintenant pour {}" + +#: tiramisu/todict.py:82 tiramisu/todict.py:91 +msgid "option {} only works when remotable is not \"none\"" +msgstr "l'option {} ne fonctionne que si remotable is \"none\"" + +#: tiramisu/todict.py:706 tiramisu/todict.py:839 +msgid "unknown form {}" +msgstr "form {} inconnu" + +#: tiramisu/todict.py:751 +msgid "not in current area" +msgstr "n'est pas dans l'espace courant" + +#: tiramisu/todict.py:771 +msgid "only multi option can have action \"add\", but \"{}\" is not a multi" +msgstr "" +"seules des options multiples peuvent avoir l'action \"add\", mais \"{}\" " +"n'est pas une valeur multiple" + +#: tiramisu/todict.py:773 +msgid "unknown action" +msgstr "action inconnue" + +#: tiramisu/value.py:427 msgid "can't set owner for the symlinkoption \"{}\"" msgstr "ne peut spécifier d'utilisateur à la symlinkoption \"{}\"" -#: tiramisu/value.py:427 tiramisu/value.py:639 +#: tiramisu/value.py:430 tiramisu/value.py:642 msgid "set owner \"{0}\" is forbidden" msgstr "assigner l'utilisateur \"{0}\" est interdit" -#: tiramisu/value.py:430 +#: tiramisu/value.py:433 msgid "no value for {0} cannot change owner to {1}" msgstr "pas de valeur pour {0} ne peut changer d'utilisateur pour {1}" -#: tiramisu/value.py:508 +#: tiramisu/value.py:511 msgid "index \"{}\" is higher than the length \"{}\" for option \"{}\"" msgstr "" "l'index \"{}\" est supérieur à la longueur de l'option \"{}\" pour l'option " diff --git a/tiramisu/locale/tiramisu.pot b/tiramisu/locale/tiramisu.pot index e77bb93..1cbc0d9 100644 --- a/tiramisu/locale/tiramisu.pot +++ b/tiramisu/locale/tiramisu.pot @@ -5,7 +5,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" -"POT-Creation-Date: 2019-04-07 10:39+CEST\n" +"POT-Creation-Date: 2019-04-08 08:41+CEST\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -15,71 +15,75 @@ msgstr "" "Generated-By: pygettext.py 1.5\n" -#: tiramisu/api.py:58 +#: tiramisu/api.py:59 msgid "Settings:" msgstr "" -#: tiramisu/api.py:59 +#: tiramisu/api.py:60 msgid "Access to option without verifying permissive properties" msgstr "" -#: tiramisu/api.py:60 +#: tiramisu/api.py:61 msgid "Access to option without property restriction" msgstr "" -#: tiramisu/api.py:64 +#: tiramisu/api.py:65 msgid "Call: {}" msgstr "" -#: tiramisu/api.py:66 +#: tiramisu/api.py:67 msgid "Commands:" msgstr "" -#: tiramisu/api.py:103 +#: tiramisu/api.py:104 msgid "index \"{}\" is higher than the leadership length \"{}\" for option \"{}\"" msgstr "" -#: tiramisu/api.py:108 +#: tiramisu/api.py:109 msgid "option must not be an optiondescription" msgstr "" -#: tiramisu/api.py:135 +#: tiramisu/api.py:136 msgid "index must be set with the follower option \"{}\"" msgstr "" -#: tiramisu/api.py:138 +#: tiramisu/api.py:139 msgid "unknown method {}" msgstr "" -#: tiramisu/api.py:360 +#: tiramisu/api.py:361 msgid "cannot add this property: \"{0}\"" msgstr "" -#: tiramisu/api.py:504 tiramisu/config.py:252 +#: tiramisu/api.py:505 tiramisu/config.py:252 msgid "can't delete a SymLinkOption" msgstr "" -#: tiramisu/api.py:637 tiramisu/api.py:1326 +#: tiramisu/api.py:639 tiramisu/api.py:1375 msgid "please specify a valid sub function ({})" msgstr "" -#: tiramisu/api.py:700 tiramisu/api.py:1146 +#: tiramisu/api.py:702 tiramisu/api.py:1176 msgid "unknown list type {}" msgstr "" -#: tiramisu/api.py:702 tiramisu/api.py:1148 +#: tiramisu/api.py:704 tiramisu/api.py:1178 msgid "unknown group_type: {0}" msgstr "" -#: tiramisu/api.py:975 +#: tiramisu/api.py:753 tiramisu/api.py:1208 +msgid "please use .dict() before .updates()" +msgstr "" + +#: tiramisu/api.py:1000 msgid "properties must be a set" msgstr "" -#: tiramisu/api.py:981 tiramisu/api.py:1003 +#: tiramisu/api.py:1006 tiramisu/api.py:1028 msgid "unknown when {} (must be in append or remove)" msgstr "" -#: tiramisu/api.py:993 tiramisu/api.py:1015 tiramisu/config.py:1249 +#: tiramisu/api.py:1018 tiramisu/api.py:1040 tiramisu/config.py:1249 msgid "unknown type {}" msgstr "" @@ -959,6 +963,30 @@ msgstr "" msgid "cannot change setting when connexion is already opened" msgstr "" +#: tiramisu/todict.py:66 +msgid "context is not supported from now for {}" +msgstr "" + +#: tiramisu/todict.py:82 tiramisu/todict.py:91 +msgid "option {} only works when remotable is not \"none\"" +msgstr "" + +#: tiramisu/todict.py:706 tiramisu/todict.py:839 +msgid "unknown form {}" +msgstr "" + +#: tiramisu/todict.py:751 +msgid "not in current area" +msgstr "" + +#: tiramisu/todict.py:771 +msgid "only multi option can have action \"add\", but \"{}\" is not a multi" +msgstr "" + +#: tiramisu/todict.py:773 +msgid "unknown action" +msgstr "" + #: tiramisu/value.py:427 msgid "can't set owner for the symlinkoption \"{}\"" msgstr "" diff --git a/tiramisu/todict.py b/tiramisu/todict.py new file mode 100644 index 0000000..2c2c7e0 --- /dev/null +++ b/tiramisu/todict.py @@ -0,0 +1,875 @@ +# -*- coding: utf-8 -*- + +import warnings +import sys +from copy import copy +from collections import OrderedDict +from .error import ValueWarning, ValueErrorWarning, PropertiesOptionError +from . import SynDynOption, RegexpOption, ChoiceOption, ParamContext, ParamOption +from .i18n import _ + + +TYPES = {'SymLinkOption': 'symlink', + 'IntOption': 'integer', + 'FloatOption': 'integer', + 'ChoiceOption': 'choice', + 'BoolOption': 'boolean', + 'PasswordOption': 'password', + 'PortOption': 'integer', + 'DateOption': 'date', + 'DomainnameOption': 'domainname', + 'StrOption': 'string' + } +INPUTS = ['string', + 'integer', + 'filename', + 'password', + 'email', + 'username', + 'ip', + 'domainname'] + +ACTION_HIDE = ['hidden', 'disabled'] + + +# return always warning (even if same warning is already returned) +warnings.simplefilter("always", ValueWarning) + + +class Callbacks(object): + def __init__(self, tiramisu_web): + self.tiramisu_web = tiramisu_web + self.clearable = tiramisu_web.clearable + self.remotable = tiramisu_web.remotable + self.callbacks = [] + + def add(self, + path, + childapi, + options, + schema, + force_store_value): + self.callbacks.append((path, childapi, options, schema, force_store_value)) + + def manage_callbacks(self, + path, + childapi, + options, + callback, + callback_params, + form, + schema): + if callback_params is not None: + remote = True + for callback_param in callback_params.args: + if isinstance(callback_param, ParamContext): + raise ValueError(_('context is not supported from now for {}').format(path)) + if isinstance(callback_param, ParamOption): + if callback.__name__ == 'tiramisu_copy': + if self.clearable == 'minimum': + form.setdefault(path, {})['clearable'] = True + if form.get(path, {}).get('remote') is not True and form[options[callback_param.option]].get('remote', False) is not True: + form.setdefault(options[callback_param.option], {}) + form[options[callback_param.option]].setdefault('copy', []).append(path) + remote = False + elif options.get(callback_param.option) is not None: + #form.setdefault(options[callback_param.option], {}) + form.setdefault(path, {}) + form[path]['remote'] = True + #break + if remote: + if self.remotable == 'none': + raise ValueError(_('option {} only works when remotable is not "none"').format(path)) + form.setdefault(path, {})['remote'] = True + else: + if 'expire' not in childapi.property.get() and childapi.owner.isdefault(): + schema[path]['value'] = childapi.value.get() + if self.clearable == 'minimum': + form.setdefault(path, {})['clearable'] = True + else: + if self.remotable == 'none': + raise ValueError(_('option {} only works when remotable is not "none"').format(path)) + # FIXME is not default, show calculate + form.setdefault(path, {})['remote'] = True + + + def process(self, + form): + for path, childapi, options, schema, force_store_value in self.callbacks: + if not childapi.option.isoptiondescription(): + callback, callback_params = childapi.option.callbacks() + if callback is not None: + if force_store_value and self.clearable != 'all': + return + self.manage_callbacks(path, + childapi, + options, + callback, + callback_params, + form, + schema) + + +class Consistencies(object): + def __init__(self, tiramisu_web): + self.not_equal = [] + self.options = {} + self.tiramisu_web = tiramisu_web + + def add(self, path, childapi): + child = childapi.option.get() + if isinstance(child, SynDynOption): + child = child._impl_getopt() + self.options[child] = path + if not childapi.option.isoptiondescription(): + for consistency in childapi.option.consistencies(): + cons_id, func, all_cons_opts, params = consistency + if func == '_cons_not_equal': + options = [] + for option in all_cons_opts: + option = option() + options.append(option) + # FIXME transitive + self.not_equal.append((options, params.get('warnings_only'))) + + def process(self, form): + for not_equal, warnings_only in self.not_equal: + not_equal_option = [] + for option in not_equal: + not_equal_option.append(self.options[option]) + for idx, path in enumerate(not_equal_option): + if form.get(path, {}).get('remote') is True: + continue + options = copy(not_equal_option) + options.pop(idx) + form.setdefault(path, {}).setdefault('not_equal', + {'options': []}) + form[path]['not_equal']['options'].extend(options) + if warnings_only or getattr(option, '_warnings_only', False): + form[path]['not_equal']['warnings'] = True + + +class Requires(object): + def __init__(self, tiramisu_web): + self.requires = {} + self.options = {} + self.tiramisu_web = tiramisu_web + self.config = tiramisu_web.config + self.remotable = tiramisu_web.remotable + + def manage_requires(self, + require_obj, + childapi, + path, + form, + action_hide, + current_action): + for requires in childapi.option.requires(): + for require in requires: + options, action, inverse, \ + transitive, same_action, operator = require + if transitive is False: + # transitive to "False" not supported yet for a requirement + if require_obj.remotable == 'none': + raise ValueError('require set for {} but remotable is "none"' + ''.format(path)) + form.setdefault(path, {'key': path})['remote'] = True + return + if same_action is False: + # same_action to "False" not supported yet for a requirement + if require_obj.remotable == 'none': + raise ValueError('require set for {} but remotable is "none"' + ''.format(path)) + form.setdefault(path, {'key': path})['remote'] = True + return + if operator == 'and': + # operator "and" not supported yet for a requirement + if require_obj.remotable == 'none': + raise ValueError('require set for {} but remotable is "none"' + ''.format(path)) + form.setdefault(path, {'key': path})['remote'] = True + return + for option, expected in options: + option_path = require_obj.options.get(option) + if option_path is not None and action in action_hide: + if current_action is None: + current_action = action + elif current_action != action: + if require_obj.remotable == 'none': + raise ValueError('require set for {} but remotable is "none"' + ''.format(path)) + form.setdefault(option_path, {'key': option_path})['remote'] = True + for exp in expected: + if inverse: + act = 'show' + inv_act = 'hide' + else: + act = 'hide' + inv_act = 'show' + require_obj.requires.setdefault(path, + {'expected': {}} + )['expected'].setdefault(exp, + {}).setdefault(act, + []).append(option_path) + if isinstance(option, ChoiceOption): + for value in require_obj.config.unrestraint.option(option_path).value.list(): + if value not in expected: + require_obj.requires.setdefault(path, + {'expected': {}} + )['expected'].setdefault(value, + {}).setdefault(inv_act, + []).append(option_path) + require_obj.requires[path].setdefault('default', {}).setdefault(inv_act, []).append(option_path) + else: + if require_obj.remotable == 'none': + raise ValueError('require set for {} but remotable est "none"' + ''.format(path)) + form.setdefault(option_path, {'key': option_path})['remote'] = True + + def add(self, path, childapi, form): + #collect id of all options + child = childapi.option.get() + if isinstance(child, SynDynOption): + child = child._impl_getopt() + self.options[child] = path + current_action = None + + self.manage_requires(self, + childapi, + path, + form, + ACTION_HIDE, + current_action) + + def is_remote(self, path, form): + if self.remotable == 'all': + return True + else: + return form.get(path) and form[path].get('remote', False) + + def process(self, form): + dependencies = {} + for path, values in self.requires.items(): + if form.get(path, {}).get('remote') is True: + continue + if 'default' in values: + for option in values['default'].get('show', []): + if path == option: + form.setdefault(path, {'key': path})['remote'] = True + if not self.is_remote(option, form): + dependencies.setdefault(option, + {'default': {}, 'expected': {}} + )['default'].setdefault('show', []) + if path not in dependencies[option]['default']['show']: + dependencies[option]['default']['show'].append(path) + for option in values['default'].get('hide', []): + if path == option: + form.setdefault(path, {'key': path})['remote'] = True + if not self.is_remote(option, form): + dependencies.setdefault(option, + {'default': {}, 'expected': {}} + )['default'].setdefault('hide', []) + if path not in dependencies[option]['default']['hide']: + dependencies[option]['default']['hide'].append(path) + for expected, actions in values['expected'].items(): + if expected is None: + expected = '' + for option in actions.get('show', []): + if path == option: + form.setdefault(path, {'key': path})['remote'] = True + if not self.is_remote(option, form): + dependencies.setdefault(option, + {'expected': {}} + )['expected'].setdefault(expected, + {}).setdefault('show', []) + if path not in dependencies[option]['expected'][expected]['show']: + dependencies[option]['expected'][expected]['show'].append(path) + for option in actions.get('hide', []): + if path == option: + form.setdefault(path, {'key': path})['remote'] = True + if not self.is_remote(option, form): + dependencies.setdefault(option, + {'expected': {}} + )['expected'].setdefault(expected, + {}).setdefault('hide', []) + if path not in dependencies[option]['expected'][expected]['hide']: + dependencies[option]['expected'][expected]['hide'].append(path) + for path, dependency in dependencies.items(): + form[path]['dependencies'] = dependency + + +class TiramisuDict: + + # propriete: + # hidden + # mandatory + # editable + + # FIXME model: + # #optionnel mais qui bouge + # choices/suggests + # warning + # + # #bouge + # owner + # properties + + def __init__(self, + config, + root=None, + clearable="all", + remotable="minimum"): + if 'demoting_error_warning' not in config.property.get(): + raise ValueError('demoting_error_warning property is mandatory') + self.config = config + self.root = root + self.requires = None + self.callbacks = None + self.consistencies = None + #all, minimum, none + self.clearable = clearable + #all, minimum, none + self.remotable = remotable + self.context_properties = self.config.property.get() + self.context_permissives = self.config.permissive.get() + + def add_help(self, + obj, + childapi): + hlp = childapi.information.get('help', None) + if hlp is not None: + obj['help'] = hlp + + def get_list(self, root, subchildapi): + for childapi in subchildapi.list('all'): + childname = childapi.option.name() + if root is None: + path = childname + else: + path = root + '.' + childname + yield path, childapi + + def walk(self, + root, + subchildapi, + schema, + model, + form, + order, + updates_status, + init=False): + if init: + if form is not None: + self.requires = Requires(self) + self.consistencies = Consistencies(self) + self.callbacks = Callbacks(self) + else: + init = False + if subchildapi is None: + if root is None: + subchildapi = self.config.unrestraint.option + else: + subchildapi = self.config.unrestraint.option(root) + isleadership = False + else: + isleadership = subchildapi.option.isleadership() + leader_len = None + for path, childapi in self.get_list(root, subchildapi): + if isleadership and leader_len is None: + leader_len = childapi.value.len() + props_no_requires = set(childapi.option.properties()) + if form is not None: + self.requires.add(path, + childapi, + form) + self.consistencies.add(path, + childapi) + self.callbacks.add(path, + childapi, + self.requires.options, + schema, + 'force_store_value' in props_no_requires) + childapi_option = childapi.option + if model is not None: + self.gen_model(model, + childapi, + path, + leader_len, + props_no_requires, + updates_status) + if order is not None: + order.append(path) + if childapi.option.isoptiondescription(): + if childapi_option.isleadership(): + type_ = 'array' + else: + type_ = 'object' + if schema is not None: + schema[path] = {'name': path, + 'properties': OrderedDict(), + 'type': type_} + subschema = schema[path]['properties'] + else: + subschema = schema + self.walk(path, + childapi, + subschema, + model, + form, + order, + updates_status) + else: + child = childapi_option.get() + childtype = child.__class__.__name__ + if childtype == 'SynDynOption': + childtype = child._impl_getopt().__class__.__name__ + if childapi_option.issymlinkoption(): + web_type = 'symlink' + else: + web_type = childapi_option.type() + value = childapi.option.default() + if value not in [[], None]: + has_value = True + else: + value = None + has_value = False + + is_multi = childapi_option.ismulti() + if is_multi: + default = childapi_option.defaultmulti() + if default not in [None, []]: + has_value = True + else: + default = None + else: + default = None + + if schema is not None: + self.gen_schema(schema, + childapi, + childapi_option, + path, + props_no_requires, + value, + default, + is_multi, + web_type) + if form is not None: + self.gen_form(form, + web_type, + path, + child, + childapi_option, + childtype, + has_value) + if schema is not None: + schema[path]['title'] = childapi_option.doc() + self.add_help(schema[path], + childapi) + if init and form is not None: + self.callbacks.process(form) + self.requires.process(form) + self.consistencies.process(form) + del self.requires + del self.consistencies + + + def gen_schema(self, + schema, + childapi, + childapi_option, + path, + props_no_requires, + value, + default, + is_multi, + web_type): + schema[path] = {'name': path, + 'type': web_type} + if childapi_option.issymlinkoption(): + schema[path]['opt_path'] = childapi_option.get().impl_getopt().impl_getpath() + else: + if value is not None: + schema[path]['value'] = value + + if default is not None: + schema[path]['default'] = default + + if is_multi: + schema[path]['isMulti'] = is_multi + + if childapi_option.issubmulti(): + schema[path]['isSubMulti'] = True + + if 'auto_freeze' in props_no_requires: + schema[path]['autoFreeze'] = True + + if web_type == 'choice': + schema[path]['enum'] = childapi.value.list() + empty_is_required = not childapi.option.isfollower() and is_multi + if (empty_is_required and not 'empty' in props_no_requires) or \ + (not empty_is_required and not 'mandatory' in props_no_requires): + schema[path]['enum'] = [''] + list(schema[path]['enum']) + + + def gen_form(self, + form, + web_type, + path, + child, + childapi_option, + childtype, + has_value): + obj_form = {} + if path in form: + obj_form.update(form[path]) + if not childapi_option.issymlinkoption(): + if self.clearable == 'all': + obj_form['clearable'] = True + if has_value and self.clearable != 'none': + obj_form['clearable'] = True + if self.remotable == 'all' or childapi_option.has_dependency(): + obj_form['remote'] = True + if web_type == 'integer': + obj_form['allowedpattern'] = '[0-9]' + if isinstance(child, RegexpOption): + obj_form['pattern'] = child._regexp.pattern + if web_type == 'domainname': + obj_form['pattern'] = child.impl_get_extra('_domain_re').pattern + if childtype in ['IPOption', 'NetworkOption', 'NetmaskOption']: + #FIXME only from 0.0.0.0 to 255.255.255.255 + obj_form['pattern'] = r'^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$' + if childtype == 'FloatOption': + obj_form['step'] = 'any' + if childtype == 'PortOption': + obj_form['min'] = child.impl_get_extra('_min_value') + obj_form['max'] = child.impl_get_extra('_max_value') + if web_type == 'choice': + obj_form['type'] = 'choice' + elif web_type in INPUTS: + obj_form['type'] = 'input' + if obj_form: + form[path] = obj_form + + def calc_raises_properties(self, childapi): + old_properties = childapi._option_bag.config_bag.properties + del childapi._option_bag.config_bag.properties + ret = childapi.option.properties(only_raises=True) + childapi._option_bag.config_bag.properties = old_properties + return ret + + def _gen_model_properties(self, + childapi, + path, + index, + props_no_requires): + obj = {} + isfollower = childapi.option.isfollower() + if index is None and isfollower: + # cannot calculated requires with follower without index + props = props_no_requires + else: + props = set(childapi.property.get()) + if self.calc_raises_properties(childapi): + obj['display'] = False + if not isfollower and childapi.option.ismulti(): + if 'empty' in props: + obj['required'] = True + props.remove('empty') + if 'mandatory' in props: + obj['needs_len'] = True + props.remove('mandatory') + elif 'mandatory' in props: + obj['required'] = True + props.remove('mandatory') + if 'frozen' in props: + obj['readOnly'] = True + props.remove('frozen') + if 'hidden' in props: + obj['hidden'] = True + props.remove('hidden') + if 'disabled' in props: + obj['hidden'] = True + props.remove('disabled') + if props: + lprops = list(props) + lprops.sort() + obj['properties'] = lprops + return obj + + def gen_model(self, + model, + childapi, + path, + leader_len, + props_no_requires, + updates_status): + if childapi.option.isoptiondescription(): + props = set(childapi.property.get()) + obj = {} + if self.calc_raises_properties(childapi): + obj['display'] = False + if props: + lprops = list(props) + lprops.sort() + obj['properties'] = lprops + if 'hidden' in props or 'disabled' in props: + obj['hidden'] = True + try: + self.config.option(path).option.get() + except PropertiesOptionError: + pass + else: + obj = self._gen_model_properties(childapi, + path, + None, + props_no_requires) + if childapi.option.isfollower(): + for index in range(leader_len): + follower_childapi = self.config.unrestraint.option(path, index) + sobj = self._gen_model_properties(follower_childapi, + path, + index, + props_no_requires) + self._get_model_value(follower_childapi, + path, + sobj, + index, + updates_status) + if sobj: + model.setdefault(path, {})[str(index)] = sobj + else: + self._get_model_value(childapi, + path, + obj, + None, + updates_status) + if obj: + if not childapi.option.isoptiondescription() and childapi.option.isfollower(): + model.setdefault(path, {})[None] = obj + else: + model[path] = obj + + def _get_model_value(self, + childapi, + path, + obj, + index, + updates_status): + # FIXME unrestraint ... + try: + nchildapi = self.config.option(path, index=index) + with warnings.catch_warnings(record=True) as warns: + value = nchildapi.value.get() + self._get_value_with_exception(obj, + childapi, + warns) + except PropertiesOptionError: + value = childapi.value.get() + warns = [] + if value is not None and value != []: + obj['value'] = value + obj['owner'] = childapi.owner.get() + + def _get_value_with_exception(self, + obj, + childapi, + values): + for value in values: + if isinstance(value.message, ValueErrorWarning): + value.message.prefix = '' + if childapi.option.isleader(): + obj.setdefault('invalid', []) + obj['invalid'].append({'error': str(value.message), + 'index': value.message.index}) + else: + obj.setdefault('error', []) + obj['error'].append(str(value.message)) + obj['invalid'] = True + else: + obj.setdefault('warnings', []) + obj['warnings'].append(str(value.message)) + obj['hasWarnings'] = True + + def get_form(self, form): + ret = [] + buttons = [] + dict_form = OrderedDict() + for form_ in form: + if 'key' in form_: + dict_form[form_['key']] = form_ + elif form_.get('type') == 'submit': + if 'cmd' not in form_: + form_['cmd'] = 'submit' + buttons.append(form_) + else: + raise ValueError(_('unknown form {}').format(form_)) + + for key, form_ in self.form.items(): + form_['key'] = key + if key in dict_form: + form_.update(dict_form[key]) + ret.append(form_) + ret.extend(buttons) + return ret + + def del_value(self, childapi, path, index): + if index is not None and childapi.option.isleader(): + childapi.value.pop(index) + elif index is None or childapi.option.isfollower(): + childapi.value.reset() + else: + multi = childapi.value.get() + multi.pop(index) + childapi.value.set(multi) + + def add_value(self, childapi, path, value): + multi = childapi.value.get() + multi.append(value) + childapi.value.set(multi) + + def mod_value(self, childapi, path, index, value): + if index is None or childapi.option.isfollower(): + childapi.value.set(value) + else: + multi = childapi.value.get() + if not multi and index == 0: + multi.append(value) + else: + multi[index] = value + childapi.value.set(multi) + + def apply_updates(self, + oripath, + updates, + model_ori): + updates_status = {} + for update in updates: + path = update['name'] + index = update.get('index') + if oripath is not None and not path.startswith(oripath): + raise ValueError(_('not in current area')) + childapi = self.config.option(path) + childapi_option = childapi.option + if childapi_option.isfollower(): + childapi = self.config.option(path, index) + with warnings.catch_warnings(record=True) as warns: + #try: + if update['action'] == 'modify': + self.mod_value(childapi, + path, + index, + update.get('value')) + elif update['action'] == 'delete': + self.del_value(childapi, + path, + index) + elif update['action'] == 'add': + if childapi_option.ismulti(): + self.add_value(childapi, path, update['value']) + else: + raise ValueError(_('only multi option can have action "add", but "{}" is not a multi').format(path)) + else: + raise ValueError(_('unknown action')) + #except ValueError as err: + # updates_status.setdefault(path, {})[index] = err + # continue + if warns != []: + updates_status.setdefault(path, {}).setdefault(index, []).extend(warns) + return updates_status + + def set_updates(self, + body): + root_path = self.root + updates = body.get('updates', []) + updates_status = self.apply_updates(root_path, + updates, + body.get('model')) + if 'model' in body: + order = [] + old_model = body['model'] + new_model = self.todict(order=order, + build_schema=False, + build_form=False, + updates_status=updates_status)['model'] + values = {'updates': list_keys(old_model, new_model, order, updates_status), + 'model': new_model} + else: + values = None + return values + + def todict(self, + custom_form=[], + build_schema=True, + build_model=True, + build_form=True, + order=None, + updates_status={}): + rootpath = self.root + if build_schema: + schema = OrderedDict() + else: + schema = None + if build_model: + model = {} + else: + model = None + if build_form: + form = {} + buttons = [] + else: + form = None + self.walk(rootpath, + None, + schema, + model, + form, + order, + updates_status, + init=True) + if build_form: + for form_ in custom_form: + if 'key' in form_: + key = form_.pop('key') + form.setdefault(key, {}).update(form_) + elif form_.get('type') == 'submit': + # FIXME if an Option has a key "null"? + form.setdefault(None, []).append(form_) + else: + raise ValueError(_('unknown form {}').format(form_)) + ret = {} + if build_schema: + ret['schema'] = schema + if build_model: + ret['model'] = model + if build_form: + ret['form'] = form + ret['version'] = '1.0' + return ret + + +def list_keys(model_a, model_b, ordered_key, updates_status): + model_a_dict = {} + model_b_dict = {} + + keys_a = set(model_a.keys()) + keys_b = set(model_b.keys()) + + keys = (keys_a ^ keys_b) | set(updates_status.keys()) + + for key in keys_a & keys_b: + keys_mod_a = set(model_a[key].keys()) + keys_mod_b = set(model_b[key].keys()) + if keys_mod_a != keys_mod_b: + keys.add(key) + else: + for skey in keys_mod_a: + if model_a[key][skey] != model_b[key][skey]: + keys.add(key) + break + def sort_key(key): + try: + return ordered_key.index(key) + except ValueError: + return -1 + return sorted(list(keys), key=sort_key)