R: Refactor Cst order attribute

0-indexed used for storage only
This commit is contained in:
Ivan 2024-09-11 20:06:01 +03:00
parent 6d84b89b14
commit fe678de8e4
17 changed files with 547 additions and 531 deletions

View File

@ -84,7 +84,7 @@ class TestVersionViews(EndpointTester):
alias='A1',
cst_type='axiom',
definition_formal='X1=X1',
order=2
order=1
)
version_id = self._create_version({'version': '1.0.0', 'description': 'test'})
a1.definition_formal = 'X1=X2'
@ -163,7 +163,7 @@ class TestVersionViews(EndpointTester):
x1.convention = 'Test2'
x1.term_raw = 'Test'
x1.save()
x3.order = 1
x3.order = 0
x3.save()
self.executeNotFound(version=invalid_id)
@ -172,10 +172,10 @@ class TestVersionViews(EndpointTester):
x1.refresh_from_db()
x2.refresh_from_db()
self.assertEqual(len(response.data['items']), 3)
self.assertEqual(x1.order, 1)
self.assertEqual(x1.order, 0)
self.assertEqual(x1.convention, 'testStart')
self.assertEqual(x1.term_raw, '')
self.assertEqual(x2.order, 2)
self.assertEqual(x2.order, 1)
self.assertEqual(response.data['items'][2]['alias'], 'D1')
self.assertEqual(response.data['items'][2]['term_raw'], 'TestTerm')

View File

@ -369,7 +369,7 @@ class OperationSchema:
self.cache.ensure_loaded()
new_mapping = self._transform_mapping(mapping, operation, destination)
alias_mapping = OperationSchema._produce_alias_mapping(new_mapping)
insert_where = self._determine_insert_position(items[0], operation, source, destination)
insert_where = self._determine_insert_position(items[0].pk, operation, source, destination)
new_cst_list = destination.insert_copy(items, insert_where, alias_mapping)
for index, cst in enumerate(new_cst_list):
new_inheritance = Inheritance.objects.create(
@ -527,20 +527,23 @@ class OperationSchema:
return result
def _determine_insert_position(
self, prototype: Constituenta,
self, prototype_id: int,
operation: Operation,
source: RSForm,
destination: RSForm
) -> int:
''' Determine insert_after for new constituenta. '''
if prototype.order == 1:
return 1
prev_cst = source.cache.constituents[prototype.order - 2]
prototype = source.cache.by_id[prototype_id]
prototype_index = source.cache.constituents.index(prototype)
if prototype_index == 0:
return 0
prev_cst = source.cache.constituents[prototype_index - 1]
inherited_prev_id = self.cache.get_successor(prev_cst.pk, operation.pk)
if inherited_prev_id is None:
return INSERT_LAST
prev_cst = destination.cache.by_id[inherited_prev_id]
return cast(int, prev_cst.order) + 1
prev_index = destination.cache.constituents.index(prev_cst)
return prev_index + 1
def _extract_data_references(self, data: dict, old_data: dict) -> set[str]:
result: set[str] = set()

View File

@ -70,7 +70,7 @@ class TestChangeConstituents(EndpointTester):
self.assertEqual(self.ks1.constituents().count(), 3)
self.assertEqual(self.ks3.constituents().count(), 5)
self.assertEqual(inherited_cst.alias, 'X4')
self.assertEqual(inherited_cst.order, 3)
self.assertEqual(inherited_cst.order, 2)
self.assertEqual(inherited_cst.definition_formal, 'X1 = X2')
@decl_endpoint('/api/rsforms/{schema}/rename-cst', method='patch')
@ -133,5 +133,5 @@ class TestChangeConstituents(EndpointTester):
d2.refresh_from_db()
self.assertEqual(self.ks1.constituents().count(), 1)
self.assertEqual(self.ks3.constituents().count(), 4)
self.assertEqual(self.ks1X2.order, 1)
self.assertEqual(self.ks1X2.order, 0)
self.assertEqual(d2.definition_formal, r'X2\X2\X3')

View File

@ -7,7 +7,8 @@ from . import models
class ConstituentaAdmin(admin.ModelAdmin):
''' Admin model: Constituenta. '''
ordering = ['schema', 'order']
list_display = ['schema', 'alias', 'term_resolved', 'definition_resolved']
list_display = ['schema', 'order', 'alias', 'term_resolved', 'definition_resolved']
search_fields = ['term_resolved', 'definition_resolved']
admin.site.register(models.Constituenta, ConstituentaAdmin)

View File

@ -0,0 +1,26 @@
# Generated by Django 5.1 on 2024-09-11 16:37
from django.db import migrations, models
def migrate_order_from_1_to_0(apps, schema_editor):
Constituenta = apps.get_model('rsform', 'Constituenta')
for cst in Constituenta.objects.all():
cst.order = max(0, cst.order - 1)
cst.save()
class Migration(migrations.Migration):
dependencies = [
('rsform', '0002_alter_constituenta_order'),
]
operations = [
migrations.AlterField(
model_name='constituenta',
name='order',
field=models.PositiveIntegerField(default=0, verbose_name='Позиция'),
),
migrations.RunPython(migrate_order_from_1_to_0),
]

View File

@ -2,7 +2,6 @@
import re
from cctext import extract_entities
from django.core.validators import MinValueValidator
from django.db.models import (
CASCADE,
CharField,
@ -57,8 +56,7 @@ class Constituenta(Model):
)
order: PositiveIntegerField = PositiveIntegerField(
verbose_name='Позиция',
validators=[MinValueValidator(1)],
default=1,
default=0,
)
alias: CharField = CharField(
verbose_name='Имя',

View File

@ -140,7 +140,8 @@ class RSForm:
if insert_after is None:
position = INSERT_LAST
else:
position = insert_after.order + 1
self.cache.ensure_loaded()
position = self.cache.constituents.index(self.cache.by_id[insert_after.pk]) + 1
result = self.insert_new(data['alias'], data['cst_type'], position)
result.convention = data.get('convention', '')
result.definition_formal = data.get('definition_formal', '')
@ -170,8 +171,7 @@ class RSForm:
position: int = INSERT_LAST,
**kwargs
) -> Constituenta:
''' Insert new constituenta at given position.
All following constituents order is shifted by 1 position. '''
''' Insert new constituenta at given position. '''
if self.constituents().filter(alias=alias).exists():
raise ValidationError(msg.aliasTaken(alias))
position = self._get_insert_position(position)
@ -298,8 +298,8 @@ class RSForm:
if cst in target:
cst.order = destination + count_moved
count_moved += 1
elif count_top + 1 < destination:
cst.order = count_top + 1
elif count_top < destination:
cst.order = count_top
count_top += 1
else:
cst.order = destination + size + count_bot
@ -417,8 +417,8 @@ class RSForm:
if count_new == 0:
return []
position = target.order + 1
self.cache.ensure_loaded()
position = self.cache.constituents.index(self.cache.by_id[target.id]) + 1
self._shift_positions(position, count_new)
result = []
cst_type = CstType.TERM if len(parse['args']) == 0 else CstType.FUNCTION
@ -456,29 +456,23 @@ class RSForm:
def _shift_positions(self, start: int, shift: int) -> None:
if shift == 0:
return
update_list: Iterable[Constituenta] = []
if not self.cache.is_loaded:
update_list = Constituenta.objects \
.only('order') \
.filter(schema=self.model, order__gte=start)
else:
update_list = [cst for cst in self.cache.constituents if cst.order >= start]
self.cache.ensure_loaded()
update_list = self.cache.constituents[start:]
for cst in update_list:
cst.order += shift
Constituenta.objects.bulk_update(update_list, ['order'])
def _get_insert_position(self, position: int) -> int:
if position <= 0 and position != INSERT_LAST:
if position < 0 and position != INSERT_LAST:
raise ValidationError(msg.invalidPosition())
lastPosition = self.constituents().count()
if position == INSERT_LAST:
position = lastPosition + 1
return lastPosition
else:
position = max(1, min(position, lastPosition + 1))
return position
return max(0, min(position, lastPosition))
def _reset_order(self) -> None:
order = 1
order = 0
changed: list[Constituenta] = []
cst_list: Iterable[Constituenta] = []
if not self.cache.is_loaded:
@ -569,14 +563,14 @@ class RSFormCache:
def insert(self, cst: Constituenta) -> None:
if self.is_loaded:
self.constituents.insert(cst.order - 1, cst)
self.constituents.insert(cst.order, cst)
self.by_id[cst.pk] = cst
self.by_alias[cst.alias] = cst
def insert_multi(self, items: Iterable[Constituenta]) -> None:
if self.is_loaded:
for cst in items:
self.constituents.insert(cst.order - 1, cst)
self.constituents.insert(cst.order, cst)
self.by_id[cst.pk] = cst
self.by_alias[cst.alias] = cst
@ -770,7 +764,7 @@ class _OrderManager:
self._items = result
def _save_order(self) -> None:
order = 1
order = 0
for cst in self._items:
cst.order = order
order += 1

View File

@ -26,7 +26,7 @@ class CstBaseSerializer(serializers.ModelSerializer):
class Meta:
''' serializer metadata. '''
model = Constituenta
fields = '__all__'
exclude = ('order',)
read_only_fields = ('id',)
@ -35,8 +35,8 @@ class CstSerializer(serializers.ModelSerializer):
class Meta:
''' serializer metadata. '''
model = Constituenta
fields = '__all__'
read_only_fields = ('id', 'schema', 'order', 'alias', 'cst_type', 'definition_resolved', 'term_resolved')
exclude = ('order',)
read_only_fields = ('id', 'schema', 'alias', 'cst_type', 'definition_resolved', 'term_resolved')
class CstUpdateSerializer(serializers.Serializer):
@ -71,7 +71,7 @@ class CstDetailsSerializer(serializers.ModelSerializer):
class Meta:
''' serializer metadata. '''
model = Constituenta
fields = '__all__'
exclude = ('order',)
class CstCreateSerializer(serializers.ModelSerializer):
@ -126,7 +126,7 @@ class RSFormSerializer(serializers.ModelSerializer):
result['items'] = []
result['oss'] = []
result['inheritance'] = []
for cst in RSForm(instance).constituents().order_by('order'):
for cst in RSForm(instance).constituents().defer('order').order_by('order'):
result['items'].append(CstSerializer(cst).data)
for oss in LibraryItem.objects.filter(operations__result=instance).only('alias'):
result['oss'].append({
@ -171,6 +171,7 @@ class RSFormSerializer(serializers.ModelSerializer):
cst_data = next(x for x in items if x['id'] == cst.pk)
new_cst = CstBaseSerializer(data=cst_data)
new_cst.is_valid(raise_exception=True)
new_cst.validated_data['order'] = ids.index(cst.pk)
new_cst.update(
instance=cst,
validated_data=new_cst.validated_data
@ -180,9 +181,11 @@ class RSFormSerializer(serializers.ModelSerializer):
for cst_data in items:
if cst_data['id'] not in processed:
cst = schema.insert_new(cst_data['alias'])
old_id = cst_data['id']
cst_data['id'] = cst.pk
new_cst = CstBaseSerializer(data=cst_data)
new_cst.is_valid(raise_exception=True)
new_cst.validated_data['order'] = ids.index(old_id)
new_cst.update(
instance=cst,
validated_data=new_cst.validated_data

View File

@ -151,7 +151,7 @@ class RSFormTRSSerializer(serializers.Serializer):
location=validated_data['location']
)
self.instance.save()
order = 1
order = 0
for cst_data in validated_data['items']:
cst = Constituenta(
alias=cst_data['alias'],
@ -174,7 +174,7 @@ class RSFormTRSSerializer(serializers.Serializer):
if 'comment' in validated_data:
instance.model.comment = validated_data['comment']
order = 1
order = 0
prev_constituents = instance.constituents()
loaded_ids = set()
for cst_data in validated_data['items']:

View File

@ -16,7 +16,7 @@ class TestConstituenta(TestCase):
def test_str(self):
testStr = 'X1'
cst = Constituenta.objects.create(alias=testStr, schema=self.schema1.model, order=1, convention='Test')
cst = Constituenta.objects.create(alias=testStr, schema=self.schema1.model, order=0, convention='Test')
self.assertEqual(str(cst), testStr)
@ -25,25 +25,18 @@ class TestConstituenta(TestCase):
Constituenta.objects.create(alias='X1', schema=self.schema1.model, order=-1)
def test_order_min_value(self):
with self.assertRaises(ValidationError):
cst = Constituenta.objects.create(alias='X1', schema=self.schema1.model, order=0)
cst.full_clean()
def test_schema_not_null(self):
with self.assertRaises(IntegrityError):
Constituenta.objects.create(alias='X1', order=1)
Constituenta.objects.create(alias='X1', order=0)
def test_create_default(self):
cst = Constituenta.objects.create(
alias='X1',
schema=self.schema1.model,
order=1
schema=self.schema1.model
)
self.assertEqual(cst.schema, self.schema1.model)
self.assertEqual(cst.order, 1)
self.assertEqual(cst.order, 0)
self.assertEqual(cst.alias, 'X1')
self.assertEqual(cst.cst_type, CstType.BASE)
self.assertEqual(cst.convention, '')
@ -57,7 +50,6 @@ class TestConstituenta(TestCase):
def test_extract_references(self):
cst = Constituenta.objects.create(
alias='X1',
order=1,
schema=self.schema1.model,
definition_formal='X1 X2',
term_raw='@{X3|sing} is a @{X4|sing}',
@ -68,7 +60,6 @@ class TestConstituenta(TestCase):
def text_apply_mapping(self):
cst = Constituenta.objects.create(
alias='X1',
order=1,
schema=self.schema1.model,
definition_formal='X1 = X2',
term_raw='@{X1|sing}',

View File

@ -23,8 +23,8 @@ class TestRSForm(DBTester):
self.assertFalse(schema1.constituents().exists())
self.assertFalse(schema2.constituents().exists())
Constituenta.objects.create(alias='X1', schema=schema1.model, order=1)
Constituenta.objects.create(alias='X2', schema=schema1.model, order=2)
Constituenta.objects.create(alias='X1', schema=schema1.model, order=0)
Constituenta.objects.create(alias='X2', schema=schema1.model, order=1)
self.assertTrue(schema1.constituents().exists())
self.assertFalse(schema2.constituents().exists())
self.assertEqual(schema1.constituents().count(), 2)
@ -32,8 +32,8 @@ class TestRSForm(DBTester):
def test_get_max_index(self):
schema1 = RSForm.create(title='Test1')
Constituenta.objects.create(alias='X1', schema=schema1.model, order=1)
Constituenta.objects.create(alias='D2', cst_type=CstType.TERM, schema=schema1.model, order=2)
Constituenta.objects.create(alias='X1', schema=schema1.model, order=0)
Constituenta.objects.create(alias='D2', cst_type=CstType.TERM, schema=schema1.model, order=1)
self.assertEqual(schema1.get_max_index(CstType.BASE), 1)
self.assertEqual(schema1.get_max_index(CstType.TERM), 2)
self.assertEqual(schema1.get_max_index(CstType.AXIOM), 0)
@ -42,37 +42,37 @@ class TestRSForm(DBTester):
def test_insert_at(self):
schema = RSForm.create(title='Test')
x1 = schema.insert_new('X1')
self.assertEqual(x1.order, 1)
self.assertEqual(x1.order, 0)
self.assertEqual(x1.schema, schema.model)
x2 = schema.insert_new('X2', position=1)
x2 = schema.insert_new('X2', position=0)
x1.refresh_from_db()
self.assertEqual(x2.order, 1)
self.assertEqual(x2.order, 0)
self.assertEqual(x2.schema, schema.model)
self.assertEqual(x1.order, 2)
self.assertEqual(x1.order, 1)
x3 = schema.insert_new('X3', position=4)
x3 = schema.insert_new('X3', position=3)
x2.refresh_from_db()
x1.refresh_from_db()
self.assertEqual(x3.order, 3)
self.assertEqual(x3.order, 2)
self.assertEqual(x3.schema, schema.model)
self.assertEqual(x2.order, 1)
self.assertEqual(x1.order, 2)
self.assertEqual(x2.order, 0)
self.assertEqual(x1.order, 1)
x4 = schema.insert_new('X4', position=3)
x4 = schema.insert_new('X4', position=2)
x3.refresh_from_db()
x2.refresh_from_db()
x1.refresh_from_db()
self.assertEqual(x4.order, 3)
self.assertEqual(x4.order, 2)
self.assertEqual(x4.schema, schema.model)
self.assertEqual(x3.order, 4)
self.assertEqual(x2.order, 1)
self.assertEqual(x1.order, 2)
self.assertEqual(x3.order, 3)
self.assertEqual(x2.order, 0)
self.assertEqual(x1.order, 1)
def test_insert_at_invalid_position(self):
with self.assertRaises(ValidationError):
self.schema.insert_new('X5', position=0)
self.schema.insert_new('X5', position=-2)
def test_insert_at_invalid_alias(self):
@ -84,24 +84,24 @@ class TestRSForm(DBTester):
def test_insert_at_reorder(self):
self.schema.insert_new('X1')
d1 = self.schema.insert_new('D1')
d2 = self.schema.insert_new('D2', position=1)
d2 = self.schema.insert_new('D2', position=0)
d1.refresh_from_db()
self.assertEqual(d1.order, 3)
self.assertEqual(d2.order, 1)
self.assertEqual(d1.order, 2)
self.assertEqual(d2.order, 0)
x2 = self.schema.insert_new('X2', position=4)
self.assertEqual(x2.order, 4)
x2 = self.schema.insert_new('X2', position=3)
self.assertEqual(x2.order, 3)
def test_insert_last(self):
x1 = self.schema.insert_new('X1')
self.assertEqual(x1.order, 1)
self.assertEqual(x1.order, 0)
self.assertEqual(x1.schema, self.schema.model)
x2 = self.schema.insert_new('X2')
self.assertEqual(x2.order, 2)
self.assertEqual(x2.order, 1)
self.assertEqual(x2.schema, self.schema.model)
self.assertEqual(x1.order, 1)
self.assertEqual(x1.order, 0)
def test_create_cst(self):
data = {
@ -120,8 +120,8 @@ class TestRSForm(DBTester):
self.assertEqual(x3.alias, data['alias'])
self.assertEqual(x3.term_raw, data['term_raw'])
self.assertEqual(x3.definition_raw, data['definition_raw'])
self.assertEqual(x2.order, 3)
self.assertEqual(x3.order, 2)
self.assertEqual(x2.order, 2)
self.assertEqual(x3.order, 1)
def test_create_cst_resolve(self):
@ -154,20 +154,20 @@ class TestRSForm(DBTester):
definition_raw='@{X10|plur}'
)
result = self.schema.insert_copy([s1, x1], 2)
result = self.schema.insert_copy([s1, x1], 1)
self.assertEqual(len(result), 2)
s1.refresh_from_db()
self.assertEqual(s1.order, 4)
self.assertEqual(s1.order, 3)
x2 = result[1]
self.assertEqual(x2.order, 3)
self.assertEqual(x2.order, 2)
self.assertEqual(x2.alias, 'X11')
self.assertEqual(x2.cst_type, CstType.BASE)
self.assertEqual(x2.convention, x1.convention)
s2 = result[0]
self.assertEqual(s2.order, 2)
self.assertEqual(s2.order, 1)
self.assertEqual(s2.alias, 'S12')
self.assertEqual(s2.cst_type, CstType.STRUCTURED)
self.assertEqual(s2.definition_formal, x2.alias)
@ -188,8 +188,8 @@ class TestRSForm(DBTester):
x2.refresh_from_db()
d1.refresh_from_db()
self.assertEqual(self.schema.constituents().count(), 2)
self.assertEqual(x2.order, 1)
self.assertEqual(d1.order, 2)
self.assertEqual(x2.order, 0)
self.assertEqual(d1.order, 1)
self.assertEqual(d1.definition_formal, 'DEL = X2')
self.assertEqual(d1.definition_raw, '@{DEL|sing}')
self.assertEqual(d1.term_raw, '@{X2|plur}')
@ -240,25 +240,25 @@ class TestRSForm(DBTester):
x2 = self.schema.insert_new('X2')
d1 = self.schema.insert_new('D1')
d2 = self.schema.insert_new('D2')
self.schema.move_cst([x2, d2], 1)
self.schema.move_cst([x2, d2], 0)
x1.refresh_from_db()
x2.refresh_from_db()
d1.refresh_from_db()
d2.refresh_from_db()
self.assertEqual(x1.order, 3)
self.assertEqual(x2.order, 1)
self.assertEqual(d1.order, 4)
self.assertEqual(d2.order, 2)
self.assertEqual(x1.order, 2)
self.assertEqual(x2.order, 0)
self.assertEqual(d1.order, 3)
self.assertEqual(d2.order, 1)
def test_move_cst_down(self):
x1 = self.schema.insert_new('X1')
x2 = self.schema.insert_new('X2')
self.schema.move_cst([x1], 2)
self.schema.move_cst([x1], 1)
x1.refresh_from_db()
x2.refresh_from_db()
self.assertEqual(x1.order, 2)
self.assertEqual(x2.order, 1)
self.assertEqual(x1.order, 1)
self.assertEqual(x2.order, 0)
def test_restore_order(self):
@ -316,18 +316,18 @@ class TestRSForm(DBTester):
f2.refresh_from_db()
a1.refresh_from_db()
self.assertEqual(x1.order, 1)
self.assertEqual(x2.order, 2)
self.assertEqual(c1.order, 3)
self.assertEqual(s1.order, 4)
self.assertEqual(d1.order, 5)
self.assertEqual(s2.order, 6)
self.assertEqual(d3.order, 7)
self.assertEqual(a1.order, 8)
self.assertEqual(d4.order, 9)
self.assertEqual(d2.order, 10)
self.assertEqual(f1.order, 11)
self.assertEqual(f2.order, 12)
self.assertEqual(x1.order, 0)
self.assertEqual(x2.order, 1)
self.assertEqual(c1.order, 2)
self.assertEqual(s1.order, 3)
self.assertEqual(d1.order, 4)
self.assertEqual(s2.order, 5)
self.assertEqual(d3.order, 6)
self.assertEqual(a1.order, 7)
self.assertEqual(d4.order, 8)
self.assertEqual(d2.order, 9)
self.assertEqual(f1.order, 10)
self.assertEqual(f2.order, 11)
def test_reset_aliases(self):

View File

@ -198,7 +198,7 @@ class TestRSFormViewset(EndpointTester):
response = self.executeCreated(data=data, item=self.owned_id)
self.assertEqual(response.data['new_cst']['alias'], 'X3')
x3 = Constituenta.objects.get(alias=response.data['new_cst']['alias'])
self.assertEqual(x3.order, 3)
self.assertEqual(x3.order, 2)
data = {
'alias': 'X4',
@ -210,7 +210,7 @@ class TestRSFormViewset(EndpointTester):
response = self.executeCreated(data=data, item=self.owned_id)
self.assertEqual(response.data['new_cst']['alias'], data['alias'])
x4 = Constituenta.objects.get(alias=response.data['new_cst']['alias'])
self.assertEqual(x4.order, 3)
self.assertEqual(x4.order, 2)
self.assertEqual(x4.term_raw, data['term_raw'])
self.assertEqual(x4.term_forms, data['term_forms'])
@ -257,7 +257,7 @@ class TestRSFormViewset(EndpointTester):
term_raw='@{X1|plur}',
definition_formal='X1'
)
self.assertEqual(x1.order, 1)
self.assertEqual(x1.order, 0)
self.assertEqual(x1.alias, 'X1')
self.assertEqual(x1.cst_type, CstType.BASE)
@ -269,7 +269,7 @@ class TestRSFormViewset(EndpointTester):
x1.refresh_from_db()
self.assertEqual(d1.term_resolved, '')
self.assertEqual(d1.term_raw, '@{D2|plur}')
self.assertEqual(x1.order, 1)
self.assertEqual(x1.order, 0)
self.assertEqual(x1.alias, 'D2')
self.assertEqual(x1.cst_type, CstType.TERM)
@ -354,7 +354,7 @@ class TestRSFormViewset(EndpointTester):
self.assertEqual(len(response.data['items']), 1)
self.assertEqual(self.owned.constituents().count(), 1)
self.assertEqual(x2.alias, 'X2')
self.assertEqual(x2.order, 1)
self.assertEqual(x2.order, 0)
x3 = self.unowned.insert_new('X1')
data = {'items': [x3.pk]}
@ -365,22 +365,22 @@ class TestRSFormViewset(EndpointTester):
def test_move_constituenta(self):
self.set_params(item=self.owned_id)
data = {'items': [1337], 'move_to': 1}
data = {'items': [1337], 'move_to': 0}
self.executeBadData(data=data)
x1 = self.owned.insert_new('X1')
x2 = self.owned.insert_new('X2')
data = {'items': [x2.pk], 'move_to': 1}
data = {'items': [x2.pk], 'move_to': 0}
response = self.executeOK(data=data)
x1.refresh_from_db()
x2.refresh_from_db()
self.assertEqual(response.data['id'], self.owned_id)
self.assertEqual(x1.order, 2)
self.assertEqual(x2.order, 1)
self.assertEqual(x1.order, 1)
self.assertEqual(x2.order, 0)
x3 = self.unowned.insert_new('X1')
data = {'items': [x3.pk], 'move_to': 1}
data = {'items': [x3.pk], 'move_to': 0}
self.executeBadData(data=data)
@ -399,11 +399,11 @@ class TestRSFormViewset(EndpointTester):
x1.refresh_from_db()
x2.refresh_from_db()
d11.refresh_from_db()
self.assertEqual(x2.order, 1)
self.assertEqual(x2.order, 0)
self.assertEqual(x2.alias, 'X1')
self.assertEqual(x1.order, 2)
self.assertEqual(x1.order, 1)
self.assertEqual(x1.alias, 'X2')
self.assertEqual(d11.order, 3)
self.assertEqual(d11.order, 2)
self.assertEqual(d11.alias, 'D1')
self.executeOK()
@ -462,9 +462,7 @@ class TestRSFormViewset(EndpointTester):
result = response.data['schema']
items = [item for item in result['items'] if item['id'] in response.data['cst_list']]
self.assertEqual(len(items), 2)
self.assertEqual(items[0]['order'], s1.order + 1)
self.assertEqual(items[0]['definition_formal'], 'Pr1(S1)')
self.assertEqual(items[1]['order'], s1.order + 2)
self.assertEqual(items[1]['definition_formal'], 'Pr2(S1)')
# Testing complex structure
@ -473,7 +471,6 @@ class TestRSFormViewset(EndpointTester):
result = response.data['schema']
items = [item for item in result['items'] if item['id'] in response.data['cst_list']]
self.assertEqual(len(items), 8)
self.assertEqual(items[0]['order'], s3.order + 1)
self.assertEqual(items[0]['definition_formal'], 'pr1(S3)')
# Testing function
@ -482,7 +479,6 @@ class TestRSFormViewset(EndpointTester):
result = response.data['schema']
items = [item for item in result['items'] if item['id'] in response.data['cst_list']]
self.assertEqual(len(items), 2)
self.assertEqual(items[0]['order'], f1.order + 1)
self.assertEqual(items[0]['definition_formal'], '[α∈X1, β∈X1] Pr1(F10[α,β])')
@ -497,7 +493,7 @@ class TestConstituentaAPI(EndpointTester):
alias='X1',
cst_type=CstType.BASE,
schema=self.rsform_owned.model,
order=1,
order=0,
convention='Test',
term_raw='Test1',
term_resolved='Test1R',
@ -506,7 +502,7 @@ class TestConstituentaAPI(EndpointTester):
alias='X2',
cst_type=CstType.BASE,
schema=self.rsform_unowned.model,
order=1,
order=0,
convention='Test1',
term_raw='Test2',
term_resolved='Test2R'
@ -514,7 +510,7 @@ class TestConstituentaAPI(EndpointTester):
self.cst3 = Constituenta.objects.create(
alias='X3',
schema=self.rsform_owned.model,
order=2,
order=1,
term_raw='Test3',
term_resolved='Test3',
definition_raw='Test1',
@ -594,14 +590,12 @@ class TestConstituentaAPI(EndpointTester):
data = {
'target': self.cst1.pk,
'item_data': {
'alias': 'X33',
'order': 10
'alias': 'X33'
}
}
response = self.executeOK(data=data, schema=self.rsform_owned.model.pk)
self.assertEqual(response.data['alias'], 'X1')
self.assertEqual(response.data['alias'], self.cst1.alias)
self.assertEqual(response.data['order'], self.cst1.order)
class TestInlineSynthesis(EndpointTester):
@ -669,8 +663,6 @@ class TestInlineSynthesis(EndpointTester):
response = self.executeOK(data=data)
result = {item['alias']: item for item in response.data['items']}
self.assertEqual(len(result), 6)
self.assertEqual(result['X2']['order'], 1)
self.assertEqual(result['X4']['order'], 2)
self.assertEqual(result['S1']['definition_formal'], 'X2')
self.assertEqual(result['S2']['definition_formal'], 'X4×X4')
self.assertEqual(result['D1']['definition_formal'], r'S1\S2\X2')

File diff suppressed because it is too large Load Diff

View File

@ -70,7 +70,9 @@ function PickConstituenta({
cell: props => <BadgeConstituenta theme={colors} value={props.row.original} prefixID={prefixID} />
}),
columnHelper.accessor(cst => describeFunc(cst), {
id: 'description'
id: 'description',
size: 1000,
minSize: 1000
})
],
[colors, prefixID, describeFunc]

View File

@ -25,11 +25,6 @@ export enum CstType {
// CstType constant for category dividers in TemplateSchemas
export const CATEGORY_CST_TYPE = CstType.THEOREM;
/**
* Represents position in linear order.
*/
export type Position = number;
/**
* Represents {@link IConstituenta} identifier type.
*/
@ -71,7 +66,6 @@ export interface TermForm {
export interface IConstituentaMeta {
id: ConstituentaID;
schema: LibraryItemID;
order: Position;
alias: string;
convention: string;
cst_type: CstType;
@ -146,7 +140,7 @@ export interface ICstCreateData
* Represents data, used in ordering a list of {@link IConstituenta}.
*/
export interface ICstMovetoData extends IConstituentaList {
move_to: Position;
move_to: number; // Note: 0-base index
}
/**

View File

@ -120,7 +120,6 @@ export function createMockConstituenta(id: ConstituentaID, alias: string, commen
children: [],
children_alias: [],
is_simple_expression: false,
order: -1,
schema: -1,
alias: alias,
convention: comment,
@ -157,8 +156,17 @@ export function isMockCst(cst: IConstituenta) {
* Apply filter based on start {@link IConstituenta} type.
*/
export function applyFilterCategory(start: IConstituenta, schema: IRSForm): IConstituenta[] {
const nextCategory = schema.items.find(cst => cst.order > start.order && cst.cst_type === CATEGORY_CST_TYPE);
return schema.items.filter(cst => cst.order >= start.order && (!nextCategory || cst.order < nextCategory.order));
const startIndex = schema.items.indexOf(start);
if (startIndex === -1) {
return [];
}
const nextCategoryIndex = schema.items.findIndex(
(cst, index) => index > startIndex && cst.cst_type === CATEGORY_CST_TYPE
);
return schema.items.filter(
(_, index) => index >= startIndex && (nextCategoryIndex === -1 || index < nextCategoryIndex)
);
}
/**

View File

@ -406,8 +406,8 @@ export const RSEditState = ({
}
return Math.min(prev, index);
}, -1);
const target = Math.max(0, currentIndex - 1) + 1;
const data = {
const target = Math.max(0, currentIndex - 1);
const data: ICstMovetoData = {
items: selected,
move_to: target
};
@ -430,7 +430,7 @@ export const RSEditState = ({
return Math.max(prev, index);
}
}, -1);
const target = Math.min(model.schema.items.length - 1, currentIndex - count + 2) + 1;
const target = Math.min(model.schema.items.length - 1, currentIndex - count + 2);
const data: ICstMovetoData = {
items: selected,
move_to: target