TDD и вообще юнит-тесты in the wild

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
77 messages Options
1234
Reply | Threaded
Open this post in threaded view
|

Re: TDD и вообще юнит-тесты in the wild

Сергей Глушенко
Вопрос на засыпку. А зачем?  я же и говорю, что не стесняюсь использовать if там где это оправданно. Такая связка в виде сущности кроме этого блока нигде не понадобится. Никогда. Зачем усложнять объект, создавая ненужную сущность. Почему Вы истинные программисты так боитесь тех же If -ов. Зачем на каждый чих создавать новый класс. Мой инженерный подход говорит мне что любую задачу можно решить милионом путей от безумно красивого но долгого до абсолютно костыльного но очень быстрого, а исскуство инженера - конструкторас найти золотую середину в решении каждой задачи, используя компромисы, и различные подходы. Вас же почему то тянет всегда на первый путь. Я в свое время был неплохим конструктором.
вторник, 13 января 2015 г., 17:01:59 UTC+5 пользователь Kleptsov Nikolay написал:
если смотреть только на один метод, могу и ошибаться,
isUseCountInTimeFunction и countTime выделить в отдельную сущность
также относиться и к
- (isUsePulseDurationFunction hasPositivDurationOutput hasNegativeDurationOutput)
-
(isUseDelayLineFunction hasDelayTimeInput delayTimeConstant hasDestinationOutput controllerDestinationpinNumber controllerDestinationpinNumber)

в этих объектах (сущностях) реализовать метод isCorrect или использовать callback методы (например, сложение разных типов чисел) где сначала идет общий метод сложения, далее у разных типов чисел через уточняющие методы происходит сложение

13 января 2015 г., 17:28 пользователь Сергей Глушенко <<a href="javascript:" target="_blank" gdf-obfuscated-mailto="uOerFbTlnAEJ" onmousedown="this.href='javascript:';return true;" onclick="this.href='javascript:';return true;">sup...@...> написал:
Не вся конечно. Классы имеют свое поведение. Умеют рисоваться, каждый тип данных (Boolean, Float, Integer ...) Это отдельный класс со своим поведением. Назначение блока задает его тим. Блок это просто хранитель данных. Его тип - его описатель. В библиотеке элементов лежат типы на основании которых создаются инстансы блоков. Переменные - это то же блок, внури которых лежит тэг. в теге лежит тип, ну и еще кое что необходимое. Поведение блока задается комбинацией содержимого. Например если значение какгого то параметра может быть константой или задаваться со входа  то в зависимости от выбора пользователя в переменной value лежит инстанс класса  InputValue или класса ConstantValue. и кода компилятор спросит у блока значение этой величины, один инстанс отдаст значение логической стоки для входа, а другой значение хранящейся в нем константы. Ну где то так только немного посложнее. Это сильное упрощение. Например константа может быть разной размерности Например: микросекунды, милисекунды, минуты-секунды-милисекунды. А в скетче нужны микросекунда. Соответственно инстанс все пересчитает. И так далее. Я знаю что это называется композиция, но конствнты находятся в иерархии с головой ParametrValue. И эти классы применяются при необходимости во всех классах. If-ы конечно есть, от них никуда не денешся. И я не считаю злом их использование. Если где то можно обойтись небольшими количеством If-ов не создавая лишний класс, я не стесняюсь их использовать. Главное что бы не было большого вложения. Если начинаются вложения, лучше сделать отдельный метод с выходами по условиям. Получается красиво и и наглядно.
Например метод проверки корректности модуля скоростного счетчика:

isCorrect

   
super isCorrect ifFalse: [^false].
    pinNumber ifNil
: [^false].
   
self isUseCountInTimeFunction ifTrue: [countTime ifNil: [^false]].
   
self isUsePulseDurationFunction
        ifTrue
:
           
[(self hasPositivDurationOutput or: [self hasNegativeDurationOutput])
                ifFalse
: [^false]].
   
self isUseDelayLineFunction
        ifTrue
:
           
[self hasDelayTimeInput ifFalse: [self delayTimeConstant ifNil: [^false]].
           
self hasDestinationOutput
                ifFalse
: [self controllerDestinationpinNumber ifNil: [^false]]].
   
^true
 P.S. Не ругайте за английский, я в нем не силен


вторник, 13 января 2015 г., 16:02:05 UTC+5 пользователь chaetal написал:
И вся эта логика на if-ах — я правильно понимаю?


--

Best regards,


Dennis Schetinin


13 января 2015 г., 10:29 пользователь Сергей Глушенко <[hidden email]> написал:
Я об этом думал, не поможет.
Вот смотри.
Реализация PostCopy  в разных блоках сильно отличается.
       Вода - выхода - вход может быть, или его может не быть. Если он есть - (не nil) то надо сделать его копию и привязать к новому блоку. Конечно ссылка на родительский объект в дочернем - это полхо - я понимаю, но поиск родителя через проект безумно тормозит отрисовку. Поэтому я пошол на этот не самый лучший шаг.  кроме входов в блоке куча других переменных. и работа с ними в разных блоках отличается. Например блок датчика DHT-11. При копировании блока необходимо в переменную содержащую модель датчика положить новый чистый инстанс модели. Блок дисплея. Если дисплей прямого подключения - его надо снести (засунуть nil), если дисплей по i2С даже копировать не надо. И так в каждом конкретном случае рассматривается, что надо скопировать. что надо снести, что надо оставить без изменения. Кое где необходимо просто поменять внутри данные, без копирования. 

Хотя сейчас пришла в голову идея для входов - выходов. Пробежаться по всем переменным, и если там лежит вход или выход (а это один класс), то произвести над ним стандартую операцию. Надо будет попробывать.
 


вторник, 13 января 2015 г., 11:11:00 UTC+5 пользователь Vladimir Musulainen написал:
Все объекты, которым надо копироваться полностью, включая копии объектов в instance variable наследуем от одного класса, который называем CopyableObject.
У класса CopyableObject определяем метод postCopy что-то типа
postCopy

postCopy
super postCopy.
myInstanceVariablesNames do: [:each | self at: each name put: each copy]


Это не решит всех проблем с PostCopy?




13 янв. 2015 г., в 7:06, Сергей Глушенко <[hidden email]> написал(а):

Для "простых" блоков где входа и выхода - коллекции у меня реализовано  автоматическая операция PostCopy. Для более навороченных которые сейчас в основном разрабатываются где входы и выходы именные все сложнее. Я пока не придумал реализацию как производить проверку правильности копирования. Плюс в блоках чаще всего вложенны другие сложные объекты. Все блоки по этому критерию отличаются так что универсального теста не сделать. Большинство блоков после создания не модернизируются.соответственно правильно сделанные и проверенные не нуждаются в дальнейшем тестировании. 
Для себя я решил проблемму старым проверенным способом. Бумажка на мониторе))) Цитирую:
PostCopy!!!!! (Там знаков большею Каждый раз когда матерюсь что забыл, ставлю один восклицательный знак.)
LAD - тип входов (при переносе в блока в LAD необходимо сменить тип входов. Все не решаюсь привести в FBD и LAD ихода и выхода к одному классу. Могут полететь старые проекты, хотя идея более менее безопасного перехода уже есть)
isCorrect- проверить (проверить правильность выполнения проверки корректности блока. Если упустить какое либо некорректное состояние блока, например не заполненное полк номера пинато пользователи обязательно на это состояние напорятся и при компиляции либо получат ошибку, либо скетч не будет работать  )

--
--
<a href="http://groups.google.ru/group/sugr" target="_blank" onmousedown="this.href='http://groups.google.ru/group/sugr';return true;" onclick="this.href='http://groups.google.ru/group/sugr';return true;">http://groups.google.ru/group/sugr
---
Вы получили это сообщение, поскольку подписаны на группу "Russian Smalltalk User Group".
Чтобы отменить подписку на эту группу и больше не получать от нее сообщения, отправьте письмо на электронный адрес sugr+uns...@googlegroups.com.
Чтобы настроить другие параметры, перейдите по ссылке <a href="https://groups.google.com/d/optout" target="_blank" onmousedown="this.href='https://groups.google.com/d/optout';return true;" onclick="this.href='https://groups.google.com/d/optout';return true;">https://groups.google.com/d/optout.

--
--
<a href="http://groups.google.ru/group/sugr" target="_blank" onmousedown="this.href='http://groups.google.ru/group/sugr';return true;" onclick="this.href='http://groups.google.ru/group/sugr';return true;">http://groups.google.ru/group/sugr
---
Вы получили это сообщение, поскольку подписаны на группу "Russian Smalltalk User Group".
Чтобы отменить подписку на эту группу и больше не получать от нее сообщения, отправьте письмо на электронный адрес <a href="javascript:" target="_blank" gdf-obfuscated-mailto="uOerFbTlnAEJ" onmousedown="this.href='javascript:';return true;" onclick="this.href='javascript:';return true;">sugr+uns...@googlegroups.com.
Чтобы настроить другие параметры, перейдите по ссылке <a href="https://groups.google.com/d/optout" target="_blank" onmousedown="this.href='https://groups.google.com/d/optout';return true;" onclick="this.href='https://groups.google.com/d/optout';return true;">https://groups.google.com/d/optout.

--
--
http://groups.google.ru/group/sugr
---
Вы получили это сообщение, поскольку подписаны на группу "Russian Smalltalk User Group".
Чтобы отменить подписку на эту группу и больше не получать от нее сообщения, отправьте письмо на электронный адрес [hidden email].
Чтобы настроить другие параметры, перейдите по ссылке https://groups.google.com/d/optout.
Reply | Threaded
Open this post in threaded view
|

Re: TDD и вообще юнит-тесты in the wild

Dennis Schetinin
In reply to this post by Сергей Глушенко
В общем-то, здесь все на if-ах и сделано :)


--

Best regards,


Dennis Schetinin


13 января 2015 г., 16:04 пользователь Сергей Глушенко <[hidden email]> написал:
Конечно

isUseCountInTimeFunction

    isUseCountInTimeFunction ifNotNil
: [^isUseCountInTimeFunction].
    isUseCountInTimeFunction
:= true.
   
^isUseCountInTimeFunction


isNeededPositiveInterruptFunction

   
self hasInputValueOutput ifTrue: [^true].
   
self isUseDelayLineFunction
        ifTrue
: [self hasDelayPositiveFront ifTrue: [^true]].
   
self isUsePulseDurationFunction ifTrue: [^true].
   
(self isUseCountPulseFunction and: [self isUsePositiveFrontForPulseCount])
        ifTrue
: [^true].
   
^false

isSpeedCounter

   
^true

hasDestinationOutput

   
^destinationOutput isNil not

canConnectOutput
: aArduinoFBDInputOutput to: aArduinoFBDConnection
aArduinoFBDInputOutput isBooleanType ifTrue
:[^aArduinoFBDConnection isBooleanType].
   
^aArduinoFBDConnection isNumberType


ну я так пробежался по тестовым методам. там их много

вторник, 13 января 2015 г., 17:00:22 UTC+5 пользователь chaetal написал:
А можно увидеть наиболее типичные реализации методов isUse…, has…?


--

Best regards,


Dennis Schetinin


13 января 2015 г., 15:28 пользователь Сергей Глушенко <[hidden email]> написал:

Не вся конечно. Классы имеют свое поведение. Умеют рисоваться, каждый тип данных (Boolean, Float, Integer ...) Это отдельный класс со своим поведением. Назначение блока задает его тим. Блок это просто хранитель данных. Его тип - его описатель. В библиотеке элементов лежат типы на основании которых создаются инстансы блоков. Переменные - это то же блок, внури которых лежит тэг. в теге лежит тип, ну и еще кое что необходимое. Поведение блока задается комбинацией содержимого. Например если значение какгого то параметра может быть константой или задаваться со входа  то в зависимости от выбора пользователя в переменной value лежит инстанс класса  InputValue или класса ConstantValue. и кода компилятор спросит у блока значение этой величины, один инстанс отдаст значение логической стоки для входа, а другой значение хранящейся в нем константы. Ну где то так только немного посложнее. Это сильное упрощение. Например константа может быть разной размерности Например: микросекунды, милисекунды, минуты-секунды-милисекунды. А в скетче нужны микросекунда. Соответственно инстанс все пересчитает. И так далее. Я знаю что это называется композиция, но конствнты находятся в иерархии с головой ParametrValue. И эти классы применяются при необходимости во всех классах. If-ы конечно есть, от них никуда не денешся. И я не считаю злом их использование. Если где то можно обойтись небольшими количеством If-ов не создавая лишний класс, я не стесняюсь их использовать. Главное что бы не было большого вложения. Если начинаются вложения, лучше сделать отдельный метод с выходами по условиям. Получается красиво и и наглядно.
Например метод проверки корректности модуля скоростного счетчика:

isCorrect

   
super isCorrect ifFalse: [^false].
    pinNumber ifNil
: [^false].
   
self isUseCountInTimeFunction ifTrue: [countTime ifNil: [^false]].
   
self isUsePulseDurationFunction
        ifTrue
:
           
[(self hasPositivDurationOutput or: [self hasNegativeDurationOutput])
                ifFalse
: [^false]].
   
self isUseDelayLineFunction
        ifTrue
:
           
[self hasDelayTimeInput ifFalse: [self delayTimeConstant ifNil: [^false]].
           
self hasDestinationOutput
                ifFalse
: [self controllerDestinationpinNumber ifNil: [^false]]].
   
^true
 P.S. Не ругайте за английский, я в нем не силен


вторник, 13 января 2015 г., 16:02:05 UTC+5 пользователь chaetal написал:
И вся эта логика на if-ах — я правильно понимаю?


--

Best regards,


Dennis Schetinin


13 января 2015 г., 10:29 пользователь Сергей Глушенко <[hidden email]> написал:
Я об этом думал, не поможет.
Вот смотри.
Реализация PostCopy  в разных блоках сильно отличается.
       Вода - выхода - вход может быть, или его может не быть. Если он есть - (не nil) то надо сделать его копию и привязать к новому блоку. Конечно ссылка на родительский объект в дочернем - это полхо - я понимаю, но поиск родителя через проект безумно тормозит отрисовку. Поэтому я пошол на этот не самый лучший шаг.  кроме входов в блоке куча других переменных. и работа с ними в разных блоках отличается. Например блок датчика DHT-11. При копировании блока необходимо в переменную содержащую модель датчика положить новый чистый инстанс модели. Блок дисплея. Если дисплей прямого подключения - его надо снести (засунуть nil), если дисплей по i2С даже копировать не надо. И так в каждом конкретном случае рассматривается, что надо скопировать. что надо снести, что надо оставить без изменения. Кое где необходимо просто поменять внутри данные, без копирования. 

Хотя сейчас пришла в голову идея для входов - выходов. Пробежаться по всем переменным, и если там лежит вход или выход (а это один класс), то произвести над ним стандартую операцию. Надо будет попробывать.
 


вторник, 13 января 2015 г., 11:11:00 UTC+5 пользователь Vladimir Musulainen написал:
Все объекты, которым надо копироваться полностью, включая копии объектов в instance variable наследуем от одного класса, который называем CopyableObject.
У класса CopyableObject определяем метод postCopy что-то типа
postCopy

postCopy
super postCopy.
myInstanceVariablesNames do: [:each | self at: each name put: each copy]


Это не решит всех проблем с PostCopy?




13 янв. 2015 г., в 7:06, Сергей Глушенко <[hidden email]> написал(а):

Для "простых" блоков где входа и выхода - коллекции у меня реализовано  автоматическая операция PostCopy. Для более навороченных которые сейчас в основном разрабатываются где входы и выходы именные все сложнее. Я пока не придумал реализацию как производить проверку правильности копирования. Плюс в блоках чаще всего вложенны другие сложные объекты. Все блоки по этому критерию отличаются так что универсального теста не сделать. Большинство блоков после создания не модернизируются.соответственно правильно сделанные и проверенные не нуждаются в дальнейшем тестировании. 
Для себя я решил проблемму старым проверенным способом. Бумажка на мониторе))) Цитирую:
PostCopy!!!!! (Там знаков большею Каждый раз когда матерюсь что забыл, ставлю один восклицательный знак.)
LAD - тип входов (при переносе в блока в LAD необходимо сменить тип входов. Все не решаюсь привести в FBD и LAD ихода и выхода к одному классу. Могут полететь старые проекты, хотя идея более менее безопасного перехода уже есть)
isCorrect- проверить (проверить правильность выполнения проверки корректности блока. Если упустить какое либо некорректное состояние блока, например не заполненное полк номера пинато пользователи обязательно на это состояние напорятся и при компиляции либо получат ошибку, либо скетч не будет работать  )

--
--
http://groups.google.ru/group/sugr
---
Вы получили это сообщение, поскольку подписаны на группу "Russian Smalltalk User Group".
Чтобы отменить подписку на эту группу и больше не получать от нее сообщения, отправьте письмо на электронный адрес sugr+uns...@googlegroups.com.
Чтобы настроить другие параметры, перейдите по ссылке https://groups.google.com/d/optout.

--
--
http://groups.google.ru/group/sugr
---
Вы получили это сообщение, поскольку подписаны на группу "Russian Smalltalk User Group".
Чтобы отменить подписку на эту группу и больше не получать от нее сообщения, отправьте письмо на электронный адрес sugr+uns...@googlegroups.com.
Чтобы настроить другие параметры, перейдите по ссылке https://groups.google.com/d/optout.

--
--
http://groups.google.ru/group/sugr
---
Вы получили это сообщение, поскольку подписаны на группу "Russian Smalltalk User Group".
Чтобы отменить подписку на эту группу и больше не получать от нее сообщения, отправьте письмо на электронный адрес [hidden email].
Чтобы настроить другие параметры, перейдите по ссылке https://groups.google.com/d/optout.

--
--
http://groups.google.ru/group/sugr
---
Вы получили это сообщение, поскольку подписаны на группу "Russian Smalltalk User Group".
Чтобы отменить подписку на эту группу и больше не получать от нее сообщения, отправьте письмо на электронный адрес [hidden email].
Чтобы настроить другие параметры, перейдите по ссылке https://groups.google.com/d/optout.
Reply | Threaded
Open this post in threaded view
|

Re: TDD и вообще юнит-тесты in the wild

Сергей Глушенко
In reply to this post by Dennis Schetinin

Попробую еще раз объяснить. Тут  нет необходимости создавать сущности. Нигде кроме данного класа они не потребуются. Я считаю класс нужно создавать только с целью его переиспользования, или если  его применеие действительно облегчит жизнь. Я не вижу облекчения жизни в создании коллекции элементов состоящих из двух - трех переменных и одного метода. Лично для меня  нагляднее примененный мной метод. Я сразу вижу все условия корректности модуля. Вложенности более одного уровня нет. Не надо плодить ненужные сущности. Они загромождают класс браузер, и мешаются по ногами эти мелкие твари.
вторник, 13 января 2015 г., 17:14:25 UTC+5 пользователь chaetal написал:
Вообще, напрашивается что-то вроде

^ elements anySatisfy: [:each | each isEffective and: [each isCorrect not]])



--

Best regards,


Dennis Schetinin


13 января 2015 г., 16:01 пользователь Nikolay Kleptsov <<a href="javascript:" target="_blank" gdf-obfuscated-mailto="ew5482DnoNkJ" onmousedown="this.href='javascript:';return true;" onclick="this.href='javascript:';return true;">kleptsov...@...> написал:
если смотреть только на один метод, могу и ошибаться,
isUseCountInTimeFunction и countTime выделить в отдельную сущность
также относиться и к
- (isUsePulseDurationFunction hasPositivDurationOutput hasNegativeDurationOutput)
-
(isUseDelayLineFunction hasDelayTimeInput delayTimeConstant hasDestinationOutput controllerDestinationpinNumber controllerDestinationpinNumber)

в этих объектах (сущностях) реализовать метод isCorrect или использовать callback методы (например, сложение разных типов чисел) где сначала идет общий метод сложения, далее у разных типов чисел через уточняющие методы происходит сложение

13 января 2015 г., 17:28 пользователь Сергей Глушенко <<a href="javascript:" target="_blank" gdf-obfuscated-mailto="ew5482DnoNkJ" onmousedown="this.href='javascript:';return true;" onclick="this.href='javascript:';return true;">sup...@...> написал:

Не вся конечно. Классы имеют свое поведение. Умеют рисоваться, каждый тип данных (Boolean, Float, Integer ...) Это отдельный класс со своим поведением. Назначение блока задает его тим. Блок это просто хранитель данных. Его тип - его описатель. В библиотеке элементов лежат типы на основании которых создаются инстансы блоков. Переменные - это то же блок, внури которых лежит тэг. в теге лежит тип, ну и еще кое что необходимое. Поведение блока задается комбинацией содержимого. Например если значение какгого то параметра может быть константой или задаваться со входа  то в зависимости от выбора пользователя в переменной value лежит инстанс класса  InputValue или класса ConstantValue. и кода компилятор спросит у блока значение этой величины, один инстанс отдаст значение логической стоки для входа, а другой значение хранящейся в нем константы. Ну где то так только немного посложнее. Это сильное упрощение. Например константа может быть разной размерности Например: микросекунды, милисекунды, минуты-секунды-милисекунды. А в скетче нужны микросекунда. Соответственно инстанс все пересчитает. И так далее. Я знаю что это называется композиция, но конствнты находятся в иерархии с головой ParametrValue. И эти классы применяются при необходимости во всех классах. If-ы конечно есть, от них никуда не денешся. И я не считаю злом их использование. Если где то можно обойтись небольшими количеством If-ов не создавая лишний класс, я не стесняюсь их использовать. Главное что бы не было большого вложения. Если начинаются вложения, лучше сделать отдельный метод с выходами по условиям. Получается красиво и и наглядно.
Например метод проверки корректности модуля скоростного счетчика:

isCorrect

   
super isCorrect ifFalse: [^false].
    pinNumber ifNil
: [^false].
   
self isUseCountInTimeFunction ifTrue: [countTime ifNil: [^false]].
   
self isUsePulseDurationFunction
        ifTrue
:
           
[(self hasPositivDurationOutput or: [self hasNegativeDurationOutput])
                ifFalse
: [^false]].
   
self isUseDelayLineFunction
        ifTrue
:
           
[self hasDelayTimeInput ifFalse: [self delayTimeConstant ifNil: [^false]].
           
self hasDestinationOutput
                ifFalse
: [self controllerDestinationpinNumber ifNil: [^false]]].
   
^true
 P.S. Не ругайте за английский, я в нем не силен


вторник, 13 января 2015 г., 16:02:05 UTC+5 пользователь chaetal написал:
И вся эта логика на if-ах — я правильно понимаю?


--

Best regards,


Dennis Schetinin


13 января 2015 г., 10:29 пользователь Сергей Глушенко <[hidden email]> написал:
Я об этом думал, не поможет.
Вот смотри.
Реализация PostCopy  в разных блоках сильно отличается.
       Вода - выхода - вход может быть, или его может не быть. Если он есть - (не nil) то надо сделать его копию и привязать к новому блоку. Конечно ссылка на родительский объект в дочернем - это полхо - я понимаю, но поиск родителя через проект безумно тормозит отрисовку. Поэтому я пошол на этот не самый лучший шаг.  кроме входов в блоке куча других переменных. и работа с ними в разных блоках отличается. Например блок датчика DHT-11. При копировании блока необходимо в переменную содержащую модель датчика положить новый чистый инстанс модели. Блок дисплея. Если дисплей прямого подключения - его надо снести (засунуть nil), если дисплей по i2С даже копировать не надо. И так в каждом конкретном случае рассматривается, что надо скопировать. что надо снести, что надо оставить без изменения. Кое где необходимо просто поменять внутри данные, без копирования. 

Хотя сейчас пришла в голову идея для входов - выходов. Пробежаться по всем переменным, и если там лежит вход или выход (а это один класс), то произвести над ним стандартую операцию. Надо будет попробывать.
 


вторник, 13 января 2015 г., 11:11:00 UTC+5 пользователь Vladimir Musulainen написал:
Все объекты, которым надо копироваться полностью, включая копии объектов в instance variable наследуем от одного класса, который называем CopyableObject.
У класса CopyableObject определяем метод postCopy что-то типа
postCopy

postCopy
super postCopy.
myInstanceVariablesNames do: [:each | self at: each name put: each copy]


Это не решит всех проблем с PostCopy?




13 янв. 2015 г., в 7:06, Сергей Глушенко <[hidden email]> написал(а):

Для "простых" блоков где входа и выхода - коллекции у меня реализовано  автоматическая операция PostCopy. Для более навороченных которые сейчас в основном разрабатываются где входы и выходы именные все сложнее. Я пока не придумал реализацию как производить проверку правильности копирования. Плюс в блоках чаще всего вложенны другие сложные объекты. Все блоки по этому критерию отличаются так что универсального теста не сделать. Большинство блоков после создания не модернизируются.соответственно правильно сделанные и проверенные не нуждаются в дальнейшем тестировании. 
Для себя я решил проблемму старым проверенным способом. Бумажка на мониторе))) Цитирую:
PostCopy!!!!! (Там знаков большею Каждый раз когда матерюсь что забыл, ставлю один восклицательный знак.)
LAD - тип входов (при переносе в блока в LAD необходимо сменить тип входов. Все не решаюсь привести в FBD и LAD ихода и выхода к одному классу. Могут полететь старые проекты, хотя идея более менее безопасного перехода уже есть)
isCorrect- проверить (проверить правильность выполнения проверки корректности блока. Если упустить какое либо некорректное состояние блока, например не заполненное полк номера пинато пользователи обязательно на это состояние напорятся и при компиляции либо получат ошибку, либо скетч не будет работать  )

--
--
<a href="http://groups.google.ru/group/sugr" target="_blank" onmousedown="this.href='http://groups.google.ru/group/sugr';return true;" onclick="this.href='http://groups.google.ru/group/sugr';return true;">http://groups.google.ru/group/sugr
---
Вы получили это сообщение, поскольку подписаны на группу "Russian Smalltalk User Group".
Чтобы отменить подписку на эту группу и больше не получать от нее сообщения, отправьте письмо на электронный адрес sugr+uns...@googlegroups.com.
Чтобы настроить другие параметры, перейдите по ссылке <a href="https://groups.google.com/d/optout" target="_blank" onmousedown="this.href='https://groups.google.com/d/optout';return true;" onclick="this.href='https://groups.google.com/d/optout';return true;">https://groups.google.com/d/optout.

--
--
<a href="http://groups.google.ru/group/sugr" target="_blank" onmousedown="this.href='http://groups.google.ru/group/sugr';return true;" onclick="this.href='http://groups.google.ru/group/sugr';return true;">http://groups.google.ru/group/sugr
---
Вы получили это сообщение, поскольку подписаны на группу "Russian Smalltalk User Group".
Чтобы отменить подписку на эту группу и больше не получать от нее сообщения, отправьте письмо на электронный адрес <a href="javascript:" target="_blank" gdf-obfuscated-mailto="ew5482DnoNkJ" onmousedown="this.href='javascript:';return true;" onclick="this.href='javascript:';return true;">sugr+uns...@googlegroups.com.
Чтобы настроить другие параметры, перейдите по ссылке <a href="https://groups.google.com/d/optout" target="_blank" onmousedown="this.href='https://groups.google.com/d/optout';return true;" onclick="this.href='https://groups.google.com/d/optout';return true;">https://groups.google.com/d/optout.

--
--
<a href="http://groups.google.ru/group/sugr" target="_blank" onmousedown="this.href='http://groups.google.ru/group/sugr';return true;" onclick="this.href='http://groups.google.ru/group/sugr';return true;">http://groups.google.ru/group/sugr
---
Вы получили это сообщение, поскольку подписаны на группу "Russian Smalltalk User Group".
Чтобы отменить подписку на эту группу и больше не получать от нее сообщения, отправьте письмо на электронный адрес <a href="javascript:" target="_blank" gdf-obfuscated-mailto="ew5482DnoNkJ" onmousedown="this.href='javascript:';return true;" onclick="this.href='javascript:';return true;">sugr+uns...@googlegroups.com.
Чтобы настроить другие параметры, перейдите по ссылке <a href="https://groups.google.com/d/optout" target="_blank" onmousedown="this.href='https://groups.google.com/d/optout';return true;" onclick="this.href='https://groups.google.com/d/optout';return true;">https://groups.google.com/d/optout.

--
--
http://groups.google.ru/group/sugr
---
Вы получили это сообщение, поскольку подписаны на группу "Russian Smalltalk User Group".
Чтобы отменить подписку на эту группу и больше не получать от нее сообщения, отправьте письмо на электронный адрес [hidden email].
Чтобы настроить другие параметры, перейдите по ссылке https://groups.google.com/d/optout.
Reply | Threaded
Open this post in threaded view
|

Re: TDD и вообще юнит-тесты in the wild

Dennis Schetinin
In reply to this post by Сергей Глушенко

13 января 2015 г., 16:16 пользователь Сергей Глушенко <[hidden email]> написал:
Вопрос на засыпку. А зачем?

У меня есть штук 5 вариантов ответа на этот вопрос, но наверное будет некорректно влезать перед автором рац. предложения :)

Еще вопрос: метод isCorrect и подобные (я, так понимаю, они есть) с развитием системы уже никогда не будут больше меняться?


--

Best regards,


Dennis Schetinin

--
--
http://groups.google.ru/group/sugr
---
Вы получили это сообщение, поскольку подписаны на группу "Russian Smalltalk User Group".
Чтобы отменить подписку на эту группу и больше не получать от нее сообщения, отправьте письмо на электронный адрес [hidden email].
Чтобы настроить другие параметры, перейдите по ссылке https://groups.google.com/d/optout.
Reply | Threaded
Open this post in threaded view
|

Re: TDD и вообще юнит-тесты in the wild

Dennis Schetinin
In reply to this post by Сергей Глушенко

13 января 2015 г., 16:23 пользователь Сергей Глушенко <[hidden email]> написал:
Нигде кроме данного класа они не потребуются.

Ну, это странно. Если они нигде не требуются, кого волнует корректны они или нет?


--

Best regards,


Dennis Schetinin

--
--
http://groups.google.ru/group/sugr
---
Вы получили это сообщение, поскольку подписаны на группу "Russian Smalltalk User Group".
Чтобы отменить подписку на эту группу и больше не получать от нее сообщения, отправьте письмо на электронный адрес [hidden email].
Чтобы настроить другие параметры, перейдите по ссылке https://groups.google.com/d/optout.
Reply | Threaded
Open this post in threaded view
|

Re: TDD и вообще юнит-тесты in the wild

Сергей Глушенко
In reply to this post by Dennis Schetinin
В данном блоке 80% нет. Точнее этот блок имеет законченную функциональность.  Соответственно саь блок меняться не будет. Максимум что может у него поменяться - добавятся интерфейсы ну например выдача значения константы какой ни будь с пересчетом например в шестнадцетиричную если это потребуется компилятору например под PIC/
Я понимаю что Вы хотели увидеть в тестовом методе

isCorrect

   
super isCorrect ifFalse: [^false].
    connectionDevice ifNil
: [^false].
    connectionDevice isCorrect ifFalse
: [^false].
   
^true



Это блок WebServer Здесь девайсом могут выстумать несколко различных шидлдов. Типа вайфай, W5100 и другие. На сегодня их три вида. Кроме этого блока данные классы являющиеся моделями устройства применяются еще в нескольких видах блоков, и количество блоков с применением этих моделей будет расти, как и количество самих моделей. Только WIFI модулей под ардуинку видов десять. И каждый работает по своему, Каждый имеет свой набор параметров. Блоки их использующие меняться больше не будут. Им глубоко плевать какую железяку в них засунули. Они хранят информацию о странице которую нуэно отправить на запрос к серверу. Каждая железяка знает о своем SubFrame  с набором параметров для себя. Соответственно описанная и отлаженная железяка то же менятся больше не будет. Она умеет дернуть свой кусок компилятора создающего код обеспечивающий ее работу. Соответственно кусок кода компилятора(метод или набор методов) отвечающий за ее программирование то же отладится один раз и забудется. При появлении у меня новой железяки просто будет написан новый класс модели железяки с тс общим интерфейсом. и таких железяк у меня уже много
AbstractExtendDevice
   
AbstractDisplay
       
DisplayOnChipHD44780
   
StepMotor
   
AbstractRealTimeClock
        DS1302RealTimeClock
        DS1307RealTimeClock
   
ServoMotor
   
UltrasonicHC_SR04
   
DigitalTemperatureAndHumidity
   
OneWire
    DS18x2x
   
IRRessiver
    BMP085
   
SevenSigmentIndicatorStatic
   
SevenSigmentIndicatorDinamic
   
Chip74HC595
   
EthernetDevice
       
EthernetShild
            ENC28J60EthernetShild
            W5100EthernetShild
        ESP8266WiFiModule
   
SDCardReader



Так что поверте что с композицией я то же умею работать. Просто нельзя зацикливаться на одном патерне, а в каждом конкретном случае надо находить компромис, приносящий оптимальный результат. Кстати как я и говорил раньще если классы тех же блоков отлаживаются один раз и забываются, то и тестировать их нет необходимости. То же касается и моделей железа





вторник, 13 января 2015 г., 17:24:44 UTC+5 пользователь chaetal написал:

13 января 2015 г., 16:16 пользователь Сергей Глушенко <<a href="javascript:" target="_blank" gdf-obfuscated-mailto="hQfybVb2g3QJ" onmousedown="this.href='javascript:';return true;" onclick="this.href='javascript:';return true;">sup...@...> написал:
Вопрос на засыпку. А зачем?

У меня есть штук 5 вариантов ответа на этот вопрос, но наверное будет некорректно влезать перед автором рац. предложения :)

Еще вопрос: метод isCorrect и подобные (я, так понимаю, они есть) с развитием системы уже никогда не будут больше меняться?


--

Best regards,


Dennis Schetinin

--
--
http://groups.google.ru/group/sugr
---
Вы получили это сообщение, поскольку подписаны на группу "Russian Smalltalk User Group".
Чтобы отменить подписку на эту группу и больше не получать от нее сообщения, отправьте письмо на электронный адрес [hidden email].
Чтобы настроить другие параметры, перейдите по ссылке https://groups.google.com/d/optout.
Reply | Threaded
Open this post in threaded view
|

Re: TDD и вообще юнит-тесты in the wild

Сергей Глушенко
In reply to this post by Dennis Schetinin

Пользователь добавив новый блок параметризует его, устанавливает константы, выбирает пины. Проверяется правильность и полноценность параметризации блока. Если блок не корректен то плата на которой он установлен будет отмечена, а так же сам некорректный блок будет отмечен. Кроме того при попытке компиляции проекта  будет выданно сообщение с номерами плат с некорректными блоками и количество некорректных модулей на каждой плате. Соответственно пока весь проект не будет корректен, компиляция производится не будет.
вторник, 13 января 2015 г., 17:27:09 UTC+5 пользователь chaetal написал:

13 января 2015 г., 16:23 пользователь Сергей Глушенко <<a href="javascript:" target="_blank" gdf-obfuscated-mailto="bj2xvRxd-AgJ" onmousedown="this.href='javascript:';return true;" onclick="this.href='javascript:';return true;">sup...@...> написал:
Нигде кроме данного класа они не потребуются.

Ну, это странно. Если они нигде не требуются, кого волнует корректны они или нет?


--

Best regards,


Dennis Schetinin

--
--
http://groups.google.ru/group/sugr
---
Вы получили это сообщение, поскольку подписаны на группу "Russian Smalltalk User Group".
Чтобы отменить подписку на эту группу и больше не получать от нее сообщения, отправьте письмо на электронный адрес [hidden email].
Чтобы настроить другие параметры, перейдите по ссылке https://groups.google.com/d/optout.
Reply | Threaded
Open this post in threaded view
|

Re: TDD и вообще юнит-тесты in the wild

Dennis Schetinin
Я тону в этой информации :)  У меня логика простая: если объект проверяется на корректность, значит где-то еще он будет использоваться. Не говоря уже о том, что где-то он был создан и сконфигурирован пользователем. Соответственно, фраза про то, что этот объект больше нигде и никем не используется вызывает определенные сомнения.


--

Best regards,


Dennis Schetinin


13 января 2015 г., 17:00 пользователь Сергей Глушенко <[hidden email]> написал:

Пользователь добавив новый блок параметризует его, устанавливает константы, выбирает пины. Проверяется правильность и полноценность параметризации блока. Если блок не корректен то плата на которой он установлен будет отмечена, а так же сам некорректный блок будет отмечен. Кроме того при попытке компиляции проекта  будет выданно сообщение с номерами плат с некорректными блоками и количество некорректных модулей на каждой плате. Соответственно пока весь проект не будет корректен, компиляция производится не будет.
вторник, 13 января 2015 г., 17:27:09 UTC+5 пользователь chaetal написал:

13 января 2015 г., 16:23 пользователь Сергей Глушенко <[hidden email]> написал:
Нигде кроме данного класа они не потребуются.

Ну, это странно. Если они нигде не требуются, кого волнует корректны они или нет?


--

Best regards,


Dennis Schetinin

--
--
http://groups.google.ru/group/sugr
---
Вы получили это сообщение, поскольку подписаны на группу "Russian Smalltalk User Group".
Чтобы отменить подписку на эту группу и больше не получать от нее сообщения, отправьте письмо на электронный адрес [hidden email].
Чтобы настроить другие параметры, перейдите по ссылке https://groups.google.com/d/optout.

--
--
http://groups.google.ru/group/sugr
---
Вы получили это сообщение, поскольку подписаны на группу "Russian Smalltalk User Group".
Чтобы отменить подписку на эту группу и больше не получать от нее сообщения, отправьте письмо на электронный адрес [hidden email].
Чтобы настроить другие параметры, перейдите по ссылке https://groups.google.com/d/optout.
Reply | Threaded
Open this post in threaded view
|

Re: TDD и вообще юнит-тесты in the wild

Сергей Глушенко
Наверное я просто плохо бъяснил. Попробую так. Когда я говорю что класс не будет менятся, я имею в виду что не будет менятся его программный код. А isCorrect используется в жизни инстанся при его эксплуатации так сазать. ТО есть когда пользователь нажимает кнопку  "Проверить проект"  выполняется код:

checkProject

   
| errors stream |
    projectFrame ifNil
: [^self].
    errors
:= self currentProject errors.
    errors isEmpty ifTrue
: [^Dialog rusButtonWarn: 'Проект корректен'].
    stream
:= String new writeStream.
    errors
do: [:each | stream nextPutAll: each]
        separatedBy
: [stream nextPut: Character cr].
   
Dialog rusButtonWarn: stream contents



соответственно у проекта
errors

   
^programm errors

 у программы
errors

   
| result |
    result
:= OrderedCollection new.
    networks doWithIndex
:
           
[:each :idx |
            result
                addAll
: (each errors collect:
                           
[:eachError |
                            eachError
                                expandMacrosWithArguments
: (OrderedCollection with: idx printString)])].
   
^result



У платы
errors

   
| notCorrectBlocks result |
    notCorrectBlocks
:= blocks select: [:each | each isCorrect not].
    notCorrectBlocks isEmpty ifTrue
: [^#()].
    result
:= OrderedCollection new.
    result add
: 'На плате №<1s> -  ' , notCorrectBlocks size printString
               
, (notCorrectBlocks size = 1
                        ifTrue
: [' некорректный  блок']
                        ifFalse
:
                           
[notCorrectBlocks size > 4
                                ifTrue
: [' некорректных блоков']
                                ifFalse
: [' некорректных блока']]).
   
^result


вот мы и пришли к тому самому  isCorrect у блока.
конечно у блока то же можно спросить  errors, но мне честно говоря пока не хочется описывать текстом все ошибки параметризации блоков. Будет куча свободного времени займусь этим. Пока пользователи не просят - значит и не надо.





вторник, 13 января 2015 г., 18:18:40 UTC+5 пользователь chaetal написал:
Я тону в этой информации :)  У меня логика простая: если объект проверяется на корректность, значит где-то еще он будет использоваться. Не говоря уже о том, что где-то он был создан и сконфигурирован пользователем. Соответственно, фраза про то, что этот объект больше нигде и никем не используется вызывает определенные сомнения.


--

Best regards,


Dennis Schetinin


13 января 2015 г., 17:00 пользователь Сергей Глушенко <<a href="javascript:" target="_blank" gdf-obfuscated-mailto="2BZ7tZ1rsOQJ" onmousedown="this.href='javascript:';return true;" onclick="this.href='javascript:';return true;">sup...@...> написал:

Пользователь добавив новый блок параметризует его, устанавливает константы, выбирает пины. Проверяется правильность и полноценность параметризации блока. Если блок не корректен то плата на которой он установлен будет отмечена, а так же сам некорректный блок будет отмечен. Кроме того при попытке компиляции проекта  будет выданно сообщение с номерами плат с некорректными блоками и количество некорректных модулей на каждой плате. Соответственно пока весь проект не будет корректен, компиляция производится не будет.
вторник, 13 января 2015 г., 17:27:09 UTC+5 пользователь chaetal написал:

13 января 2015 г., 16:23 пользователь Сергей Глушенко <[hidden email]> написал:
Нигде кроме данного класа они не потребуются.

Ну, это странно. Если они нигде не требуются, кого волнует корректны они или нет?


--

Best regards,


Dennis Schetinin

--
--
<a href="http://groups.google.ru/group/sugr" target="_blank" onmousedown="this.href='http://groups.google.ru/group/sugr';return true;" onclick="this.href='http://groups.google.ru/group/sugr';return true;">http://groups.google.ru/group/sugr
---
Вы получили это сообщение, поскольку подписаны на группу "Russian Smalltalk User Group".
Чтобы отменить подписку на эту группу и больше не получать от нее сообщения, отправьте письмо на электронный адрес <a href="javascript:" target="_blank" gdf-obfuscated-mailto="2BZ7tZ1rsOQJ" onmousedown="this.href='javascript:';return true;" onclick="this.href='javascript:';return true;">sugr+uns...@googlegroups.com.
Чтобы настроить другие параметры, перейдите по ссылке <a href="https://groups.google.com/d/optout" target="_blank" onmousedown="this.href='https://groups.google.com/d/optout';return true;" onclick="this.href='https://groups.google.com/d/optout';return true;">https://groups.google.com/d/optout.

--
--
http://groups.google.ru/group/sugr
---
Вы получили это сообщение, поскольку подписаны на группу "Russian Smalltalk User Group".
Чтобы отменить подписку на эту группу и больше не получать от нее сообщения, отправьте письмо на электронный адрес [hidden email].
Чтобы настроить другие параметры, перейдите по ссылке https://groups.google.com/d/optout.
Reply | Threaded
Open this post in threaded view
|

Re: TDD и вообще юнит-тесты in the wild

Dennis Schetinin
Есть блок. Он корректен. Пользователь установил isUseCountInTimeFunction в false. Где-то это значение будет использовано? Там будет код типа:

block isUseCountInTimeFunction ifTrue: [...] ifFalse: […]

Так?




--

Best regards,


Dennis Schetinin


13 января 2015 г., 17:33 пользователь Сергей Глушенко <[hidden email]> написал:
Наверное я просто плохо бъяснил. Попробую так. Когда я говорю что класс не будет менятся, я имею в виду что не будет менятся его программный код. А isCorrect используется в жизни инстанся при его эксплуатации так сазать. ТО есть когда пользователь нажимает кнопку  "Проверить проект"  выполняется код:

checkProject

   
| errors stream |
    projectFrame ifNil
: [^self].
    errors
:= self currentProject errors.
    errors isEmpty ifTrue
: [^Dialog rusButtonWarn: 'Проект корректен'].
    stream
:= String new writeStream.
    errors
do: [:each | stream nextPutAll: each]
        separatedBy
: [stream nextPut: Character cr].
   
Dialog rusButtonWarn: stream contents



соответственно у проекта
errors

   
^programm errors

 у программы
errors

   
| result |
    result
:= OrderedCollection new.
    networks doWithIndex
:
           
[:each :idx |
            result
                addAll
: (each errors collect:
                           
[:eachError |
                            eachError
                                expandMacrosWithArguments
: (OrderedCollection with: idx printString)])].
   
^result



У платы
errors

   
| notCorrectBlocks result |
    notCorrectBlocks
:= blocks select: [:each | each isCorrect not].
    notCorrectBlocks isEmpty ifTrue
: [^#()].
    result
:= OrderedCollection new.
    result add
: 'На плате №<1s> -  ' , notCorrectBlocks size printString
               
, (notCorrectBlocks size = 1
                        ifTrue
: [' некорректный  блок']
                        ifFalse
:
                           
[notCorrectBlocks size > 4
                                ifTrue
: [' некорректных блоков']
                                ifFalse
: [' некорректных блока']]).
   
^result


вот мы и пришли к тому самому  isCorrect у блока.
конечно у блока то же можно спросить  errors, но мне честно говоря пока не хочется описывать текстом все ошибки параметризации блоков. Будет куча свободного времени займусь этим. Пока пользователи не просят - значит и не надо.





вторник, 13 января 2015 г., 18:18:40 UTC+5 пользователь chaetal написал:
Я тону в этой информации :)  У меня логика простая: если объект проверяется на корректность, значит где-то еще он будет использоваться. Не говоря уже о том, что где-то он был создан и сконфигурирован пользователем. Соответственно, фраза про то, что этот объект больше нигде и никем не используется вызывает определенные сомнения.


--

Best regards,


Dennis Schetinin


13 января 2015 г., 17:00 пользователь Сергей Глушенко <[hidden email]> написал:

Пользователь добавив новый блок параметризует его, устанавливает константы, выбирает пины. Проверяется правильность и полноценность параметризации блока. Если блок не корректен то плата на которой он установлен будет отмечена, а так же сам некорректный блок будет отмечен. Кроме того при попытке компиляции проекта  будет выданно сообщение с номерами плат с некорректными блоками и количество некорректных модулей на каждой плате. Соответственно пока весь проект не будет корректен, компиляция производится не будет.
вторник, 13 января 2015 г., 17:27:09 UTC+5 пользователь chaetal написал:

13 января 2015 г., 16:23 пользователь Сергей Глушенко <[hidden email]> написал:
Нигде кроме данного класа они не потребуются.

Ну, это странно. Если они нигде не требуются, кого волнует корректны они или нет?


--

Best regards,


Dennis Schetinin

--
--
http://groups.google.ru/group/sugr
---
Вы получили это сообщение, поскольку подписаны на группу "Russian Smalltalk User Group".
Чтобы отменить подписку на эту группу и больше не получать от нее сообщения, отправьте письмо на электронный адрес sugr+uns...@googlegroups.com.
Чтобы настроить другие параметры, перейдите по ссылке https://groups.google.com/d/optout.

--
--
http://groups.google.ru/group/sugr
---
Вы получили это сообщение, поскольку подписаны на группу "Russian Smalltalk User Group".
Чтобы отменить подписку на эту группу и больше не получать от нее сообщения, отправьте письмо на электронный адрес [hidden email].
Чтобы настроить другие параметры, перейдите по ссылке https://groups.google.com/d/optout.

--
--
http://groups.google.ru/group/sugr
---
Вы получили это сообщение, поскольку подписаны на группу "Russian Smalltalk User Group".
Чтобы отменить подписку на эту группу и больше не получать от нее сообщения, отправьте письмо на электронный адрес [hidden email].
Чтобы настроить другие параметры, перейдите по ссылке https://groups.google.com/d/optout.
Reply | Threaded
Open this post in threaded view
|

Re: TDD и вообще юнит-тесты in the wild

Сергей Глушенко
Совершенно верно
конкретно так

negativeFrontInterrupFunctionForCountInTimeFunctionWithBlock: aBlock

   
| stream |
    aBlock isUseCountInTimeFunction ifFalse
: [^''].
    stream
:= String new writeStream.
    stream
        nextPutAll
: aBlock declaringImpulseCountName;
        nextPutAll
: '++;';
        nextPut
: Character cr.
   
^stream contents

Это компилятор. ну и естественно на тот метод смотрин холдер  чекбокса на фрейме


вторник, 13 января 2015 г., 19:38:26 UTC+5 пользователь chaetal написал:
Есть блок. Он корректен. Пользователь установил isUseCountInTimeFunction в false. Где-то это значение будет использовано? Там будет код типа:

block isUseCountInTimeFunction ifTrue: [...] ifFalse: […]

Так?




--

Best regards,


Dennis Schetinin


13 января 2015 г., 17:33 пользователь Сергей Глушенко <<a href="javascript:" target="_blank" gdf-obfuscated-mailto="dNknQzE9YK8J" onmousedown="this.href='javascript:';return true;" onclick="this.href='javascript:';return true;">sup...@...> написал:
Наверное я просто плохо бъяснил. Попробую так. Когда я говорю что класс не будет менятся, я имею в виду что не будет менятся его программный код. А isCorrect используется в жизни инстанся при его эксплуатации так сазать. ТО есть когда пользователь нажимает кнопку  "Проверить проект"  выполняется код:

checkProject

   
| errors stream |
    projectFrame ifNil
: [^self].
    errors
:= self currentProject errors.
    errors isEmpty ifTrue
: [^Dialog rusButtonWarn: 'Проект корректен'].
    stream
:= String new writeStream.
    errors
do: [:each | stream nextPutAll: each]
        separatedBy
: [stream nextPut: Character cr].
   
Dialog rusButtonWarn: stream contents



соответственно у проекта
errors

   
^programm errors

 у программы
errors

   
| result |
    result
:= OrderedCollection new.
    networks doWithIndex
:
           
[:each :idx |
            result
                addAll
: (each errors collect:
                           
[:eachError |
                            eachError
                                expandMacrosWithArguments
: (OrderedCollection with: idx printString)])].
   
^result



У платы
errors

   
| notCorrectBlocks result |
    notCorrectBlocks
:= blocks select: [:each | each isCorrect not].
    notCorrectBlocks isEmpty ifTrue
: [^#()].
    result
:= OrderedCollection new.
    result add
: 'На плате №<1s> -  ' , notCorrectBlocks size printString
               
, (notCorrectBlocks size = 1
                        ifTrue
: [' некорректный  блок']
                        ifFalse
:
                           
[notCorrectBlocks size > 4
                                ifTrue
: [' некорректных блоков']
                                ifFalse
: [' некорректных блока']]).
   
^result


вот мы и пришли к тому самому  isCorrect у блока.
конечно у блока то же можно спросить  errors, но мне честно говоря пока не хочется описывать текстом все ошибки параметризации блоков. Будет куча свободного времени займусь этим. Пока пользователи не просят - значит и не надо.





вторник, 13 января 2015 г., 18:18:40 UTC+5 пользователь chaetal написал:
Я тону в этой информации :)  У меня логика простая: если объект проверяется на корректность, значит где-то еще он будет использоваться. Не говоря уже о том, что где-то он был создан и сконфигурирован пользователем. Соответственно, фраза про то, что этот объект больше нигде и никем не используется вызывает определенные сомнения.


--

Best regards,


Dennis Schetinin


13 января 2015 г., 17:00 пользователь Сергей Глушенко <[hidden email]> написал:

Пользователь добавив новый блок параметризует его, устанавливает константы, выбирает пины. Проверяется правильность и полноценность параметризации блока. Если блок не корректен то плата на которой он установлен будет отмечена, а так же сам некорректный блок будет отмечен. Кроме того при попытке компиляции проекта  будет выданно сообщение с номерами плат с некорректными блоками и количество некорректных модулей на каждой плате. Соответственно пока весь проект не будет корректен, компиляция производится не будет.
вторник, 13 января 2015 г., 17:27:09 UTC+5 пользователь chaetal написал:

13 января 2015 г., 16:23 пользователь Сергей Глушенко <[hidden email]> написал:
Нигде кроме данного класа они не потребуются.

Ну, это странно. Если они нигде не требуются, кого волнует корректны они или нет?


--

Best regards,


Dennis Schetinin

--
--
<a href="http://groups.google.ru/group/sugr" target="_blank" onmousedown="this.href='http://groups.google.ru/group/sugr';return true;" onclick="this.href='http://groups.google.ru/group/sugr';return true;">http://groups.google.ru/group/sugr
---
Вы получили это сообщение, поскольку подписаны на группу "Russian Smalltalk User Group".
Чтобы отменить подписку на эту группу и больше не получать от нее сообщения, отправьте письмо на электронный адрес sugr+uns...@googlegroups.com.
Чтобы настроить другие параметры, перейдите по ссылке <a href="https://groups.google.com/d/optout" target="_blank" onmousedown="this.href='https://groups.google.com/d/optout';return true;" onclick="this.href='https://groups.google.com/d/optout';return true;">https://groups.google.com/d/optout.

--
--
<a href="http://groups.google.ru/group/sugr" target="_blank" onmousedown="this.href='http://groups.google.ru/group/sugr';return true;" onclick="this.href='http://groups.google.ru/group/sugr';return true;">http://groups.google.ru/group/sugr
---
Вы получили это сообщение, поскольку подписаны на группу "Russian Smalltalk User Group".
Чтобы отменить подписку на эту группу и больше не получать от нее сообщения, отправьте письмо на электронный адрес <a href="javascript:" target="_blank" gdf-obfuscated-mailto="dNknQzE9YK8J" onmousedown="this.href='javascript:';return true;" onclick="this.href='javascript:';return true;">sugr+uns...@googlegroups.com.
Чтобы настроить другие параметры, перейдите по ссылке <a href="https://groups.google.com/d/optout" target="_blank" onmousedown="this.href='https://groups.google.com/d/optout';return true;" onclick="this.href='https://groups.google.com/d/optout';return true;">https://groups.google.com/d/optout.

--
--
http://groups.google.ru/group/sugr
---
Вы получили это сообщение, поскольку подписаны на группу "Russian Smalltalk User Group".
Чтобы отменить подписку на эту группу и больше не получать от нее сообщения, отправьте письмо на электронный адрес [hidden email].
Чтобы настроить другие параметры, перейдите по ссылке https://groups.google.com/d/optout.
Reply | Threaded
Open this post in threaded view
|

Re: TDD и вообще юнит-тесты in the wild

Сергей Глушенко
Ну все для меня на сегодня дебаты закончены. Смена кончилась - поехал в общагу. Там интернет мобильный, то есть никакой. Почитать Ваши сообщения смогу, отвечу утром .

вторник, 13 января 2015 г., 19:44:39 UTC+5 пользователь Сергей Глушенко написал:
Совершенно верно
конкретно так

negativeFrontInterrupFunctionForCountInTimeFunctionWithBlock: aBlock

   
| stream |
    aBlock isUseCountInTimeFunction ifFalse
: [^''].
    stream
:= String new writeStream.
    stream
        nextPutAll
: aBlock declaringImpulseCountName;
        nextPutAll
: '++;';
        nextPut
: Character cr.
   
^stream contents

Это компилятор. ну и естественно на тот метод смотрин холдер  чекбокса на фрейме


вторник, 13 января 2015 г., 19:38:26 UTC+5 пользователь chaetal написал:
Есть блок. Он корректен. Пользователь установил isUseCountInTimeFunction в false. Где-то это значение будет использовано? Там будет код типа:

block isUseCountInTimeFunction ifTrue: [...] ifFalse: […]

Так?




--

Best regards,


Dennis Schetinin


13 января 2015 г., 17:33 пользователь Сергей Глушенко <[hidden email]> написал:
Наверное я просто плохо бъяснил. Попробую так. Когда я говорю что класс не будет менятся, я имею в виду что не будет менятся его программный код. А isCorrect используется в жизни инстанся при его эксплуатации так сазать. ТО есть когда пользователь нажимает кнопку  "Проверить проект"  выполняется код:

checkProject

   
| errors stream |
    projectFrame ifNil
: [^self].
    errors
:= self currentProject errors.
    errors isEmpty ifTrue
: [^Dialog rusButtonWarn: 'Проект корректен'].
    stream
:= String new writeStream.
    errors
do: [:each | stream nextPutAll: each]
        separatedBy
: [stream nextPut: Character cr].
   
Dialog rusButtonWarn: stream contents



соответственно у проекта
errors

   
^programm errors

 у программы
errors

   
| result |
    result
:= OrderedCollection new.
    networks doWithIndex
:
           
[:each :idx |
            result
                addAll
: (each errors collect:
                           
[:eachError |
                            eachError
                                expandMacrosWithArguments
: (OrderedCollection with: idx printString)])].
   
^result



У платы
errors

   
| notCorrectBlocks result |
    notCorrectBlocks
:= blocks select: [:each | each isCorrect not].
    notCorrectBlocks isEmpty ifTrue
: [^#()].
    result
:= OrderedCollection new.
    result add
: 'На плате №<1s> -  ' , notCorrectBlocks size printString
               
, (notCorrectBlocks size = 1
                        ifTrue
: [' некорректный  блок']
                        ifFalse
:
                           
[notCorrectBlocks size > 4
                                ifTrue
: [' некорректных блоков']
                                ifFalse
: [' некорректных блока']]).
   
^result


вот мы и пришли к тому самому  isCorrect у блока.
конечно у блока то же можно спросить  errors, но мне честно говоря пока не хочется описывать текстом все ошибки параметризации блоков. Будет куча свободного времени займусь этим. Пока пользователи не просят - значит и не надо.





вторник, 13 января 2015 г., 18:18:40 UTC+5 пользователь chaetal написал:
Я тону в этой информации :)  У меня логика простая: если объект проверяется на корректность, значит где-то еще он будет использоваться. Не говоря уже о том, что где-то он был создан и сконфигурирован пользователем. Соответственно, фраза про то, что этот объект больше нигде и никем не используется вызывает определенные сомнения.


--

Best regards,


Dennis Schetinin


13 января 2015 г., 17:00 пользователь Сергей Глушенко <[hidden email]> написал:

Пользователь добавив новый блок параметризует его, устанавливает константы, выбирает пины. Проверяется правильность и полноценность параметризации блока. Если блок не корректен то плата на которой он установлен будет отмечена, а так же сам некорректный блок будет отмечен. Кроме того при попытке компиляции проекта  будет выданно сообщение с номерами плат с некорректными блоками и количество некорректных модулей на каждой плате. Соответственно пока весь проект не будет корректен, компиляция производится не будет.
вторник, 13 января 2015 г., 17:27:09 UTC+5 пользователь chaetal написал:

13 января 2015 г., 16:23 пользователь Сергей Глушенко <[hidden email]> написал:
Нигде кроме данного класа они не потребуются.

Ну, это странно. Если они нигде не требуются, кого волнует корректны они или нет?


--

Best regards,


Dennis Schetinin

--
--
<a href="http://groups.google.ru/group/sugr" target="_blank" onmousedown="this.href='http://groups.google.ru/group/sugr';return true;" onclick="this.href='http://groups.google.ru/group/sugr';return true;">http://groups.google.ru/group/sugr
---
Вы получили это сообщение, поскольку подписаны на группу "Russian Smalltalk User Group".
Чтобы отменить подписку на эту группу и больше не получать от нее сообщения, отправьте письмо на электронный адрес sugr+uns...@googlegroups.com.
Чтобы настроить другие параметры, перейдите по ссылке <a href="https://groups.google.com/d/optout" target="_blank" onmousedown="this.href='https://groups.google.com/d/optout';return true;" onclick="this.href='https://groups.google.com/d/optout';return true;">https://groups.google.com/d/optout.

--
--
<a href="http://groups.google.ru/group/sugr" target="_blank" onmousedown="this.href='http://groups.google.ru/group/sugr';return true;" onclick="this.href='http://groups.google.ru/group/sugr';return true;">http://groups.google.ru/group/sugr
---
Вы получили это сообщение, поскольку подписаны на группу "Russian Smalltalk User Group".
Чтобы отменить подписку на эту группу и больше не получать от нее сообщения, отправьте письмо на электронный адрес [hidden email].
Чтобы настроить другие параметры, перейдите по ссылке <a href="https://groups.google.com/d/optout" target="_blank" onmousedown="this.href='https://groups.google.com/d/optout';return true;" onclick="this.href='https://groups.google.com/d/optout';return true;">https://groups.google.com/d/optout.

--
--
http://groups.google.ru/group/sugr
---
Вы получили это сообщение, поскольку подписаны на группу "Russian Smalltalk User Group".
Чтобы отменить подписку на эту группу и больше не получать от нее сообщения, отправьте письмо на электронный адрес [hidden email].
Чтобы настроить другие параметры, перейдите по ссылке https://groups.google.com/d/optout.
Reply | Threaded
Open this post in threaded view
|

Re: TDD и вообще юнит-тесты in the wild

Dennis Schetinin

13 января 2015 г., 19:00 пользователь Сергей Глушенко <[hidden email]> написал:
Ну все для меня на сегодня дебаты закончены.

"Вот так всегда: на самом интересном месте!" (с)


Но мы, собственно, почти закончили — нашли сущность, имеющую следующую функциональность:
- показывает себя и позволяет пользователю задавать свое состояние
- проверяет корректность своего состояния
- "компилирует" себя

В общем-то, это все стандартно. Сейчас эта функциональность (опять же, стандартным образом) "размазана". Это приводит к многократному дублированию. О последствиях этого уже много написано в умных книгах умными людьми. …Но если есть желание испытать это на собственном опыте до/после/вместо прочтения этих самых книг — никто помешать не сможет :)

--

Best regards,


Dennis Schetinin

--
--
http://groups.google.ru/group/sugr
---
Вы получили это сообщение, поскольку подписаны на группу "Russian Smalltalk User Group".
Чтобы отменить подписку на эту группу и больше не получать от нее сообщения, отправьте письмо на электронный адрес [hidden email].
Чтобы настроить другие параметры, перейдите по ссылке https://groups.google.com/d/optout.
Reply | Threaded
Open this post in threaded view
|

Re: TDD и вообще юнит-тесты in the wild

Сергей Глушенко
Ну вы почти полностью описали функционал класса AbstractBlock являющегося родителем для всех остальных блоков. Каждый блок умеет правильно показываться пользователю для своей параметризации. То есть каждый блок знает свой фрейм параметризации и является для него моделью. Он сам рисуется на нужном месте (у него реализован метод displayOn:.  У некоторых блоков в иерархии он перекрыт если нужна нестандартная отрисовка). Каждый блок контролирует корректность своего заполнеия. Все совершенно академически. А где Вы увидали размазаность?
Единственное место где она возможна, это компиляция. Блок не умеет сам компилироваться. Это сделанно сознательно. Проект изначально создавался под возможность подключения различных компиляторов. Поэтому блоки ничего не знают о компиляторе, а только умеют правильно отвечать на его вопросы. Дело в том что в принципе все контроллеры на сегодняшний день программируются либо на С либо на его переделанных вариантах. Язык Wiring который используется в Ардуино - это тот же С с добавление синтаксического сахара и с некоторыми встроенными специализированными функциями которых нет в чистом С.  Соответственно базовый синтаксис у всех одинаковый. О вещах которые связаны с базовым синтаксисом блоки знают. Но с другой стороны структура программы, использование библиотек , специлизированные функциии отличаются не только для разных микроконтроллеров, но и даже для различных плат ардуино. О все этом знает компилятор. Поэтому при прибавлении поддержки нового контроллера мне необходимо только добавить новый класс компилятора и использовать его при компиляции. О необходимом классе компилятора знает модель - описатель контроллера которая хранится в проекте. При необходимости единственное что может потребоваться от блоков - дописать дополнительные интерфейсы для ответа новому компилятору если существующих интерфейсов будет не хватать. Как раз скоро мне предстоит опробовать данную систему в боевых условиях добавления поддержки принципиально новых контроллеров. в качестве основной среды для разрабатывания. Там вообще PIC. Ну наверное больше о компиляторе рассказывать ничего не буде.Все таки компилятор это мое ноу - хау
вторник, 13 января 2015 г., 20:16:14 UTC+5 пользователь chaetal написал:

13 января 2015 г., 19:00 пользователь Сергей Глушенко <<a href="javascript:" target="_blank" gdf-obfuscated-mailto="-YaLQyUMpt0J" onmousedown="this.href='javascript:';return true;" onclick="this.href='javascript:';return true;">sup...@...> написал:
Ну все для меня на сегодня дебаты закончены.

"Вот так всегда: на самом интересном месте!" (с)


Но мы, собственно, почти закончили — нашли сущность, имеющую следующую функциональность:
- показывает себя и позволяет пользователю задавать свое состояние
- проверяет корректность своего состояния
- "компилирует" себя

В общем-то, это все стандартно. Сейчас эта функциональность (опять же, стандартным образом) "размазана". Это приводит к многократному дублированию. О последствиях этого уже много написано в умных книгах умными людьми. …Но если есть желание испытать это на собственном опыте до/после/вместо прочтения этих самых книг — никто помешать не сможет :)

--

Best regards,


Dennis Schetinin

--
--
http://groups.google.ru/group/sugr
---
Вы получили это сообщение, поскольку подписаны на группу "Russian Smalltalk User Group".
Чтобы отменить подписку на эту группу и больше не получать от нее сообщения, отправьте письмо на электронный адрес [hidden email].
Чтобы настроить другие параметры, перейдите по ссылке https://groups.google.com/d/optout.
Reply | Threaded
Open this post in threaded view
|

Re: TDD и вообще юнит-тесты in the wild

Dennis Schetinin

14 января 2015 г., 10:34 пользователь Сергей Глушенко <[hidden email]> написал:
А где Вы увидали размазаность?

Внутри блока я увидел компоненты с указанной функциональностью. (Если она совпадает с функциональностью всего блока — есть повод задуматься.) Только в отличие от блока эта функциональность реализована неявно и не в этих компонентах, а в методах других классов (блоков и м.б. чего-то еще?).

Из-за этой размазанности как раз возникают и проблемы с пониманием типа "а как и что тут тестировать?!". Очень знакомая ситуация, на самом деле.


--

Best regards,


Dennis Schetinin

--
--
http://groups.google.ru/group/sugr
---
Вы получили это сообщение, поскольку подписаны на группу "Russian Smalltalk User Group".
Чтобы отменить подписку на эту группу и больше не получать от нее сообщения, отправьте письмо на электронный адрес [hidden email].
Чтобы настроить другие параметры, перейдите по ссылке https://groups.google.com/d/optout.
Reply | Threaded
Open this post in threaded view
|

Re: TDD и вообще юнит-тесты in the wild

Сергей Глушенко
Естественно внутри блока есть другие сущности которые то же умеют все это делать. Например входы отрисовывают себя сами в указанном ими блоком  месте. Устройства лежащие внутри некоторых блоков имеют свои субфреймы позволяющие их парамерировать. В этом случае блок просто спрашивает у устройства какой фрейм отрисовать на соответвующей субканве создает данный фрейм и отдаее ему устройство в качестве модели. Так же устройство само тестирует правильность своей параметризации. Естественно одноименный функционал разных сущностей не дублирует друг друга. Выход рисуется не так как блок, ну а устройство имеет совершенно другой набор бараметров чем блок. Да и разные устройства которые могут присутствовать в одном блоке чаще всего отличаются набором параметров а иногда и поведением. Например EthernetShild и WifiShield абсолютно отличаются друг от друга, но при этом на базе каждого из них можно построить вэб сервер или вэб клиент. Получается что каждый класс имеет свою собственную законченную функциональность. Я опять не вижу размазанности. Каждый из них знает и умеет то что ему нужно и ничего лишнего. Например зачем блоку знать IP адрес карты на котором установлен сервер. Если его об этом спросит компилятор он спросит об этом устройство.

среда, 14 января 2015 г., 12:14:37 UTC+5 пользователь chaetal написал:

14 января 2015 г., 10:34 пользователь Сергей Глушенко <<a href="javascript:" target="_blank" gdf-obfuscated-mailto="1-fNZ8vFCcMJ" onmousedown="this.href='javascript:';return true;" onclick="this.href='javascript:';return true;">sup...@...> написал:
А где Вы увидали размазаность?

Внутри блока я увидел компоненты с указанной функциональностью. (Если она совпадает с функциональностью всего блока — есть повод задуматься.) Только в отличие от блока эта функциональность реализована неявно и не в этих компонентах, а в методах других классов (блоков и м.б. чего-то еще?).

Из-за этой размазанности как раз возникают и проблемы с пониманием типа "а как и что тут тестировать?!". Очень знакомая ситуация, на самом деле.


--

Best regards,


Dennis Schetinin

--
--
http://groups.google.ru/group/sugr
---
Вы получили это сообщение, поскольку подписаны на группу "Russian Smalltalk User Group".
Чтобы отменить подписку на эту группу и больше не получать от нее сообщения, отправьте письмо на электронный адрес [hidden email].
Чтобы настроить другие параметры, перейдите по ссылке https://groups.google.com/d/optout.
Reply | Threaded
Open this post in threaded view
|

Re: TDD и вообще юнит-тесты in the wild

Сергей Глушенко
Я тут немного оговорился и что бы избежать ненужных воросов сразу поправлюсь.

блок просто спрашивает у устройства какой фрейм отрисовать на соответвующей субканве создает данный фрейм и отдаее ему устройство в качестве модели

немного не так. Блок не занимается отрисовкой фрейма. Конечно же фрейм блока  знает о своих субфреймах и спрашивает у блока  устройство. И фрейм - же создает субфрейм кладет себе в переменную и передает взятое у блоке устройство субфрейму в качестве модели.

среда, 14 января 2015 г., 12:55:50 UTC+5 пользователь Сергей Глушенко написал:
Естественно внутри блока есть другие сущности которые то же умеют все это делать. Например входы отрисовывают себя сами в указанном ими блоком  месте. Устройства лежащие внутри некоторых блоков имеют свои субфреймы позволяющие их парамерировать. В этом случае блок просто спрашивает у устройства какой фрейм отрисовать на соответвующей субканве создает данный фрейм и отдаее ему устройство в качестве модели. Так же устройство само тестирует правильность своей параметризации. Естественно одноименный функционал разных сущностей не дублирует друг друга. Выход рисуется не так как блок, ну а устройство имеет совершенно другой набор бараметров чем блок. Да и разные устройства которые могут присутствовать в одном блоке чаще всего отличаются набором параметров а иногда и поведением. Например EthernetShild и WifiShield абсолютно отличаются друг от друга, но при этом на базе каждого из них можно построить вэб сервер или вэб клиент. Получается что каждый класс имеет свою собственную законченную функциональность. Я опять не вижу размазанности. Каждый из них знает и умеет то что ему нужно и ничего лишнего. Например зачем блоку знать IP адрес карты на котором установлен сервер. Если его об этом спросит компилятор он спросит об этом устройство.

среда, 14 января 2015 г., 12:14:37 UTC+5 пользователь chaetal написал:

14 января 2015 г., 10:34 пользователь Сергей Глушенко <[hidden email]> написал:
А где Вы увидали размазаность?

Внутри блока я увидел компоненты с указанной функциональностью. (Если она совпадает с функциональностью всего блока — есть повод задуматься.) Только в отличие от блока эта функциональность реализована неявно и не в этих компонентах, а в методах других классов (блоков и м.б. чего-то еще?).

Из-за этой размазанности как раз возникают и проблемы с пониманием типа "а как и что тут тестировать?!". Очень знакомая ситуация, на самом деле.


--

Best regards,


Dennis Schetinin

--
--
http://groups.google.ru/group/sugr
---
Вы получили это сообщение, поскольку подписаны на группу "Russian Smalltalk User Group".
Чтобы отменить подписку на эту группу и больше не получать от нее сообщения, отправьте письмо на электронный адрес [hidden email].
Чтобы настроить другие параметры, перейдите по ссылке https://groups.google.com/d/optout.
1234